diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-29 12:41:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-01-29 12:41:47 -0500 |
commit | 1c1f395b2873f59830979cf82324fbf00edfb80c (patch) | |
tree | e84c9b53a4d4bdb91ec9f4f5c059dc38dad21c76 | |
parent | 49f9c3552ccc30f4f98c45d94d7f9b335596913f (diff) | |
parent | 1c9609e3a8cf5997bd35205cfda1ff2218ee793b (diff) |
Merge tag 'sound-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai:
"The major changes in the core API side in this cycle are the still
on-going ASoC componentization works. Other than that, only few small
changes such as 20bit PCM format support are found.
Meanwhile the rest majority of changes are for ASoC drivers:
- Large cleanups of some of the TI CODEC drivers
- Continued work on Intel ASoC stuff for new quirks, ACPI GPIO
handling, Kconfigs and lots of cleanups
- Refactoring of the Freescale SSI driver, as preliminary work for
the upcoming changes
- Work on ST DFSDM driver, including the required IIO patches
- New drivers for Allwinner A83T, Maxim MAX89373, SocioNext UiniPhier
EVEA Tempo Semiconductor TSCS42xx and TI PCM816x, TAS5722 and
TAS6424 devices
- Removal of dead codes for SN95031 and board drivers
Last but not least, a few HD-audio and USB-audio quirks are included
as usual, too"
* tag 'sound-4.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (303 commits)
ALSA: hda - Reduce the suspend time consumption for ALC256
ASoC: use seq_file to dump the contents of dai_list,platform_list and codec_list
ASoC: soc-core: add missing EXPORT_SYMBOL_GPL() for snd_soc_rtdcom_lookup
IIO: ADC: stm32-dfsdm: remove unused variable again
ASoC: bcm2835: fix hw_params error when device is in prepared state
ASoC: mxs-sgtl5000: Do not print error on probe deferral
ASoC: sgtl5000: Do not print error on probe deferral
ASoC: Intel: remove select on non-existing SND_SOC_INTEL_COMMON
ALSA: usb-audio: Support changing input on Sound Blaster E1
ASoC: Intel: remove second duplicated assignment to pointer 'res'
ALSA: hda/realtek - update ALC215 depop optimize
ALSA: hda/realtek - Support headset mode for ALC215/ALC285/ALC289
ALSA: pcm: Fix trailing semicolon
ASoC: add Component level .read/.write
ASoC: cx20442: fix regression by adding back .read/.write
ASoC: uda1380: fix regression by adding back .read/.write
ASoC: tlv320dac33: fix regression by adding back .read/.write
ALSA: hda - Use IS_REACHABLE() for dependency on input
IIO: ADC: stm32-dfsdm: fix static check warning
IIO: ADC: stm32-dfsdm: code optimization
...
231 files changed, 15768 insertions, 5278 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32 b/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32 new file mode 100644 index 000000000000..da9822309f07 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-iio-dfsdm-adc-stm32 | |||
@@ -0,0 +1,16 @@ | |||
1 | What: /sys/bus/iio/devices/iio:deviceX/in_voltage_spi_clk_freq | ||
2 | KernelVersion: 4.14 | ||
3 | Contact: arnaud.pouliquen@st.com | ||
4 | Description: | ||
5 | For audio purpose only. | ||
6 | Used by audio driver to set/get the spi input frequency. | ||
7 | This is mandatory if DFSDM is slave on SPI bus, to | ||
8 | provide information on the SPI clock frequency during runtime | ||
9 | Notice that the SPI frequency should be a multiple of sample | ||
10 | frequency to ensure the precision. | ||
11 | if DFSDM input is SPI master | ||
12 | Reading SPI clkout frequency, | ||
13 | error on writing | ||
14 | If DFSDM input is SPI Slave: | ||
15 | Reading returns value previously set. | ||
16 | Writing value before starting conversions. \ No newline at end of file | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt new file mode 100644 index 000000000000..e9ebb8a20e0d --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/sigma-delta-modulator.txt | |||
@@ -0,0 +1,13 @@ | |||
1 | Device-Tree bindings for sigma delta modulator | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "ads1201", "sd-modulator". "sd-modulator" can be use | ||
5 | as a generic SD modulator if modulator not specified in compatible list. | ||
6 | - #io-channel-cells = <1>: See the IIO bindings section "IIO consumers". | ||
7 | |||
8 | Example node: | ||
9 | |||
10 | ads1202: adc@0 { | ||
11 | compatible = "sd-modulator"; | ||
12 | #io-channel-cells = <1>; | ||
13 | }; | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt new file mode 100644 index 000000000000..911492da48f3 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.txt | |||
@@ -0,0 +1,128 @@ | |||
1 | STMicroelectronics STM32 DFSDM ADC device driver | ||
2 | |||
3 | |||
4 | STM32 DFSDM ADC is a sigma delta analog-to-digital converter dedicated to | ||
5 | interface external sigma delta modulators to STM32 micro controllers. | ||
6 | It is mainly targeted for: | ||
7 | - Sigma delta modulators (motor control, metering...) | ||
8 | - PDM microphones (audio digital microphone) | ||
9 | |||
10 | It features up to 8 serial digital interfaces (SPI or Manchester) and | ||
11 | up to 4 filters on stm32h7. | ||
12 | |||
13 | Each child node match with a filter instance. | ||
14 | |||
15 | Contents of a STM32 DFSDM root node: | ||
16 | ------------------------------------ | ||
17 | Required properties: | ||
18 | - compatible: Should be "st,stm32h7-dfsdm". | ||
19 | - reg: Offset and length of the DFSDM block register set. | ||
20 | - clocks: IP and serial interfaces clocking. Should be set according | ||
21 | to rcc clock ID and "clock-names". | ||
22 | - clock-names: Input clock name "dfsdm" must be defined, | ||
23 | "audio" is optional. If defined CLKOUT is based on the audio | ||
24 | clock, else "dfsdm" is used. | ||
25 | - #interrupt-cells = <1>; | ||
26 | - #address-cells = <1>; | ||
27 | - #size-cells = <0>; | ||
28 | |||
29 | Optional properties: | ||
30 | - spi-max-frequency: Requested only for SPI master mode. | ||
31 | SPI clock OUT frequency (Hz). This clock must be set according | ||
32 | to "clock" property. Frequency must be a multiple of the rcc | ||
33 | clock frequency. If not, SPI CLKOUT frequency will not be | ||
34 | accurate. | ||
35 | |||
36 | Contents of a STM32 DFSDM child nodes: | ||
37 | -------------------------------------- | ||
38 | |||
39 | Required properties: | ||
40 | - compatible: Must be: | ||
41 | "st,stm32-dfsdm-adc" for sigma delta ADCs | ||
42 | "st,stm32-dfsdm-dmic" for audio digital microphone. | ||
43 | - reg: Specifies the DFSDM filter instance used. | ||
44 | - interrupts: IRQ lines connected to each DFSDM filter instance. | ||
45 | - st,adc-channels: List of single-ended channels muxed for this ADC. | ||
46 | valid values: | ||
47 | "st,stm32h7-dfsdm" compatibility: 0 to 7. | ||
48 | - st,adc-channel-names: List of single-ended channel names. | ||
49 | - st,filter-order: SinC filter order from 0 to 5. | ||
50 | 0: FastSinC | ||
51 | [1-5]: order 1 to 5. | ||
52 | For audio purpose it is recommended to use order 3 to 5. | ||
53 | - #io-channel-cells = <1>: See the IIO bindings section "IIO consumers". | ||
54 | |||
55 | Required properties for "st,stm32-dfsdm-adc" compatibility: | ||
56 | - io-channels: From common IIO binding. Used to pipe external sigma delta | ||
57 | modulator or internal ADC output to DFSDM channel. | ||
58 | This is not required for "st,stm32-dfsdm-pdm" compatibility as | ||
59 | PDM microphone is binded in Audio DT node. | ||
60 | |||
61 | Required properties for "st,stm32-dfsdm-pdm" compatibility: | ||
62 | - #sound-dai-cells: Must be set to 0. | ||
63 | - dma: DMA controller phandle and DMA request line associated to the | ||
64 | filter instance (specified by the field "reg") | ||
65 | - dma-names: Must be "rx" | ||
66 | |||
67 | Optional properties: | ||
68 | - st,adc-channel-types: Single-ended channel input type. | ||
69 | - "SPI_R": SPI with data on rising edge (default) | ||
70 | - "SPI_F": SPI with data on falling edge | ||
71 | - "MANCH_R": manchester codec, rising edge = logic 0 | ||
72 | - "MANCH_F": manchester codec, falling edge = logic 1 | ||
73 | - st,adc-channel-clk-src: Conversion clock source. | ||
74 | - "CLKIN": external SPI clock (CLKIN x) | ||
75 | - "CLKOUT": internal SPI clock (CLKOUT) (default) | ||
76 | - "CLKOUT_F": internal SPI clock divided by 2 (falling edge). | ||
77 | - "CLKOUT_R": internal SPI clock divided by 2 (rising edge). | ||
78 | |||
79 | - st,adc-alt-channel: Must be defined if two sigma delta modulator are | ||
80 | connected on same SPI input. | ||
81 | If not set, channel n is connected to SPI input n. | ||
82 | If set, channel n is connected to SPI input n + 1. | ||
83 | |||
84 | - st,filter0-sync: Set to 1 to synchronize with DFSDM filter instance 0. | ||
85 | Used for multi microphones synchronization. | ||
86 | |||
87 | Example of a sigma delta adc connected on DFSDM SPI port 0 | ||
88 | and a pdm microphone connected on DFSDM SPI port 1: | ||
89 | |||
90 | ads1202: simple_sd_adc@0 { | ||
91 | compatible = "ads1202"; | ||
92 | #io-channel-cells = <1>; | ||
93 | }; | ||
94 | |||
95 | dfsdm: dfsdm@40017000 { | ||
96 | compatible = "st,stm32h7-dfsdm"; | ||
97 | reg = <0x40017000 0x400>; | ||
98 | clocks = <&rcc DFSDM1_CK>; | ||
99 | clock-names = "dfsdm"; | ||
100 | #interrupt-cells = <1>; | ||
101 | #address-cells = <1>; | ||
102 | #size-cells = <0>; | ||
103 | |||
104 | dfsdm_adc0: filter@0 { | ||
105 | compatible = "st,stm32-dfsdm-adc"; | ||
106 | #io-channel-cells = <1>; | ||
107 | reg = <0>; | ||
108 | interrupts = <110>; | ||
109 | st,adc-channels = <0>; | ||
110 | st,adc-channel-names = "sd_adc0"; | ||
111 | st,adc-channel-types = "SPI_F"; | ||
112 | st,adc-channel-clk-src = "CLKOUT"; | ||
113 | io-channels = <&ads1202 0>; | ||
114 | st,filter-order = <3>; | ||
115 | }; | ||
116 | dfsdm_pdm1: filter@1 { | ||
117 | compatible = "st,stm32-dfsdm-dmic"; | ||
118 | reg = <1>; | ||
119 | interrupts = <111>; | ||
120 | dmas = <&dmamux1 102 0x400 0x00>; | ||
121 | dma-names = "rx"; | ||
122 | st,adc-channels = <1>; | ||
123 | st,adc-channel-names = "dmic1"; | ||
124 | st,adc-channel-types = "SPI_R"; | ||
125 | st,adc-channel-clk-src = "CLKOUT"; | ||
126 | st,filter-order = <5>; | ||
127 | }; | ||
128 | } | ||
diff --git a/Documentation/devicetree/bindings/sound/dmic.txt b/Documentation/devicetree/bindings/sound/dmic.txt index 54c8ef6498a8..f7bf65611453 100644 --- a/Documentation/devicetree/bindings/sound/dmic.txt +++ b/Documentation/devicetree/bindings/sound/dmic.txt | |||
@@ -7,10 +7,12 @@ Required properties: | |||
7 | 7 | ||
8 | Optional properties: | 8 | Optional properties: |
9 | - dmicen-gpios: GPIO specifier for dmic to control start and stop | 9 | - dmicen-gpios: GPIO specifier for dmic to control start and stop |
10 | - num-channels: Number of microphones on this DAI | ||
10 | 11 | ||
11 | Example node: | 12 | Example node: |
12 | 13 | ||
13 | dmic_codec: dmic@0 { | 14 | dmic_codec: dmic@0 { |
14 | compatible = "dmic-codec"; | 15 | compatible = "dmic-codec"; |
15 | dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; | 16 | dmicen-gpios = <&gpio4 3 GPIO_ACTIVE_HIGH>; |
17 | num-channels = <1>; | ||
16 | }; | 18 | }; |
diff --git a/Documentation/devicetree/bindings/sound/max98373.txt b/Documentation/devicetree/bindings/sound/max98373.txt new file mode 100644 index 000000000000..456cb1c59353 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98373.txt | |||
@@ -0,0 +1,40 @@ | |||
1 | Maxim Integrated MAX98373 Speaker Amplifier | ||
2 | |||
3 | This device supports I2C. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "maxim,max98373" | ||
8 | |||
9 | - reg : the I2C address of the device. | ||
10 | |||
11 | Optional properties: | ||
12 | |||
13 | - maxim,vmon-slot-no : slot number used to send voltage information | ||
14 | or in inteleave mode this will be used as | ||
15 | interleave slot. | ||
16 | slot range : 0 ~ 15, Default : 0 | ||
17 | |||
18 | - maxim,imon-slot-no : slot number used to send current information | ||
19 | slot range : 0 ~ 15, Default : 0 | ||
20 | |||
21 | - maxim,spkfb-slot-no : slot number used to send speaker feedback information | ||
22 | slot range : 0 ~ 15, Default : 0 | ||
23 | |||
24 | - maxim,interleave-mode : For cases where a single combined channel | ||
25 | for the I/V sense data is not sufficient, the device can also be configured | ||
26 | to share a single data output channel on alternating frames. | ||
27 | In this configuration, the current and voltage data will be frame interleaved | ||
28 | on a single output channel. | ||
29 | Boolean, define to enable the interleave mode, Default : false | ||
30 | |||
31 | Example: | ||
32 | |||
33 | codec: max98373@31 { | ||
34 | compatible = "maxim,max98373"; | ||
35 | reg = <0x31>; | ||
36 | maxim,vmon-slot-no = <0>; | ||
37 | maxim,imon-slot-no = <1>; | ||
38 | maxim,spkfb-slot-no = <2>; | ||
39 | maxim,interleave-mode; | ||
40 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt index 77a57f84bed4..6df87b97f7cb 100644 --- a/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt +++ b/Documentation/devicetree/bindings/sound/mt2701-afe-pcm.txt | |||
@@ -2,153 +2,143 @@ Mediatek AFE PCM controller for mt2701 | |||
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible = "mediatek,mt2701-audio"; | 4 | - compatible = "mediatek,mt2701-audio"; |
5 | - reg: register location and size | ||
6 | - interrupts: should contain AFE and ASYS interrupts | 5 | - interrupts: should contain AFE and ASYS interrupts |
7 | - interrupt-names: should be "afe" and "asys" | 6 | - interrupt-names: should be "afe" and "asys" |
8 | - power-domains: should define the power domain | 7 | - power-domains: should define the power domain |
8 | - clocks: Must contain an entry for each entry in clock-names | ||
9 | See ../clocks/clock-bindings.txt for details | ||
9 | - clock-names: should have these clock names: | 10 | - clock-names: should have these clock names: |
10 | "infra_sys_audio_clk", | 11 | "infra_sys_audio_clk", |
11 | "top_audio_mux1_sel", | 12 | "top_audio_mux1_sel", |
12 | "top_audio_mux2_sel", | 13 | "top_audio_mux2_sel", |
13 | "top_audio_mux1_div", | 14 | "top_audio_a1sys_hp", |
14 | "top_audio_mux2_div", | 15 | "top_audio_a2sys_hp", |
15 | "top_audio_48k_timing", | 16 | "i2s0_src_sel", |
16 | "top_audio_44k_timing", | 17 | "i2s1_src_sel", |
17 | "top_audpll_mux_sel", | 18 | "i2s2_src_sel", |
18 | "top_apll_sel", | 19 | "i2s3_src_sel", |
19 | "top_aud1_pll_98M", | 20 | "i2s0_src_div", |
20 | "top_aud2_pll_90M", | 21 | "i2s1_src_div", |
21 | "top_hadds2_pll_98M", | 22 | "i2s2_src_div", |
22 | "top_hadds2_pll_294M", | 23 | "i2s3_src_div", |
23 | "top_audpll", | 24 | "i2s0_mclk_en", |
24 | "top_audpll_d4", | 25 | "i2s1_mclk_en", |
25 | "top_audpll_d8", | 26 | "i2s2_mclk_en", |
26 | "top_audpll_d16", | 27 | "i2s3_mclk_en", |
27 | "top_audpll_d24", | 28 | "i2so0_hop_ck", |
28 | "top_audintbus_sel", | 29 | "i2so1_hop_ck", |
29 | "clk_26m", | 30 | "i2so2_hop_ck", |
30 | "top_syspll1_d4", | 31 | "i2so3_hop_ck", |
31 | "top_aud_k1_src_sel", | 32 | "i2si0_hop_ck", |
32 | "top_aud_k2_src_sel", | 33 | "i2si1_hop_ck", |
33 | "top_aud_k3_src_sel", | 34 | "i2si2_hop_ck", |
34 | "top_aud_k4_src_sel", | 35 | "i2si3_hop_ck", |
35 | "top_aud_k5_src_sel", | 36 | "asrc0_out_ck", |
36 | "top_aud_k6_src_sel", | 37 | "asrc1_out_ck", |
37 | "top_aud_k1_src_div", | 38 | "asrc2_out_ck", |
38 | "top_aud_k2_src_div", | 39 | "asrc3_out_ck", |
39 | "top_aud_k3_src_div", | 40 | "audio_afe_pd", |
40 | "top_aud_k4_src_div", | 41 | "audio_afe_conn_pd", |
41 | "top_aud_k5_src_div", | 42 | "audio_a1sys_pd", |
42 | "top_aud_k6_src_div", | 43 | "audio_a2sys_pd", |
43 | "top_aud_i2s1_mclk", | 44 | "audio_mrgif_pd"; |
44 | "top_aud_i2s2_mclk", | 45 | - assigned-clocks: list of input clocks and dividers for the audio system. |
45 | "top_aud_i2s3_mclk", | 46 | See ../clocks/clock-bindings.txt for details. |
46 | "top_aud_i2s4_mclk", | 47 | - assigned-clocks-parents: parent of input clocks of assigned clocks. |
47 | "top_aud_i2s5_mclk", | 48 | - assigned-clock-rates: list of clock frequencies of assigned clocks. |
48 | "top_aud_i2s6_mclk", | 49 | |
49 | "top_asm_m_sel", | 50 | Must be a subnode of MediaTek audsys device tree node. |
50 | "top_asm_h_sel", | 51 | See ../arm/mediatek/mediatek,audsys.txt for details about the parent node. |
51 | "top_univpll2_d4", | ||
52 | "top_univpll2_d2", | ||
53 | "top_syspll_d5"; | ||
54 | 52 | ||
55 | Example: | 53 | Example: |
56 | 54 | ||
57 | afe: mt2701-afe-pcm@11220000 { | 55 | audsys: audio-subsystem@11220000 { |
58 | compatible = "mediatek,mt2701-audio"; | 56 | compatible = "mediatek,mt2701-audsys", "syscon", "simple-mfd"; |
59 | reg = <0 0x11220000 0 0x2000>, | 57 | ... |
60 | <0 0x112A0000 0 0x20000>; | 58 | |
61 | interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, | 59 | afe: audio-controller { |
62 | <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; | 60 | compatible = "mediatek,mt2701-audio"; |
63 | interrupt-names = "afe", "asys"; | 61 | interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>, |
64 | power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; | 62 | <GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>; |
65 | clocks = <&infracfg CLK_INFRA_AUDIO>, | 63 | interrupt-names = "afe", "asys"; |
66 | <&topckgen CLK_TOP_AUD_MUX1_SEL>, | 64 | power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>; |
67 | <&topckgen CLK_TOP_AUD_MUX2_SEL>, | 65 | |
68 | <&topckgen CLK_TOP_AUD_MUX1_DIV>, | 66 | clocks = <&infracfg CLK_INFRA_AUDIO>, |
69 | <&topckgen CLK_TOP_AUD_MUX2_DIV>, | 67 | <&topckgen CLK_TOP_AUD_MUX1_SEL>, |
70 | <&topckgen CLK_TOP_AUD_48K_TIMING>, | 68 | <&topckgen CLK_TOP_AUD_MUX2_SEL>, |
71 | <&topckgen CLK_TOP_AUD_44K_TIMING>, | 69 | <&topckgen CLK_TOP_AUD_48K_TIMING>, |
72 | <&topckgen CLK_TOP_AUDPLL_MUX_SEL>, | 70 | <&topckgen CLK_TOP_AUD_44K_TIMING>, |
73 | <&topckgen CLK_TOP_APLL_SEL>, | 71 | <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, |
74 | <&topckgen CLK_TOP_AUD1PLL_98M>, | 72 | <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, |
75 | <&topckgen CLK_TOP_AUD2PLL_90M>, | 73 | <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, |
76 | <&topckgen CLK_TOP_HADDS2PLL_98M>, | 74 | <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, |
77 | <&topckgen CLK_TOP_HADDS2PLL_294M>, | 75 | <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, |
78 | <&topckgen CLK_TOP_AUDPLL>, | 76 | <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, |
79 | <&topckgen CLK_TOP_AUDPLL_D4>, | 77 | <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, |
80 | <&topckgen CLK_TOP_AUDPLL_D8>, | 78 | <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, |
81 | <&topckgen CLK_TOP_AUDPLL_D16>, | 79 | <&topckgen CLK_TOP_AUD_I2S1_MCLK>, |
82 | <&topckgen CLK_TOP_AUDPLL_D24>, | 80 | <&topckgen CLK_TOP_AUD_I2S2_MCLK>, |
83 | <&topckgen CLK_TOP_AUDINTBUS_SEL>, | 81 | <&topckgen CLK_TOP_AUD_I2S3_MCLK>, |
84 | <&clk26m>, | 82 | <&topckgen CLK_TOP_AUD_I2S4_MCLK>, |
85 | <&topckgen CLK_TOP_SYSPLL1_D4>, | 83 | <&audsys CLK_AUD_I2SO1>, |
86 | <&topckgen CLK_TOP_AUD_K1_SRC_SEL>, | 84 | <&audsys CLK_AUD_I2SO2>, |
87 | <&topckgen CLK_TOP_AUD_K2_SRC_SEL>, | 85 | <&audsys CLK_AUD_I2SO3>, |
88 | <&topckgen CLK_TOP_AUD_K3_SRC_SEL>, | 86 | <&audsys CLK_AUD_I2SO4>, |
89 | <&topckgen CLK_TOP_AUD_K4_SRC_SEL>, | 87 | <&audsys CLK_AUD_I2SIN1>, |
90 | <&topckgen CLK_TOP_AUD_K5_SRC_SEL>, | 88 | <&audsys CLK_AUD_I2SIN2>, |
91 | <&topckgen CLK_TOP_AUD_K6_SRC_SEL>, | 89 | <&audsys CLK_AUD_I2SIN3>, |
92 | <&topckgen CLK_TOP_AUD_K1_SRC_DIV>, | 90 | <&audsys CLK_AUD_I2SIN4>, |
93 | <&topckgen CLK_TOP_AUD_K2_SRC_DIV>, | 91 | <&audsys CLK_AUD_ASRCO1>, |
94 | <&topckgen CLK_TOP_AUD_K3_SRC_DIV>, | 92 | <&audsys CLK_AUD_ASRCO2>, |
95 | <&topckgen CLK_TOP_AUD_K4_SRC_DIV>, | 93 | <&audsys CLK_AUD_ASRCO3>, |
96 | <&topckgen CLK_TOP_AUD_K5_SRC_DIV>, | 94 | <&audsys CLK_AUD_ASRCO4>, |
97 | <&topckgen CLK_TOP_AUD_K6_SRC_DIV>, | 95 | <&audsys CLK_AUD_AFE>, |
98 | <&topckgen CLK_TOP_AUD_I2S1_MCLK>, | 96 | <&audsys CLK_AUD_AFE_CONN>, |
99 | <&topckgen CLK_TOP_AUD_I2S2_MCLK>, | 97 | <&audsys CLK_AUD_A1SYS>, |
100 | <&topckgen CLK_TOP_AUD_I2S3_MCLK>, | 98 | <&audsys CLK_AUD_A2SYS>, |
101 | <&topckgen CLK_TOP_AUD_I2S4_MCLK>, | 99 | <&audsys CLK_AUD_AFE_MRGIF>; |
102 | <&topckgen CLK_TOP_AUD_I2S5_MCLK>, | 100 | |
103 | <&topckgen CLK_TOP_AUD_I2S6_MCLK>, | 101 | clock-names = "infra_sys_audio_clk", |
104 | <&topckgen CLK_TOP_ASM_M_SEL>, | 102 | "top_audio_mux1_sel", |
105 | <&topckgen CLK_TOP_ASM_H_SEL>, | 103 | "top_audio_mux2_sel", |
106 | <&topckgen CLK_TOP_UNIVPLL2_D4>, | 104 | "top_audio_a1sys_hp", |
107 | <&topckgen CLK_TOP_UNIVPLL2_D2>, | 105 | "top_audio_a2sys_hp", |
108 | <&topckgen CLK_TOP_SYSPLL_D5>; | 106 | "i2s0_src_sel", |
107 | "i2s1_src_sel", | ||
108 | "i2s2_src_sel", | ||
109 | "i2s3_src_sel", | ||
110 | "i2s0_src_div", | ||
111 | "i2s1_src_div", | ||
112 | "i2s2_src_div", | ||
113 | "i2s3_src_div", | ||
114 | "i2s0_mclk_en", | ||
115 | "i2s1_mclk_en", | ||
116 | "i2s2_mclk_en", | ||
117 | "i2s3_mclk_en", | ||
118 | "i2so0_hop_ck", | ||
119 | "i2so1_hop_ck", | ||
120 | "i2so2_hop_ck", | ||
121 | "i2so3_hop_ck", | ||
122 | "i2si0_hop_ck", | ||
123 | "i2si1_hop_ck", | ||
124 | "i2si2_hop_ck", | ||
125 | "i2si3_hop_ck", | ||
126 | "asrc0_out_ck", | ||
127 | "asrc1_out_ck", | ||
128 | "asrc2_out_ck", | ||
129 | "asrc3_out_ck", | ||
130 | "audio_afe_pd", | ||
131 | "audio_afe_conn_pd", | ||
132 | "audio_a1sys_pd", | ||
133 | "audio_a2sys_pd", | ||
134 | "audio_mrgif_pd"; | ||
109 | 135 | ||
110 | clock-names = "infra_sys_audio_clk", | 136 | assigned-clocks = <&topckgen CLK_TOP_AUD_MUX1_SEL>, |
111 | "top_audio_mux1_sel", | 137 | <&topckgen CLK_TOP_AUD_MUX2_SEL>, |
112 | "top_audio_mux2_sel", | 138 | <&topckgen CLK_TOP_AUD_MUX1_DIV>, |
113 | "top_audio_mux1_div", | 139 | <&topckgen CLK_TOP_AUD_MUX2_DIV>; |
114 | "top_audio_mux2_div", | 140 | assigned-clock-parents = <&topckgen CLK_TOP_AUD1PLL_98M>, |
115 | "top_audio_48k_timing", | 141 | <&topckgen CLK_TOP_AUD2PLL_90M>; |
116 | "top_audio_44k_timing", | 142 | assigned-clock-rates = <0>, <0>, <49152000>, <45158400>; |
117 | "top_audpll_mux_sel", | 143 | }; |
118 | "top_apll_sel", | ||
119 | "top_aud1_pll_98M", | ||
120 | "top_aud2_pll_90M", | ||
121 | "top_hadds2_pll_98M", | ||
122 | "top_hadds2_pll_294M", | ||
123 | "top_audpll", | ||
124 | "top_audpll_d4", | ||
125 | "top_audpll_d8", | ||
126 | "top_audpll_d16", | ||
127 | "top_audpll_d24", | ||
128 | "top_audintbus_sel", | ||
129 | "clk_26m", | ||
130 | "top_syspll1_d4", | ||
131 | "top_aud_k1_src_sel", | ||
132 | "top_aud_k2_src_sel", | ||
133 | "top_aud_k3_src_sel", | ||
134 | "top_aud_k4_src_sel", | ||
135 | "top_aud_k5_src_sel", | ||
136 | "top_aud_k6_src_sel", | ||
137 | "top_aud_k1_src_div", | ||
138 | "top_aud_k2_src_div", | ||
139 | "top_aud_k3_src_div", | ||
140 | "top_aud_k4_src_div", | ||
141 | "top_aud_k5_src_div", | ||
142 | "top_aud_k6_src_div", | ||
143 | "top_aud_i2s1_mclk", | ||
144 | "top_aud_i2s2_mclk", | ||
145 | "top_aud_i2s3_mclk", | ||
146 | "top_aud_i2s4_mclk", | ||
147 | "top_aud_i2s5_mclk", | ||
148 | "top_aud_i2s6_mclk", | ||
149 | "top_asm_m_sel", | ||
150 | "top_asm_h_sel", | ||
151 | "top_univpll2_d4", | ||
152 | "top_univpll2_d2", | ||
153 | "top_syspll_d5"; | ||
154 | }; | 144 | }; |
diff --git a/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt b/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt index 601c518eddaa..4eb980bd0287 100644 --- a/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt +++ b/Documentation/devicetree/bindings/sound/mxs-audio-sgtl5000.txt | |||
@@ -1,10 +1,31 @@ | |||
1 | * Freescale MXS audio complex with SGTL5000 codec | 1 | * Freescale MXS audio complex with SGTL5000 codec |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - compatible: "fsl,mxs-audio-sgtl5000" | 4 | - compatible : "fsl,mxs-audio-sgtl5000" |
5 | - model: The user-visible name of this sound complex | 5 | - model : The user-visible name of this sound complex |
6 | - saif-controllers: The phandle list of the MXS SAIF controller | 6 | - saif-controllers : The phandle list of the MXS SAIF controller |
7 | - audio-codec: The phandle of the SGTL5000 audio codec | 7 | - audio-codec : The phandle of the SGTL5000 audio codec |
8 | - audio-routing : A list of the connections between audio components. | ||
9 | Each entry is a pair of strings, the first being the | ||
10 | connection's sink, the second being the connection's | ||
11 | source. Valid names could be power supplies, SGTL5000 | ||
12 | pins, and the jacks on the board: | ||
13 | |||
14 | Power supplies: | ||
15 | * Mic Bias | ||
16 | |||
17 | SGTL5000 pins: | ||
18 | * MIC_IN | ||
19 | * LINE_IN | ||
20 | * HP_OUT | ||
21 | * LINE_OUT | ||
22 | |||
23 | Board connectors: | ||
24 | * Mic Jack | ||
25 | * Line In Jack | ||
26 | * Headphone Jack | ||
27 | * Line Out Jack | ||
28 | * Ext Spk | ||
8 | 29 | ||
9 | Example: | 30 | Example: |
10 | 31 | ||
@@ -14,4 +35,8 @@ sound { | |||
14 | model = "imx28-evk-sgtl5000"; | 35 | model = "imx28-evk-sgtl5000"; |
15 | saif-controllers = <&saif0 &saif1>; | 36 | saif-controllers = <&saif0 &saif1>; |
16 | audio-codec = <&sgtl5000>; | 37 | audio-codec = <&sgtl5000>; |
38 | audio-routing = | ||
39 | "MIC_IN", "Mic Jack", | ||
40 | "Mic Jack", "Mic Bias", | ||
41 | "Headphone Jack", "HP_OUT"; | ||
17 | }; | 42 | }; |
diff --git a/Documentation/devicetree/bindings/sound/nau8825.txt b/Documentation/devicetree/bindings/sound/nau8825.txt index 2f5e973285a6..d16d96839bcb 100644 --- a/Documentation/devicetree/bindings/sound/nau8825.txt +++ b/Documentation/devicetree/bindings/sound/nau8825.txt | |||
@@ -69,7 +69,7 @@ Optional properties: | |||
69 | - nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms | 69 | - nuvoton,jack-insert-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms |
70 | - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms | 70 | - nuvoton,jack-eject-debounce: number from 0 to 7 that sets debounce time to 2^(n+2) ms |
71 | 71 | ||
72 | - nuvoton,crosstalk-bypass: make crosstalk function bypass if set. | 72 | - nuvoton,crosstalk-enable: make crosstalk function enable if set. |
73 | 73 | ||
74 | - clocks: list of phandle and clock specifier pairs according to common clock bindings for the | 74 | - clocks: list of phandle and clock specifier pairs according to common clock bindings for the |
75 | clocks described in clock-names | 75 | clocks described in clock-names |
@@ -98,7 +98,7 @@ Example: | |||
98 | nuvoton,short-key-debounce = <2>; | 98 | nuvoton,short-key-debounce = <2>; |
99 | nuvoton,jack-insert-debounce = <7>; | 99 | nuvoton,jack-insert-debounce = <7>; |
100 | nuvoton,jack-eject-debounce = <7>; | 100 | nuvoton,jack-eject-debounce = <7>; |
101 | nuvoton,crosstalk-bypass; | 101 | nuvoton,crosstalk-enable; |
102 | 102 | ||
103 | clock-names = "mclk"; | 103 | clock-names = "mclk"; |
104 | clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>; | 104 | clocks = <&tegra_car TEGRA210_CLK_CLK_OUT_2>; |
diff --git a/Documentation/devicetree/bindings/sound/pcm186x.txt b/Documentation/devicetree/bindings/sound/pcm186x.txt new file mode 100644 index 000000000000..1087f4855980 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/pcm186x.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | Texas Instruments PCM186x Universal Audio ADC | ||
2 | |||
3 | These devices support both I2C and SPI (configured with pin strapping | ||
4 | on the board). | ||
5 | |||
6 | Required properties: | ||
7 | |||
8 | - compatible : "ti,pcm1862", | ||
9 | "ti,pcm1863", | ||
10 | "ti,pcm1864", | ||
11 | "ti,pcm1865" | ||
12 | |||
13 | - reg : The I2C address of the device for I2C, the chip select | ||
14 | number for SPI. | ||
15 | |||
16 | - avdd-supply: Analog core power supply (3.3v) | ||
17 | - dvdd-supply: Digital core power supply | ||
18 | - iovdd-supply: Digital IO power supply | ||
19 | See regulator/regulator.txt for more information | ||
20 | |||
21 | CODEC input pins: | ||
22 | * VINL1 | ||
23 | * VINR1 | ||
24 | * VINL2 | ||
25 | * VINR2 | ||
26 | * VINL3 | ||
27 | * VINR3 | ||
28 | * VINL4 | ||
29 | * VINR4 | ||
30 | |||
31 | The pins can be used in referring sound node's audio-routing property. | ||
32 | |||
33 | Example: | ||
34 | |||
35 | pcm186x: audio-codec@4a { | ||
36 | compatible = "ti,pcm1865"; | ||
37 | reg = <0x4a>; | ||
38 | |||
39 | avdd-supply = <®_3v3_analog>; | ||
40 | dvdd-supply = <®_3v3>; | ||
41 | iovdd-supply = <®_1v8>; | ||
42 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt index 085bec364caf..5bed9a595772 100644 --- a/Documentation/devicetree/bindings/sound/renesas,rsnd.txt +++ b/Documentation/devicetree/bindings/sound/renesas,rsnd.txt | |||
@@ -4,7 +4,7 @@ Renesas R-Car sound | |||
4 | * Modules | 4 | * Modules |
5 | ============================================= | 5 | ============================================= |
6 | 6 | ||
7 | Renesas R-Car sound is constructed from below modules | 7 | Renesas R-Car and RZ/G sound is constructed from below modules |
8 | (for Gen2 or later) | 8 | (for Gen2 or later) |
9 | 9 | ||
10 | SCU : Sampling Rate Converter Unit | 10 | SCU : Sampling Rate Converter Unit |
@@ -197,12 +197,17 @@ Ex) | |||
197 | [MEM] -> [SRC2] -> [CTU03] -+ | 197 | [MEM] -> [SRC2] -> [CTU03] -+ |
198 | 198 | ||
199 | sound { | 199 | sound { |
200 | #address-cells = <1>; | ||
201 | #size-cells = <0>; | ||
202 | |||
200 | compatible = "simple-scu-audio-card"; | 203 | compatible = "simple-scu-audio-card"; |
201 | ... | 204 | ... |
202 | simple-audio-card,cpu-0 { | 205 | simple-audio-card,cpu@0 { |
206 | reg = <0>; | ||
203 | sound-dai = <&rcar_sound 0>; | 207 | sound-dai = <&rcar_sound 0>; |
204 | }; | 208 | }; |
205 | simple-audio-card,cpu-1 { | 209 | simple-audio-card,cpu@1 { |
210 | reg = <1>; | ||
206 | sound-dai = <&rcar_sound 1>; | 211 | sound-dai = <&rcar_sound 1>; |
207 | }; | 212 | }; |
208 | simple-audio-card,codec { | 213 | simple-audio-card,codec { |
@@ -334,9 +339,11 @@ Required properties: | |||
334 | 339 | ||
335 | - compatible : "renesas,rcar_sound-<soctype>", fallbacks | 340 | - compatible : "renesas,rcar_sound-<soctype>", fallbacks |
336 | "renesas,rcar_sound-gen1" if generation1, and | 341 | "renesas,rcar_sound-gen1" if generation1, and |
337 | "renesas,rcar_sound-gen2" if generation2 | 342 | "renesas,rcar_sound-gen2" if generation2 (or RZ/G1) |
338 | "renesas,rcar_sound-gen3" if generation3 | 343 | "renesas,rcar_sound-gen3" if generation3 |
339 | Examples with soctypes are: | 344 | Examples with soctypes are: |
345 | - "renesas,rcar_sound-r8a7743" (RZ/G1M) | ||
346 | - "renesas,rcar_sound-r8a7745" (RZ/G1E) | ||
340 | - "renesas,rcar_sound-r8a7778" (R-Car M1A) | 347 | - "renesas,rcar_sound-r8a7778" (R-Car M1A) |
341 | - "renesas,rcar_sound-r8a7779" (R-Car H1) | 348 | - "renesas,rcar_sound-r8a7779" (R-Car H1) |
342 | - "renesas,rcar_sound-r8a7790" (R-Car H2) | 349 | - "renesas,rcar_sound-r8a7790" (R-Car H2) |
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 166f2290233b..17c13e74667d 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt | |||
@@ -140,6 +140,7 @@ sound { | |||
140 | simple-audio-card,name = "Cubox Audio"; | 140 | simple-audio-card,name = "Cubox Audio"; |
141 | 141 | ||
142 | simple-audio-card,dai-link@0 { /* I2S - HDMI */ | 142 | simple-audio-card,dai-link@0 { /* I2S - HDMI */ |
143 | reg = <0>; | ||
143 | format = "i2s"; | 144 | format = "i2s"; |
144 | cpu { | 145 | cpu { |
145 | sound-dai = <&audio1 0>; | 146 | sound-dai = <&audio1 0>; |
@@ -150,6 +151,7 @@ sound { | |||
150 | }; | 151 | }; |
151 | 152 | ||
152 | simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */ | 153 | simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */ |
154 | reg = <1>; | ||
153 | cpu { | 155 | cpu { |
154 | sound-dai = <&audio1 1>; | 156 | sound-dai = <&audio1 1>; |
155 | }; | 157 | }; |
@@ -159,6 +161,7 @@ sound { | |||
159 | }; | 161 | }; |
160 | 162 | ||
161 | simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */ | 163 | simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */ |
164 | reg = <2>; | ||
162 | cpu { | 165 | cpu { |
163 | sound-dai = <&audio1 1>; | 166 | sound-dai = <&audio1 1>; |
164 | }; | 167 | }; |
diff --git a/Documentation/devicetree/bindings/sound/st,stm32-adfsdm.txt b/Documentation/devicetree/bindings/sound/st,stm32-adfsdm.txt new file mode 100644 index 000000000000..864f5b00b031 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/st,stm32-adfsdm.txt | |||
@@ -0,0 +1,63 @@ | |||
1 | STMicroelectronics Audio Digital Filter Sigma Delta modulators(DFSDM) | ||
2 | |||
3 | The DFSDM allows PDM microphones capture through SPI interface. The Audio | ||
4 | interface is seems as a sub block of the DFSDM device. | ||
5 | For details on DFSDM bindings refer to ../iio/adc/st,stm32-dfsdm-adc.txt | ||
6 | |||
7 | Required properties: | ||
8 | - compatible: "st,stm32h7-dfsdm-dai". | ||
9 | |||
10 | - #sound-dai-cells : Must be equal to 0 | ||
11 | |||
12 | - io-channels : phandle to iio dfsdm instance node. | ||
13 | |||
14 | Example of a sound card using audio DFSDM node. | ||
15 | |||
16 | sound_card { | ||
17 | compatible = "audio-graph-card"; | ||
18 | |||
19 | dais = <&cpu_port>; | ||
20 | }; | ||
21 | |||
22 | dfsdm: dfsdm@40017000 { | ||
23 | compatible = "st,stm32h7-dfsdm"; | ||
24 | reg = <0x40017000 0x400>; | ||
25 | clocks = <&rcc DFSDM1_CK>; | ||
26 | clock-names = "dfsdm"; | ||
27 | #interrupt-cells = <1>; | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <0>; | ||
30 | |||
31 | dfsdm_adc0: filter@0 { | ||
32 | compatible = "st,stm32-dfsdm-dmic"; | ||
33 | reg = <0>; | ||
34 | interrupts = <110>; | ||
35 | dmas = <&dmamux1 101 0x400 0x00>; | ||
36 | dma-names = "rx"; | ||
37 | st,adc-channels = <1>; | ||
38 | st,adc-channel-names = "dmic0"; | ||
39 | st,adc-channel-types = "SPI_R"; | ||
40 | st,adc-channel-clk-src = "CLKOUT"; | ||
41 | st,filter-order = <5>; | ||
42 | |||
43 | dfsdm_dai0: dfsdm-dai { | ||
44 | compatible = "st,stm32h7-dfsdm-dai"; | ||
45 | #sound-dai-cells = <0>; | ||
46 | io-channels = <&dfsdm_adc0 0>; | ||
47 | cpu_port: port { | ||
48 | dfsdm_endpoint: endpoint { | ||
49 | remote-endpoint = <&dmic0_endpoint>; | ||
50 | }; | ||
51 | }; | ||
52 | }; | ||
53 | }; | ||
54 | |||
55 | dmic0: dmic@0 { | ||
56 | compatible = "dmic-codec"; | ||
57 | #sound-dai-cells = <0>; | ||
58 | port { | ||
59 | dmic0_endpoint: endpoint { | ||
60 | remote-endpoint = <&dfsdm_endpoint>; | ||
61 | }; | ||
62 | }; | ||
63 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/st,stm32-sai.txt b/Documentation/devicetree/bindings/sound/st,stm32-sai.txt index 1f9cd7095337..b1acc1a256ba 100644 --- a/Documentation/devicetree/bindings/sound/st,stm32-sai.txt +++ b/Documentation/devicetree/bindings/sound/st,stm32-sai.txt | |||
@@ -20,11 +20,6 @@ Required properties: | |||
20 | 20 | ||
21 | Optional properties: | 21 | Optional properties: |
22 | - resets: Reference to a reset controller asserting the SAI | 22 | - resets: Reference to a reset controller asserting the SAI |
23 | - st,sync: specify synchronization mode. | ||
24 | By default SAI sub-block is in asynchronous mode. | ||
25 | This property sets SAI sub-block as slave of another SAI sub-block. | ||
26 | Must contain the phandle and index of the sai sub-block providing | ||
27 | the synchronization. | ||
28 | 23 | ||
29 | SAI subnodes: | 24 | SAI subnodes: |
30 | Two subnodes corresponding to SAI sub-block instances A et B can be defined. | 25 | Two subnodes corresponding to SAI sub-block instances A et B can be defined. |
@@ -44,6 +39,13 @@ SAI subnodes required properties: | |||
44 | - pinctrl-names: should contain only value "default" | 39 | - pinctrl-names: should contain only value "default" |
45 | - pinctrl-0: see Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt | 40 | - pinctrl-0: see Documentation/devicetree/bindings/pinctrl/pinctrl-stm32.txt |
46 | 41 | ||
42 | SAI subnodes Optional properties: | ||
43 | - st,sync: specify synchronization mode. | ||
44 | By default SAI sub-block is in asynchronous mode. | ||
45 | This property sets SAI sub-block as slave of another SAI sub-block. | ||
46 | Must contain the phandle and index of the sai sub-block providing | ||
47 | the synchronization. | ||
48 | |||
47 | The device node should contain one 'port' child node with one child 'endpoint' | 49 | The device node should contain one 'port' child node with one child 'endpoint' |
48 | node, according to the bindings defined in Documentation/devicetree/bindings/ | 50 | node, according to the bindings defined in Documentation/devicetree/bindings/ |
49 | graph.txt. | 51 | graph.txt. |
diff --git a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt index 05d7135a8d2f..b9d50d6cdef3 100644 --- a/Documentation/devicetree/bindings/sound/sun4i-i2s.txt +++ b/Documentation/devicetree/bindings/sound/sun4i-i2s.txt | |||
@@ -8,6 +8,7 @@ Required properties: | |||
8 | - compatible: should be one of the following: | 8 | - compatible: should be one of the following: |
9 | - "allwinner,sun4i-a10-i2s" | 9 | - "allwinner,sun4i-a10-i2s" |
10 | - "allwinner,sun6i-a31-i2s" | 10 | - "allwinner,sun6i-a31-i2s" |
11 | - "allwinner,sun8i-a83t-i2s" | ||
11 | - "allwinner,sun8i-h3-i2s" | 12 | - "allwinner,sun8i-h3-i2s" |
12 | - reg: physical base address of the controller and length of memory mapped | 13 | - reg: physical base address of the controller and length of memory mapped |
13 | region. | 14 | region. |
@@ -23,6 +24,7 @@ Required properties: | |||
23 | 24 | ||
24 | Required properties for the following compatibles: | 25 | Required properties for the following compatibles: |
25 | - "allwinner,sun6i-a31-i2s" | 26 | - "allwinner,sun6i-a31-i2s" |
27 | - "allwinner,sun8i-a83t-i2s" | ||
26 | - "allwinner,sun8i-h3-i2s" | 28 | - "allwinner,sun8i-h3-i2s" |
27 | - resets: phandle to the reset line for this codec | 29 | - resets: phandle to the reset line for this codec |
28 | 30 | ||
diff --git a/Documentation/devicetree/bindings/sound/tas5720.txt b/Documentation/devicetree/bindings/sound/tas5720.txt index 40d94f82beb3..7481653fe8e3 100644 --- a/Documentation/devicetree/bindings/sound/tas5720.txt +++ b/Documentation/devicetree/bindings/sound/tas5720.txt | |||
@@ -6,10 +6,12 @@ audio playback. For more product information please see the links below: | |||
6 | 6 | ||
7 | http://www.ti.com/product/TAS5720L | 7 | http://www.ti.com/product/TAS5720L |
8 | http://www.ti.com/product/TAS5720M | 8 | http://www.ti.com/product/TAS5720M |
9 | http://www.ti.com/product/TAS5722L | ||
9 | 10 | ||
10 | Required properties: | 11 | Required properties: |
11 | 12 | ||
12 | - compatible : "ti,tas5720" | 13 | - compatible : "ti,tas5720", |
14 | "ti,tas5722" | ||
13 | - reg : I2C slave address | 15 | - reg : I2C slave address |
14 | - dvdd-supply : phandle to a 3.3-V supply for the digital circuitry | 16 | - dvdd-supply : phandle to a 3.3-V supply for the digital circuitry |
15 | - pvdd-supply : phandle to a supply used for the Class-D amp and the analog | 17 | - pvdd-supply : phandle to a supply used for the Class-D amp and the analog |
diff --git a/Documentation/devicetree/bindings/sound/tfa9879.txt b/Documentation/devicetree/bindings/sound/tfa9879.txt index 23ba522d9e2b..1620e6848436 100644 --- a/Documentation/devicetree/bindings/sound/tfa9879.txt +++ b/Documentation/devicetree/bindings/sound/tfa9879.txt | |||
@@ -6,18 +6,18 @@ Required properties: | |||
6 | 6 | ||
7 | - reg : the I2C address of the device | 7 | - reg : the I2C address of the device |
8 | 8 | ||
9 | - #sound-dai-cells : must be 0. | ||
10 | |||
9 | Example: | 11 | Example: |
10 | 12 | ||
11 | &i2c1 { | 13 | &i2c1 { |
12 | clock-frequency = <100000>; | ||
13 | pinctrl-names = "default"; | 14 | pinctrl-names = "default"; |
14 | pinctrl-0 = <&pinctrl_i2c1>; | 15 | pinctrl-0 = <&pinctrl_i2c1>; |
15 | status = "okay"; | ||
16 | 16 | ||
17 | codec: tfa9879@6c { | 17 | amp: amp@6c { |
18 | #sound-dai-cells = <0>; | 18 | #sound-dai-cells = <0>; |
19 | compatible = "nxp,tfa9879"; | 19 | compatible = "nxp,tfa9879"; |
20 | reg = <0x6c>; | 20 | reg = <0x6c>; |
21 | }; | 21 | }; |
22 | }; | 22 | }; |
23 | 23 | ||
diff --git a/Documentation/devicetree/bindings/sound/ti,tas6424.txt b/Documentation/devicetree/bindings/sound/ti,tas6424.txt new file mode 100644 index 000000000000..1c4ada0eef4e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,tas6424.txt | |||
@@ -0,0 +1,20 @@ | |||
1 | Texas Instruments TAS6424 Quad-Channel Audio amplifier | ||
2 | |||
3 | The TAS6424 serial control bus communicates through I2C protocols. | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: "ti,tas6424" - TAS6424 | ||
7 | - reg: I2C slave address | ||
8 | - sound-dai-cells: must be equal to 0 | ||
9 | |||
10 | Example: | ||
11 | |||
12 | tas6424: tas6424@6a { | ||
13 | compatible = "ti,tas6424"; | ||
14 | reg = <0x6a>; | ||
15 | |||
16 | #sound-dai-cells = <0>; | ||
17 | }; | ||
18 | |||
19 | For more product information please see the link below: | ||
20 | http://www.ti.com/product/TAS6424-Q1 | ||
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt index 6fbba562eaa7..5b3c33bb99e5 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic31xx.txt | |||
@@ -22,7 +22,7 @@ Required properties: | |||
22 | 22 | ||
23 | Optional properties: | 23 | Optional properties: |
24 | 24 | ||
25 | - gpio-reset - gpio pin number used for codec reset | 25 | - reset-gpios - GPIO specification for the active low RESET input. |
26 | - ai31xx-micbias-vg - MicBias Voltage setting | 26 | - ai31xx-micbias-vg - MicBias Voltage setting |
27 | 1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V | 27 | 1 or MICBIAS_2_0V - MICBIAS output is powered to 2.0V |
28 | 2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V | 28 | 2 or MICBIAS_2_5V - MICBIAS output is powered to 2.5V |
@@ -30,6 +30,10 @@ Optional properties: | |||
30 | If this node is not mentioned or if the value is unknown, then | 30 | If this node is not mentioned or if the value is unknown, then |
31 | micbias is set to 2.0V. | 31 | micbias is set to 2.0V. |
32 | 32 | ||
33 | Deprecated properties: | ||
34 | |||
35 | - gpio-reset - gpio pin number used for codec reset | ||
36 | |||
33 | CODEC output pins: | 37 | CODEC output pins: |
34 | * HPL | 38 | * HPL |
35 | * HPR | 39 | * HPR |
@@ -48,6 +52,7 @@ CODEC input pins: | |||
48 | The pins can be used in referring sound node's audio-routing property. | 52 | The pins can be used in referring sound node's audio-routing property. |
49 | 53 | ||
50 | Example: | 54 | Example: |
55 | #include <dt-bindings/gpio/gpio.h> | ||
51 | #include <dt-bindings/sound/tlv320aic31xx-micbias.h> | 56 | #include <dt-bindings/sound/tlv320aic31xx-micbias.h> |
52 | 57 | ||
53 | tlv320aic31xx: tlv320aic31xx@18 { | 58 | tlv320aic31xx: tlv320aic31xx@18 { |
@@ -56,6 +61,8 @@ tlv320aic31xx: tlv320aic31xx@18 { | |||
56 | 61 | ||
57 | ai31xx-micbias-vg = <MICBIAS_OFF>; | 62 | ai31xx-micbias-vg = <MICBIAS_OFF>; |
58 | 63 | ||
64 | reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; | ||
65 | |||
59 | HPVDD-supply = <®ulator>; | 66 | HPVDD-supply = <®ulator>; |
60 | SPRVDD-supply = <®ulator>; | 67 | SPRVDD-supply = <®ulator>; |
61 | SPLVDD-supply = <®ulator>; | 68 | SPLVDD-supply = <®ulator>; |
diff --git a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt index ba5b45c483f5..9796c4639262 100644 --- a/Documentation/devicetree/bindings/sound/tlv320aic3x.txt +++ b/Documentation/devicetree/bindings/sound/tlv320aic3x.txt | |||
@@ -17,7 +17,7 @@ Required properties: | |||
17 | 17 | ||
18 | Optional properties: | 18 | Optional properties: |
19 | 19 | ||
20 | - gpio-reset - gpio pin number used for codec reset | 20 | - reset-gpios - GPIO specification for the active low RESET input. |
21 | - ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality | 21 | - ai3x-gpio-func - <array of 2 int> - AIC3X_GPIO1 & AIC3X_GPIO2 Functionality |
22 | - Not supported on tlv320aic3104 | 22 | - Not supported on tlv320aic3104 |
23 | - ai3x-micbias-vg - MicBias Voltage required. | 23 | - ai3x-micbias-vg - MicBias Voltage required. |
@@ -34,6 +34,10 @@ Optional properties: | |||
34 | - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the | 34 | - AVDD-supply, IOVDD-supply, DRVDD-supply, DVDD-supply : power supplies for the |
35 | device as covered in Documentation/devicetree/bindings/regulator/regulator.txt | 35 | device as covered in Documentation/devicetree/bindings/regulator/regulator.txt |
36 | 36 | ||
37 | Deprecated properties: | ||
38 | |||
39 | - gpio-reset - gpio pin number used for codec reset | ||
40 | |||
37 | CODEC output pins: | 41 | CODEC output pins: |
38 | * LLOUT | 42 | * LLOUT |
39 | * RLOUT | 43 | * RLOUT |
@@ -61,10 +65,14 @@ The pins can be used in referring sound node's audio-routing property. | |||
61 | 65 | ||
62 | Example: | 66 | Example: |
63 | 67 | ||
68 | #include <dt-bindings/gpio/gpio.h> | ||
69 | |||
64 | tlv320aic3x: tlv320aic3x@1b { | 70 | tlv320aic3x: tlv320aic3x@1b { |
65 | compatible = "ti,tlv320aic3x"; | 71 | compatible = "ti,tlv320aic3x"; |
66 | reg = <0x1b>; | 72 | reg = <0x1b>; |
67 | 73 | ||
74 | reset-gpios = <&gpio1 17 GPIO_ACTIVE_LOW>; | ||
75 | |||
68 | AVDD-supply = <®ulator>; | 76 | AVDD-supply = <®ulator>; |
69 | IOVDD-supply = <®ulator>; | 77 | IOVDD-supply = <®ulator>; |
70 | DRVDD-supply = <®ulator>; | 78 | DRVDD-supply = <®ulator>; |
diff --git a/Documentation/devicetree/bindings/sound/tscs42xx.txt b/Documentation/devicetree/bindings/sound/tscs42xx.txt new file mode 100644 index 000000000000..2ac2f0996697 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/tscs42xx.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | TSCS42XX Audio CODEC | ||
2 | |||
3 | Required Properties: | ||
4 | |||
5 | - compatible : "tempo,tscs42A1" for analog mic | ||
6 | "tempo,tscs42A2" for digital mic | ||
7 | |||
8 | - reg : <0x71> for analog mic | ||
9 | <0x69> for digital mic | ||
10 | |||
11 | Example: | ||
12 | |||
13 | wookie: codec@69 { | ||
14 | compatible = "tempo,tscs42A2"; | ||
15 | reg = <0x69>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/uniphier,evea.txt b/Documentation/devicetree/bindings/sound/uniphier,evea.txt new file mode 100644 index 000000000000..3f31b235f18b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/uniphier,evea.txt | |||
@@ -0,0 +1,26 @@ | |||
1 | Socionext EVEA - UniPhier SoC internal codec driver | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : should be "socionext,uniphier-evea". | ||
5 | - reg : offset and length of the register set for the device. | ||
6 | - clock-names : should include following entries: | ||
7 | "evea", "exiv" | ||
8 | - clocks : a list of phandle, should contain an entry for each | ||
9 | entries in clock-names. | ||
10 | - reset-names : should include following entries: | ||
11 | "evea", "exiv", "adamv" | ||
12 | - resets : a list of phandle, should contain reset entries of | ||
13 | reset-names. | ||
14 | - #sound-dai-cells: should be 1. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | codec { | ||
19 | compatible = "socionext,uniphier-evea"; | ||
20 | reg = <0x57900000 0x1000>; | ||
21 | clock-names = "evea", "exiv"; | ||
22 | clocks = <&sys_clk 41>, <&sys_clk 42>; | ||
23 | reset-names = "evea", "exiv", "adamv"; | ||
24 | resets = <&sys_rst 41>, <&sys_rst 42>, <&adamv_rst 0>; | ||
25 | #sound-dai-cells = <1>; | ||
26 | }; | ||
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt index 0994bdd82cd3..f776fb804a8c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.txt +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt | |||
@@ -347,6 +347,7 @@ tcg Trusted Computing Group | |||
347 | tcl Toby Churchill Ltd. | 347 | tcl Toby Churchill Ltd. |
348 | technexion TechNexion | 348 | technexion TechNexion |
349 | technologic Technologic Systems | 349 | technologic Technologic Systems |
350 | tempo Tempo Semiconductor | ||
350 | terasic Terasic Inc. | 351 | terasic Terasic Inc. |
351 | thine THine Electronics, Inc. | 352 | thine THine Electronics, Inc. |
352 | ti Texas Instruments | 353 | ti Texas Instruments |
diff --git a/Documentation/driver-api/iio/hw-consumer.rst b/Documentation/driver-api/iio/hw-consumer.rst new file mode 100644 index 000000000000..8facce6a6733 --- /dev/null +++ b/Documentation/driver-api/iio/hw-consumer.rst | |||
@@ -0,0 +1,51 @@ | |||
1 | =========== | ||
2 | HW consumer | ||
3 | =========== | ||
4 | An IIO device can be directly connected to another device in hardware. in this | ||
5 | case the buffers between IIO provider and IIO consumer are handled by hardware. | ||
6 | The Industrial I/O HW consumer offers a way to bond these IIO devices without | ||
7 | software buffer for data. The implementation can be found under | ||
8 | :file:`drivers/iio/buffer/hw-consumer.c` | ||
9 | |||
10 | |||
11 | * struct :c:type:`iio_hw_consumer` — Hardware consumer structure | ||
12 | * :c:func:`iio_hw_consumer_alloc` — Allocate IIO hardware consumer | ||
13 | * :c:func:`iio_hw_consumer_free` — Free IIO hardware consumer | ||
14 | * :c:func:`iio_hw_consumer_enable` — Enable IIO hardware consumer | ||
15 | * :c:func:`iio_hw_consumer_disable` — Disable IIO hardware consumer | ||
16 | |||
17 | |||
18 | HW consumer setup | ||
19 | ================= | ||
20 | |||
21 | As standard IIO device the implementation is based on IIO provider/consumer. | ||
22 | A typical IIO HW consumer setup looks like this:: | ||
23 | |||
24 | static struct iio_hw_consumer *hwc; | ||
25 | |||
26 | static const struct iio_info adc_info = { | ||
27 | .read_raw = adc_read_raw, | ||
28 | }; | ||
29 | |||
30 | static int adc_read_raw(struct iio_dev *indio_dev, | ||
31 | struct iio_chan_spec const *chan, int *val, | ||
32 | int *val2, long mask) | ||
33 | { | ||
34 | ret = iio_hw_consumer_enable(hwc); | ||
35 | |||
36 | /* Acquire data */ | ||
37 | |||
38 | ret = iio_hw_consumer_disable(hwc); | ||
39 | } | ||
40 | |||
41 | static int adc_probe(struct platform_device *pdev) | ||
42 | { | ||
43 | hwc = devm_iio_hw_consumer_alloc(&iio->dev); | ||
44 | } | ||
45 | |||
46 | More details | ||
47 | ============ | ||
48 | .. kernel-doc:: include/linux/iio/hw-consumer.h | ||
49 | .. kernel-doc:: drivers/iio/buffer/industrialio-hw-consumer.c | ||
50 | :export: | ||
51 | |||
diff --git a/Documentation/driver-api/iio/index.rst b/Documentation/driver-api/iio/index.rst index e5c3922d1b6f..7fba341bd8b2 100644 --- a/Documentation/driver-api/iio/index.rst +++ b/Documentation/driver-api/iio/index.rst | |||
@@ -15,3 +15,4 @@ Contents: | |||
15 | buffers | 15 | buffers |
16 | triggers | 16 | triggers |
17 | triggered-buffers | 17 | triggered-buffers |
18 | hw-consumer | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 845fc25812f1..5046003ea162 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9802,6 +9802,7 @@ NXP TFA9879 DRIVER | |||
9802 | M: Peter Rosin <peda@axentia.se> | 9802 | M: Peter Rosin <peda@axentia.se> |
9803 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 9803 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
9804 | S: Maintained | 9804 | S: Maintained |
9805 | F: Documentation/devicetree/bindings/sound/tfa9879.txt | ||
9805 | F: sound/soc/codecs/tfa9879* | 9806 | F: sound/soc/codecs/tfa9879* |
9806 | 9807 | ||
9807 | NXP-NCI NFC DRIVER | 9808 | NXP-NCI NFC DRIVER |
@@ -12590,6 +12591,12 @@ F: include/media/soc* | |||
12590 | F: drivers/media/i2c/soc_camera/ | 12591 | F: drivers/media/i2c/soc_camera/ |
12591 | F: drivers/media/platform/soc_camera/ | 12592 | F: drivers/media/platform/soc_camera/ |
12592 | 12593 | ||
12594 | SOCIONEXT UNIPHIER SOUND DRIVER | ||
12595 | M: Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com> | ||
12596 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | ||
12597 | S: Maintained | ||
12598 | F: sound/soc/uniphier/ | ||
12599 | |||
12593 | SOEKRIS NET48XX LED SUPPORT | 12600 | SOEKRIS NET48XX LED SUPPORT |
12594 | M: Chris Boot <bootc@bootc.net> | 12601 | M: Chris Boot <bootc@bootc.net> |
12595 | S: Maintained | 12602 | S: Maintained |
@@ -13848,6 +13855,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial.git | |||
13848 | S: Maintained | 13855 | S: Maintained |
13849 | K: ^Subject:.*(?i)trivial | 13856 | K: ^Subject:.*(?i)trivial |
13850 | 13857 | ||
13858 | TEMPO SEMICONDUCTOR DRIVERS | ||
13859 | M: Steven Eckhoff <steven.eckhoff.opensource@gmail.com> | ||
13860 | S: Maintained | ||
13861 | F: sound/soc/codecs/tscs*.c | ||
13862 | F: sound/soc/codecs/tscs*.h | ||
13863 | F: Documentation/devicetree/bindings/sound/tscs*.txt | ||
13864 | |||
13851 | TTY LAYER | 13865 | TTY LAYER |
13852 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 13866 | M: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
13853 | M: Jiri Slaby <jslaby@suse.com> | 13867 | M: Jiri Slaby <jslaby@suse.com> |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 9d49a1acebe3..78db97687f26 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -737,16 +737,17 @@ bool acpi_dev_found(const char *hid) | |||
737 | } | 737 | } |
738 | EXPORT_SYMBOL(acpi_dev_found); | 738 | EXPORT_SYMBOL(acpi_dev_found); |
739 | 739 | ||
740 | struct acpi_dev_present_info { | 740 | struct acpi_dev_match_info { |
741 | const char *dev_name; | ||
741 | struct acpi_device_id hid[2]; | 742 | struct acpi_device_id hid[2]; |
742 | const char *uid; | 743 | const char *uid; |
743 | s64 hrv; | 744 | s64 hrv; |
744 | }; | 745 | }; |
745 | 746 | ||
746 | static int acpi_dev_present_cb(struct device *dev, void *data) | 747 | static int acpi_dev_match_cb(struct device *dev, void *data) |
747 | { | 748 | { |
748 | struct acpi_device *adev = to_acpi_device(dev); | 749 | struct acpi_device *adev = to_acpi_device(dev); |
749 | struct acpi_dev_present_info *match = data; | 750 | struct acpi_dev_match_info *match = data; |
750 | unsigned long long hrv; | 751 | unsigned long long hrv; |
751 | acpi_status status; | 752 | acpi_status status; |
752 | 753 | ||
@@ -757,6 +758,8 @@ static int acpi_dev_present_cb(struct device *dev, void *data) | |||
757 | strcmp(adev->pnp.unique_id, match->uid))) | 758 | strcmp(adev->pnp.unique_id, match->uid))) |
758 | return 0; | 759 | return 0; |
759 | 760 | ||
761 | match->dev_name = acpi_dev_name(adev); | ||
762 | |||
760 | if (match->hrv == -1) | 763 | if (match->hrv == -1) |
761 | return 1; | 764 | return 1; |
762 | 765 | ||
@@ -789,20 +792,44 @@ static int acpi_dev_present_cb(struct device *dev, void *data) | |||
789 | */ | 792 | */ |
790 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) | 793 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) |
791 | { | 794 | { |
792 | struct acpi_dev_present_info match = {}; | 795 | struct acpi_dev_match_info match = {}; |
793 | struct device *dev; | 796 | struct device *dev; |
794 | 797 | ||
795 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | 798 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); |
796 | match.uid = uid; | 799 | match.uid = uid; |
797 | match.hrv = hrv; | 800 | match.hrv = hrv; |
798 | 801 | ||
799 | dev = bus_find_device(&acpi_bus_type, NULL, &match, | 802 | dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); |
800 | acpi_dev_present_cb); | ||
801 | |||
802 | return !!dev; | 803 | return !!dev; |
803 | } | 804 | } |
804 | EXPORT_SYMBOL(acpi_dev_present); | 805 | EXPORT_SYMBOL(acpi_dev_present); |
805 | 806 | ||
807 | /** | ||
808 | * acpi_dev_get_first_match_name - Return name of first match of ACPI device | ||
809 | * @hid: Hardware ID of the device. | ||
810 | * @uid: Unique ID of the device, pass NULL to not check _UID | ||
811 | * @hrv: Hardware Revision of the device, pass -1 to not check _HRV | ||
812 | * | ||
813 | * Return device name if a matching device was present | ||
814 | * at the moment of invocation, or NULL otherwise. | ||
815 | * | ||
816 | * See additional information in acpi_dev_present() as well. | ||
817 | */ | ||
818 | const char * | ||
819 | acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) | ||
820 | { | ||
821 | struct acpi_dev_match_info match = {}; | ||
822 | struct device *dev; | ||
823 | |||
824 | strlcpy(match.hid[0].id, hid, sizeof(match.hid[0].id)); | ||
825 | match.uid = uid; | ||
826 | match.hrv = hrv; | ||
827 | |||
828 | dev = bus_find_device(&acpi_bus_type, NULL, &match, acpi_dev_match_cb); | ||
829 | return dev ? match.dev_name : NULL; | ||
830 | } | ||
831 | EXPORT_SYMBOL(acpi_dev_get_first_match_name); | ||
832 | |||
806 | /* | 833 | /* |
807 | * acpi_backlight= handling, this is done here rather then in video_detect.c | 834 | * acpi_backlight= handling, this is done here rather then in video_detect.c |
808 | * because __setup cannot be used in modules. | 835 | * because __setup cannot be used in modules. |
diff --git a/drivers/gpio/gpio-merrifield.c b/drivers/gpio/gpio-merrifield.c index dd67a31ac337..c38624ea0251 100644 --- a/drivers/gpio/gpio-merrifield.c +++ b/drivers/gpio/gpio-merrifield.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/acpi.h> | ||
12 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
13 | #include <linux/gpio/driver.h> | 14 | #include <linux/gpio/driver.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
@@ -380,9 +381,16 @@ static void mrfld_irq_init_hw(struct mrfld_gpio *priv) | |||
380 | } | 381 | } |
381 | } | 382 | } |
382 | 383 | ||
384 | static const char *mrfld_gpio_get_pinctrl_dev_name(void) | ||
385 | { | ||
386 | const char *dev_name = acpi_dev_get_first_match_name("INTC1002", NULL, -1); | ||
387 | return dev_name ? dev_name : "pinctrl-merrifield"; | ||
388 | } | ||
389 | |||
383 | static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 390 | static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
384 | { | 391 | { |
385 | const struct mrfld_gpio_pinrange *range; | 392 | const struct mrfld_gpio_pinrange *range; |
393 | const char *pinctrl_dev_name; | ||
386 | struct mrfld_gpio *priv; | 394 | struct mrfld_gpio *priv; |
387 | u32 gpio_base, irq_base; | 395 | u32 gpio_base, irq_base; |
388 | void __iomem *base; | 396 | void __iomem *base; |
@@ -439,10 +447,11 @@ static int mrfld_gpio_probe(struct pci_dev *pdev, const struct pci_device_id *id | |||
439 | return retval; | 447 | return retval; |
440 | } | 448 | } |
441 | 449 | ||
450 | pinctrl_dev_name = mrfld_gpio_get_pinctrl_dev_name(); | ||
442 | for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { | 451 | for (i = 0; i < ARRAY_SIZE(mrfld_gpio_ranges); i++) { |
443 | range = &mrfld_gpio_ranges[i]; | 452 | range = &mrfld_gpio_ranges[i]; |
444 | retval = gpiochip_add_pin_range(&priv->chip, | 453 | retval = gpiochip_add_pin_range(&priv->chip, |
445 | "pinctrl-merrifield", | 454 | pinctrl_dev_name, |
446 | range->gpio_base, | 455 | range->gpio_base, |
447 | range->pin_base, | 456 | range->pin_base, |
448 | range->npins); | 457 | range->npins); |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index ef86296b8b0d..39e3b345a6c8 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -629,6 +629,18 @@ config SPEAR_ADC | |||
629 | To compile this driver as a module, choose M here: the | 629 | To compile this driver as a module, choose M here: the |
630 | module will be called spear_adc. | 630 | module will be called spear_adc. |
631 | 631 | ||
632 | config SD_ADC_MODULATOR | ||
633 | tristate "Generic sigma delta modulator" | ||
634 | depends on OF | ||
635 | select IIO_BUFFER | ||
636 | select IIO_TRIGGERED_BUFFER | ||
637 | help | ||
638 | Select this option to enables sigma delta modulator. This driver can | ||
639 | support generic sigma delta modulators. | ||
640 | |||
641 | This driver can also be built as a module. If so, the module | ||
642 | will be called sd_adc_modulator. | ||
643 | |||
632 | config STM32_ADC_CORE | 644 | config STM32_ADC_CORE |
633 | tristate "STMicroelectronics STM32 adc core" | 645 | tristate "STMicroelectronics STM32 adc core" |
634 | depends on ARCH_STM32 || COMPILE_TEST | 646 | depends on ARCH_STM32 || COMPILE_TEST |
@@ -656,6 +668,31 @@ config STM32_ADC | |||
656 | This driver can also be built as a module. If so, the module | 668 | This driver can also be built as a module. If so, the module |
657 | will be called stm32-adc. | 669 | will be called stm32-adc. |
658 | 670 | ||
671 | config STM32_DFSDM_CORE | ||
672 | tristate "STMicroelectronics STM32 DFSDM core" | ||
673 | depends on (ARCH_STM32 && OF) || COMPILE_TEST | ||
674 | select REGMAP | ||
675 | select REGMAP_MMIO | ||
676 | help | ||
677 | Select this option to enable the driver for STMicroelectronics | ||
678 | STM32 digital filter for sigma delta converter. | ||
679 | |||
680 | This driver can also be built as a module. If so, the module | ||
681 | will be called stm32-dfsdm-core. | ||
682 | |||
683 | config STM32_DFSDM_ADC | ||
684 | tristate "STMicroelectronics STM32 dfsdm adc" | ||
685 | depends on (ARCH_STM32 && OF) || COMPILE_TEST | ||
686 | select STM32_DFSDM_CORE | ||
687 | select REGMAP_MMIO | ||
688 | select IIO_BUFFER_HW_CONSUMER | ||
689 | help | ||
690 | Select this option to support ADCSigma delta modulator for | ||
691 | STMicroelectronics STM32 digital filter for sigma delta converter. | ||
692 | |||
693 | This driver can also be built as a module. If so, the module | ||
694 | will be called stm32-dfsdm-adc. | ||
695 | |||
659 | config STX104 | 696 | config STX104 |
660 | tristate "Apex Embedded Systems STX104 driver" | 697 | tristate "Apex Embedded Systems STX104 driver" |
661 | depends on PC104 && X86 && ISA_BUS_API | 698 | depends on PC104 && X86 && ISA_BUS_API |
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index 9572c1090f35..28a9423997f3 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile | |||
@@ -64,6 +64,8 @@ obj-$(CONFIG_STX104) += stx104.o | |||
64 | obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o | 64 | obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o |
65 | obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o | 65 | obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o |
66 | obj-$(CONFIG_STM32_ADC) += stm32-adc.o | 66 | obj-$(CONFIG_STM32_ADC) += stm32-adc.o |
67 | obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o | ||
68 | obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o | ||
67 | obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o | 69 | obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o |
68 | obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o | 70 | obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o |
69 | obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o | 71 | obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o |
@@ -82,3 +84,4 @@ obj-$(CONFIG_VF610_ADC) += vf610_adc.o | |||
82 | obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o | 84 | obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o |
83 | xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o | 85 | xilinx-xadc-y := xilinx-xadc-core.o xilinx-xadc-events.o |
84 | obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o | 86 | obj-$(CONFIG_XILINX_XADC) += xilinx-xadc.o |
87 | obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o | ||
diff --git a/drivers/iio/adc/sd_adc_modulator.c b/drivers/iio/adc/sd_adc_modulator.c new file mode 100644 index 000000000000..560d8c7d9d86 --- /dev/null +++ b/drivers/iio/adc/sd_adc_modulator.c | |||
@@ -0,0 +1,68 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Generic sigma delta modulator driver | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>. | ||
7 | */ | ||
8 | |||
9 | #include <linux/iio/iio.h> | ||
10 | #include <linux/iio/triggered_buffer.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/of_device.h> | ||
13 | |||
14 | static const struct iio_info iio_sd_mod_iio_info; | ||
15 | |||
16 | static const struct iio_chan_spec iio_sd_mod_ch = { | ||
17 | .type = IIO_VOLTAGE, | ||
18 | .indexed = 1, | ||
19 | .scan_type = { | ||
20 | .sign = 'u', | ||
21 | .realbits = 1, | ||
22 | .shift = 0, | ||
23 | }, | ||
24 | }; | ||
25 | |||
26 | static int iio_sd_mod_probe(struct platform_device *pdev) | ||
27 | { | ||
28 | struct device *dev = &pdev->dev; | ||
29 | struct iio_dev *iio; | ||
30 | |||
31 | iio = devm_iio_device_alloc(dev, 0); | ||
32 | if (!iio) | ||
33 | return -ENOMEM; | ||
34 | |||
35 | iio->dev.parent = dev; | ||
36 | iio->dev.of_node = dev->of_node; | ||
37 | iio->name = dev_name(dev); | ||
38 | iio->info = &iio_sd_mod_iio_info; | ||
39 | iio->modes = INDIO_BUFFER_HARDWARE; | ||
40 | |||
41 | iio->num_channels = 1; | ||
42 | iio->channels = &iio_sd_mod_ch; | ||
43 | |||
44 | platform_set_drvdata(pdev, iio); | ||
45 | |||
46 | return devm_iio_device_register(&pdev->dev, iio); | ||
47 | } | ||
48 | |||
49 | static const struct of_device_id sd_adc_of_match[] = { | ||
50 | { .compatible = "sd-modulator" }, | ||
51 | { .compatible = "ads1201" }, | ||
52 | { } | ||
53 | }; | ||
54 | MODULE_DEVICE_TABLE(of, sd_adc_of_match); | ||
55 | |||
56 | static struct platform_driver iio_sd_mod_adc = { | ||
57 | .driver = { | ||
58 | .name = "iio_sd_adc_mod", | ||
59 | .of_match_table = of_match_ptr(sd_adc_of_match), | ||
60 | }, | ||
61 | .probe = iio_sd_mod_probe, | ||
62 | }; | ||
63 | |||
64 | module_platform_driver(iio_sd_mod_adc); | ||
65 | |||
66 | MODULE_DESCRIPTION("Basic sigma delta modulator"); | ||
67 | MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); | ||
68 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/adc/stm32-dfsdm-adc.c b/drivers/iio/adc/stm32-dfsdm-adc.c new file mode 100644 index 000000000000..daa026d6a94f --- /dev/null +++ b/drivers/iio/adc/stm32-dfsdm-adc.c | |||
@@ -0,0 +1,1205 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * This file is the ADC part of the STM32 DFSDM driver | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Author: Arnaud Pouliquen <arnaud.pouliquen@st.com>. | ||
7 | */ | ||
8 | |||
9 | #include <linux/dmaengine.h> | ||
10 | #include <linux/dma-mapping.h> | ||
11 | #include <linux/interrupt.h> | ||
12 | #include <linux/iio/buffer.h> | ||
13 | #include <linux/iio/hw-consumer.h> | ||
14 | #include <linux/iio/iio.h> | ||
15 | #include <linux/iio/sysfs.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/regmap.h> | ||
20 | #include <linux/slab.h> | ||
21 | |||
22 | #include "stm32-dfsdm.h" | ||
23 | |||
24 | #define DFSDM_DMA_BUFFER_SIZE (4 * PAGE_SIZE) | ||
25 | |||
26 | /* Conversion timeout */ | ||
27 | #define DFSDM_TIMEOUT_US 100000 | ||
28 | #define DFSDM_TIMEOUT (msecs_to_jiffies(DFSDM_TIMEOUT_US / 1000)) | ||
29 | |||
30 | /* Oversampling attribute default */ | ||
31 | #define DFSDM_DEFAULT_OVERSAMPLING 100 | ||
32 | |||
33 | /* Oversampling max values */ | ||
34 | #define DFSDM_MAX_INT_OVERSAMPLING 256 | ||
35 | #define DFSDM_MAX_FL_OVERSAMPLING 1024 | ||
36 | |||
37 | /* Max sample resolutions */ | ||
38 | #define DFSDM_MAX_RES BIT(31) | ||
39 | #define DFSDM_DATA_RES BIT(23) | ||
40 | |||
41 | enum sd_converter_type { | ||
42 | DFSDM_AUDIO, | ||
43 | DFSDM_IIO, | ||
44 | }; | ||
45 | |||
46 | struct stm32_dfsdm_dev_data { | ||
47 | int type; | ||
48 | int (*init)(struct iio_dev *indio_dev); | ||
49 | unsigned int num_channels; | ||
50 | const struct regmap_config *regmap_cfg; | ||
51 | }; | ||
52 | |||
53 | struct stm32_dfsdm_adc { | ||
54 | struct stm32_dfsdm *dfsdm; | ||
55 | const struct stm32_dfsdm_dev_data *dev_data; | ||
56 | unsigned int fl_id; | ||
57 | unsigned int ch_id; | ||
58 | |||
59 | /* ADC specific */ | ||
60 | unsigned int oversamp; | ||
61 | struct iio_hw_consumer *hwc; | ||
62 | struct completion completion; | ||
63 | u32 *buffer; | ||
64 | |||
65 | /* Audio specific */ | ||
66 | unsigned int spi_freq; /* SPI bus clock frequency */ | ||
67 | unsigned int sample_freq; /* Sample frequency after filter decimation */ | ||
68 | int (*cb)(const void *data, size_t size, void *cb_priv); | ||
69 | void *cb_priv; | ||
70 | |||
71 | /* DMA */ | ||
72 | u8 *rx_buf; | ||
73 | unsigned int bufi; /* Buffer current position */ | ||
74 | unsigned int buf_sz; /* Buffer size */ | ||
75 | struct dma_chan *dma_chan; | ||
76 | dma_addr_t dma_buf; | ||
77 | }; | ||
78 | |||
79 | struct stm32_dfsdm_str2field { | ||
80 | const char *name; | ||
81 | unsigned int val; | ||
82 | }; | ||
83 | |||
84 | /* DFSDM channel serial interface type */ | ||
85 | static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_type[] = { | ||
86 | { "SPI_R", 0 }, /* SPI with data on rising edge */ | ||
87 | { "SPI_F", 1 }, /* SPI with data on falling edge */ | ||
88 | { "MANCH_R", 2 }, /* Manchester codec, rising edge = logic 0 */ | ||
89 | { "MANCH_F", 3 }, /* Manchester codec, falling edge = logic 1 */ | ||
90 | {}, | ||
91 | }; | ||
92 | |||
93 | /* DFSDM channel clock source */ | ||
94 | static const struct stm32_dfsdm_str2field stm32_dfsdm_chan_src[] = { | ||
95 | /* External SPI clock (CLKIN x) */ | ||
96 | { "CLKIN", DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL }, | ||
97 | /* Internal SPI clock (CLKOUT) */ | ||
98 | { "CLKOUT", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL }, | ||
99 | /* Internal SPI clock divided by 2 (falling edge) */ | ||
100 | { "CLKOUT_F", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING }, | ||
101 | /* Internal SPI clock divided by 2 (falling edge) */ | ||
102 | { "CLKOUT_R", DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING }, | ||
103 | {}, | ||
104 | }; | ||
105 | |||
106 | static int stm32_dfsdm_str2val(const char *str, | ||
107 | const struct stm32_dfsdm_str2field *list) | ||
108 | { | ||
109 | const struct stm32_dfsdm_str2field *p = list; | ||
110 | |||
111 | for (p = list; p && p->name; p++) | ||
112 | if (!strcmp(p->name, str)) | ||
113 | return p->val; | ||
114 | |||
115 | return -EINVAL; | ||
116 | } | ||
117 | |||
118 | static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl, | ||
119 | unsigned int fast, unsigned int oversamp) | ||
120 | { | ||
121 | unsigned int i, d, fosr, iosr; | ||
122 | u64 res; | ||
123 | s64 delta; | ||
124 | unsigned int m = 1; /* multiplication factor */ | ||
125 | unsigned int p = fl->ford; /* filter order (ford) */ | ||
126 | |||
127 | pr_debug("%s: Requested oversampling: %d\n", __func__, oversamp); | ||
128 | /* | ||
129 | * This function tries to compute filter oversampling and integrator | ||
130 | * oversampling, base on oversampling ratio requested by user. | ||
131 | * | ||
132 | * Decimation d depends on the filter order and the oversampling ratios. | ||
133 | * ford: filter order | ||
134 | * fosr: filter over sampling ratio | ||
135 | * iosr: integrator over sampling ratio | ||
136 | */ | ||
137 | if (fl->ford == DFSDM_FASTSINC_ORDER) { | ||
138 | m = 2; | ||
139 | p = 2; | ||
140 | } | ||
141 | |||
142 | /* | ||
143 | * Look for filter and integrator oversampling ratios which allows | ||
144 | * to reach 24 bits data output resolution. | ||
145 | * Leave as soon as if exact resolution if reached. | ||
146 | * Otherwise the higher resolution below 32 bits is kept. | ||
147 | */ | ||
148 | for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) { | ||
149 | for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) { | ||
150 | if (fast) | ||
151 | d = fosr * iosr; | ||
152 | else if (fl->ford == DFSDM_FASTSINC_ORDER) | ||
153 | d = fosr * (iosr + 3) + 2; | ||
154 | else | ||
155 | d = fosr * (iosr - 1 + p) + p; | ||
156 | |||
157 | if (d > oversamp) | ||
158 | break; | ||
159 | else if (d != oversamp) | ||
160 | continue; | ||
161 | /* | ||
162 | * Check resolution (limited to signed 32 bits) | ||
163 | * res <= 2^31 | ||
164 | * Sincx filters: | ||
165 | * res = m * fosr^p x iosr (with m=1, p=ford) | ||
166 | * FastSinc filter | ||
167 | * res = m * fosr^p x iosr (with m=2, p=2) | ||
168 | */ | ||
169 | res = fosr; | ||
170 | for (i = p - 1; i > 0; i--) { | ||
171 | res = res * (u64)fosr; | ||
172 | if (res > DFSDM_MAX_RES) | ||
173 | break; | ||
174 | } | ||
175 | if (res > DFSDM_MAX_RES) | ||
176 | continue; | ||
177 | res = res * (u64)m * (u64)iosr; | ||
178 | if (res > DFSDM_MAX_RES) | ||
179 | continue; | ||
180 | |||
181 | delta = res - DFSDM_DATA_RES; | ||
182 | |||
183 | if (res >= fl->res) { | ||
184 | fl->res = res; | ||
185 | fl->fosr = fosr; | ||
186 | fl->iosr = iosr; | ||
187 | fl->fast = fast; | ||
188 | pr_debug("%s: fosr = %d, iosr = %d\n", | ||
189 | __func__, fl->fosr, fl->iosr); | ||
190 | } | ||
191 | |||
192 | if (!delta) | ||
193 | return 0; | ||
194 | } | ||
195 | } | ||
196 | |||
197 | if (!fl->fosr) | ||
198 | return -EINVAL; | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int stm32_dfsdm_start_channel(struct stm32_dfsdm *dfsdm, | ||
204 | unsigned int ch_id) | ||
205 | { | ||
206 | return regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id), | ||
207 | DFSDM_CHCFGR1_CHEN_MASK, | ||
208 | DFSDM_CHCFGR1_CHEN(1)); | ||
209 | } | ||
210 | |||
211 | static void stm32_dfsdm_stop_channel(struct stm32_dfsdm *dfsdm, | ||
212 | unsigned int ch_id) | ||
213 | { | ||
214 | regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(ch_id), | ||
215 | DFSDM_CHCFGR1_CHEN_MASK, DFSDM_CHCFGR1_CHEN(0)); | ||
216 | } | ||
217 | |||
218 | static int stm32_dfsdm_chan_configure(struct stm32_dfsdm *dfsdm, | ||
219 | struct stm32_dfsdm_channel *ch) | ||
220 | { | ||
221 | unsigned int id = ch->id; | ||
222 | struct regmap *regmap = dfsdm->regmap; | ||
223 | int ret; | ||
224 | |||
225 | ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(id), | ||
226 | DFSDM_CHCFGR1_SITP_MASK, | ||
227 | DFSDM_CHCFGR1_SITP(ch->type)); | ||
228 | if (ret < 0) | ||
229 | return ret; | ||
230 | ret = regmap_update_bits(regmap, DFSDM_CHCFGR1(id), | ||
231 | DFSDM_CHCFGR1_SPICKSEL_MASK, | ||
232 | DFSDM_CHCFGR1_SPICKSEL(ch->src)); | ||
233 | if (ret < 0) | ||
234 | return ret; | ||
235 | return regmap_update_bits(regmap, DFSDM_CHCFGR1(id), | ||
236 | DFSDM_CHCFGR1_CHINSEL_MASK, | ||
237 | DFSDM_CHCFGR1_CHINSEL(ch->alt_si)); | ||
238 | } | ||
239 | |||
240 | static int stm32_dfsdm_start_filter(struct stm32_dfsdm *dfsdm, | ||
241 | unsigned int fl_id) | ||
242 | { | ||
243 | int ret; | ||
244 | |||
245 | /* Enable filter */ | ||
246 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id), | ||
247 | DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(1)); | ||
248 | if (ret < 0) | ||
249 | return ret; | ||
250 | |||
251 | /* Start conversion */ | ||
252 | return regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id), | ||
253 | DFSDM_CR1_RSWSTART_MASK, | ||
254 | DFSDM_CR1_RSWSTART(1)); | ||
255 | } | ||
256 | |||
257 | static void stm32_dfsdm_stop_filter(struct stm32_dfsdm *dfsdm, unsigned int fl_id) | ||
258 | { | ||
259 | /* Disable conversion */ | ||
260 | regmap_update_bits(dfsdm->regmap, DFSDM_CR1(fl_id), | ||
261 | DFSDM_CR1_DFEN_MASK, DFSDM_CR1_DFEN(0)); | ||
262 | } | ||
263 | |||
264 | static int stm32_dfsdm_filter_configure(struct stm32_dfsdm *dfsdm, | ||
265 | unsigned int fl_id, unsigned int ch_id) | ||
266 | { | ||
267 | struct regmap *regmap = dfsdm->regmap; | ||
268 | struct stm32_dfsdm_filter *fl = &dfsdm->fl_list[fl_id]; | ||
269 | int ret; | ||
270 | |||
271 | /* Average integrator oversampling */ | ||
272 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_IOSR_MASK, | ||
273 | DFSDM_FCR_IOSR(fl->iosr - 1)); | ||
274 | if (ret) | ||
275 | return ret; | ||
276 | |||
277 | /* Filter order and Oversampling */ | ||
278 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FOSR_MASK, | ||
279 | DFSDM_FCR_FOSR(fl->fosr - 1)); | ||
280 | if (ret) | ||
281 | return ret; | ||
282 | |||
283 | ret = regmap_update_bits(regmap, DFSDM_FCR(fl_id), DFSDM_FCR_FORD_MASK, | ||
284 | DFSDM_FCR_FORD(fl->ford)); | ||
285 | if (ret) | ||
286 | return ret; | ||
287 | |||
288 | /* No scan mode supported for the moment */ | ||
289 | ret = regmap_update_bits(regmap, DFSDM_CR1(fl_id), DFSDM_CR1_RCH_MASK, | ||
290 | DFSDM_CR1_RCH(ch_id)); | ||
291 | if (ret) | ||
292 | return ret; | ||
293 | |||
294 | return regmap_update_bits(regmap, DFSDM_CR1(fl_id), | ||
295 | DFSDM_CR1_RSYNC_MASK, | ||
296 | DFSDM_CR1_RSYNC(fl->sync_mode)); | ||
297 | } | ||
298 | |||
299 | static int stm32_dfsdm_channel_parse_of(struct stm32_dfsdm *dfsdm, | ||
300 | struct iio_dev *indio_dev, | ||
301 | struct iio_chan_spec *ch) | ||
302 | { | ||
303 | struct stm32_dfsdm_channel *df_ch; | ||
304 | const char *of_str; | ||
305 | int chan_idx = ch->scan_index; | ||
306 | int ret, val; | ||
307 | |||
308 | ret = of_property_read_u32_index(indio_dev->dev.of_node, | ||
309 | "st,adc-channels", chan_idx, | ||
310 | &ch->channel); | ||
311 | if (ret < 0) { | ||
312 | dev_err(&indio_dev->dev, | ||
313 | " Error parsing 'st,adc-channels' for idx %d\n", | ||
314 | chan_idx); | ||
315 | return ret; | ||
316 | } | ||
317 | if (ch->channel >= dfsdm->num_chs) { | ||
318 | dev_err(&indio_dev->dev, | ||
319 | " Error bad channel number %d (max = %d)\n", | ||
320 | ch->channel, dfsdm->num_chs); | ||
321 | return -EINVAL; | ||
322 | } | ||
323 | |||
324 | ret = of_property_read_string_index(indio_dev->dev.of_node, | ||
325 | "st,adc-channel-names", chan_idx, | ||
326 | &ch->datasheet_name); | ||
327 | if (ret < 0) { | ||
328 | dev_err(&indio_dev->dev, | ||
329 | " Error parsing 'st,adc-channel-names' for idx %d\n", | ||
330 | chan_idx); | ||
331 | return ret; | ||
332 | } | ||
333 | |||
334 | df_ch = &dfsdm->ch_list[ch->channel]; | ||
335 | df_ch->id = ch->channel; | ||
336 | |||
337 | ret = of_property_read_string_index(indio_dev->dev.of_node, | ||
338 | "st,adc-channel-types", chan_idx, | ||
339 | &of_str); | ||
340 | if (!ret) { | ||
341 | val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_type); | ||
342 | if (val < 0) | ||
343 | return val; | ||
344 | } else { | ||
345 | val = 0; | ||
346 | } | ||
347 | df_ch->type = val; | ||
348 | |||
349 | ret = of_property_read_string_index(indio_dev->dev.of_node, | ||
350 | "st,adc-channel-clk-src", chan_idx, | ||
351 | &of_str); | ||
352 | if (!ret) { | ||
353 | val = stm32_dfsdm_str2val(of_str, stm32_dfsdm_chan_src); | ||
354 | if (val < 0) | ||
355 | return val; | ||
356 | } else { | ||
357 | val = 0; | ||
358 | } | ||
359 | df_ch->src = val; | ||
360 | |||
361 | ret = of_property_read_u32_index(indio_dev->dev.of_node, | ||
362 | "st,adc-alt-channel", chan_idx, | ||
363 | &df_ch->alt_si); | ||
364 | if (ret < 0) | ||
365 | df_ch->alt_si = 0; | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
370 | static ssize_t dfsdm_adc_audio_get_spiclk(struct iio_dev *indio_dev, | ||
371 | uintptr_t priv, | ||
372 | const struct iio_chan_spec *chan, | ||
373 | char *buf) | ||
374 | { | ||
375 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
376 | |||
377 | return snprintf(buf, PAGE_SIZE, "%d\n", adc->spi_freq); | ||
378 | } | ||
379 | |||
380 | static ssize_t dfsdm_adc_audio_set_spiclk(struct iio_dev *indio_dev, | ||
381 | uintptr_t priv, | ||
382 | const struct iio_chan_spec *chan, | ||
383 | const char *buf, size_t len) | ||
384 | { | ||
385 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
386 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | ||
387 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; | ||
388 | unsigned int sample_freq = adc->sample_freq; | ||
389 | unsigned int spi_freq; | ||
390 | int ret; | ||
391 | |||
392 | dev_err(&indio_dev->dev, "enter %s\n", __func__); | ||
393 | /* If DFSDM is master on SPI, SPI freq can not be updated */ | ||
394 | if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) | ||
395 | return -EPERM; | ||
396 | |||
397 | ret = kstrtoint(buf, 0, &spi_freq); | ||
398 | if (ret) | ||
399 | return ret; | ||
400 | |||
401 | if (!spi_freq) | ||
402 | return -EINVAL; | ||
403 | |||
404 | if (sample_freq) { | ||
405 | if (spi_freq % sample_freq) | ||
406 | dev_warn(&indio_dev->dev, | ||
407 | "Sampling rate not accurate (%d)\n", | ||
408 | spi_freq / (spi_freq / sample_freq)); | ||
409 | |||
410 | ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / sample_freq)); | ||
411 | if (ret < 0) { | ||
412 | dev_err(&indio_dev->dev, | ||
413 | "No filter parameters that match!\n"); | ||
414 | return ret; | ||
415 | } | ||
416 | } | ||
417 | adc->spi_freq = spi_freq; | ||
418 | |||
419 | return len; | ||
420 | } | ||
421 | |||
422 | static int stm32_dfsdm_start_conv(struct stm32_dfsdm_adc *adc, bool dma) | ||
423 | { | ||
424 | struct regmap *regmap = adc->dfsdm->regmap; | ||
425 | int ret; | ||
426 | unsigned int dma_en = 0, cont_en = 0; | ||
427 | |||
428 | ret = stm32_dfsdm_start_channel(adc->dfsdm, adc->ch_id); | ||
429 | if (ret < 0) | ||
430 | return ret; | ||
431 | |||
432 | ret = stm32_dfsdm_filter_configure(adc->dfsdm, adc->fl_id, | ||
433 | adc->ch_id); | ||
434 | if (ret < 0) | ||
435 | goto stop_channels; | ||
436 | |||
437 | if (dma) { | ||
438 | /* Enable DMA transfer*/ | ||
439 | dma_en = DFSDM_CR1_RDMAEN(1); | ||
440 | /* Enable conversion triggered by SPI clock*/ | ||
441 | cont_en = DFSDM_CR1_RCONT(1); | ||
442 | } | ||
443 | /* Enable DMA transfer*/ | ||
444 | ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | ||
445 | DFSDM_CR1_RDMAEN_MASK, dma_en); | ||
446 | if (ret < 0) | ||
447 | goto stop_channels; | ||
448 | |||
449 | /* Enable conversion triggered by SPI clock*/ | ||
450 | ret = regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | ||
451 | DFSDM_CR1_RCONT_MASK, cont_en); | ||
452 | if (ret < 0) | ||
453 | goto stop_channels; | ||
454 | |||
455 | ret = stm32_dfsdm_start_filter(adc->dfsdm, adc->fl_id); | ||
456 | if (ret < 0) | ||
457 | goto stop_channels; | ||
458 | |||
459 | return 0; | ||
460 | |||
461 | stop_channels: | ||
462 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | ||
463 | DFSDM_CR1_RDMAEN_MASK, 0); | ||
464 | |||
465 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | ||
466 | DFSDM_CR1_RCONT_MASK, 0); | ||
467 | stm32_dfsdm_stop_channel(adc->dfsdm, adc->fl_id); | ||
468 | |||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | static void stm32_dfsdm_stop_conv(struct stm32_dfsdm_adc *adc) | ||
473 | { | ||
474 | struct regmap *regmap = adc->dfsdm->regmap; | ||
475 | |||
476 | stm32_dfsdm_stop_filter(adc->dfsdm, adc->fl_id); | ||
477 | |||
478 | /* Clean conversion options */ | ||
479 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | ||
480 | DFSDM_CR1_RDMAEN_MASK, 0); | ||
481 | |||
482 | regmap_update_bits(regmap, DFSDM_CR1(adc->fl_id), | ||
483 | DFSDM_CR1_RCONT_MASK, 0); | ||
484 | |||
485 | stm32_dfsdm_stop_channel(adc->dfsdm, adc->ch_id); | ||
486 | } | ||
487 | |||
488 | static int stm32_dfsdm_set_watermark(struct iio_dev *indio_dev, | ||
489 | unsigned int val) | ||
490 | { | ||
491 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
492 | unsigned int watermark = DFSDM_DMA_BUFFER_SIZE / 2; | ||
493 | |||
494 | /* | ||
495 | * DMA cyclic transfers are used, buffer is split into two periods. | ||
496 | * There should be : | ||
497 | * - always one buffer (period) DMA is working on | ||
498 | * - one buffer (period) driver pushed to ASoC side. | ||
499 | */ | ||
500 | watermark = min(watermark, val * (unsigned int)(sizeof(u32))); | ||
501 | adc->buf_sz = watermark * 2; | ||
502 | |||
503 | return 0; | ||
504 | } | ||
505 | |||
506 | static unsigned int stm32_dfsdm_adc_dma_residue(struct stm32_dfsdm_adc *adc) | ||
507 | { | ||
508 | struct dma_tx_state state; | ||
509 | enum dma_status status; | ||
510 | |||
511 | status = dmaengine_tx_status(adc->dma_chan, | ||
512 | adc->dma_chan->cookie, | ||
513 | &state); | ||
514 | if (status == DMA_IN_PROGRESS) { | ||
515 | /* Residue is size in bytes from end of buffer */ | ||
516 | unsigned int i = adc->buf_sz - state.residue; | ||
517 | unsigned int size; | ||
518 | |||
519 | /* Return available bytes */ | ||
520 | if (i >= adc->bufi) | ||
521 | size = i - adc->bufi; | ||
522 | else | ||
523 | size = adc->buf_sz + i - adc->bufi; | ||
524 | |||
525 | return size; | ||
526 | } | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | static void stm32_dfsdm_audio_dma_buffer_done(void *data) | ||
532 | { | ||
533 | struct iio_dev *indio_dev = data; | ||
534 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
535 | int available = stm32_dfsdm_adc_dma_residue(adc); | ||
536 | size_t old_pos; | ||
537 | |||
538 | /* | ||
539 | * FIXME: In Kernel interface does not support cyclic DMA buffer,and | ||
540 | * offers only an interface to push data samples per samples. | ||
541 | * For this reason IIO buffer interface is not used and interface is | ||
542 | * bypassed using a private callback registered by ASoC. | ||
543 | * This should be a temporary solution waiting a cyclic DMA engine | ||
544 | * support in IIO. | ||
545 | */ | ||
546 | |||
547 | dev_dbg(&indio_dev->dev, "%s: pos = %d, available = %d\n", __func__, | ||
548 | adc->bufi, available); | ||
549 | old_pos = adc->bufi; | ||
550 | |||
551 | while (available >= indio_dev->scan_bytes) { | ||
552 | u32 *buffer = (u32 *)&adc->rx_buf[adc->bufi]; | ||
553 | |||
554 | /* Mask 8 LSB that contains the channel ID */ | ||
555 | *buffer = (*buffer & 0xFFFFFF00) << 8; | ||
556 | available -= indio_dev->scan_bytes; | ||
557 | adc->bufi += indio_dev->scan_bytes; | ||
558 | if (adc->bufi >= adc->buf_sz) { | ||
559 | if (adc->cb) | ||
560 | adc->cb(&adc->rx_buf[old_pos], | ||
561 | adc->buf_sz - old_pos, adc->cb_priv); | ||
562 | adc->bufi = 0; | ||
563 | old_pos = 0; | ||
564 | } | ||
565 | } | ||
566 | if (adc->cb) | ||
567 | adc->cb(&adc->rx_buf[old_pos], adc->bufi - old_pos, | ||
568 | adc->cb_priv); | ||
569 | } | ||
570 | |||
571 | static int stm32_dfsdm_adc_dma_start(struct iio_dev *indio_dev) | ||
572 | { | ||
573 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
574 | struct dma_async_tx_descriptor *desc; | ||
575 | dma_cookie_t cookie; | ||
576 | int ret; | ||
577 | |||
578 | if (!adc->dma_chan) | ||
579 | return -EINVAL; | ||
580 | |||
581 | dev_dbg(&indio_dev->dev, "%s size=%d watermark=%d\n", __func__, | ||
582 | adc->buf_sz, adc->buf_sz / 2); | ||
583 | |||
584 | /* Prepare a DMA cyclic transaction */ | ||
585 | desc = dmaengine_prep_dma_cyclic(adc->dma_chan, | ||
586 | adc->dma_buf, | ||
587 | adc->buf_sz, adc->buf_sz / 2, | ||
588 | DMA_DEV_TO_MEM, | ||
589 | DMA_PREP_INTERRUPT); | ||
590 | if (!desc) | ||
591 | return -EBUSY; | ||
592 | |||
593 | desc->callback = stm32_dfsdm_audio_dma_buffer_done; | ||
594 | desc->callback_param = indio_dev; | ||
595 | |||
596 | cookie = dmaengine_submit(desc); | ||
597 | ret = dma_submit_error(cookie); | ||
598 | if (ret) { | ||
599 | dmaengine_terminate_all(adc->dma_chan); | ||
600 | return ret; | ||
601 | } | ||
602 | |||
603 | /* Issue pending DMA requests */ | ||
604 | dma_async_issue_pending(adc->dma_chan); | ||
605 | |||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static int stm32_dfsdm_postenable(struct iio_dev *indio_dev) | ||
610 | { | ||
611 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
612 | int ret; | ||
613 | |||
614 | /* Reset adc buffer index */ | ||
615 | adc->bufi = 0; | ||
616 | |||
617 | ret = stm32_dfsdm_start_dfsdm(adc->dfsdm); | ||
618 | if (ret < 0) | ||
619 | return ret; | ||
620 | |||
621 | ret = stm32_dfsdm_start_conv(adc, true); | ||
622 | if (ret) { | ||
623 | dev_err(&indio_dev->dev, "Can't start conversion\n"); | ||
624 | goto stop_dfsdm; | ||
625 | } | ||
626 | |||
627 | if (adc->dma_chan) { | ||
628 | ret = stm32_dfsdm_adc_dma_start(indio_dev); | ||
629 | if (ret) { | ||
630 | dev_err(&indio_dev->dev, "Can't start DMA\n"); | ||
631 | goto err_stop_conv; | ||
632 | } | ||
633 | } | ||
634 | |||
635 | return 0; | ||
636 | |||
637 | err_stop_conv: | ||
638 | stm32_dfsdm_stop_conv(adc); | ||
639 | stop_dfsdm: | ||
640 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); | ||
641 | |||
642 | return ret; | ||
643 | } | ||
644 | |||
645 | static int stm32_dfsdm_predisable(struct iio_dev *indio_dev) | ||
646 | { | ||
647 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
648 | |||
649 | if (adc->dma_chan) | ||
650 | dmaengine_terminate_all(adc->dma_chan); | ||
651 | |||
652 | stm32_dfsdm_stop_conv(adc); | ||
653 | |||
654 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); | ||
655 | |||
656 | return 0; | ||
657 | } | ||
658 | |||
659 | static const struct iio_buffer_setup_ops stm32_dfsdm_buffer_setup_ops = { | ||
660 | .postenable = &stm32_dfsdm_postenable, | ||
661 | .predisable = &stm32_dfsdm_predisable, | ||
662 | }; | ||
663 | |||
664 | /** | ||
665 | * stm32_dfsdm_get_buff_cb() - register a callback that will be called when | ||
666 | * DMA transfer period is achieved. | ||
667 | * | ||
668 | * @iio_dev: Handle to IIO device. | ||
669 | * @cb: Pointer to callback function: | ||
670 | * - data: pointer to data buffer | ||
671 | * - size: size in byte of the data buffer | ||
672 | * - private: pointer to consumer private structure. | ||
673 | * @private: Pointer to consumer private structure. | ||
674 | */ | ||
675 | int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev, | ||
676 | int (*cb)(const void *data, size_t size, | ||
677 | void *private), | ||
678 | void *private) | ||
679 | { | ||
680 | struct stm32_dfsdm_adc *adc; | ||
681 | |||
682 | if (!iio_dev) | ||
683 | return -EINVAL; | ||
684 | adc = iio_priv(iio_dev); | ||
685 | |||
686 | adc->cb = cb; | ||
687 | adc->cb_priv = private; | ||
688 | |||
689 | return 0; | ||
690 | } | ||
691 | EXPORT_SYMBOL_GPL(stm32_dfsdm_get_buff_cb); | ||
692 | |||
693 | /** | ||
694 | * stm32_dfsdm_release_buff_cb - unregister buffer callback | ||
695 | * | ||
696 | * @iio_dev: Handle to IIO device. | ||
697 | */ | ||
698 | int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev) | ||
699 | { | ||
700 | struct stm32_dfsdm_adc *adc; | ||
701 | |||
702 | if (!iio_dev) | ||
703 | return -EINVAL; | ||
704 | adc = iio_priv(iio_dev); | ||
705 | |||
706 | adc->cb = NULL; | ||
707 | adc->cb_priv = NULL; | ||
708 | |||
709 | return 0; | ||
710 | } | ||
711 | EXPORT_SYMBOL_GPL(stm32_dfsdm_release_buff_cb); | ||
712 | |||
713 | static int stm32_dfsdm_single_conv(struct iio_dev *indio_dev, | ||
714 | const struct iio_chan_spec *chan, int *res) | ||
715 | { | ||
716 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
717 | long timeout; | ||
718 | int ret; | ||
719 | |||
720 | reinit_completion(&adc->completion); | ||
721 | |||
722 | adc->buffer = res; | ||
723 | |||
724 | ret = stm32_dfsdm_start_dfsdm(adc->dfsdm); | ||
725 | if (ret < 0) | ||
726 | return ret; | ||
727 | |||
728 | ret = regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), | ||
729 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(1)); | ||
730 | if (ret < 0) | ||
731 | goto stop_dfsdm; | ||
732 | |||
733 | ret = stm32_dfsdm_start_conv(adc, false); | ||
734 | if (ret < 0) { | ||
735 | regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), | ||
736 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); | ||
737 | goto stop_dfsdm; | ||
738 | } | ||
739 | |||
740 | timeout = wait_for_completion_interruptible_timeout(&adc->completion, | ||
741 | DFSDM_TIMEOUT); | ||
742 | |||
743 | /* Mask IRQ for regular conversion achievement*/ | ||
744 | regmap_update_bits(adc->dfsdm->regmap, DFSDM_CR2(adc->fl_id), | ||
745 | DFSDM_CR2_REOCIE_MASK, DFSDM_CR2_REOCIE(0)); | ||
746 | |||
747 | if (timeout == 0) | ||
748 | ret = -ETIMEDOUT; | ||
749 | else if (timeout < 0) | ||
750 | ret = timeout; | ||
751 | else | ||
752 | ret = IIO_VAL_INT; | ||
753 | |||
754 | stm32_dfsdm_stop_conv(adc); | ||
755 | |||
756 | stop_dfsdm: | ||
757 | stm32_dfsdm_stop_dfsdm(adc->dfsdm); | ||
758 | |||
759 | return ret; | ||
760 | } | ||
761 | |||
762 | static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev, | ||
763 | struct iio_chan_spec const *chan, | ||
764 | int val, int val2, long mask) | ||
765 | { | ||
766 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
767 | struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id]; | ||
768 | struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[adc->ch_id]; | ||
769 | unsigned int spi_freq = adc->spi_freq; | ||
770 | int ret = -EINVAL; | ||
771 | |||
772 | switch (mask) { | ||
773 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: | ||
774 | ret = stm32_dfsdm_set_osrs(fl, 0, val); | ||
775 | if (!ret) | ||
776 | adc->oversamp = val; | ||
777 | |||
778 | return ret; | ||
779 | |||
780 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
781 | if (!val) | ||
782 | return -EINVAL; | ||
783 | if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) | ||
784 | spi_freq = adc->dfsdm->spi_master_freq; | ||
785 | |||
786 | if (spi_freq % val) | ||
787 | dev_warn(&indio_dev->dev, | ||
788 | "Sampling rate not accurate (%d)\n", | ||
789 | spi_freq / (spi_freq / val)); | ||
790 | |||
791 | ret = stm32_dfsdm_set_osrs(fl, 0, (spi_freq / val)); | ||
792 | if (ret < 0) { | ||
793 | dev_err(&indio_dev->dev, | ||
794 | "Not able to find parameter that match!\n"); | ||
795 | return ret; | ||
796 | } | ||
797 | adc->sample_freq = val; | ||
798 | |||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | return -EINVAL; | ||
803 | } | ||
804 | |||
805 | static int stm32_dfsdm_read_raw(struct iio_dev *indio_dev, | ||
806 | struct iio_chan_spec const *chan, int *val, | ||
807 | int *val2, long mask) | ||
808 | { | ||
809 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
810 | int ret; | ||
811 | |||
812 | switch (mask) { | ||
813 | case IIO_CHAN_INFO_RAW: | ||
814 | ret = iio_hw_consumer_enable(adc->hwc); | ||
815 | if (ret < 0) { | ||
816 | dev_err(&indio_dev->dev, | ||
817 | "%s: IIO enable failed (channel %d)\n", | ||
818 | __func__, chan->channel); | ||
819 | return ret; | ||
820 | } | ||
821 | ret = stm32_dfsdm_single_conv(indio_dev, chan, val); | ||
822 | iio_hw_consumer_disable(adc->hwc); | ||
823 | if (ret < 0) { | ||
824 | dev_err(&indio_dev->dev, | ||
825 | "%s: Conversion failed (channel %d)\n", | ||
826 | __func__, chan->channel); | ||
827 | return ret; | ||
828 | } | ||
829 | return IIO_VAL_INT; | ||
830 | |||
831 | case IIO_CHAN_INFO_OVERSAMPLING_RATIO: | ||
832 | *val = adc->oversamp; | ||
833 | |||
834 | return IIO_VAL_INT; | ||
835 | |||
836 | case IIO_CHAN_INFO_SAMP_FREQ: | ||
837 | *val = adc->sample_freq; | ||
838 | |||
839 | return IIO_VAL_INT; | ||
840 | } | ||
841 | |||
842 | return -EINVAL; | ||
843 | } | ||
844 | |||
845 | static const struct iio_info stm32_dfsdm_info_audio = { | ||
846 | .hwfifo_set_watermark = stm32_dfsdm_set_watermark, | ||
847 | .read_raw = stm32_dfsdm_read_raw, | ||
848 | .write_raw = stm32_dfsdm_write_raw, | ||
849 | }; | ||
850 | |||
851 | static const struct iio_info stm32_dfsdm_info_adc = { | ||
852 | .read_raw = stm32_dfsdm_read_raw, | ||
853 | .write_raw = stm32_dfsdm_write_raw, | ||
854 | }; | ||
855 | |||
856 | static irqreturn_t stm32_dfsdm_irq(int irq, void *arg) | ||
857 | { | ||
858 | struct stm32_dfsdm_adc *adc = arg; | ||
859 | struct iio_dev *indio_dev = iio_priv_to_dev(adc); | ||
860 | struct regmap *regmap = adc->dfsdm->regmap; | ||
861 | unsigned int status, int_en; | ||
862 | |||
863 | regmap_read(regmap, DFSDM_ISR(adc->fl_id), &status); | ||
864 | regmap_read(regmap, DFSDM_CR2(adc->fl_id), &int_en); | ||
865 | |||
866 | if (status & DFSDM_ISR_REOCF_MASK) { | ||
867 | /* Read the data register clean the IRQ status */ | ||
868 | regmap_read(regmap, DFSDM_RDATAR(adc->fl_id), adc->buffer); | ||
869 | complete(&adc->completion); | ||
870 | } | ||
871 | |||
872 | if (status & DFSDM_ISR_ROVRF_MASK) { | ||
873 | if (int_en & DFSDM_CR2_ROVRIE_MASK) | ||
874 | dev_warn(&indio_dev->dev, "Overrun detected\n"); | ||
875 | regmap_update_bits(regmap, DFSDM_ICR(adc->fl_id), | ||
876 | DFSDM_ICR_CLRROVRF_MASK, | ||
877 | DFSDM_ICR_CLRROVRF_MASK); | ||
878 | } | ||
879 | |||
880 | return IRQ_HANDLED; | ||
881 | } | ||
882 | |||
883 | /* | ||
884 | * Define external info for SPI Frequency and audio sampling rate that can be | ||
885 | * configured by ASoC driver through consumer.h API | ||
886 | */ | ||
887 | static const struct iio_chan_spec_ext_info dfsdm_adc_audio_ext_info[] = { | ||
888 | /* spi_clk_freq : clock freq on SPI/manchester bus used by channel */ | ||
889 | { | ||
890 | .name = "spi_clk_freq", | ||
891 | .shared = IIO_SHARED_BY_TYPE, | ||
892 | .read = dfsdm_adc_audio_get_spiclk, | ||
893 | .write = dfsdm_adc_audio_set_spiclk, | ||
894 | }, | ||
895 | {}, | ||
896 | }; | ||
897 | |||
898 | static void stm32_dfsdm_dma_release(struct iio_dev *indio_dev) | ||
899 | { | ||
900 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
901 | |||
902 | if (adc->dma_chan) { | ||
903 | dma_free_coherent(adc->dma_chan->device->dev, | ||
904 | DFSDM_DMA_BUFFER_SIZE, | ||
905 | adc->rx_buf, adc->dma_buf); | ||
906 | dma_release_channel(adc->dma_chan); | ||
907 | } | ||
908 | } | ||
909 | |||
910 | static int stm32_dfsdm_dma_request(struct iio_dev *indio_dev) | ||
911 | { | ||
912 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
913 | struct dma_slave_config config = { | ||
914 | .src_addr = (dma_addr_t)adc->dfsdm->phys_base + | ||
915 | DFSDM_RDATAR(adc->fl_id), | ||
916 | .src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES, | ||
917 | }; | ||
918 | int ret; | ||
919 | |||
920 | adc->dma_chan = dma_request_slave_channel(&indio_dev->dev, "rx"); | ||
921 | if (!adc->dma_chan) | ||
922 | return -EINVAL; | ||
923 | |||
924 | adc->rx_buf = dma_alloc_coherent(adc->dma_chan->device->dev, | ||
925 | DFSDM_DMA_BUFFER_SIZE, | ||
926 | &adc->dma_buf, GFP_KERNEL); | ||
927 | if (!adc->rx_buf) { | ||
928 | ret = -ENOMEM; | ||
929 | goto err_release; | ||
930 | } | ||
931 | |||
932 | ret = dmaengine_slave_config(adc->dma_chan, &config); | ||
933 | if (ret) | ||
934 | goto err_free; | ||
935 | |||
936 | return 0; | ||
937 | |||
938 | err_free: | ||
939 | dma_free_coherent(adc->dma_chan->device->dev, DFSDM_DMA_BUFFER_SIZE, | ||
940 | adc->rx_buf, adc->dma_buf); | ||
941 | err_release: | ||
942 | dma_release_channel(adc->dma_chan); | ||
943 | |||
944 | return ret; | ||
945 | } | ||
946 | |||
947 | static int stm32_dfsdm_adc_chan_init_one(struct iio_dev *indio_dev, | ||
948 | struct iio_chan_spec *ch) | ||
949 | { | ||
950 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
951 | int ret; | ||
952 | |||
953 | ret = stm32_dfsdm_channel_parse_of(adc->dfsdm, indio_dev, ch); | ||
954 | if (ret < 0) | ||
955 | return ret; | ||
956 | |||
957 | ch->type = IIO_VOLTAGE; | ||
958 | ch->indexed = 1; | ||
959 | |||
960 | /* | ||
961 | * IIO_CHAN_INFO_RAW: used to compute regular conversion | ||
962 | * IIO_CHAN_INFO_OVERSAMPLING_RATIO: used to set oversampling | ||
963 | */ | ||
964 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); | ||
965 | ch->info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO); | ||
966 | |||
967 | if (adc->dev_data->type == DFSDM_AUDIO) { | ||
968 | ch->scan_type.sign = 's'; | ||
969 | ch->ext_info = dfsdm_adc_audio_ext_info; | ||
970 | } else { | ||
971 | ch->scan_type.sign = 'u'; | ||
972 | } | ||
973 | ch->scan_type.realbits = 24; | ||
974 | ch->scan_type.storagebits = 32; | ||
975 | adc->ch_id = ch->channel; | ||
976 | |||
977 | return stm32_dfsdm_chan_configure(adc->dfsdm, | ||
978 | &adc->dfsdm->ch_list[ch->channel]); | ||
979 | } | ||
980 | |||
981 | static int stm32_dfsdm_audio_init(struct iio_dev *indio_dev) | ||
982 | { | ||
983 | struct iio_chan_spec *ch; | ||
984 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
985 | struct stm32_dfsdm_channel *d_ch; | ||
986 | int ret; | ||
987 | |||
988 | indio_dev->modes |= INDIO_BUFFER_SOFTWARE; | ||
989 | indio_dev->setup_ops = &stm32_dfsdm_buffer_setup_ops; | ||
990 | |||
991 | ch = devm_kzalloc(&indio_dev->dev, sizeof(*ch), GFP_KERNEL); | ||
992 | if (!ch) | ||
993 | return -ENOMEM; | ||
994 | |||
995 | ch->scan_index = 0; | ||
996 | |||
997 | ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch); | ||
998 | if (ret < 0) { | ||
999 | dev_err(&indio_dev->dev, "Channels init failed\n"); | ||
1000 | return ret; | ||
1001 | } | ||
1002 | ch->info_mask_separate = BIT(IIO_CHAN_INFO_SAMP_FREQ); | ||
1003 | |||
1004 | d_ch = &adc->dfsdm->ch_list[adc->ch_id]; | ||
1005 | if (d_ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL) | ||
1006 | adc->spi_freq = adc->dfsdm->spi_master_freq; | ||
1007 | |||
1008 | indio_dev->num_channels = 1; | ||
1009 | indio_dev->channels = ch; | ||
1010 | |||
1011 | return stm32_dfsdm_dma_request(indio_dev); | ||
1012 | } | ||
1013 | |||
1014 | static int stm32_dfsdm_adc_init(struct iio_dev *indio_dev) | ||
1015 | { | ||
1016 | struct iio_chan_spec *ch; | ||
1017 | struct stm32_dfsdm_adc *adc = iio_priv(indio_dev); | ||
1018 | int num_ch; | ||
1019 | int ret, chan_idx; | ||
1020 | |||
1021 | adc->oversamp = DFSDM_DEFAULT_OVERSAMPLING; | ||
1022 | ret = stm32_dfsdm_set_osrs(&adc->dfsdm->fl_list[adc->fl_id], 0, | ||
1023 | adc->oversamp); | ||
1024 | if (ret < 0) | ||
1025 | return ret; | ||
1026 | |||
1027 | num_ch = of_property_count_u32_elems(indio_dev->dev.of_node, | ||
1028 | "st,adc-channels"); | ||
1029 | if (num_ch < 0 || num_ch > adc->dfsdm->num_chs) { | ||
1030 | dev_err(&indio_dev->dev, "Bad st,adc-channels\n"); | ||
1031 | return num_ch < 0 ? num_ch : -EINVAL; | ||
1032 | } | ||
1033 | |||
1034 | /* Bind to SD modulator IIO device */ | ||
1035 | adc->hwc = devm_iio_hw_consumer_alloc(&indio_dev->dev); | ||
1036 | if (IS_ERR(adc->hwc)) | ||
1037 | return -EPROBE_DEFER; | ||
1038 | |||
1039 | ch = devm_kcalloc(&indio_dev->dev, num_ch, sizeof(*ch), | ||
1040 | GFP_KERNEL); | ||
1041 | if (!ch) | ||
1042 | return -ENOMEM; | ||
1043 | |||
1044 | for (chan_idx = 0; chan_idx < num_ch; chan_idx++) { | ||
1045 | ch->scan_index = chan_idx; | ||
1046 | ret = stm32_dfsdm_adc_chan_init_one(indio_dev, ch); | ||
1047 | if (ret < 0) { | ||
1048 | dev_err(&indio_dev->dev, "Channels init failed\n"); | ||
1049 | return ret; | ||
1050 | } | ||
1051 | } | ||
1052 | |||
1053 | indio_dev->num_channels = num_ch; | ||
1054 | indio_dev->channels = ch; | ||
1055 | |||
1056 | init_completion(&adc->completion); | ||
1057 | |||
1058 | return 0; | ||
1059 | } | ||
1060 | |||
1061 | static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_adc_data = { | ||
1062 | .type = DFSDM_IIO, | ||
1063 | .init = stm32_dfsdm_adc_init, | ||
1064 | }; | ||
1065 | |||
1066 | static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_audio_data = { | ||
1067 | .type = DFSDM_AUDIO, | ||
1068 | .init = stm32_dfsdm_audio_init, | ||
1069 | }; | ||
1070 | |||
1071 | static const struct of_device_id stm32_dfsdm_adc_match[] = { | ||
1072 | { | ||
1073 | .compatible = "st,stm32-dfsdm-adc", | ||
1074 | .data = &stm32h7_dfsdm_adc_data, | ||
1075 | }, | ||
1076 | { | ||
1077 | .compatible = "st,stm32-dfsdm-dmic", | ||
1078 | .data = &stm32h7_dfsdm_audio_data, | ||
1079 | }, | ||
1080 | {} | ||
1081 | }; | ||
1082 | |||
1083 | static int stm32_dfsdm_adc_probe(struct platform_device *pdev) | ||
1084 | { | ||
1085 | struct device *dev = &pdev->dev; | ||
1086 | struct stm32_dfsdm_adc *adc; | ||
1087 | struct device_node *np = dev->of_node; | ||
1088 | const struct stm32_dfsdm_dev_data *dev_data; | ||
1089 | struct iio_dev *iio; | ||
1090 | char *name; | ||
1091 | int ret, irq, val; | ||
1092 | |||
1093 | |||
1094 | dev_data = of_device_get_match_data(dev); | ||
1095 | iio = devm_iio_device_alloc(dev, sizeof(*adc)); | ||
1096 | if (!iio) { | ||
1097 | dev_err(dev, "%s: Failed to allocate IIO\n", __func__); | ||
1098 | return -ENOMEM; | ||
1099 | } | ||
1100 | |||
1101 | adc = iio_priv(iio); | ||
1102 | adc->dfsdm = dev_get_drvdata(dev->parent); | ||
1103 | |||
1104 | iio->dev.parent = dev; | ||
1105 | iio->dev.of_node = np; | ||
1106 | iio->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; | ||
1107 | |||
1108 | platform_set_drvdata(pdev, adc); | ||
1109 | |||
1110 | ret = of_property_read_u32(dev->of_node, "reg", &adc->fl_id); | ||
1111 | if (ret != 0) { | ||
1112 | dev_err(dev, "Missing reg property\n"); | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1115 | |||
1116 | name = devm_kzalloc(dev, sizeof("dfsdm-adc0"), GFP_KERNEL); | ||
1117 | if (!name) | ||
1118 | return -ENOMEM; | ||
1119 | if (dev_data->type == DFSDM_AUDIO) { | ||
1120 | iio->info = &stm32_dfsdm_info_audio; | ||
1121 | snprintf(name, sizeof("dfsdm-pdm0"), "dfsdm-pdm%d", adc->fl_id); | ||
1122 | } else { | ||
1123 | iio->info = &stm32_dfsdm_info_adc; | ||
1124 | snprintf(name, sizeof("dfsdm-adc0"), "dfsdm-adc%d", adc->fl_id); | ||
1125 | } | ||
1126 | iio->name = name; | ||
1127 | |||
1128 | /* | ||
1129 | * In a first step IRQs generated for channels are not treated. | ||
1130 | * So IRQ associated to filter instance 0 is dedicated to the Filter 0. | ||
1131 | */ | ||
1132 | irq = platform_get_irq(pdev, 0); | ||
1133 | ret = devm_request_irq(dev, irq, stm32_dfsdm_irq, | ||
1134 | 0, pdev->name, adc); | ||
1135 | if (ret < 0) { | ||
1136 | dev_err(dev, "Failed to request IRQ\n"); | ||
1137 | return ret; | ||
1138 | } | ||
1139 | |||
1140 | ret = of_property_read_u32(dev->of_node, "st,filter-order", &val); | ||
1141 | if (ret < 0) { | ||
1142 | dev_err(dev, "Failed to set filter order\n"); | ||
1143 | return ret; | ||
1144 | } | ||
1145 | |||
1146 | adc->dfsdm->fl_list[adc->fl_id].ford = val; | ||
1147 | |||
1148 | ret = of_property_read_u32(dev->of_node, "st,filter0-sync", &val); | ||
1149 | if (!ret) | ||
1150 | adc->dfsdm->fl_list[adc->fl_id].sync_mode = val; | ||
1151 | |||
1152 | adc->dev_data = dev_data; | ||
1153 | ret = dev_data->init(iio); | ||
1154 | if (ret < 0) | ||
1155 | return ret; | ||
1156 | |||
1157 | ret = iio_device_register(iio); | ||
1158 | if (ret < 0) | ||
1159 | goto err_cleanup; | ||
1160 | |||
1161 | dev_err(dev, "of_platform_populate\n"); | ||
1162 | if (dev_data->type == DFSDM_AUDIO) { | ||
1163 | ret = of_platform_populate(np, NULL, NULL, dev); | ||
1164 | if (ret < 0) { | ||
1165 | dev_err(dev, "Failed to find an audio DAI\n"); | ||
1166 | goto err_unregister; | ||
1167 | } | ||
1168 | } | ||
1169 | |||
1170 | return 0; | ||
1171 | |||
1172 | err_unregister: | ||
1173 | iio_device_unregister(iio); | ||
1174 | err_cleanup: | ||
1175 | stm32_dfsdm_dma_release(iio); | ||
1176 | |||
1177 | return ret; | ||
1178 | } | ||
1179 | |||
1180 | static int stm32_dfsdm_adc_remove(struct platform_device *pdev) | ||
1181 | { | ||
1182 | struct stm32_dfsdm_adc *adc = platform_get_drvdata(pdev); | ||
1183 | struct iio_dev *indio_dev = iio_priv_to_dev(adc); | ||
1184 | |||
1185 | if (adc->dev_data->type == DFSDM_AUDIO) | ||
1186 | of_platform_depopulate(&pdev->dev); | ||
1187 | iio_device_unregister(indio_dev); | ||
1188 | stm32_dfsdm_dma_release(indio_dev); | ||
1189 | |||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | static struct platform_driver stm32_dfsdm_adc_driver = { | ||
1194 | .driver = { | ||
1195 | .name = "stm32-dfsdm-adc", | ||
1196 | .of_match_table = stm32_dfsdm_adc_match, | ||
1197 | }, | ||
1198 | .probe = stm32_dfsdm_adc_probe, | ||
1199 | .remove = stm32_dfsdm_adc_remove, | ||
1200 | }; | ||
1201 | module_platform_driver(stm32_dfsdm_adc_driver); | ||
1202 | |||
1203 | MODULE_DESCRIPTION("STM32 sigma delta ADC"); | ||
1204 | MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); | ||
1205 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/adc/stm32-dfsdm-core.c b/drivers/iio/adc/stm32-dfsdm-core.c new file mode 100644 index 000000000000..6290332cfd3f --- /dev/null +++ b/drivers/iio/adc/stm32-dfsdm-core.c | |||
@@ -0,0 +1,302 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * This file is part the core part STM32 DFSDM driver | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com> for STMicroelectronics. | ||
7 | */ | ||
8 | |||
9 | #include <linux/clk.h> | ||
10 | #include <linux/iio/iio.h> | ||
11 | #include <linux/iio/sysfs.h> | ||
12 | #include <linux/interrupt.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of_device.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include <linux/slab.h> | ||
17 | |||
18 | #include "stm32-dfsdm.h" | ||
19 | |||
20 | struct stm32_dfsdm_dev_data { | ||
21 | unsigned int num_filters; | ||
22 | unsigned int num_channels; | ||
23 | const struct regmap_config *regmap_cfg; | ||
24 | }; | ||
25 | |||
26 | #define STM32H7_DFSDM_NUM_FILTERS 4 | ||
27 | #define STM32H7_DFSDM_NUM_CHANNELS 8 | ||
28 | |||
29 | static bool stm32_dfsdm_volatile_reg(struct device *dev, unsigned int reg) | ||
30 | { | ||
31 | if (reg < DFSDM_FILTER_BASE_ADR) | ||
32 | return false; | ||
33 | |||
34 | /* | ||
35 | * Mask is done on register to avoid to list registers of all | ||
36 | * filter instances. | ||
37 | */ | ||
38 | switch (reg & DFSDM_FILTER_REG_MASK) { | ||
39 | case DFSDM_CR1(0) & DFSDM_FILTER_REG_MASK: | ||
40 | case DFSDM_ISR(0) & DFSDM_FILTER_REG_MASK: | ||
41 | case DFSDM_JDATAR(0) & DFSDM_FILTER_REG_MASK: | ||
42 | case DFSDM_RDATAR(0) & DFSDM_FILTER_REG_MASK: | ||
43 | return true; | ||
44 | } | ||
45 | |||
46 | return false; | ||
47 | } | ||
48 | |||
49 | static const struct regmap_config stm32h7_dfsdm_regmap_cfg = { | ||
50 | .reg_bits = 32, | ||
51 | .val_bits = 32, | ||
52 | .reg_stride = sizeof(u32), | ||
53 | .max_register = 0x2B8, | ||
54 | .volatile_reg = stm32_dfsdm_volatile_reg, | ||
55 | .fast_io = true, | ||
56 | }; | ||
57 | |||
58 | static const struct stm32_dfsdm_dev_data stm32h7_dfsdm_data = { | ||
59 | .num_filters = STM32H7_DFSDM_NUM_FILTERS, | ||
60 | .num_channels = STM32H7_DFSDM_NUM_CHANNELS, | ||
61 | .regmap_cfg = &stm32h7_dfsdm_regmap_cfg, | ||
62 | }; | ||
63 | |||
64 | struct dfsdm_priv { | ||
65 | struct platform_device *pdev; /* platform device */ | ||
66 | |||
67 | struct stm32_dfsdm dfsdm; /* common data exported for all instances */ | ||
68 | |||
69 | unsigned int spi_clk_out_div; /* SPI clkout divider value */ | ||
70 | atomic_t n_active_ch; /* number of current active channels */ | ||
71 | |||
72 | struct clk *clk; /* DFSDM clock */ | ||
73 | struct clk *aclk; /* audio clock */ | ||
74 | }; | ||
75 | |||
76 | /** | ||
77 | * stm32_dfsdm_start_dfsdm - start global dfsdm interface. | ||
78 | * | ||
79 | * Enable interface if n_active_ch is not null. | ||
80 | * @dfsdm: Handle used to retrieve dfsdm context. | ||
81 | */ | ||
82 | int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm) | ||
83 | { | ||
84 | struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm); | ||
85 | struct device *dev = &priv->pdev->dev; | ||
86 | unsigned int clk_div = priv->spi_clk_out_div; | ||
87 | int ret; | ||
88 | |||
89 | if (atomic_inc_return(&priv->n_active_ch) == 1) { | ||
90 | ret = clk_prepare_enable(priv->clk); | ||
91 | if (ret < 0) { | ||
92 | dev_err(dev, "Failed to start clock\n"); | ||
93 | goto error_ret; | ||
94 | } | ||
95 | if (priv->aclk) { | ||
96 | ret = clk_prepare_enable(priv->aclk); | ||
97 | if (ret < 0) { | ||
98 | dev_err(dev, "Failed to start audio clock\n"); | ||
99 | goto disable_clk; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* Output the SPI CLKOUT (if clk_div == 0 clock if OFF) */ | ||
104 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), | ||
105 | DFSDM_CHCFGR1_CKOUTDIV_MASK, | ||
106 | DFSDM_CHCFGR1_CKOUTDIV(clk_div)); | ||
107 | if (ret < 0) | ||
108 | goto disable_aclk; | ||
109 | |||
110 | /* Global enable of DFSDM interface */ | ||
111 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), | ||
112 | DFSDM_CHCFGR1_DFSDMEN_MASK, | ||
113 | DFSDM_CHCFGR1_DFSDMEN(1)); | ||
114 | if (ret < 0) | ||
115 | goto disable_aclk; | ||
116 | } | ||
117 | |||
118 | dev_dbg(dev, "%s: n_active_ch %d\n", __func__, | ||
119 | atomic_read(&priv->n_active_ch)); | ||
120 | |||
121 | return 0; | ||
122 | |||
123 | disable_aclk: | ||
124 | clk_disable_unprepare(priv->aclk); | ||
125 | disable_clk: | ||
126 | clk_disable_unprepare(priv->clk); | ||
127 | |||
128 | error_ret: | ||
129 | atomic_dec(&priv->n_active_ch); | ||
130 | |||
131 | return ret; | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(stm32_dfsdm_start_dfsdm); | ||
134 | |||
135 | /** | ||
136 | * stm32_dfsdm_stop_dfsdm - stop global DFSDM interface. | ||
137 | * | ||
138 | * Disable interface if n_active_ch is null | ||
139 | * @dfsdm: Handle used to retrieve dfsdm context. | ||
140 | */ | ||
141 | int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm) | ||
142 | { | ||
143 | struct dfsdm_priv *priv = container_of(dfsdm, struct dfsdm_priv, dfsdm); | ||
144 | int ret; | ||
145 | |||
146 | if (atomic_dec_and_test(&priv->n_active_ch)) { | ||
147 | /* Global disable of DFSDM interface */ | ||
148 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), | ||
149 | DFSDM_CHCFGR1_DFSDMEN_MASK, | ||
150 | DFSDM_CHCFGR1_DFSDMEN(0)); | ||
151 | if (ret < 0) | ||
152 | return ret; | ||
153 | |||
154 | /* Stop SPI CLKOUT */ | ||
155 | ret = regmap_update_bits(dfsdm->regmap, DFSDM_CHCFGR1(0), | ||
156 | DFSDM_CHCFGR1_CKOUTDIV_MASK, | ||
157 | DFSDM_CHCFGR1_CKOUTDIV(0)); | ||
158 | if (ret < 0) | ||
159 | return ret; | ||
160 | |||
161 | clk_disable_unprepare(priv->clk); | ||
162 | if (priv->aclk) | ||
163 | clk_disable_unprepare(priv->aclk); | ||
164 | } | ||
165 | dev_dbg(&priv->pdev->dev, "%s: n_active_ch %d\n", __func__, | ||
166 | atomic_read(&priv->n_active_ch)); | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | EXPORT_SYMBOL_GPL(stm32_dfsdm_stop_dfsdm); | ||
171 | |||
172 | static int stm32_dfsdm_parse_of(struct platform_device *pdev, | ||
173 | struct dfsdm_priv *priv) | ||
174 | { | ||
175 | struct device_node *node = pdev->dev.of_node; | ||
176 | struct resource *res; | ||
177 | unsigned long clk_freq; | ||
178 | unsigned int spi_freq, rem; | ||
179 | int ret; | ||
180 | |||
181 | if (!node) | ||
182 | return -EINVAL; | ||
183 | |||
184 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
185 | if (!res) { | ||
186 | dev_err(&pdev->dev, "Failed to get memory resource\n"); | ||
187 | return -ENODEV; | ||
188 | } | ||
189 | priv->dfsdm.phys_base = res->start; | ||
190 | priv->dfsdm.base = devm_ioremap_resource(&pdev->dev, res); | ||
191 | |||
192 | /* | ||
193 | * "dfsdm" clock is mandatory for DFSDM peripheral clocking. | ||
194 | * "dfsdm" or "audio" clocks can be used as source clock for | ||
195 | * the SPI clock out signal and internal processing, depending | ||
196 | * on use case. | ||
197 | */ | ||
198 | priv->clk = devm_clk_get(&pdev->dev, "dfsdm"); | ||
199 | if (IS_ERR(priv->clk)) { | ||
200 | dev_err(&pdev->dev, "No stm32_dfsdm_clk clock found\n"); | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | priv->aclk = devm_clk_get(&pdev->dev, "audio"); | ||
205 | if (IS_ERR(priv->aclk)) | ||
206 | priv->aclk = NULL; | ||
207 | |||
208 | if (priv->aclk) | ||
209 | clk_freq = clk_get_rate(priv->aclk); | ||
210 | else | ||
211 | clk_freq = clk_get_rate(priv->clk); | ||
212 | |||
213 | /* SPI clock out frequency */ | ||
214 | ret = of_property_read_u32(pdev->dev.of_node, "spi-max-frequency", | ||
215 | &spi_freq); | ||
216 | if (ret < 0) { | ||
217 | /* No SPI master mode */ | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | priv->spi_clk_out_div = div_u64_rem(clk_freq, spi_freq, &rem) - 1; | ||
222 | priv->dfsdm.spi_master_freq = spi_freq; | ||
223 | |||
224 | if (rem) { | ||
225 | dev_warn(&pdev->dev, "SPI clock not accurate\n"); | ||
226 | dev_warn(&pdev->dev, "%ld = %d * %d + %d\n", | ||
227 | clk_freq, spi_freq, priv->spi_clk_out_div + 1, rem); | ||
228 | } | ||
229 | |||
230 | return 0; | ||
231 | }; | ||
232 | |||
233 | static const struct of_device_id stm32_dfsdm_of_match[] = { | ||
234 | { | ||
235 | .compatible = "st,stm32h7-dfsdm", | ||
236 | .data = &stm32h7_dfsdm_data, | ||
237 | }, | ||
238 | {} | ||
239 | }; | ||
240 | MODULE_DEVICE_TABLE(of, stm32_dfsdm_of_match); | ||
241 | |||
242 | static int stm32_dfsdm_probe(struct platform_device *pdev) | ||
243 | { | ||
244 | struct dfsdm_priv *priv; | ||
245 | const struct stm32_dfsdm_dev_data *dev_data; | ||
246 | struct stm32_dfsdm *dfsdm; | ||
247 | int ret; | ||
248 | |||
249 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||
250 | if (!priv) | ||
251 | return -ENOMEM; | ||
252 | |||
253 | priv->pdev = pdev; | ||
254 | |||
255 | dev_data = of_device_get_match_data(&pdev->dev); | ||
256 | |||
257 | dfsdm = &priv->dfsdm; | ||
258 | dfsdm->fl_list = devm_kcalloc(&pdev->dev, dev_data->num_filters, | ||
259 | sizeof(*dfsdm->fl_list), GFP_KERNEL); | ||
260 | if (!dfsdm->fl_list) | ||
261 | return -ENOMEM; | ||
262 | |||
263 | dfsdm->num_fls = dev_data->num_filters; | ||
264 | dfsdm->ch_list = devm_kcalloc(&pdev->dev, dev_data->num_channels, | ||
265 | sizeof(*dfsdm->ch_list), | ||
266 | GFP_KERNEL); | ||
267 | if (!dfsdm->ch_list) | ||
268 | return -ENOMEM; | ||
269 | dfsdm->num_chs = dev_data->num_channels; | ||
270 | |||
271 | ret = stm32_dfsdm_parse_of(pdev, priv); | ||
272 | if (ret < 0) | ||
273 | return ret; | ||
274 | |||
275 | dfsdm->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "dfsdm", | ||
276 | dfsdm->base, | ||
277 | &stm32h7_dfsdm_regmap_cfg); | ||
278 | if (IS_ERR(dfsdm->regmap)) { | ||
279 | ret = PTR_ERR(dfsdm->regmap); | ||
280 | dev_err(&pdev->dev, "%s: Failed to allocate regmap: %d\n", | ||
281 | __func__, ret); | ||
282 | return ret; | ||
283 | } | ||
284 | |||
285 | platform_set_drvdata(pdev, dfsdm); | ||
286 | |||
287 | return devm_of_platform_populate(&pdev->dev); | ||
288 | } | ||
289 | |||
290 | static struct platform_driver stm32_dfsdm_driver = { | ||
291 | .probe = stm32_dfsdm_probe, | ||
292 | .driver = { | ||
293 | .name = "stm32-dfsdm", | ||
294 | .of_match_table = stm32_dfsdm_of_match, | ||
295 | }, | ||
296 | }; | ||
297 | |||
298 | module_platform_driver(stm32_dfsdm_driver); | ||
299 | |||
300 | MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); | ||
301 | MODULE_DESCRIPTION("STMicroelectronics STM32 dfsdm driver"); | ||
302 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/adc/stm32-dfsdm.h b/drivers/iio/adc/stm32-dfsdm.h new file mode 100644 index 000000000000..8708394b0725 --- /dev/null +++ b/drivers/iio/adc/stm32-dfsdm.h | |||
@@ -0,0 +1,310 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * This file is part of STM32 DFSDM driver | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>. | ||
7 | */ | ||
8 | |||
9 | #ifndef MDF_STM32_DFSDM__H | ||
10 | #define MDF_STM32_DFSDM__H | ||
11 | |||
12 | #include <linux/bitfield.h> | ||
13 | |||
14 | /* | ||
15 | * STM32 DFSDM - global register map | ||
16 | * ________________________________________________________ | ||
17 | * | Offset | Registers block | | ||
18 | * -------------------------------------------------------- | ||
19 | * | 0x000 | CHANNEL 0 + COMMON CHANNEL FIELDS | | ||
20 | * -------------------------------------------------------- | ||
21 | * | 0x020 | CHANNEL 1 | | ||
22 | * -------------------------------------------------------- | ||
23 | * | ... | ..... | | ||
24 | * -------------------------------------------------------- | ||
25 | * | 0x0E0 | CHANNEL 7 | | ||
26 | * -------------------------------------------------------- | ||
27 | * | 0x100 | FILTER 0 + COMMON FILTER FIELDs | | ||
28 | * -------------------------------------------------------- | ||
29 | * | 0x200 | FILTER 1 | | ||
30 | * -------------------------------------------------------- | ||
31 | * | 0x300 | FILTER 2 | | ||
32 | * -------------------------------------------------------- | ||
33 | * | 0x400 | FILTER 3 | | ||
34 | * -------------------------------------------------------- | ||
35 | */ | ||
36 | |||
37 | /* | ||
38 | * Channels register definitions | ||
39 | */ | ||
40 | #define DFSDM_CHCFGR1(y) ((y) * 0x20 + 0x00) | ||
41 | #define DFSDM_CHCFGR2(y) ((y) * 0x20 + 0x04) | ||
42 | #define DFSDM_AWSCDR(y) ((y) * 0x20 + 0x08) | ||
43 | #define DFSDM_CHWDATR(y) ((y) * 0x20 + 0x0C) | ||
44 | #define DFSDM_CHDATINR(y) ((y) * 0x20 + 0x10) | ||
45 | |||
46 | /* CHCFGR1: Channel configuration register 1 */ | ||
47 | #define DFSDM_CHCFGR1_SITP_MASK GENMASK(1, 0) | ||
48 | #define DFSDM_CHCFGR1_SITP(v) FIELD_PREP(DFSDM_CHCFGR1_SITP_MASK, v) | ||
49 | #define DFSDM_CHCFGR1_SPICKSEL_MASK GENMASK(3, 2) | ||
50 | #define DFSDM_CHCFGR1_SPICKSEL(v) FIELD_PREP(DFSDM_CHCFGR1_SPICKSEL_MASK, v) | ||
51 | #define DFSDM_CHCFGR1_SCDEN_MASK BIT(5) | ||
52 | #define DFSDM_CHCFGR1_SCDEN(v) FIELD_PREP(DFSDM_CHCFGR1_SCDEN_MASK, v) | ||
53 | #define DFSDM_CHCFGR1_CKABEN_MASK BIT(6) | ||
54 | #define DFSDM_CHCFGR1_CKABEN(v) FIELD_PREP(DFSDM_CHCFGR1_CKABEN_MASK, v) | ||
55 | #define DFSDM_CHCFGR1_CHEN_MASK BIT(7) | ||
56 | #define DFSDM_CHCFGR1_CHEN(v) FIELD_PREP(DFSDM_CHCFGR1_CHEN_MASK, v) | ||
57 | #define DFSDM_CHCFGR1_CHINSEL_MASK BIT(8) | ||
58 | #define DFSDM_CHCFGR1_CHINSEL(v) FIELD_PREP(DFSDM_CHCFGR1_CHINSEL_MASK, v) | ||
59 | #define DFSDM_CHCFGR1_DATMPX_MASK GENMASK(13, 12) | ||
60 | #define DFSDM_CHCFGR1_DATMPX(v) FIELD_PREP(DFSDM_CHCFGR1_DATMPX_MASK, v) | ||
61 | #define DFSDM_CHCFGR1_DATPACK_MASK GENMASK(15, 14) | ||
62 | #define DFSDM_CHCFGR1_DATPACK(v) FIELD_PREP(DFSDM_CHCFGR1_DATPACK_MASK, v) | ||
63 | #define DFSDM_CHCFGR1_CKOUTDIV_MASK GENMASK(23, 16) | ||
64 | #define DFSDM_CHCFGR1_CKOUTDIV(v) FIELD_PREP(DFSDM_CHCFGR1_CKOUTDIV_MASK, v) | ||
65 | #define DFSDM_CHCFGR1_CKOUTSRC_MASK BIT(30) | ||
66 | #define DFSDM_CHCFGR1_CKOUTSRC(v) FIELD_PREP(DFSDM_CHCFGR1_CKOUTSRC_MASK, v) | ||
67 | #define DFSDM_CHCFGR1_DFSDMEN_MASK BIT(31) | ||
68 | #define DFSDM_CHCFGR1_DFSDMEN(v) FIELD_PREP(DFSDM_CHCFGR1_DFSDMEN_MASK, v) | ||
69 | |||
70 | /* CHCFGR2: Channel configuration register 2 */ | ||
71 | #define DFSDM_CHCFGR2_DTRBS_MASK GENMASK(7, 3) | ||
72 | #define DFSDM_CHCFGR2_DTRBS(v) FIELD_PREP(DFSDM_CHCFGR2_DTRBS_MASK, v) | ||
73 | #define DFSDM_CHCFGR2_OFFSET_MASK GENMASK(31, 8) | ||
74 | #define DFSDM_CHCFGR2_OFFSET(v) FIELD_PREP(DFSDM_CHCFGR2_OFFSET_MASK, v) | ||
75 | |||
76 | /* AWSCDR: Channel analog watchdog and short circuit detector */ | ||
77 | #define DFSDM_AWSCDR_SCDT_MASK GENMASK(7, 0) | ||
78 | #define DFSDM_AWSCDR_SCDT(v) FIELD_PREP(DFSDM_AWSCDR_SCDT_MASK, v) | ||
79 | #define DFSDM_AWSCDR_BKSCD_MASK GENMASK(15, 12) | ||
80 | #define DFSDM_AWSCDR_BKSCD(v) FIELD_PREP(DFSDM_AWSCDR_BKSCD_MASK, v) | ||
81 | #define DFSDM_AWSCDR_AWFOSR_MASK GENMASK(20, 16) | ||
82 | #define DFSDM_AWSCDR_AWFOSR(v) FIELD_PREP(DFSDM_AWSCDR_AWFOSR_MASK, v) | ||
83 | #define DFSDM_AWSCDR_AWFORD_MASK GENMASK(23, 22) | ||
84 | #define DFSDM_AWSCDR_AWFORD(v) FIELD_PREP(DFSDM_AWSCDR_AWFORD_MASK, v) | ||
85 | |||
86 | /* | ||
87 | * Filters register definitions | ||
88 | */ | ||
89 | #define DFSDM_FILTER_BASE_ADR 0x100 | ||
90 | #define DFSDM_FILTER_REG_MASK 0x7F | ||
91 | #define DFSDM_FILTER_X_BASE_ADR(x) ((x) * 0x80 + DFSDM_FILTER_BASE_ADR) | ||
92 | |||
93 | #define DFSDM_CR1(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x00) | ||
94 | #define DFSDM_CR2(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x04) | ||
95 | #define DFSDM_ISR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x08) | ||
96 | #define DFSDM_ICR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x0C) | ||
97 | #define DFSDM_JCHGR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x10) | ||
98 | #define DFSDM_FCR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x14) | ||
99 | #define DFSDM_JDATAR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x18) | ||
100 | #define DFSDM_RDATAR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x1C) | ||
101 | #define DFSDM_AWHTR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x20) | ||
102 | #define DFSDM_AWLTR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x24) | ||
103 | #define DFSDM_AWSR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x28) | ||
104 | #define DFSDM_AWCFR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x2C) | ||
105 | #define DFSDM_EXMAX(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x30) | ||
106 | #define DFSDM_EXMIN(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x34) | ||
107 | #define DFSDM_CNVTIMR(x) (DFSDM_FILTER_X_BASE_ADR(x) + 0x38) | ||
108 | |||
109 | /* CR1 Control register 1 */ | ||
110 | #define DFSDM_CR1_DFEN_MASK BIT(0) | ||
111 | #define DFSDM_CR1_DFEN(v) FIELD_PREP(DFSDM_CR1_DFEN_MASK, v) | ||
112 | #define DFSDM_CR1_JSWSTART_MASK BIT(1) | ||
113 | #define DFSDM_CR1_JSWSTART(v) FIELD_PREP(DFSDM_CR1_JSWSTART_MASK, v) | ||
114 | #define DFSDM_CR1_JSYNC_MASK BIT(3) | ||
115 | #define DFSDM_CR1_JSYNC(v) FIELD_PREP(DFSDM_CR1_JSYNC_MASK, v) | ||
116 | #define DFSDM_CR1_JSCAN_MASK BIT(4) | ||
117 | #define DFSDM_CR1_JSCAN(v) FIELD_PREP(DFSDM_CR1_JSCAN_MASK, v) | ||
118 | #define DFSDM_CR1_JDMAEN_MASK BIT(5) | ||
119 | #define DFSDM_CR1_JDMAEN(v) FIELD_PREP(DFSDM_CR1_JDMAEN_MASK, v) | ||
120 | #define DFSDM_CR1_JEXTSEL_MASK GENMASK(12, 8) | ||
121 | #define DFSDM_CR1_JEXTSEL(v) FIELD_PREP(DFSDM_CR1_JEXTSEL_MASK, v) | ||
122 | #define DFSDM_CR1_JEXTEN_MASK GENMASK(14, 13) | ||
123 | #define DFSDM_CR1_JEXTEN(v) FIELD_PREP(DFSDM_CR1_JEXTEN_MASK, v) | ||
124 | #define DFSDM_CR1_RSWSTART_MASK BIT(17) | ||
125 | #define DFSDM_CR1_RSWSTART(v) FIELD_PREP(DFSDM_CR1_RSWSTART_MASK, v) | ||
126 | #define DFSDM_CR1_RCONT_MASK BIT(18) | ||
127 | #define DFSDM_CR1_RCONT(v) FIELD_PREP(DFSDM_CR1_RCONT_MASK, v) | ||
128 | #define DFSDM_CR1_RSYNC_MASK BIT(19) | ||
129 | #define DFSDM_CR1_RSYNC(v) FIELD_PREP(DFSDM_CR1_RSYNC_MASK, v) | ||
130 | #define DFSDM_CR1_RDMAEN_MASK BIT(21) | ||
131 | #define DFSDM_CR1_RDMAEN(v) FIELD_PREP(DFSDM_CR1_RDMAEN_MASK, v) | ||
132 | #define DFSDM_CR1_RCH_MASK GENMASK(26, 24) | ||
133 | #define DFSDM_CR1_RCH(v) FIELD_PREP(DFSDM_CR1_RCH_MASK, v) | ||
134 | #define DFSDM_CR1_FAST_MASK BIT(29) | ||
135 | #define DFSDM_CR1_FAST(v) FIELD_PREP(DFSDM_CR1_FAST_MASK, v) | ||
136 | #define DFSDM_CR1_AWFSEL_MASK BIT(30) | ||
137 | #define DFSDM_CR1_AWFSEL(v) FIELD_PREP(DFSDM_CR1_AWFSEL_MASK, v) | ||
138 | |||
139 | /* CR2: Control register 2 */ | ||
140 | #define DFSDM_CR2_IE_MASK GENMASK(6, 0) | ||
141 | #define DFSDM_CR2_IE(v) FIELD_PREP(DFSDM_CR2_IE_MASK, v) | ||
142 | #define DFSDM_CR2_JEOCIE_MASK BIT(0) | ||
143 | #define DFSDM_CR2_JEOCIE(v) FIELD_PREP(DFSDM_CR2_JEOCIE_MASK, v) | ||
144 | #define DFSDM_CR2_REOCIE_MASK BIT(1) | ||
145 | #define DFSDM_CR2_REOCIE(v) FIELD_PREP(DFSDM_CR2_REOCIE_MASK, v) | ||
146 | #define DFSDM_CR2_JOVRIE_MASK BIT(2) | ||
147 | #define DFSDM_CR2_JOVRIE(v) FIELD_PREP(DFSDM_CR2_JOVRIE_MASK, v) | ||
148 | #define DFSDM_CR2_ROVRIE_MASK BIT(3) | ||
149 | #define DFSDM_CR2_ROVRIE(v) FIELD_PREP(DFSDM_CR2_ROVRIE_MASK, v) | ||
150 | #define DFSDM_CR2_AWDIE_MASK BIT(4) | ||
151 | #define DFSDM_CR2_AWDIE(v) FIELD_PREP(DFSDM_CR2_AWDIE_MASK, v) | ||
152 | #define DFSDM_CR2_SCDIE_MASK BIT(5) | ||
153 | #define DFSDM_CR2_SCDIE(v) FIELD_PREP(DFSDM_CR2_SCDIE_MASK, v) | ||
154 | #define DFSDM_CR2_CKABIE_MASK BIT(6) | ||
155 | #define DFSDM_CR2_CKABIE(v) FIELD_PREP(DFSDM_CR2_CKABIE_MASK, v) | ||
156 | #define DFSDM_CR2_EXCH_MASK GENMASK(15, 8) | ||
157 | #define DFSDM_CR2_EXCH(v) FIELD_PREP(DFSDM_CR2_EXCH_MASK, v) | ||
158 | #define DFSDM_CR2_AWDCH_MASK GENMASK(23, 16) | ||
159 | #define DFSDM_CR2_AWDCH(v) FIELD_PREP(DFSDM_CR2_AWDCH_MASK, v) | ||
160 | |||
161 | /* ISR: Interrupt status register */ | ||
162 | #define DFSDM_ISR_JEOCF_MASK BIT(0) | ||
163 | #define DFSDM_ISR_JEOCF(v) FIELD_PREP(DFSDM_ISR_JEOCF_MASK, v) | ||
164 | #define DFSDM_ISR_REOCF_MASK BIT(1) | ||
165 | #define DFSDM_ISR_REOCF(v) FIELD_PREP(DFSDM_ISR_REOCF_MASK, v) | ||
166 | #define DFSDM_ISR_JOVRF_MASK BIT(2) | ||
167 | #define DFSDM_ISR_JOVRF(v) FIELD_PREP(DFSDM_ISR_JOVRF_MASK, v) | ||
168 | #define DFSDM_ISR_ROVRF_MASK BIT(3) | ||
169 | #define DFSDM_ISR_ROVRF(v) FIELD_PREP(DFSDM_ISR_ROVRF_MASK, v) | ||
170 | #define DFSDM_ISR_AWDF_MASK BIT(4) | ||
171 | #define DFSDM_ISR_AWDF(v) FIELD_PREP(DFSDM_ISR_AWDF_MASK, v) | ||
172 | #define DFSDM_ISR_JCIP_MASK BIT(13) | ||
173 | #define DFSDM_ISR_JCIP(v) FIELD_PREP(DFSDM_ISR_JCIP_MASK, v) | ||
174 | #define DFSDM_ISR_RCIP_MASK BIT(14) | ||
175 | #define DFSDM_ISR_RCIP(v) FIELD_PREP(DFSDM_ISR_RCIP, v) | ||
176 | #define DFSDM_ISR_CKABF_MASK GENMASK(23, 16) | ||
177 | #define DFSDM_ISR_CKABF(v) FIELD_PREP(DFSDM_ISR_CKABF_MASK, v) | ||
178 | #define DFSDM_ISR_SCDF_MASK GENMASK(31, 24) | ||
179 | #define DFSDM_ISR_SCDF(v) FIELD_PREP(DFSDM_ISR_SCDF_MASK, v) | ||
180 | |||
181 | /* ICR: Interrupt flag clear register */ | ||
182 | #define DFSDM_ICR_CLRJOVRF_MASK BIT(2) | ||
183 | #define DFSDM_ICR_CLRJOVRF(v) FIELD_PREP(DFSDM_ICR_CLRJOVRF_MASK, v) | ||
184 | #define DFSDM_ICR_CLRROVRF_MASK BIT(3) | ||
185 | #define DFSDM_ICR_CLRROVRF(v) FIELD_PREP(DFSDM_ICR_CLRROVRF_MASK, v) | ||
186 | #define DFSDM_ICR_CLRCKABF_MASK GENMASK(23, 16) | ||
187 | #define DFSDM_ICR_CLRCKABF(v) FIELD_PREP(DFSDM_ICR_CLRCKABF_MASK, v) | ||
188 | #define DFSDM_ICR_CLRCKABF_CH_MASK(y) BIT(16 + (y)) | ||
189 | #define DFSDM_ICR_CLRCKABF_CH(v, y) \ | ||
190 | (((v) << (16 + (y))) & DFSDM_ICR_CLRCKABF_CH_MASK(y)) | ||
191 | #define DFSDM_ICR_CLRSCDF_MASK GENMASK(31, 24) | ||
192 | #define DFSDM_ICR_CLRSCDF(v) FIELD_PREP(DFSDM_ICR_CLRSCDF_MASK, v) | ||
193 | #define DFSDM_ICR_CLRSCDF_CH_MASK(y) BIT(24 + (y)) | ||
194 | #define DFSDM_ICR_CLRSCDF_CH(v, y) \ | ||
195 | (((v) << (24 + (y))) & DFSDM_ICR_CLRSCDF_MASK(y)) | ||
196 | |||
197 | /* FCR: Filter control register */ | ||
198 | #define DFSDM_FCR_IOSR_MASK GENMASK(7, 0) | ||
199 | #define DFSDM_FCR_IOSR(v) FIELD_PREP(DFSDM_FCR_IOSR_MASK, v) | ||
200 | #define DFSDM_FCR_FOSR_MASK GENMASK(25, 16) | ||
201 | #define DFSDM_FCR_FOSR(v) FIELD_PREP(DFSDM_FCR_FOSR_MASK, v) | ||
202 | #define DFSDM_FCR_FORD_MASK GENMASK(31, 29) | ||
203 | #define DFSDM_FCR_FORD(v) FIELD_PREP(DFSDM_FCR_FORD_MASK, v) | ||
204 | |||
205 | /* RDATAR: Filter data register for regular channel */ | ||
206 | #define DFSDM_DATAR_CH_MASK GENMASK(2, 0) | ||
207 | #define DFSDM_DATAR_DATA_OFFSET 8 | ||
208 | #define DFSDM_DATAR_DATA_MASK GENMASK(31, DFSDM_DATAR_DATA_OFFSET) | ||
209 | |||
210 | /* AWLTR: Filter analog watchdog low threshold register */ | ||
211 | #define DFSDM_AWLTR_BKAWL_MASK GENMASK(3, 0) | ||
212 | #define DFSDM_AWLTR_BKAWL(v) FIELD_PREP(DFSDM_AWLTR_BKAWL_MASK, v) | ||
213 | #define DFSDM_AWLTR_AWLT_MASK GENMASK(31, 8) | ||
214 | #define DFSDM_AWLTR_AWLT(v) FIELD_PREP(DFSDM_AWLTR_AWLT_MASK, v) | ||
215 | |||
216 | /* AWHTR: Filter analog watchdog low threshold register */ | ||
217 | #define DFSDM_AWHTR_BKAWH_MASK GENMASK(3, 0) | ||
218 | #define DFSDM_AWHTR_BKAWH(v) FIELD_PREP(DFSDM_AWHTR_BKAWH_MASK, v) | ||
219 | #define DFSDM_AWHTR_AWHT_MASK GENMASK(31, 8) | ||
220 | #define DFSDM_AWHTR_AWHT(v) FIELD_PREP(DFSDM_AWHTR_AWHT_MASK, v) | ||
221 | |||
222 | /* AWSR: Filter watchdog status register */ | ||
223 | #define DFSDM_AWSR_AWLTF_MASK GENMASK(7, 0) | ||
224 | #define DFSDM_AWSR_AWLTF(v) FIELD_PREP(DFSDM_AWSR_AWLTF_MASK, v) | ||
225 | #define DFSDM_AWSR_AWHTF_MASK GENMASK(15, 8) | ||
226 | #define DFSDM_AWSR_AWHTF(v) FIELD_PREP(DFSDM_AWSR_AWHTF_MASK, v) | ||
227 | |||
228 | /* AWCFR: Filter watchdog status register */ | ||
229 | #define DFSDM_AWCFR_AWLTF_MASK GENMASK(7, 0) | ||
230 | #define DFSDM_AWCFR_AWLTF(v) FIELD_PREP(DFSDM_AWCFR_AWLTF_MASK, v) | ||
231 | #define DFSDM_AWCFR_AWHTF_MASK GENMASK(15, 8) | ||
232 | #define DFSDM_AWCFR_AWHTF(v) FIELD_PREP(DFSDM_AWCFR_AWHTF_MASK, v) | ||
233 | |||
234 | /* DFSDM filter order */ | ||
235 | enum stm32_dfsdm_sinc_order { | ||
236 | DFSDM_FASTSINC_ORDER, /* FastSinc filter type */ | ||
237 | DFSDM_SINC1_ORDER, /* Sinc 1 filter type */ | ||
238 | DFSDM_SINC2_ORDER, /* Sinc 2 filter type */ | ||
239 | DFSDM_SINC3_ORDER, /* Sinc 3 filter type */ | ||
240 | DFSDM_SINC4_ORDER, /* Sinc 4 filter type (N.A. for watchdog) */ | ||
241 | DFSDM_SINC5_ORDER, /* Sinc 5 filter type (N.A. for watchdog) */ | ||
242 | DFSDM_NB_SINC_ORDER, | ||
243 | }; | ||
244 | |||
245 | /** | ||
246 | * struct stm32_dfsdm_filter - structure relative to stm32 FDSDM filter | ||
247 | * @iosr: integrator oversampling | ||
248 | * @fosr: filter oversampling | ||
249 | * @ford: filter order | ||
250 | * @res: output sample resolution | ||
251 | * @sync_mode: filter synchronized with filter 0 | ||
252 | * @fast: filter fast mode | ||
253 | */ | ||
254 | struct stm32_dfsdm_filter { | ||
255 | unsigned int iosr; | ||
256 | unsigned int fosr; | ||
257 | enum stm32_dfsdm_sinc_order ford; | ||
258 | u64 res; | ||
259 | unsigned int sync_mode; | ||
260 | unsigned int fast; | ||
261 | }; | ||
262 | |||
263 | /** | ||
264 | * struct stm32_dfsdm_channel - structure relative to stm32 FDSDM channel | ||
265 | * @id: id of the channel | ||
266 | * @type: interface type linked to stm32_dfsdm_chan_type | ||
267 | * @src: interface type linked to stm32_dfsdm_chan_src | ||
268 | * @alt_si: alternative serial input interface | ||
269 | */ | ||
270 | struct stm32_dfsdm_channel { | ||
271 | unsigned int id; | ||
272 | unsigned int type; | ||
273 | unsigned int src; | ||
274 | unsigned int alt_si; | ||
275 | }; | ||
276 | |||
277 | /** | ||
278 | * struct stm32_dfsdm - stm32 FDSDM driver common data (for all instances) | ||
279 | * @base: control registers base cpu addr | ||
280 | * @phys_base: DFSDM IP register physical address | ||
281 | * @regmap: regmap for register read/write | ||
282 | * @fl_list: filter resources list | ||
283 | * @num_fls: number of filter resources available | ||
284 | * @ch_list: channel resources list | ||
285 | * @num_chs: number of channel resources available | ||
286 | * @spi_master_freq: SPI clock out frequency | ||
287 | */ | ||
288 | struct stm32_dfsdm { | ||
289 | void __iomem *base; | ||
290 | phys_addr_t phys_base; | ||
291 | struct regmap *regmap; | ||
292 | struct stm32_dfsdm_filter *fl_list; | ||
293 | unsigned int num_fls; | ||
294 | struct stm32_dfsdm_channel *ch_list; | ||
295 | unsigned int num_chs; | ||
296 | unsigned int spi_master_freq; | ||
297 | }; | ||
298 | |||
299 | /* DFSDM channel serial spi clock source */ | ||
300 | enum stm32_dfsdm_spi_clk_src { | ||
301 | DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL, | ||
302 | DFSDM_CHANNEL_SPI_CLOCK_INTERNAL, | ||
303 | DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING, | ||
304 | DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING | ||
305 | }; | ||
306 | |||
307 | int stm32_dfsdm_start_dfsdm(struct stm32_dfsdm *dfsdm); | ||
308 | int stm32_dfsdm_stop_dfsdm(struct stm32_dfsdm *dfsdm); | ||
309 | |||
310 | #endif | ||
diff --git a/drivers/iio/buffer/Kconfig b/drivers/iio/buffer/Kconfig index 4ffd3db7817f..338774cba19b 100644 --- a/drivers/iio/buffer/Kconfig +++ b/drivers/iio/buffer/Kconfig | |||
@@ -29,6 +29,16 @@ config IIO_BUFFER_DMAENGINE | |||
29 | 29 | ||
30 | Should be selected by drivers that want to use this functionality. | 30 | Should be selected by drivers that want to use this functionality. |
31 | 31 | ||
32 | config IIO_BUFFER_HW_CONSUMER | ||
33 | tristate "Industrial I/O HW buffering" | ||
34 | help | ||
35 | Provides a way to bonding when an IIO device has a direct connection | ||
36 | to another device in hardware. In this case buffers for data transfers | ||
37 | are handled by hardware. | ||
38 | |||
39 | Should be selected by drivers that want to use the generic Hw consumer | ||
40 | interface. | ||
41 | |||
32 | config IIO_KFIFO_BUF | 42 | config IIO_KFIFO_BUF |
33 | tristate "Industrial I/O buffering based on kfifo" | 43 | tristate "Industrial I/O buffering based on kfifo" |
34 | help | 44 | help |
diff --git a/drivers/iio/buffer/Makefile b/drivers/iio/buffer/Makefile index 95f9f41c58b7..1403eb2f9409 100644 --- a/drivers/iio/buffer/Makefile +++ b/drivers/iio/buffer/Makefile | |||
@@ -7,5 +7,6 @@ | |||
7 | obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o | 7 | obj-$(CONFIG_IIO_BUFFER_CB) += industrialio-buffer-cb.o |
8 | obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o | 8 | obj-$(CONFIG_IIO_BUFFER_DMA) += industrialio-buffer-dma.o |
9 | obj-$(CONFIG_IIO_BUFFER_DMAENGINE) += industrialio-buffer-dmaengine.o | 9 | obj-$(CONFIG_IIO_BUFFER_DMAENGINE) += industrialio-buffer-dmaengine.o |
10 | obj-$(CONFIG_IIO_BUFFER_HW_CONSUMER) += industrialio-hw-consumer.o | ||
10 | obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o | 11 | obj-$(CONFIG_IIO_TRIGGERED_BUFFER) += industrialio-triggered-buffer.o |
11 | obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o | 12 | obj-$(CONFIG_IIO_KFIFO_BUF) += kfifo_buf.o |
diff --git a/drivers/iio/buffer/industrialio-buffer-cb.c b/drivers/iio/buffer/industrialio-buffer-cb.c index 4847534700e7..ea63c838eeae 100644 --- a/drivers/iio/buffer/industrialio-buffer-cb.c +++ b/drivers/iio/buffer/industrialio-buffer-cb.c | |||
@@ -104,6 +104,17 @@ error_free_cb_buff: | |||
104 | } | 104 | } |
105 | EXPORT_SYMBOL_GPL(iio_channel_get_all_cb); | 105 | EXPORT_SYMBOL_GPL(iio_channel_get_all_cb); |
106 | 106 | ||
107 | int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buff, | ||
108 | size_t watermark) | ||
109 | { | ||
110 | if (!watermark) | ||
111 | return -EINVAL; | ||
112 | cb_buff->buffer.watermark = watermark; | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | EXPORT_SYMBOL_GPL(iio_channel_cb_set_buffer_watermark); | ||
117 | |||
107 | int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff) | 118 | int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff) |
108 | { | 119 | { |
109 | return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer, | 120 | return iio_update_buffers(cb_buff->indio_dev, &cb_buff->buffer, |
diff --git a/drivers/iio/buffer/industrialio-hw-consumer.c b/drivers/iio/buffer/industrialio-hw-consumer.c new file mode 100644 index 000000000000..95165697d8ae --- /dev/null +++ b/drivers/iio/buffer/industrialio-hw-consumer.c | |||
@@ -0,0 +1,247 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Copyright 2017 Analog Devices Inc. | ||
4 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
5 | */ | ||
6 | |||
7 | #include <linux/err.h> | ||
8 | #include <linux/export.h> | ||
9 | #include <linux/slab.h> | ||
10 | #include <linux/module.h> | ||
11 | |||
12 | #include <linux/iio/iio.h> | ||
13 | #include <linux/iio/consumer.h> | ||
14 | #include <linux/iio/hw-consumer.h> | ||
15 | #include <linux/iio/buffer_impl.h> | ||
16 | |||
17 | /** | ||
18 | * struct iio_hw_consumer - IIO hw consumer block | ||
19 | * @buffers: hardware buffers list head. | ||
20 | * @channels: IIO provider channels. | ||
21 | */ | ||
22 | struct iio_hw_consumer { | ||
23 | struct list_head buffers; | ||
24 | struct iio_channel *channels; | ||
25 | }; | ||
26 | |||
27 | struct hw_consumer_buffer { | ||
28 | struct list_head head; | ||
29 | struct iio_dev *indio_dev; | ||
30 | struct iio_buffer buffer; | ||
31 | long scan_mask[]; | ||
32 | }; | ||
33 | |||
34 | static struct hw_consumer_buffer *iio_buffer_to_hw_consumer_buffer( | ||
35 | struct iio_buffer *buffer) | ||
36 | { | ||
37 | return container_of(buffer, struct hw_consumer_buffer, buffer); | ||
38 | } | ||
39 | |||
40 | static void iio_hw_buf_release(struct iio_buffer *buffer) | ||
41 | { | ||
42 | struct hw_consumer_buffer *hw_buf = | ||
43 | iio_buffer_to_hw_consumer_buffer(buffer); | ||
44 | kfree(hw_buf); | ||
45 | } | ||
46 | |||
47 | static const struct iio_buffer_access_funcs iio_hw_buf_access = { | ||
48 | .release = &iio_hw_buf_release, | ||
49 | .modes = INDIO_BUFFER_HARDWARE, | ||
50 | }; | ||
51 | |||
52 | static struct hw_consumer_buffer *iio_hw_consumer_get_buffer( | ||
53 | struct iio_hw_consumer *hwc, struct iio_dev *indio_dev) | ||
54 | { | ||
55 | size_t mask_size = BITS_TO_LONGS(indio_dev->masklength) * sizeof(long); | ||
56 | struct hw_consumer_buffer *buf; | ||
57 | |||
58 | list_for_each_entry(buf, &hwc->buffers, head) { | ||
59 | if (buf->indio_dev == indio_dev) | ||
60 | return buf; | ||
61 | } | ||
62 | |||
63 | buf = kzalloc(sizeof(*buf) + mask_size, GFP_KERNEL); | ||
64 | if (!buf) | ||
65 | return NULL; | ||
66 | |||
67 | buf->buffer.access = &iio_hw_buf_access; | ||
68 | buf->indio_dev = indio_dev; | ||
69 | buf->buffer.scan_mask = buf->scan_mask; | ||
70 | |||
71 | iio_buffer_init(&buf->buffer); | ||
72 | list_add_tail(&buf->head, &hwc->buffers); | ||
73 | |||
74 | return buf; | ||
75 | } | ||
76 | |||
77 | /** | ||
78 | * iio_hw_consumer_alloc() - Allocate IIO hardware consumer | ||
79 | * @dev: Pointer to consumer device. | ||
80 | * | ||
81 | * Returns a valid iio_hw_consumer on success or a ERR_PTR() on failure. | ||
82 | */ | ||
83 | struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev) | ||
84 | { | ||
85 | struct hw_consumer_buffer *buf; | ||
86 | struct iio_hw_consumer *hwc; | ||
87 | struct iio_channel *chan; | ||
88 | int ret; | ||
89 | |||
90 | hwc = kzalloc(sizeof(*hwc), GFP_KERNEL); | ||
91 | if (!hwc) | ||
92 | return ERR_PTR(-ENOMEM); | ||
93 | |||
94 | INIT_LIST_HEAD(&hwc->buffers); | ||
95 | |||
96 | hwc->channels = iio_channel_get_all(dev); | ||
97 | if (IS_ERR(hwc->channels)) { | ||
98 | ret = PTR_ERR(hwc->channels); | ||
99 | goto err_free_hwc; | ||
100 | } | ||
101 | |||
102 | chan = &hwc->channels[0]; | ||
103 | while (chan->indio_dev) { | ||
104 | buf = iio_hw_consumer_get_buffer(hwc, chan->indio_dev); | ||
105 | if (!buf) { | ||
106 | ret = -ENOMEM; | ||
107 | goto err_put_buffers; | ||
108 | } | ||
109 | set_bit(chan->channel->scan_index, buf->buffer.scan_mask); | ||
110 | chan++; | ||
111 | } | ||
112 | |||
113 | return hwc; | ||
114 | |||
115 | err_put_buffers: | ||
116 | list_for_each_entry(buf, &hwc->buffers, head) | ||
117 | iio_buffer_put(&buf->buffer); | ||
118 | iio_channel_release_all(hwc->channels); | ||
119 | err_free_hwc: | ||
120 | kfree(hwc); | ||
121 | return ERR_PTR(ret); | ||
122 | } | ||
123 | EXPORT_SYMBOL_GPL(iio_hw_consumer_alloc); | ||
124 | |||
125 | /** | ||
126 | * iio_hw_consumer_free() - Free IIO hardware consumer | ||
127 | * @hwc: hw consumer to free. | ||
128 | */ | ||
129 | void iio_hw_consumer_free(struct iio_hw_consumer *hwc) | ||
130 | { | ||
131 | struct hw_consumer_buffer *buf, *n; | ||
132 | |||
133 | iio_channel_release_all(hwc->channels); | ||
134 | list_for_each_entry_safe(buf, n, &hwc->buffers, head) | ||
135 | iio_buffer_put(&buf->buffer); | ||
136 | kfree(hwc); | ||
137 | } | ||
138 | EXPORT_SYMBOL_GPL(iio_hw_consumer_free); | ||
139 | |||
140 | static void devm_iio_hw_consumer_release(struct device *dev, void *res) | ||
141 | { | ||
142 | iio_hw_consumer_free(*(struct iio_hw_consumer **)res); | ||
143 | } | ||
144 | |||
145 | static int devm_iio_hw_consumer_match(struct device *dev, void *res, void *data) | ||
146 | { | ||
147 | struct iio_hw_consumer **r = res; | ||
148 | |||
149 | if (!r || !*r) { | ||
150 | WARN_ON(!r || !*r); | ||
151 | return 0; | ||
152 | } | ||
153 | return *r == data; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * devm_iio_hw_consumer_alloc - Resource-managed iio_hw_consumer_alloc() | ||
158 | * @dev: Pointer to consumer device. | ||
159 | * | ||
160 | * Managed iio_hw_consumer_alloc. iio_hw_consumer allocated with this function | ||
161 | * is automatically freed on driver detach. | ||
162 | * | ||
163 | * If an iio_hw_consumer allocated with this function needs to be freed | ||
164 | * separately, devm_iio_hw_consumer_free() must be used. | ||
165 | * | ||
166 | * returns pointer to allocated iio_hw_consumer on success, NULL on failure. | ||
167 | */ | ||
168 | struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev) | ||
169 | { | ||
170 | struct iio_hw_consumer **ptr, *iio_hwc; | ||
171 | |||
172 | ptr = devres_alloc(devm_iio_hw_consumer_release, sizeof(*ptr), | ||
173 | GFP_KERNEL); | ||
174 | if (!ptr) | ||
175 | return NULL; | ||
176 | |||
177 | iio_hwc = iio_hw_consumer_alloc(dev); | ||
178 | if (IS_ERR(iio_hwc)) { | ||
179 | devres_free(ptr); | ||
180 | } else { | ||
181 | *ptr = iio_hwc; | ||
182 | devres_add(dev, ptr); | ||
183 | } | ||
184 | |||
185 | return iio_hwc; | ||
186 | } | ||
187 | EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_alloc); | ||
188 | |||
189 | /** | ||
190 | * devm_iio_hw_consumer_free - Resource-managed iio_hw_consumer_free() | ||
191 | * @dev: Pointer to consumer device. | ||
192 | * @hwc: iio_hw_consumer to free. | ||
193 | * | ||
194 | * Free iio_hw_consumer allocated with devm_iio_hw_consumer_alloc(). | ||
195 | */ | ||
196 | void devm_iio_hw_consumer_free(struct device *dev, struct iio_hw_consumer *hwc) | ||
197 | { | ||
198 | int rc; | ||
199 | |||
200 | rc = devres_release(dev, devm_iio_hw_consumer_release, | ||
201 | devm_iio_hw_consumer_match, hwc); | ||
202 | WARN_ON(rc); | ||
203 | } | ||
204 | EXPORT_SYMBOL_GPL(devm_iio_hw_consumer_free); | ||
205 | |||
206 | /** | ||
207 | * iio_hw_consumer_enable() - Enable IIO hardware consumer | ||
208 | * @hwc: iio_hw_consumer to enable. | ||
209 | * | ||
210 | * Returns 0 on success. | ||
211 | */ | ||
212 | int iio_hw_consumer_enable(struct iio_hw_consumer *hwc) | ||
213 | { | ||
214 | struct hw_consumer_buffer *buf; | ||
215 | int ret; | ||
216 | |||
217 | list_for_each_entry(buf, &hwc->buffers, head) { | ||
218 | ret = iio_update_buffers(buf->indio_dev, &buf->buffer, NULL); | ||
219 | if (ret) | ||
220 | goto err_disable_buffers; | ||
221 | } | ||
222 | |||
223 | return 0; | ||
224 | |||
225 | err_disable_buffers: | ||
226 | list_for_each_entry_continue_reverse(buf, &hwc->buffers, head) | ||
227 | iio_update_buffers(buf->indio_dev, NULL, &buf->buffer); | ||
228 | return ret; | ||
229 | } | ||
230 | EXPORT_SYMBOL_GPL(iio_hw_consumer_enable); | ||
231 | |||
232 | /** | ||
233 | * iio_hw_consumer_disable() - Disable IIO hardware consumer | ||
234 | * @hwc: iio_hw_consumer to disable. | ||
235 | */ | ||
236 | void iio_hw_consumer_disable(struct iio_hw_consumer *hwc) | ||
237 | { | ||
238 | struct hw_consumer_buffer *buf; | ||
239 | |||
240 | list_for_each_entry(buf, &hwc->buffers, head) | ||
241 | iio_update_buffers(buf->indio_dev, NULL, &buf->buffer); | ||
242 | } | ||
243 | EXPORT_SYMBOL_GPL(iio_hw_consumer_disable); | ||
244 | |||
245 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
246 | MODULE_DESCRIPTION("Hardware consumer buffer the IIO framework"); | ||
247 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c index 069defcc6d9b..ec98790e2a28 100644 --- a/drivers/iio/inkern.c +++ b/drivers/iio/inkern.c | |||
@@ -664,9 +664,8 @@ err_unlock: | |||
664 | } | 664 | } |
665 | EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); | 665 | EXPORT_SYMBOL_GPL(iio_convert_raw_to_processed); |
666 | 666 | ||
667 | static int iio_read_channel_attribute(struct iio_channel *chan, | 667 | int iio_read_channel_attribute(struct iio_channel *chan, int *val, int *val2, |
668 | int *val, int *val2, | 668 | enum iio_chan_info_enum attribute) |
669 | enum iio_chan_info_enum attribute) | ||
670 | { | 669 | { |
671 | int ret; | 670 | int ret; |
672 | 671 | ||
@@ -682,6 +681,7 @@ err_unlock: | |||
682 | 681 | ||
683 | return ret; | 682 | return ret; |
684 | } | 683 | } |
684 | EXPORT_SYMBOL_GPL(iio_read_channel_attribute); | ||
685 | 685 | ||
686 | int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2) | 686 | int iio_read_channel_offset(struct iio_channel *chan, int *val, int *val2) |
687 | { | 687 | { |
@@ -850,7 +850,8 @@ static int iio_channel_write(struct iio_channel *chan, int val, int val2, | |||
850 | chan->channel, val, val2, info); | 850 | chan->channel, val, val2, info); |
851 | } | 851 | } |
852 | 852 | ||
853 | int iio_write_channel_raw(struct iio_channel *chan, int val) | 853 | int iio_write_channel_attribute(struct iio_channel *chan, int val, int val2, |
854 | enum iio_chan_info_enum attribute) | ||
854 | { | 855 | { |
855 | int ret; | 856 | int ret; |
856 | 857 | ||
@@ -860,12 +861,18 @@ int iio_write_channel_raw(struct iio_channel *chan, int val) | |||
860 | goto err_unlock; | 861 | goto err_unlock; |
861 | } | 862 | } |
862 | 863 | ||
863 | ret = iio_channel_write(chan, val, 0, IIO_CHAN_INFO_RAW); | 864 | ret = iio_channel_write(chan, val, val2, attribute); |
864 | err_unlock: | 865 | err_unlock: |
865 | mutex_unlock(&chan->indio_dev->info_exist_lock); | 866 | mutex_unlock(&chan->indio_dev->info_exist_lock); |
866 | 867 | ||
867 | return ret; | 868 | return ret; |
868 | } | 869 | } |
870 | EXPORT_SYMBOL_GPL(iio_write_channel_attribute); | ||
871 | |||
872 | int iio_write_channel_raw(struct iio_channel *chan, int val) | ||
873 | { | ||
874 | return iio_write_channel_attribute(chan, val, 0, IIO_CHAN_INFO_RAW); | ||
875 | } | ||
869 | EXPORT_SYMBOL_GPL(iio_write_channel_raw); | 876 | EXPORT_SYMBOL_GPL(iio_write_channel_raw); |
870 | 877 | ||
871 | unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan) | 878 | unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan) |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 79287629c888..c9608b0b80c6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -91,6 +91,9 @@ acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *guid, u64 rev, | |||
91 | bool acpi_dev_found(const char *hid); | 91 | bool acpi_dev_found(const char *hid); |
92 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); | 92 | bool acpi_dev_present(const char *hid, const char *uid, s64 hrv); |
93 | 93 | ||
94 | const char * | ||
95 | acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv); | ||
96 | |||
94 | #ifdef CONFIG_ACPI | 97 | #ifdef CONFIG_ACPI |
95 | 98 | ||
96 | #include <linux/proc_fs.h> | 99 | #include <linux/proc_fs.h> |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index dc1ebfeeb5ec..d918f1ea84e6 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -640,6 +640,12 @@ static inline bool acpi_dev_present(const char *hid, const char *uid, s64 hrv) | |||
640 | return false; | 640 | return false; |
641 | } | 641 | } |
642 | 642 | ||
643 | static inline const char * | ||
644 | acpi_dev_get_first_match_name(const char *hid, const char *uid, s64 hrv) | ||
645 | { | ||
646 | return NULL; | ||
647 | } | ||
648 | |||
643 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) | 649 | static inline bool is_acpi_node(struct fwnode_handle *fwnode) |
644 | { | 650 | { |
645 | return false; | 651 | return false; |
diff --git a/include/linux/iio/adc/stm32-dfsdm-adc.h b/include/linux/iio/adc/stm32-dfsdm-adc.h new file mode 100644 index 000000000000..e7dc7a542a4e --- /dev/null +++ b/include/linux/iio/adc/stm32-dfsdm-adc.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * This file discribe the STM32 DFSDM IIO driver API for audio part | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>. | ||
7 | */ | ||
8 | |||
9 | #ifndef STM32_DFSDM_ADC_H | ||
10 | #define STM32_DFSDM_ADC_H | ||
11 | |||
12 | int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev, | ||
13 | int (*cb)(const void *data, size_t size, | ||
14 | void *private), | ||
15 | void *private); | ||
16 | int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev); | ||
17 | |||
18 | #endif | ||
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index 5e347a9805fd..9887f4f8e2a8 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h | |||
@@ -134,6 +134,17 @@ struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev, | |||
134 | void *private), | 134 | void *private), |
135 | void *private); | 135 | void *private); |
136 | /** | 136 | /** |
137 | * iio_channel_cb_set_buffer_watermark() - set the buffer watermark. | ||
138 | * @cb_buffer: The callback buffer from whom we want the channel | ||
139 | * information. | ||
140 | * @watermark: buffer watermark in bytes. | ||
141 | * | ||
142 | * This function allows to configure the buffer watermark. | ||
143 | */ | ||
144 | int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buffer, | ||
145 | size_t watermark); | ||
146 | |||
147 | /** | ||
137 | * iio_channel_release_all_cb() - release and unregister the callback. | 148 | * iio_channel_release_all_cb() - release and unregister the callback. |
138 | * @cb_buffer: The callback buffer that was allocated. | 149 | * @cb_buffer: The callback buffer that was allocated. |
139 | */ | 150 | */ |
@@ -216,6 +227,32 @@ int iio_read_channel_average_raw(struct iio_channel *chan, int *val); | |||
216 | int iio_read_channel_processed(struct iio_channel *chan, int *val); | 227 | int iio_read_channel_processed(struct iio_channel *chan, int *val); |
217 | 228 | ||
218 | /** | 229 | /** |
230 | * iio_write_channel_attribute() - Write values to the device attribute. | ||
231 | * @chan: The channel being queried. | ||
232 | * @val: Value being written. | ||
233 | * @val2: Value being written.val2 use depends on attribute type. | ||
234 | * @attribute: info attribute to be read. | ||
235 | * | ||
236 | * Returns an error code or 0. | ||
237 | */ | ||
238 | int iio_write_channel_attribute(struct iio_channel *chan, int val, | ||
239 | int val2, enum iio_chan_info_enum attribute); | ||
240 | |||
241 | /** | ||
242 | * iio_read_channel_attribute() - Read values from the device attribute. | ||
243 | * @chan: The channel being queried. | ||
244 | * @val: Value being written. | ||
245 | * @val2: Value being written.Val2 use depends on attribute type. | ||
246 | * @attribute: info attribute to be written. | ||
247 | * | ||
248 | * Returns an error code if failed. Else returns a description of what is in val | ||
249 | * and val2, such as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val | ||
250 | * + val2/1e6 | ||
251 | */ | ||
252 | int iio_read_channel_attribute(struct iio_channel *chan, int *val, | ||
253 | int *val2, enum iio_chan_info_enum attribute); | ||
254 | |||
255 | /** | ||
219 | * iio_write_channel_raw() - write to a given channel | 256 | * iio_write_channel_raw() - write to a given channel |
220 | * @chan: The channel being queried. | 257 | * @chan: The channel being queried. |
221 | * @val: Value being written. | 258 | * @val: Value being written. |
diff --git a/include/linux/iio/hw-consumer.h b/include/linux/iio/hw-consumer.h new file mode 100644 index 000000000000..44d48bb1d39f --- /dev/null +++ b/include/linux/iio/hw-consumer.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Industrial I/O in kernel hardware consumer interface | ||
4 | * | ||
5 | * Copyright 2017 Analog Devices Inc. | ||
6 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
7 | */ | ||
8 | |||
9 | #ifndef LINUX_IIO_HW_CONSUMER_H | ||
10 | #define LINUX_IIO_HW_CONSUMER_H | ||
11 | |||
12 | struct iio_hw_consumer; | ||
13 | |||
14 | struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev); | ||
15 | void iio_hw_consumer_free(struct iio_hw_consumer *hwc); | ||
16 | struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev); | ||
17 | void devm_iio_hw_consumer_free(struct device *dev, struct iio_hw_consumer *hwc); | ||
18 | int iio_hw_consumer_enable(struct iio_hw_consumer *hwc); | ||
19 | void iio_hw_consumer_disable(struct iio_hw_consumer *hwc); | ||
20 | |||
21 | #endif | ||
diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index 20b61347ea58..f12a61be1ede 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h | |||
@@ -20,34 +20,6 @@ | |||
20 | * Currently assumes nano seconds. | 20 | * Currently assumes nano seconds. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | enum iio_chan_info_enum { | ||
24 | IIO_CHAN_INFO_RAW = 0, | ||
25 | IIO_CHAN_INFO_PROCESSED, | ||
26 | IIO_CHAN_INFO_SCALE, | ||
27 | IIO_CHAN_INFO_OFFSET, | ||
28 | IIO_CHAN_INFO_CALIBSCALE, | ||
29 | IIO_CHAN_INFO_CALIBBIAS, | ||
30 | IIO_CHAN_INFO_PEAK, | ||
31 | IIO_CHAN_INFO_PEAK_SCALE, | ||
32 | IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW, | ||
33 | IIO_CHAN_INFO_AVERAGE_RAW, | ||
34 | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, | ||
35 | IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY, | ||
36 | IIO_CHAN_INFO_SAMP_FREQ, | ||
37 | IIO_CHAN_INFO_FREQUENCY, | ||
38 | IIO_CHAN_INFO_PHASE, | ||
39 | IIO_CHAN_INFO_HARDWAREGAIN, | ||
40 | IIO_CHAN_INFO_HYSTERESIS, | ||
41 | IIO_CHAN_INFO_INT_TIME, | ||
42 | IIO_CHAN_INFO_ENABLE, | ||
43 | IIO_CHAN_INFO_CALIBHEIGHT, | ||
44 | IIO_CHAN_INFO_CALIBWEIGHT, | ||
45 | IIO_CHAN_INFO_DEBOUNCE_COUNT, | ||
46 | IIO_CHAN_INFO_DEBOUNCE_TIME, | ||
47 | IIO_CHAN_INFO_CALIBEMISSIVITY, | ||
48 | IIO_CHAN_INFO_OVERSAMPLING_RATIO, | ||
49 | }; | ||
50 | |||
51 | enum iio_shared_by { | 23 | enum iio_shared_by { |
52 | IIO_SEPARATE, | 24 | IIO_SEPARATE, |
53 | IIO_SHARED_BY_TYPE, | 25 | IIO_SHARED_BY_TYPE, |
diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 2aa7b6384d64..6eb3d683ef62 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h | |||
@@ -34,4 +34,32 @@ enum iio_available_type { | |||
34 | IIO_AVAIL_RANGE, | 34 | IIO_AVAIL_RANGE, |
35 | }; | 35 | }; |
36 | 36 | ||
37 | enum iio_chan_info_enum { | ||
38 | IIO_CHAN_INFO_RAW = 0, | ||
39 | IIO_CHAN_INFO_PROCESSED, | ||
40 | IIO_CHAN_INFO_SCALE, | ||
41 | IIO_CHAN_INFO_OFFSET, | ||
42 | IIO_CHAN_INFO_CALIBSCALE, | ||
43 | IIO_CHAN_INFO_CALIBBIAS, | ||
44 | IIO_CHAN_INFO_PEAK, | ||
45 | IIO_CHAN_INFO_PEAK_SCALE, | ||
46 | IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW, | ||
47 | IIO_CHAN_INFO_AVERAGE_RAW, | ||
48 | IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY, | ||
49 | IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY, | ||
50 | IIO_CHAN_INFO_SAMP_FREQ, | ||
51 | IIO_CHAN_INFO_FREQUENCY, | ||
52 | IIO_CHAN_INFO_PHASE, | ||
53 | IIO_CHAN_INFO_HARDWAREGAIN, | ||
54 | IIO_CHAN_INFO_HYSTERESIS, | ||
55 | IIO_CHAN_INFO_INT_TIME, | ||
56 | IIO_CHAN_INFO_ENABLE, | ||
57 | IIO_CHAN_INFO_CALIBHEIGHT, | ||
58 | IIO_CHAN_INFO_CALIBWEIGHT, | ||
59 | IIO_CHAN_INFO_DEBOUNCE_COUNT, | ||
60 | IIO_CHAN_INFO_DEBOUNCE_TIME, | ||
61 | IIO_CHAN_INFO_CALIBEMISSIVITY, | ||
62 | IIO_CHAN_INFO_OVERSAMPLING_RATIO, | ||
63 | }; | ||
64 | |||
37 | #endif /* _IIO_TYPES_H_ */ | 65 | #endif /* _IIO_TYPES_H_ */ |
diff --git a/include/linux/sound.h b/include/linux/sound.h index 3c6d393c7f29..ec85b7a1f8d1 100644 --- a/include/linux/sound.h +++ b/include/linux/sound.h | |||
@@ -12,11 +12,9 @@ struct device; | |||
12 | extern int register_sound_special(const struct file_operations *fops, int unit); | 12 | extern int register_sound_special(const struct file_operations *fops, int unit); |
13 | extern int register_sound_special_device(const struct file_operations *fops, int unit, struct device *dev); | 13 | extern int register_sound_special_device(const struct file_operations *fops, int unit, struct device *dev); |
14 | extern int register_sound_mixer(const struct file_operations *fops, int dev); | 14 | extern int register_sound_mixer(const struct file_operations *fops, int dev); |
15 | extern int register_sound_midi(const struct file_operations *fops, int dev); | ||
16 | extern int register_sound_dsp(const struct file_operations *fops, int dev); | 15 | extern int register_sound_dsp(const struct file_operations *fops, int dev); |
17 | 16 | ||
18 | extern void unregister_sound_special(int unit); | 17 | extern void unregister_sound_special(int unit); |
19 | extern void unregister_sound_mixer(int unit); | 18 | extern void unregister_sound_mixer(int unit); |
20 | extern void unregister_sound_midi(int unit); | ||
21 | extern void unregister_sound_dsp(int unit); | 19 | extern void unregister_sound_dsp(int unit); |
22 | #endif /* _LINUX_SOUND_H */ | 20 | #endif /* _LINUX_SOUND_H */ |
diff --git a/include/sound/hdaudio_ext.h b/include/sound/hdaudio_ext.h index ca00130cb028..9c14e21dda85 100644 --- a/include/sound/hdaudio_ext.h +++ b/include/sound/hdaudio_ext.h | |||
@@ -193,7 +193,7 @@ struct hda_dai_map { | |||
193 | * @pvt_data - private data, for asoc contains asoc codec object | 193 | * @pvt_data - private data, for asoc contains asoc codec object |
194 | */ | 194 | */ |
195 | struct hdac_ext_device { | 195 | struct hdac_ext_device { |
196 | struct hdac_device hdac; | 196 | struct hdac_device hdev; |
197 | struct hdac_ext_bus *ebus; | 197 | struct hdac_ext_bus *ebus; |
198 | 198 | ||
199 | /* soc-dai to nid map */ | 199 | /* soc-dai to nid map */ |
@@ -213,7 +213,7 @@ struct hdac_ext_dma_params { | |||
213 | u8 stream_tag; | 213 | u8 stream_tag; |
214 | }; | 214 | }; |
215 | #define to_ehdac_device(dev) (container_of((dev), \ | 215 | #define to_ehdac_device(dev) (container_of((dev), \ |
216 | struct hdac_ext_device, hdac)) | 216 | struct hdac_ext_device, hdev)) |
217 | /* | 217 | /* |
218 | * HD-audio codec base driver | 218 | * HD-audio codec base driver |
219 | */ | 219 | */ |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 24febf9e177c..e054c583d3b3 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -169,6 +169,10 @@ struct snd_pcm_ops { | |||
169 | #define SNDRV_PCM_FMTBIT_IMA_ADPCM _SNDRV_PCM_FMTBIT(IMA_ADPCM) | 169 | #define SNDRV_PCM_FMTBIT_IMA_ADPCM _SNDRV_PCM_FMTBIT(IMA_ADPCM) |
170 | #define SNDRV_PCM_FMTBIT_MPEG _SNDRV_PCM_FMTBIT(MPEG) | 170 | #define SNDRV_PCM_FMTBIT_MPEG _SNDRV_PCM_FMTBIT(MPEG) |
171 | #define SNDRV_PCM_FMTBIT_GSM _SNDRV_PCM_FMTBIT(GSM) | 171 | #define SNDRV_PCM_FMTBIT_GSM _SNDRV_PCM_FMTBIT(GSM) |
172 | #define SNDRV_PCM_FMTBIT_S20_LE _SNDRV_PCM_FMTBIT(S20_LE) | ||
173 | #define SNDRV_PCM_FMTBIT_U20_LE _SNDRV_PCM_FMTBIT(U20_LE) | ||
174 | #define SNDRV_PCM_FMTBIT_S20_BE _SNDRV_PCM_FMTBIT(S20_BE) | ||
175 | #define SNDRV_PCM_FMTBIT_U20_BE _SNDRV_PCM_FMTBIT(U20_BE) | ||
172 | #define SNDRV_PCM_FMTBIT_SPECIAL _SNDRV_PCM_FMTBIT(SPECIAL) | 176 | #define SNDRV_PCM_FMTBIT_SPECIAL _SNDRV_PCM_FMTBIT(SPECIAL) |
173 | #define SNDRV_PCM_FMTBIT_S24_3LE _SNDRV_PCM_FMTBIT(S24_3LE) | 177 | #define SNDRV_PCM_FMTBIT_S24_3LE _SNDRV_PCM_FMTBIT(S24_3LE) |
174 | #define SNDRV_PCM_FMTBIT_U24_3LE _SNDRV_PCM_FMTBIT(U24_3LE) | 178 | #define SNDRV_PCM_FMTBIT_U24_3LE _SNDRV_PCM_FMTBIT(U24_3LE) |
@@ -202,6 +206,8 @@ struct snd_pcm_ops { | |||
202 | #define SNDRV_PCM_FMTBIT_FLOAT SNDRV_PCM_FMTBIT_FLOAT_LE | 206 | #define SNDRV_PCM_FMTBIT_FLOAT SNDRV_PCM_FMTBIT_FLOAT_LE |
203 | #define SNDRV_PCM_FMTBIT_FLOAT64 SNDRV_PCM_FMTBIT_FLOAT64_LE | 207 | #define SNDRV_PCM_FMTBIT_FLOAT64 SNDRV_PCM_FMTBIT_FLOAT64_LE |
204 | #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | 208 | #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE |
209 | #define SNDRV_PCM_FMTBIT_S20 SNDRV_PCM_FMTBIT_S20_LE | ||
210 | #define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_LE | ||
205 | #endif | 211 | #endif |
206 | #ifdef SNDRV_BIG_ENDIAN | 212 | #ifdef SNDRV_BIG_ENDIAN |
207 | #define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_BE | 213 | #define SNDRV_PCM_FMTBIT_S16 SNDRV_PCM_FMTBIT_S16_BE |
@@ -213,6 +219,8 @@ struct snd_pcm_ops { | |||
213 | #define SNDRV_PCM_FMTBIT_FLOAT SNDRV_PCM_FMTBIT_FLOAT_BE | 219 | #define SNDRV_PCM_FMTBIT_FLOAT SNDRV_PCM_FMTBIT_FLOAT_BE |
214 | #define SNDRV_PCM_FMTBIT_FLOAT64 SNDRV_PCM_FMTBIT_FLOAT64_BE | 220 | #define SNDRV_PCM_FMTBIT_FLOAT64 SNDRV_PCM_FMTBIT_FLOAT64_BE |
215 | #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE | 221 | #define SNDRV_PCM_FMTBIT_IEC958_SUBFRAME SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE |
222 | #define SNDRV_PCM_FMTBIT_S20 SNDRV_PCM_FMTBIT_S20_BE | ||
223 | #define SNDRV_PCM_FMTBIT_U20 SNDRV_PCM_FMTBIT_U20_BE | ||
216 | #endif | 224 | #endif |
217 | 225 | ||
218 | struct snd_pcm_file { | 226 | struct snd_pcm_file { |
diff --git a/include/sound/rt5514.h b/include/sound/rt5514.h index ef18494769ee..64d027dbaaca 100644 --- a/include/sound/rt5514.h +++ b/include/sound/rt5514.h | |||
@@ -14,6 +14,8 @@ | |||
14 | 14 | ||
15 | struct rt5514_platform_data { | 15 | struct rt5514_platform_data { |
16 | unsigned int dmic_init_delay; | 16 | unsigned int dmic_init_delay; |
17 | const char *dsp_calib_clk_name; | ||
18 | unsigned int dsp_calib_clk_rate; | ||
17 | }; | 19 | }; |
18 | 20 | ||
19 | #endif | 21 | #endif |
diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h index d0c33a9972b9..f218c742f08e 100644 --- a/include/sound/rt5645.h +++ b/include/sound/rt5645.h | |||
@@ -25,6 +25,9 @@ struct rt5645_platform_data { | |||
25 | bool level_trigger_irq; | 25 | bool level_trigger_irq; |
26 | /* Invert JD1_1 status polarity */ | 26 | /* Invert JD1_1 status polarity */ |
27 | bool inv_jd1_1; | 27 | bool inv_jd1_1; |
28 | |||
29 | /* Value to asign to snd_soc_card.long_name */ | ||
30 | const char *long_name; | ||
28 | }; | 31 | }; |
29 | 32 | ||
30 | #endif | 33 | #endif |
diff --git a/include/sound/soc-acpi-intel-match.h b/include/sound/soc-acpi-intel-match.h index 1a9191cd4bb3..9da6388c20a1 100644 --- a/include/sound/soc-acpi-intel-match.h +++ b/include/sound/soc-acpi-intel-match.h | |||
@@ -16,6 +16,7 @@ | |||
16 | #ifndef __LINUX_SND_SOC_ACPI_INTEL_MATCH_H | 16 | #ifndef __LINUX_SND_SOC_ACPI_INTEL_MATCH_H |
17 | #define __LINUX_SND_SOC_ACPI_INTEL_MATCH_H | 17 | #define __LINUX_SND_SOC_ACPI_INTEL_MATCH_H |
18 | 18 | ||
19 | #include <linux/module.h> | ||
19 | #include <linux/stddef.h> | 20 | #include <linux/stddef.h> |
20 | #include <linux/acpi.h> | 21 | #include <linux/acpi.h> |
21 | 22 | ||
diff --git a/include/sound/soc-acpi.h b/include/sound/soc-acpi.h index a7d8d335b043..082224275f52 100644 --- a/include/sound/soc-acpi.h +++ b/include/sound/soc-acpi.h | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/stddef.h> | 18 | #include <linux/stddef.h> |
19 | #include <linux/acpi.h> | 19 | #include <linux/acpi.h> |
20 | #include <linux/mod_devicetable.h> | ||
20 | 21 | ||
21 | struct snd_soc_acpi_package_context { | 22 | struct snd_soc_acpi_package_context { |
22 | char *name; /* package name */ | 23 | char *name; /* package name */ |
@@ -26,17 +27,13 @@ struct snd_soc_acpi_package_context { | |||
26 | bool data_valid; | 27 | bool data_valid; |
27 | }; | 28 | }; |
28 | 29 | ||
30 | /* codec name is used in DAIs is i2c-<HID>:00 with HID being 8 chars */ | ||
31 | #define SND_ACPI_I2C_ID_LEN (4 + ACPI_ID_LEN + 3 + 1) | ||
32 | |||
29 | #if IS_ENABLED(CONFIG_ACPI) | 33 | #if IS_ENABLED(CONFIG_ACPI) |
30 | /* translation fron HID to I2C name, needed for DAI codec_name */ | ||
31 | const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]); | ||
32 | bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | 34 | bool snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], |
33 | struct snd_soc_acpi_package_context *ctx); | 35 | struct snd_soc_acpi_package_context *ctx); |
34 | #else | 36 | #else |
35 | static inline const char * | ||
36 | snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) | ||
37 | { | ||
38 | return NULL; | ||
39 | } | ||
40 | static inline bool | 37 | static inline bool |
41 | snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | 38 | snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], |
42 | struct snd_soc_acpi_package_context *ctx) | 39 | struct snd_soc_acpi_package_context *ctx) |
@@ -49,9 +46,6 @@ snd_soc_acpi_find_package_from_hid(const u8 hid[ACPI_ID_LEN], | |||
49 | struct snd_soc_acpi_mach * | 46 | struct snd_soc_acpi_mach * |
50 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines); | 47 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines); |
51 | 48 | ||
52 | /* acpi check hid */ | ||
53 | bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN]); | ||
54 | |||
55 | /** | 49 | /** |
56 | * snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are | 50 | * snd_soc_acpi_mach: ACPI-based machine descriptor. Most of the fields are |
57 | * related to the hardware, except for the firmware and topology file names. | 51 | * related to the hardware, except for the firmware and topology file names. |
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 58acd00cae19..8ad11669e4d8 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
@@ -102,6 +102,8 @@ struct snd_compr_stream; | |||
102 | SNDRV_PCM_FMTBIT_S16_BE |\ | 102 | SNDRV_PCM_FMTBIT_S16_BE |\ |
103 | SNDRV_PCM_FMTBIT_S20_3LE |\ | 103 | SNDRV_PCM_FMTBIT_S20_3LE |\ |
104 | SNDRV_PCM_FMTBIT_S20_3BE |\ | 104 | SNDRV_PCM_FMTBIT_S20_3BE |\ |
105 | SNDRV_PCM_FMTBIT_S20_LE |\ | ||
106 | SNDRV_PCM_FMTBIT_S20_BE |\ | ||
105 | SNDRV_PCM_FMTBIT_S24_3LE |\ | 107 | SNDRV_PCM_FMTBIT_S24_3LE |\ |
106 | SNDRV_PCM_FMTBIT_S24_3BE |\ | 108 | SNDRV_PCM_FMTBIT_S24_3BE |\ |
107 | SNDRV_PCM_FMTBIT_S32_LE |\ | 109 | SNDRV_PCM_FMTBIT_S32_LE |\ |
@@ -294,9 +296,6 @@ struct snd_soc_dai { | |||
294 | /* DAI runtime info */ | 296 | /* DAI runtime info */ |
295 | unsigned int capture_active:1; /* stream is in use */ | 297 | unsigned int capture_active:1; /* stream is in use */ |
296 | unsigned int playback_active:1; /* stream is in use */ | 298 | unsigned int playback_active:1; /* stream is in use */ |
297 | unsigned int symmetric_rates:1; | ||
298 | unsigned int symmetric_channels:1; | ||
299 | unsigned int symmetric_samplebits:1; | ||
300 | unsigned int probed:1; | 299 | unsigned int probed:1; |
301 | 300 | ||
302 | unsigned int active; | 301 | unsigned int active; |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 1a7323238c49..b655d987fbe7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -494,6 +494,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num); | |||
494 | int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); | 494 | int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num); |
495 | #endif | 495 | #endif |
496 | 496 | ||
497 | void snd_soc_disconnect_sync(struct device *dev); | ||
498 | |||
497 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, | 499 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, |
498 | const char *dai_link, int stream); | 500 | const char *dai_link, int stream); |
499 | struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, | 501 | struct snd_soc_pcm_runtime *snd_soc_get_pcm_runtime(struct snd_soc_card *card, |
@@ -802,6 +804,9 @@ struct snd_soc_component_driver { | |||
802 | int (*suspend)(struct snd_soc_component *); | 804 | int (*suspend)(struct snd_soc_component *); |
803 | int (*resume)(struct snd_soc_component *); | 805 | int (*resume)(struct snd_soc_component *); |
804 | 806 | ||
807 | unsigned int (*read)(struct snd_soc_component *, unsigned int); | ||
808 | int (*write)(struct snd_soc_component *, unsigned int, unsigned int); | ||
809 | |||
805 | /* pcm creation and destruction */ | 810 | /* pcm creation and destruction */ |
806 | int (*pcm_new)(struct snd_soc_pcm_runtime *); | 811 | int (*pcm_new)(struct snd_soc_pcm_runtime *); |
807 | void (*pcm_free)(struct snd_pcm *); | 812 | void (*pcm_free)(struct snd_pcm *); |
@@ -858,12 +863,10 @@ struct snd_soc_component { | |||
858 | struct list_head card_aux_list; /* for auxiliary bound components */ | 863 | struct list_head card_aux_list; /* for auxiliary bound components */ |
859 | struct list_head card_list; | 864 | struct list_head card_list; |
860 | 865 | ||
861 | struct snd_soc_dai_driver *dai_drv; | ||
862 | int num_dai; | ||
863 | |||
864 | const struct snd_soc_component_driver *driver; | 866 | const struct snd_soc_component_driver *driver; |
865 | 867 | ||
866 | struct list_head dai_list; | 868 | struct list_head dai_list; |
869 | int num_dai; | ||
867 | 870 | ||
868 | int (*read)(struct snd_soc_component *, unsigned int, unsigned int *); | 871 | int (*read)(struct snd_soc_component *, unsigned int, unsigned int *); |
869 | int (*write)(struct snd_soc_component *, unsigned int, unsigned int); | 872 | int (*write)(struct snd_soc_component *, unsigned int, unsigned int); |
diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h index c227ccba60ae..07d61583fd02 100644 --- a/include/uapi/sound/asound.h +++ b/include/uapi/sound/asound.h | |||
@@ -214,6 +214,11 @@ typedef int __bitwise snd_pcm_format_t; | |||
214 | #define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22) | 214 | #define SNDRV_PCM_FORMAT_IMA_ADPCM ((__force snd_pcm_format_t) 22) |
215 | #define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23) | 215 | #define SNDRV_PCM_FORMAT_MPEG ((__force snd_pcm_format_t) 23) |
216 | #define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24) | 216 | #define SNDRV_PCM_FORMAT_GSM ((__force snd_pcm_format_t) 24) |
217 | #define SNDRV_PCM_FORMAT_S20_LE ((__force snd_pcm_format_t) 25) /* in four bytes, LSB justified */ | ||
218 | #define SNDRV_PCM_FORMAT_S20_BE ((__force snd_pcm_format_t) 26) /* in four bytes, LSB justified */ | ||
219 | #define SNDRV_PCM_FORMAT_U20_LE ((__force snd_pcm_format_t) 27) /* in four bytes, LSB justified */ | ||
220 | #define SNDRV_PCM_FORMAT_U20_BE ((__force snd_pcm_format_t) 28) /* in four bytes, LSB justified */ | ||
221 | /* gap in the numbering for a future standard linear format */ | ||
217 | #define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31) | 222 | #define SNDRV_PCM_FORMAT_SPECIAL ((__force snd_pcm_format_t) 31) |
218 | #define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */ | 223 | #define SNDRV_PCM_FORMAT_S24_3LE ((__force snd_pcm_format_t) 32) /* in three bytes */ |
219 | #define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */ | 224 | #define SNDRV_PCM_FORMAT_S24_3BE ((__force snd_pcm_format_t) 33) /* in three bytes */ |
@@ -248,6 +253,8 @@ typedef int __bitwise snd_pcm_format_t; | |||
248 | #define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE | 253 | #define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_LE |
249 | #define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE | 254 | #define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_LE |
250 | #define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE | 255 | #define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE |
256 | #define SNDRV_PCM_FORMAT_S20 SNDRV_PCM_FORMAT_S20_LE | ||
257 | #define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_LE | ||
251 | #endif | 258 | #endif |
252 | #ifdef SNDRV_BIG_ENDIAN | 259 | #ifdef SNDRV_BIG_ENDIAN |
253 | #define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE | 260 | #define SNDRV_PCM_FORMAT_S16 SNDRV_PCM_FORMAT_S16_BE |
@@ -259,6 +266,8 @@ typedef int __bitwise snd_pcm_format_t; | |||
259 | #define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE | 266 | #define SNDRV_PCM_FORMAT_FLOAT SNDRV_PCM_FORMAT_FLOAT_BE |
260 | #define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE | 267 | #define SNDRV_PCM_FORMAT_FLOAT64 SNDRV_PCM_FORMAT_FLOAT64_BE |
261 | #define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE | 268 | #define SNDRV_PCM_FORMAT_IEC958_SUBFRAME SNDRV_PCM_FORMAT_IEC958_SUBFRAME_BE |
269 | #define SNDRV_PCM_FORMAT_S20 SNDRV_PCM_FORMAT_S20_BE | ||
270 | #define SNDRV_PCM_FORMAT_U20 SNDRV_PCM_FORMAT_U20_BE | ||
262 | #endif | 271 | #endif |
263 | 272 | ||
264 | typedef int __bitwise snd_pcm_subformat_t; | 273 | typedef int __bitwise snd_pcm_subformat_t; |
diff --git a/include/uapi/sound/snd_sst_tokens.h b/include/uapi/sound/snd_sst_tokens.h index 326054a72bc7..8ba0112e5336 100644 --- a/include/uapi/sound/snd_sst_tokens.h +++ b/include/uapi/sound/snd_sst_tokens.h | |||
@@ -222,6 +222,17 @@ | |||
222 | * %SKL_TKN_MM_U32_NUM_IN_FMT: Number of input formats | 222 | * %SKL_TKN_MM_U32_NUM_IN_FMT: Number of input formats |
223 | * %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats | 223 | * %SKL_TKN_MM_U32_NUM_OUT_FMT: Number of output formats |
224 | * | 224 | * |
225 | * %SKL_TKN_U32_ASTATE_IDX: Table Index for the A-State entry to be filled | ||
226 | * with kcps and clock source | ||
227 | * | ||
228 | * %SKL_TKN_U32_ASTATE_COUNT: Number of valid entries in A-State table | ||
229 | * | ||
230 | * %SKL_TKN_U32_ASTATE_KCPS: Specifies the core load threshold (in kilo | ||
231 | * cycles per second) below which DSP is clocked | ||
232 | * from source specified by clock source. | ||
233 | * | ||
234 | * %SKL_TKN_U32_ASTATE_CLK_SRC: Clock source for A-State entry | ||
235 | * | ||
225 | * module_id and loadable flags dont have tokens as these values will be | 236 | * module_id and loadable flags dont have tokens as these values will be |
226 | * read from the DSP FW manifest | 237 | * read from the DSP FW manifest |
227 | * | 238 | * |
@@ -309,7 +320,11 @@ enum SKL_TKNS { | |||
309 | SKL_TKN_MM_U32_NUM_IN_FMT, | 320 | SKL_TKN_MM_U32_NUM_IN_FMT, |
310 | SKL_TKN_MM_U32_NUM_OUT_FMT, | 321 | SKL_TKN_MM_U32_NUM_OUT_FMT, |
311 | 322 | ||
312 | SKL_TKN_MAX = SKL_TKN_MM_U32_NUM_OUT_FMT, | 323 | SKL_TKN_U32_ASTATE_IDX, |
324 | SKL_TKN_U32_ASTATE_COUNT, | ||
325 | SKL_TKN_U32_ASTATE_KCPS, | ||
326 | SKL_TKN_U32_ASTATE_CLK_SRC, | ||
327 | SKL_TKN_MAX = SKL_TKN_U32_ASTATE_CLK_SRC, | ||
313 | }; | 328 | }; |
314 | 329 | ||
315 | #endif | 330 | #endif |
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index c2db7e905f7d..e8b19876c420 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c | |||
@@ -186,7 +186,7 @@ static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params, | |||
186 | { | 186 | { |
187 | int changed; | 187 | int changed; |
188 | changed = snd_mask_refine(hw_param_mask(params, var), val); | 188 | changed = snd_mask_refine(hw_param_mask(params, var), val); |
189 | if (changed) { | 189 | if (changed > 0) { |
190 | params->cmask |= 1 << var; | 190 | params->cmask |= 1 << var; |
191 | params->rmask |= 1 << var; | 191 | params->rmask |= 1 << var; |
192 | } | 192 | } |
@@ -233,7 +233,7 @@ static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params, | |||
233 | val, open); | 233 | val, open); |
234 | else | 234 | else |
235 | return -EINVAL; | 235 | return -EINVAL; |
236 | if (changed) { | 236 | if (changed > 0) { |
237 | params->cmask |= 1 << var; | 237 | params->cmask |= 1 << var; |
238 | params->rmask |= 1 << var; | 238 | params->rmask |= 1 << var; |
239 | } | 239 | } |
@@ -294,7 +294,7 @@ static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params, | |||
294 | val, open); | 294 | val, open); |
295 | else | 295 | else |
296 | return -EINVAL; | 296 | return -EINVAL; |
297 | if (changed) { | 297 | if (changed > 0) { |
298 | params->cmask |= 1 << var; | 298 | params->cmask |= 1 << var; |
299 | params->rmask |= 1 << var; | 299 | params->rmask |= 1 << var; |
300 | } | 300 | } |
@@ -499,7 +499,7 @@ static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params, | |||
499 | } | 499 | } |
500 | } else | 500 | } else |
501 | return -EINVAL; | 501 | return -EINVAL; |
502 | if (changed) { | 502 | if (changed > 0) { |
503 | params->cmask |= 1 << var; | 503 | params->cmask |= 1 << var; |
504 | params->rmask |= 1 << var; | 504 | params->rmask |= 1 << var; |
505 | } | 505 | } |
@@ -539,7 +539,7 @@ static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params, | |||
539 | { | 539 | { |
540 | int changed; | 540 | int changed; |
541 | changed = snd_interval_setinteger(hw_param_interval(params, var)); | 541 | changed = snd_interval_setinteger(hw_param_interval(params, var)); |
542 | if (changed) { | 542 | if (changed > 0) { |
543 | params->cmask |= 1 << var; | 543 | params->cmask |= 1 << var; |
544 | params->rmask |= 1 << var; | 544 | params->rmask |= 1 << var; |
545 | } | 545 | } |
@@ -842,7 +842,7 @@ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream, | |||
842 | if (!(mutex_trylock(&runtime->oss.params_lock))) | 842 | if (!(mutex_trylock(&runtime->oss.params_lock))) |
843 | return -EAGAIN; | 843 | return -EAGAIN; |
844 | } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) | 844 | } else if (mutex_lock_interruptible(&runtime->oss.params_lock)) |
845 | return -EINTR; | 845 | return -ERESTARTSYS; |
846 | sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); | 846 | sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL); |
847 | params = kmalloc(sizeof(*params), GFP_KERNEL); | 847 | params = kmalloc(sizeof(*params), GFP_KERNEL); |
848 | sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); | 848 | sparams = kmalloc(sizeof(*sparams), GFP_KERNEL); |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index faa67861cbc1..a83152e7d387 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1602,7 +1602,7 @@ static int _snd_pcm_hw_param_first(struct snd_pcm_hw_params *params, | |||
1602 | changed = snd_interval_refine_first(hw_param_interval(params, var)); | 1602 | changed = snd_interval_refine_first(hw_param_interval(params, var)); |
1603 | else | 1603 | else |
1604 | return -EINVAL; | 1604 | return -EINVAL; |
1605 | if (changed) { | 1605 | if (changed > 0) { |
1606 | params->cmask |= 1 << var; | 1606 | params->cmask |= 1 << var; |
1607 | params->rmask |= 1 << var; | 1607 | params->rmask |= 1 << var; |
1608 | } | 1608 | } |
@@ -1648,7 +1648,7 @@ static int _snd_pcm_hw_param_last(struct snd_pcm_hw_params *params, | |||
1648 | changed = snd_interval_refine_last(hw_param_interval(params, var)); | 1648 | changed = snd_interval_refine_last(hw_param_interval(params, var)); |
1649 | else | 1649 | else |
1650 | return -EINVAL; | 1650 | return -EINVAL; |
1651 | if (changed) { | 1651 | if (changed > 0) { |
1652 | params->cmask |= 1 << var; | 1652 | params->cmask |= 1 << var; |
1653 | params->rmask |= 1 << var; | 1653 | params->rmask |= 1 << var; |
1654 | } | 1654 | } |
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 9be81025372f..c4eb561d2008 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -163,13 +163,30 @@ static struct pcm_format_data pcm_formats[(INT)SNDRV_PCM_FORMAT_LAST+1] = { | |||
163 | .width = 32, .phys = 32, .le = 0, .signd = 0, | 163 | .width = 32, .phys = 32, .le = 0, .signd = 0, |
164 | .silence = { 0x69, 0x69, 0x69, 0x69 }, | 164 | .silence = { 0x69, 0x69, 0x69, 0x69 }, |
165 | }, | 165 | }, |
166 | /* FIXME: the following three formats are not defined properly yet */ | 166 | /* FIXME: the following two formats are not defined properly yet */ |
167 | [SNDRV_PCM_FORMAT_MPEG] = { | 167 | [SNDRV_PCM_FORMAT_MPEG] = { |
168 | .le = -1, .signd = -1, | 168 | .le = -1, .signd = -1, |
169 | }, | 169 | }, |
170 | [SNDRV_PCM_FORMAT_GSM] = { | 170 | [SNDRV_PCM_FORMAT_GSM] = { |
171 | .le = -1, .signd = -1, | 171 | .le = -1, .signd = -1, |
172 | }, | 172 | }, |
173 | [SNDRV_PCM_FORMAT_S20_LE] = { | ||
174 | .width = 20, .phys = 32, .le = 1, .signd = 1, | ||
175 | .silence = {}, | ||
176 | }, | ||
177 | [SNDRV_PCM_FORMAT_S20_BE] = { | ||
178 | .width = 20, .phys = 32, .le = 0, .signd = 1, | ||
179 | .silence = {}, | ||
180 | }, | ||
181 | [SNDRV_PCM_FORMAT_U20_LE] = { | ||
182 | .width = 20, .phys = 32, .le = 1, .signd = 0, | ||
183 | .silence = { 0x00, 0x00, 0x08, 0x00 }, | ||
184 | }, | ||
185 | [SNDRV_PCM_FORMAT_U20_BE] = { | ||
186 | .width = 20, .phys = 32, .le = 0, .signd = 0, | ||
187 | .silence = { 0x00, 0x08, 0x00, 0x00 }, | ||
188 | }, | ||
189 | /* FIXME: the following format is not defined properly yet */ | ||
173 | [SNDRV_PCM_FORMAT_SPECIAL] = { | 190 | [SNDRV_PCM_FORMAT_SPECIAL] = { |
174 | .le = -1, .signd = -1, | 191 | .le = -1, .signd = -1, |
175 | }, | 192 | }, |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index f08772568c17..484a18d96371 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
@@ -3446,7 +3446,7 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); | |||
3446 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, | 3446 | int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, |
3447 | struct vm_area_struct *area) | 3447 | struct vm_area_struct *area) |
3448 | { | 3448 | { |
3449 | struct snd_pcm_runtime *runtime = substream->runtime;; | 3449 | struct snd_pcm_runtime *runtime = substream->runtime; |
3450 | 3450 | ||
3451 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); | 3451 | area->vm_page_prot = pgprot_noncached(area->vm_page_prot); |
3452 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); | 3452 | return vm_iomap_memory(area, runtime->dma_addr, runtime->dma_bytes); |
diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c index 79e0c5604ef8..0428e9061b47 100644 --- a/sound/core/seq/seq_queue.c +++ b/sound/core/seq/seq_queue.c | |||
@@ -497,9 +497,7 @@ int snd_seq_queue_timer_set_tempo(int queueid, int client, | |||
497 | return -EPERM; | 497 | return -EPERM; |
498 | } | 498 | } |
499 | 499 | ||
500 | result = snd_seq_timer_set_tempo(q->timer, info->tempo); | 500 | result = snd_seq_timer_set_tempo_ppq(q->timer, info->tempo, info->ppq); |
501 | if (result >= 0) | ||
502 | result = snd_seq_timer_set_ppq(q->timer, info->ppq); | ||
503 | if (result >= 0 && info->skew_base > 0) | 501 | if (result >= 0 && info->skew_base > 0) |
504 | result = snd_seq_timer_set_skew(q->timer, info->skew_value, | 502 | result = snd_seq_timer_set_skew(q->timer, info->skew_value, |
505 | info->skew_base); | 503 | info->skew_base); |
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index b80985fbc334..23167578231f 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c | |||
@@ -191,14 +191,15 @@ int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo) | |||
191 | return 0; | 191 | return 0; |
192 | } | 192 | } |
193 | 193 | ||
194 | /* set current ppq */ | 194 | /* set current tempo and ppq in a shot */ |
195 | int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) | 195 | int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq) |
196 | { | 196 | { |
197 | int changed; | ||
197 | unsigned long flags; | 198 | unsigned long flags; |
198 | 199 | ||
199 | if (snd_BUG_ON(!tmr)) | 200 | if (snd_BUG_ON(!tmr)) |
200 | return -EINVAL; | 201 | return -EINVAL; |
201 | if (ppq <= 0) | 202 | if (tempo <= 0 || ppq <= 0) |
202 | return -EINVAL; | 203 | return -EINVAL; |
203 | spin_lock_irqsave(&tmr->lock, flags); | 204 | spin_lock_irqsave(&tmr->lock, flags); |
204 | if (tmr->running && (ppq != tmr->ppq)) { | 205 | if (tmr->running && (ppq != tmr->ppq)) { |
@@ -208,9 +209,11 @@ int snd_seq_timer_set_ppq(struct snd_seq_timer * tmr, int ppq) | |||
208 | pr_debug("ALSA: seq: cannot change ppq of a running timer\n"); | 209 | pr_debug("ALSA: seq: cannot change ppq of a running timer\n"); |
209 | return -EBUSY; | 210 | return -EBUSY; |
210 | } | 211 | } |
211 | 212 | changed = (tempo != tmr->tempo) || (ppq != tmr->ppq); | |
213 | tmr->tempo = tempo; | ||
212 | tmr->ppq = ppq; | 214 | tmr->ppq = ppq; |
213 | snd_seq_timer_set_tick_resolution(tmr); | 215 | if (changed) |
216 | snd_seq_timer_set_tick_resolution(tmr); | ||
214 | spin_unlock_irqrestore(&tmr->lock, flags); | 217 | spin_unlock_irqrestore(&tmr->lock, flags); |
215 | return 0; | 218 | return 0; |
216 | } | 219 | } |
diff --git a/sound/core/seq/seq_timer.h b/sound/core/seq/seq_timer.h index 9506b661fe5b..62f390671096 100644 --- a/sound/core/seq/seq_timer.h +++ b/sound/core/seq/seq_timer.h | |||
@@ -131,7 +131,7 @@ int snd_seq_timer_stop(struct snd_seq_timer *tmr); | |||
131 | int snd_seq_timer_start(struct snd_seq_timer *tmr); | 131 | int snd_seq_timer_start(struct snd_seq_timer *tmr); |
132 | int snd_seq_timer_continue(struct snd_seq_timer *tmr); | 132 | int snd_seq_timer_continue(struct snd_seq_timer *tmr); |
133 | int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo); | 133 | int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo); |
134 | int snd_seq_timer_set_ppq(struct snd_seq_timer *tmr, int ppq); | 134 | int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq); |
135 | int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position); | 135 | int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position); |
136 | int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position); | 136 | int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position); |
137 | int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base); | 137 | int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base); |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index 7b2b1f766b00..69db45bc0197 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -830,7 +830,7 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el | |||
830 | static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol, | 830 | static int snd_dummy_iobox_info(struct snd_kcontrol *kcontrol, |
831 | struct snd_ctl_elem_info *info) | 831 | struct snd_ctl_elem_info *info) |
832 | { | 832 | { |
833 | const char *const names[] = { "None", "CD Player" }; | 833 | static const char *const names[] = { "None", "CD Player" }; |
834 | 834 | ||
835 | return snd_ctl_enum_info(info, 1, 2, names); | 835 | return snd_ctl_enum_info(info, 1, 2, names); |
836 | } | 836 | } |
diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 31b510c5ca0b..0daf31383084 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c | |||
@@ -146,7 +146,7 @@ int snd_hdac_ext_bus_device_init(struct hdac_ext_bus *ebus, int addr) | |||
146 | edev = kzalloc(sizeof(*edev), GFP_KERNEL); | 146 | edev = kzalloc(sizeof(*edev), GFP_KERNEL); |
147 | if (!edev) | 147 | if (!edev) |
148 | return -ENOMEM; | 148 | return -ENOMEM; |
149 | hdev = &edev->hdac; | 149 | hdev = &edev->hdev; |
150 | edev->ebus = ebus; | 150 | edev->ebus = ebus; |
151 | 151 | ||
152 | snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr); | 152 | snprintf(name, sizeof(name), "ehdaudio%dD%d", ebus->idx, addr); |
diff --git a/sound/isa/gus/gus_dma.c b/sound/isa/gus/gus_dma.c index 36c27c832360..7f95f452f106 100644 --- a/sound/isa/gus/gus_dma.c +++ b/sound/isa/gus/gus_dma.c | |||
@@ -201,10 +201,9 @@ int snd_gf1_dma_transfer_block(struct snd_gus_card * gus, | |||
201 | struct snd_gf1_dma_block *block; | 201 | struct snd_gf1_dma_block *block; |
202 | 202 | ||
203 | block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL); | 203 | block = kmalloc(sizeof(*block), atomic ? GFP_ATOMIC : GFP_KERNEL); |
204 | if (block == NULL) { | 204 | if (!block) |
205 | snd_printk(KERN_ERR "gf1: DMA transfer failure; not enough memory\n"); | ||
206 | return -ENOMEM; | 205 | return -ENOMEM; |
207 | } | 206 | |
208 | *block = *__block; | 207 | *block = *__block; |
209 | block->next = NULL; | 208 | block->next = NULL; |
210 | 209 | ||
diff --git a/sound/mips/hal2.c b/sound/mips/hal2.c index 37d378a26a50..c8904e732aaa 100644 --- a/sound/mips/hal2.c +++ b/sound/mips/hal2.c | |||
@@ -814,7 +814,7 @@ static int hal2_create(struct snd_card *card, struct snd_hal2 **rchip) | |||
814 | struct hpc3_regs *hpc3 = hpc3c0; | 814 | struct hpc3_regs *hpc3 = hpc3c0; |
815 | int err; | 815 | int err; |
816 | 816 | ||
817 | hal2 = kzalloc(sizeof(struct snd_hal2), GFP_KERNEL); | 817 | hal2 = kzalloc(sizeof(*hal2), GFP_KERNEL); |
818 | if (!hal2) | 818 | if (!hal2) |
819 | return -ENOMEM; | 819 | return -ENOMEM; |
820 | 820 | ||
diff --git a/sound/mips/sgio2audio.c b/sound/mips/sgio2audio.c index 71c942162c25..9fb68b35de5a 100644 --- a/sound/mips/sgio2audio.c +++ b/sound/mips/sgio2audio.c | |||
@@ -840,7 +840,7 @@ static int snd_sgio2audio_create(struct snd_card *card, | |||
840 | if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) | 840 | if (!(readq(&mace->perif.audio.control) & AUDIO_CONTROL_CODEC_PRESENT)) |
841 | return -ENOENT; | 841 | return -ENOENT; |
842 | 842 | ||
843 | chip = kzalloc(sizeof(struct snd_sgio2audio), GFP_KERNEL); | 843 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
844 | if (chip == NULL) | 844 | if (chip == NULL) |
845 | return -ENOMEM; | 845 | return -ENOMEM; |
846 | 846 | ||
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 7f3b5ed81995..f7a492c382d9 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -88,7 +88,6 @@ config SND_HDA_PATCH_LOADER | |||
88 | config SND_HDA_CODEC_REALTEK | 88 | config SND_HDA_CODEC_REALTEK |
89 | tristate "Build Realtek HD-audio codec support" | 89 | tristate "Build Realtek HD-audio codec support" |
90 | select SND_HDA_GENERIC | 90 | select SND_HDA_GENERIC |
91 | select INPUT | ||
92 | help | 91 | help |
93 | Say Y or M here to include Realtek HD-audio codec support in | 92 | Say Y or M here to include Realtek HD-audio codec support in |
94 | snd-hda-intel driver, such as ALC880. | 93 | snd-hda-intel driver, such as ALC880. |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9aafc6c86132..23475888192b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -3154,11 +3154,13 @@ static void alc256_shutup(struct hda_codec *codec) | |||
3154 | if (hp_pin_sense) | 3154 | if (hp_pin_sense) |
3155 | msleep(85); | 3155 | msleep(85); |
3156 | 3156 | ||
3157 | /* 3k pull low control for Headset jack. */ | ||
3158 | /* NOTE: call this before clearing the pin, otherwise codec stalls */ | ||
3159 | alc_update_coef_idx(codec, 0x46, 0, 3 << 12); | ||
3160 | |||
3157 | snd_hda_codec_write(codec, hp_pin, 0, | 3161 | snd_hda_codec_write(codec, hp_pin, 0, |
3158 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 3162 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
3159 | 3163 | ||
3160 | alc_update_coef_idx(codec, 0x46, 0, 3 << 12); /* 3k pull low control for Headset jack. */ | ||
3161 | |||
3162 | if (hp_pin_sense) | 3164 | if (hp_pin_sense) |
3163 | msleep(100); | 3165 | msleep(100); |
3164 | 3166 | ||
@@ -3166,6 +3168,93 @@ static void alc256_shutup(struct hda_codec *codec) | |||
3166 | snd_hda_shutup_pins(codec); | 3168 | snd_hda_shutup_pins(codec); |
3167 | } | 3169 | } |
3168 | 3170 | ||
3171 | static void alc225_init(struct hda_codec *codec) | ||
3172 | { | ||
3173 | struct alc_spec *spec = codec->spec; | ||
3174 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3175 | bool hp1_pin_sense, hp2_pin_sense; | ||
3176 | |||
3177 | if (!hp_pin) | ||
3178 | return; | ||
3179 | |||
3180 | msleep(30); | ||
3181 | |||
3182 | hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
3183 | hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); | ||
3184 | |||
3185 | if (hp1_pin_sense || hp2_pin_sense) | ||
3186 | msleep(2); | ||
3187 | |||
3188 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ | ||
3189 | |||
3190 | if (hp1_pin_sense) | ||
3191 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3192 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3193 | if (hp2_pin_sense) | ||
3194 | snd_hda_codec_write(codec, 0x16, 0, | ||
3195 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3196 | |||
3197 | if (hp1_pin_sense || hp2_pin_sense) | ||
3198 | msleep(85); | ||
3199 | |||
3200 | if (hp1_pin_sense) | ||
3201 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3202 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3203 | if (hp2_pin_sense) | ||
3204 | snd_hda_codec_write(codec, 0x16, 0, | ||
3205 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3206 | |||
3207 | if (hp1_pin_sense || hp2_pin_sense) | ||
3208 | msleep(100); | ||
3209 | |||
3210 | alc_update_coef_idx(codec, 0x4a, 3 << 10, 0); | ||
3211 | alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x4); /* Hight power */ | ||
3212 | } | ||
3213 | |||
3214 | static void alc225_shutup(struct hda_codec *codec) | ||
3215 | { | ||
3216 | struct alc_spec *spec = codec->spec; | ||
3217 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | ||
3218 | bool hp1_pin_sense, hp2_pin_sense; | ||
3219 | |||
3220 | if (!hp_pin) { | ||
3221 | alc269_shutup(codec); | ||
3222 | return; | ||
3223 | } | ||
3224 | |||
3225 | /* 3k pull low control for Headset jack. */ | ||
3226 | alc_update_coef_idx(codec, 0x4a, 0, 3 << 10); | ||
3227 | |||
3228 | hp1_pin_sense = snd_hda_jack_detect(codec, hp_pin); | ||
3229 | hp2_pin_sense = snd_hda_jack_detect(codec, 0x16); | ||
3230 | |||
3231 | if (hp1_pin_sense || hp2_pin_sense) | ||
3232 | msleep(2); | ||
3233 | |||
3234 | if (hp1_pin_sense) | ||
3235 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3236 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3237 | if (hp2_pin_sense) | ||
3238 | snd_hda_codec_write(codec, 0x16, 0, | ||
3239 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3240 | |||
3241 | if (hp1_pin_sense || hp2_pin_sense) | ||
3242 | msleep(85); | ||
3243 | |||
3244 | if (hp1_pin_sense) | ||
3245 | snd_hda_codec_write(codec, hp_pin, 0, | ||
3246 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
3247 | if (hp2_pin_sense) | ||
3248 | snd_hda_codec_write(codec, 0x16, 0, | ||
3249 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
3250 | |||
3251 | if (hp1_pin_sense || hp2_pin_sense) | ||
3252 | msleep(100); | ||
3253 | |||
3254 | alc_auto_setup_eapd(codec, false); | ||
3255 | snd_hda_shutup_pins(codec); | ||
3256 | } | ||
3257 | |||
3169 | static void alc_default_init(struct hda_codec *codec) | 3258 | static void alc_default_init(struct hda_codec *codec) |
3170 | { | 3259 | { |
3171 | struct alc_spec *spec = codec->spec; | 3260 | struct alc_spec *spec = codec->spec; |
@@ -3723,6 +3812,7 @@ static void alc280_fixup_hp_gpio4(struct hda_codec *codec, | |||
3723 | } | 3812 | } |
3724 | } | 3813 | } |
3725 | 3814 | ||
3815 | #if IS_REACHABLE(INPUT) | ||
3726 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, | 3816 | static void gpio2_mic_hotkey_event(struct hda_codec *codec, |
3727 | struct hda_jack_callback *event) | 3817 | struct hda_jack_callback *event) |
3728 | { | 3818 | { |
@@ -3855,6 +3945,10 @@ static void alc233_fixup_lenovo_line2_mic_hotkey(struct hda_codec *codec, | |||
3855 | spec->kb_dev = NULL; | 3945 | spec->kb_dev = NULL; |
3856 | } | 3946 | } |
3857 | } | 3947 | } |
3948 | #else /* INPUT */ | ||
3949 | #define alc280_fixup_hp_gpio2_mic_hotkey NULL | ||
3950 | #define alc233_fixup_lenovo_line2_mic_hotkey NULL | ||
3951 | #endif /* INPUT */ | ||
3858 | 3952 | ||
3859 | static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, | 3953 | static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec, |
3860 | const struct hda_fixup *fix, int action) | 3954 | const struct hda_fixup *fix, int action) |
@@ -3994,8 +4088,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) | |||
3994 | case 0x10ec0668: | 4088 | case 0x10ec0668: |
3995 | alc_process_coef_fw(codec, coef0668); | 4089 | alc_process_coef_fw(codec, coef0668); |
3996 | break; | 4090 | break; |
4091 | case 0x10ec0215: | ||
3997 | case 0x10ec0225: | 4092 | case 0x10ec0225: |
4093 | case 0x10ec0285: | ||
3998 | case 0x10ec0295: | 4094 | case 0x10ec0295: |
4095 | case 0x10ec0289: | ||
3999 | case 0x10ec0299: | 4096 | case 0x10ec0299: |
4000 | alc_process_coef_fw(codec, coef0225); | 4097 | alc_process_coef_fw(codec, coef0225); |
4001 | break; | 4098 | break; |
@@ -4117,8 +4214,11 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
4117 | alc_process_coef_fw(codec, coef0688); | 4214 | alc_process_coef_fw(codec, coef0688); |
4118 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 4215 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
4119 | break; | 4216 | break; |
4217 | case 0x10ec0215: | ||
4120 | case 0x10ec0225: | 4218 | case 0x10ec0225: |
4219 | case 0x10ec0285: | ||
4121 | case 0x10ec0295: | 4220 | case 0x10ec0295: |
4221 | case 0x10ec0289: | ||
4122 | case 0x10ec0299: | 4222 | case 0x10ec0299: |
4123 | alc_process_coef_fw(codec, alc225_pre_hsmode); | 4223 | alc_process_coef_fw(codec, alc225_pre_hsmode); |
4124 | alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); | 4224 | alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10); |
@@ -4189,8 +4289,11 @@ static void alc_headset_mode_default(struct hda_codec *codec) | |||
4189 | }; | 4289 | }; |
4190 | 4290 | ||
4191 | switch (codec->core.vendor_id) { | 4291 | switch (codec->core.vendor_id) { |
4292 | case 0x10ec0215: | ||
4192 | case 0x10ec0225: | 4293 | case 0x10ec0225: |
4294 | case 0x10ec0285: | ||
4193 | case 0x10ec0295: | 4295 | case 0x10ec0295: |
4296 | case 0x10ec0289: | ||
4194 | case 0x10ec0299: | 4297 | case 0x10ec0299: |
4195 | alc_process_coef_fw(codec, alc225_pre_hsmode); | 4298 | alc_process_coef_fw(codec, alc225_pre_hsmode); |
4196 | alc_process_coef_fw(codec, coef0225); | 4299 | alc_process_coef_fw(codec, coef0225); |
@@ -4332,8 +4435,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) | |||
4332 | case 0x10ec0668: | 4435 | case 0x10ec0668: |
4333 | alc_process_coef_fw(codec, coef0688); | 4436 | alc_process_coef_fw(codec, coef0688); |
4334 | break; | 4437 | break; |
4438 | case 0x10ec0215: | ||
4335 | case 0x10ec0225: | 4439 | case 0x10ec0225: |
4440 | case 0x10ec0285: | ||
4336 | case 0x10ec0295: | 4441 | case 0x10ec0295: |
4442 | case 0x10ec0289: | ||
4337 | case 0x10ec0299: | 4443 | case 0x10ec0299: |
4338 | val = alc_read_coef_idx(codec, 0x45); | 4444 | val = alc_read_coef_idx(codec, 0x45); |
4339 | if (val & (1 << 9)) | 4445 | if (val & (1 << 9)) |
@@ -4436,8 +4542,11 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) | |||
4436 | case 0x10ec0668: | 4542 | case 0x10ec0668: |
4437 | alc_process_coef_fw(codec, coef0688); | 4543 | alc_process_coef_fw(codec, coef0688); |
4438 | break; | 4544 | break; |
4545 | case 0x10ec0215: | ||
4439 | case 0x10ec0225: | 4546 | case 0x10ec0225: |
4547 | case 0x10ec0285: | ||
4440 | case 0x10ec0295: | 4548 | case 0x10ec0295: |
4549 | case 0x10ec0289: | ||
4441 | case 0x10ec0299: | 4550 | case 0x10ec0299: |
4442 | alc_process_coef_fw(codec, coef0225); | 4551 | alc_process_coef_fw(codec, coef0225); |
4443 | break; | 4552 | break; |
@@ -4566,9 +4675,18 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
4566 | val = alc_read_coef_idx(codec, 0xbe); | 4675 | val = alc_read_coef_idx(codec, 0xbe); |
4567 | is_ctia = (val & 0x1c02) == 0x1c02; | 4676 | is_ctia = (val & 0x1c02) == 0x1c02; |
4568 | break; | 4677 | break; |
4678 | case 0x10ec0215: | ||
4569 | case 0x10ec0225: | 4679 | case 0x10ec0225: |
4680 | case 0x10ec0285: | ||
4570 | case 0x10ec0295: | 4681 | case 0x10ec0295: |
4682 | case 0x10ec0289: | ||
4571 | case 0x10ec0299: | 4683 | case 0x10ec0299: |
4684 | snd_hda_codec_write(codec, 0x21, 0, | ||
4685 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
4686 | msleep(80); | ||
4687 | snd_hda_codec_write(codec, 0x21, 0, | ||
4688 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | ||
4689 | |||
4572 | alc_process_coef_fw(codec, alc225_pre_hsmode); | 4690 | alc_process_coef_fw(codec, alc225_pre_hsmode); |
4573 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); | 4691 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x1000); |
4574 | val = alc_read_coef_idx(codec, 0x45); | 4692 | val = alc_read_coef_idx(codec, 0x45); |
@@ -4588,6 +4706,12 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
4588 | alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); | 4706 | alc_update_coef_idx(codec, 0x4a, 7<<6, 7<<6); |
4589 | alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); | 4707 | alc_update_coef_idx(codec, 0x4a, 3<<4, 3<<4); |
4590 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); | 4708 | alc_update_coef_idx(codec, 0x67, 0xf000, 0x3000); |
4709 | |||
4710 | snd_hda_codec_write(codec, 0x21, 0, | ||
4711 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
4712 | msleep(80); | ||
4713 | snd_hda_codec_write(codec, 0x21, 0, | ||
4714 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | ||
4591 | break; | 4715 | break; |
4592 | case 0x10ec0867: | 4716 | case 0x10ec0867: |
4593 | is_ctia = true; | 4717 | is_ctia = true; |
@@ -6920,16 +7044,17 @@ static int patch_alc269(struct hda_codec *codec) | |||
6920 | case 0x10ec0285: | 7044 | case 0x10ec0285: |
6921 | case 0x10ec0289: | 7045 | case 0x10ec0289: |
6922 | spec->codec_variant = ALC269_TYPE_ALC215; | 7046 | spec->codec_variant = ALC269_TYPE_ALC215; |
7047 | spec->shutup = alc225_shutup; | ||
7048 | spec->init_hook = alc225_init; | ||
6923 | spec->gen.mixer_nid = 0; | 7049 | spec->gen.mixer_nid = 0; |
6924 | break; | 7050 | break; |
6925 | case 0x10ec0225: | 7051 | case 0x10ec0225: |
6926 | case 0x10ec0295: | 7052 | case 0x10ec0295: |
6927 | spec->codec_variant = ALC269_TYPE_ALC225; | ||
6928 | spec->gen.mixer_nid = 0; /* no loopback on ALC225 ALC295 */ | ||
6929 | break; | ||
6930 | case 0x10ec0299: | 7053 | case 0x10ec0299: |
6931 | spec->codec_variant = ALC269_TYPE_ALC225; | 7054 | spec->codec_variant = ALC269_TYPE_ALC225; |
6932 | spec->gen.mixer_nid = 0; /* no loopback on ALC299 */ | 7055 | spec->shutup = alc225_shutup; |
7056 | spec->init_hook = alc225_init; | ||
7057 | spec->gen.mixer_nid = 0; /* no loopback on ALC225, ALC295 and ALC299 */ | ||
6933 | break; | 7058 | break; |
6934 | case 0x10ec0234: | 7059 | case 0x10ec0234: |
6935 | case 0x10ec0274: | 7060 | case 0x10ec0274: |
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c index 2697402b5195..8dabd4d0211d 100644 --- a/sound/pci/ice1712/prodigy_hifi.c +++ b/sound/pci/ice1712/prodigy_hifi.c | |||
@@ -965,13 +965,32 @@ static int prodigy_hd2_add_controls(struct snd_ice1712 *ice) | |||
965 | return 0; | 965 | return 0; |
966 | } | 966 | } |
967 | 967 | ||
968 | static void wm8766_init(struct snd_ice1712 *ice) | ||
969 | { | ||
970 | static unsigned short wm8766_inits[] = { | ||
971 | WM8766_RESET, 0x0000, | ||
972 | WM8766_DAC_CTRL, 0x0120, | ||
973 | WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ | ||
974 | WM8766_DAC_CTRL2, 0x0001, | ||
975 | WM8766_DAC_CTRL3, 0x0080, | ||
976 | WM8766_LDA1, 0x0100, | ||
977 | WM8766_LDA2, 0x0100, | ||
978 | WM8766_LDA3, 0x0100, | ||
979 | WM8766_RDA1, 0x0100, | ||
980 | WM8766_RDA2, 0x0100, | ||
981 | WM8766_RDA3, 0x0100, | ||
982 | WM8766_MUTE1, 0x0000, | ||
983 | WM8766_MUTE2, 0x0000, | ||
984 | }; | ||
985 | unsigned int i; | ||
968 | 986 | ||
969 | /* | 987 | for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) |
970 | * initialize the chip | 988 | wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i + 1]); |
971 | */ | 989 | } |
972 | static int prodigy_hifi_init(struct snd_ice1712 *ice) | 990 | |
991 | static void wm8776_init(struct snd_ice1712 *ice) | ||
973 | { | 992 | { |
974 | static unsigned short wm_inits[] = { | 993 | static unsigned short wm8776_inits[] = { |
975 | /* These come first to reduce init pop noise */ | 994 | /* These come first to reduce init pop noise */ |
976 | WM_ADC_MUX, 0x0003, /* ADC mute */ | 995 | WM_ADC_MUX, 0x0003, /* ADC mute */ |
977 | /* 0x00c0 replaced by 0x0003 */ | 996 | /* 0x00c0 replaced by 0x0003 */ |
@@ -982,7 +1001,76 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) | |||
982 | WM_POWERDOWN, 0x0008, /* All power-up except HP */ | 1001 | WM_POWERDOWN, 0x0008, /* All power-up except HP */ |
983 | WM_RESET, 0x0000, /* reset */ | 1002 | WM_RESET, 0x0000, /* reset */ |
984 | }; | 1003 | }; |
985 | static unsigned short wm_inits2[] = { | 1004 | unsigned int i; |
1005 | |||
1006 | for (i = 0; i < ARRAY_SIZE(wm8776_inits); i += 2) | ||
1007 | wm_put(ice, wm8776_inits[i], wm8776_inits[i + 1]); | ||
1008 | } | ||
1009 | |||
1010 | #ifdef CONFIG_PM_SLEEP | ||
1011 | static int prodigy_hifi_resume(struct snd_ice1712 *ice) | ||
1012 | { | ||
1013 | static unsigned short wm8776_reinit_registers[] = { | ||
1014 | WM_MASTER_CTRL, | ||
1015 | WM_DAC_INT, | ||
1016 | WM_ADC_INT, | ||
1017 | WM_OUT_MUX, | ||
1018 | WM_HP_ATTEN_L, | ||
1019 | WM_HP_ATTEN_R, | ||
1020 | WM_PHASE_SWAP, | ||
1021 | WM_DAC_CTRL2, | ||
1022 | WM_ADC_ATTEN_L, | ||
1023 | WM_ADC_ATTEN_R, | ||
1024 | WM_ALC_CTRL1, | ||
1025 | WM_ALC_CTRL2, | ||
1026 | WM_ALC_CTRL3, | ||
1027 | WM_NOISE_GATE, | ||
1028 | WM_ADC_MUX, | ||
1029 | /* no DAC attenuation here */ | ||
1030 | }; | ||
1031 | struct prodigy_hifi_spec *spec = ice->spec; | ||
1032 | int i, ch; | ||
1033 | |||
1034 | mutex_lock(&ice->gpio_mutex); | ||
1035 | |||
1036 | /* reinitialize WM8776 and re-apply old register values */ | ||
1037 | wm8776_init(ice); | ||
1038 | schedule_timeout_uninterruptible(1); | ||
1039 | for (i = 0; i < ARRAY_SIZE(wm8776_reinit_registers); i++) | ||
1040 | wm_put(ice, wm8776_reinit_registers[i], | ||
1041 | wm_get(ice, wm8776_reinit_registers[i])); | ||
1042 | |||
1043 | /* reinitialize WM8766 and re-apply volumes for all DACs */ | ||
1044 | wm8766_init(ice); | ||
1045 | for (ch = 0; ch < 2; ch++) { | ||
1046 | wm_set_vol(ice, WM_DAC_ATTEN_L + ch, | ||
1047 | spec->vol[2 + ch], spec->master[ch]); | ||
1048 | |||
1049 | wm8766_set_vol(ice, WM8766_LDA1 + ch, | ||
1050 | spec->vol[0 + ch], spec->master[ch]); | ||
1051 | |||
1052 | wm8766_set_vol(ice, WM8766_LDA2 + ch, | ||
1053 | spec->vol[4 + ch], spec->master[ch]); | ||
1054 | |||
1055 | wm8766_set_vol(ice, WM8766_LDA3 + ch, | ||
1056 | spec->vol[6 + ch], spec->master[ch]); | ||
1057 | } | ||
1058 | |||
1059 | /* unmute WM8776 DAC */ | ||
1060 | wm_put(ice, WM_DAC_MUTE, 0x00); | ||
1061 | wm_put(ice, WM_DAC_CTRL1, 0x90); | ||
1062 | |||
1063 | mutex_unlock(&ice->gpio_mutex); | ||
1064 | return 0; | ||
1065 | } | ||
1066 | #endif | ||
1067 | |||
1068 | /* | ||
1069 | * initialize the chip | ||
1070 | */ | ||
1071 | static int prodigy_hifi_init(struct snd_ice1712 *ice) | ||
1072 | { | ||
1073 | static unsigned short wm8776_defaults[] = { | ||
986 | WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ | 1074 | WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ |
987 | WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ | 1075 | WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ |
988 | WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ | 1076 | WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ |
@@ -1010,22 +1098,6 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) | |||
1010 | WM_DAC_MUTE, 0x0000, /* DAC unmute */ | 1098 | WM_DAC_MUTE, 0x0000, /* DAC unmute */ |
1011 | WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ | 1099 | WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ |
1012 | }; | 1100 | }; |
1013 | static unsigned short wm8766_inits[] = { | ||
1014 | WM8766_RESET, 0x0000, | ||
1015 | WM8766_DAC_CTRL, 0x0120, | ||
1016 | WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */ | ||
1017 | WM8766_DAC_CTRL2, 0x0001, | ||
1018 | WM8766_DAC_CTRL3, 0x0080, | ||
1019 | WM8766_LDA1, 0x0100, | ||
1020 | WM8766_LDA2, 0x0100, | ||
1021 | WM8766_LDA3, 0x0100, | ||
1022 | WM8766_RDA1, 0x0100, | ||
1023 | WM8766_RDA2, 0x0100, | ||
1024 | WM8766_RDA3, 0x0100, | ||
1025 | WM8766_MUTE1, 0x0000, | ||
1026 | WM8766_MUTE2, 0x0000, | ||
1027 | }; | ||
1028 | |||
1029 | struct prodigy_hifi_spec *spec; | 1101 | struct prodigy_hifi_spec *spec; |
1030 | unsigned int i; | 1102 | unsigned int i; |
1031 | 1103 | ||
@@ -1052,16 +1124,17 @@ static int prodigy_hifi_init(struct snd_ice1712 *ice) | |||
1052 | ice->spec = spec; | 1124 | ice->spec = spec; |
1053 | 1125 | ||
1054 | /* initialize WM8776 codec */ | 1126 | /* initialize WM8776 codec */ |
1055 | for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2) | 1127 | wm8776_init(ice); |
1056 | wm_put(ice, wm_inits[i], wm_inits[i+1]); | ||
1057 | schedule_timeout_uninterruptible(1); | 1128 | schedule_timeout_uninterruptible(1); |
1058 | for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2) | 1129 | for (i = 0; i < ARRAY_SIZE(wm8776_defaults); i += 2) |
1059 | wm_put(ice, wm_inits2[i], wm_inits2[i+1]); | 1130 | wm_put(ice, wm8776_defaults[i], wm8776_defaults[i + 1]); |
1060 | 1131 | ||
1061 | /* initialize WM8766 codec */ | 1132 | wm8766_init(ice); |
1062 | for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2) | ||
1063 | wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]); | ||
1064 | 1133 | ||
1134 | #ifdef CONFIG_PM_SLEEP | ||
1135 | ice->pm_resume = &prodigy_hifi_resume; | ||
1136 | ice->pm_suspend_enabled = 1; | ||
1137 | #endif | ||
1065 | 1138 | ||
1066 | return 0; | 1139 | return 0; |
1067 | } | 1140 | } |
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index c7b007164c99..4206ba44d8bb 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c | |||
@@ -2348,7 +2348,6 @@ static int snd_korg1212_create(struct snd_card *card, struct pci_dev *pci, | |||
2348 | 2348 | ||
2349 | err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); | 2349 | err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); |
2350 | if (err < 0) { | 2350 | if (err < 0) { |
2351 | release_firmware(dsp_code); | ||
2352 | snd_printk(KERN_ERR "firmware not available\n"); | 2351 | snd_printk(KERN_ERR "firmware not available\n"); |
2353 | snd_korg1212_free(korg1212); | 2352 | snd_korg1212_free(korg1212); |
2354 | return err; | 2353 | return err; |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index d22758165496..84c3582f3982 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
@@ -71,6 +71,7 @@ source "sound/soc/stm/Kconfig" | |||
71 | source "sound/soc/sunxi/Kconfig" | 71 | source "sound/soc/sunxi/Kconfig" |
72 | source "sound/soc/tegra/Kconfig" | 72 | source "sound/soc/tegra/Kconfig" |
73 | source "sound/soc/txx9/Kconfig" | 73 | source "sound/soc/txx9/Kconfig" |
74 | source "sound/soc/uniphier/Kconfig" | ||
74 | source "sound/soc/ux500/Kconfig" | 75 | source "sound/soc/ux500/Kconfig" |
75 | source "sound/soc/xtensa/Kconfig" | 76 | source "sound/soc/xtensa/Kconfig" |
76 | source "sound/soc/zte/Kconfig" | 77 | source "sound/soc/zte/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 5327f4d6c668..74cd1858d38b 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_SND_SOC) += stm/ | |||
55 | obj-$(CONFIG_SND_SOC) += sunxi/ | 55 | obj-$(CONFIG_SND_SOC) += sunxi/ |
56 | obj-$(CONFIG_SND_SOC) += tegra/ | 56 | obj-$(CONFIG_SND_SOC) += tegra/ |
57 | obj-$(CONFIG_SND_SOC) += txx9/ | 57 | obj-$(CONFIG_SND_SOC) += txx9/ |
58 | obj-$(CONFIG_SND_SOC) += uniphier/ | ||
58 | obj-$(CONFIG_SND_SOC) += ux500/ | 59 | obj-$(CONFIG_SND_SOC) += ux500/ |
59 | obj-$(CONFIG_SND_SOC) += xtensa/ | 60 | obj-$(CONFIG_SND_SOC) += xtensa/ |
60 | obj-$(CONFIG_SND_SOC) += zte/ | 61 | obj-$(CONFIG_SND_SOC) += zte/ |
diff --git a/sound/soc/amd/acp-pcm-dma.c b/sound/soc/amd/acp-pcm-dma.c index b5e41df6bb3a..c33a512283a4 100644 --- a/sound/soc/amd/acp-pcm-dma.c +++ b/sound/soc/amd/acp-pcm-dma.c | |||
@@ -850,6 +850,9 @@ static snd_pcm_uframes_t acp_dma_pointer(struct snd_pcm_substream *substream) | |||
850 | struct snd_pcm_runtime *runtime = substream->runtime; | 850 | struct snd_pcm_runtime *runtime = substream->runtime; |
851 | struct audio_substream_data *rtd = runtime->private_data; | 851 | struct audio_substream_data *rtd = runtime->private_data; |
852 | 852 | ||
853 | if (!rtd) | ||
854 | return -EINVAL; | ||
855 | |||
853 | buffersize = frames_to_bytes(runtime, runtime->buffer_size); | 856 | buffersize = frames_to_bytes(runtime, runtime->buffer_size); |
854 | bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream); | 857 | bytescount = acp_get_byte_count(rtd->acp_mmio, substream->stream); |
855 | 858 | ||
@@ -875,6 +878,8 @@ static int acp_dma_prepare(struct snd_pcm_substream *substream) | |||
875 | struct snd_pcm_runtime *runtime = substream->runtime; | 878 | struct snd_pcm_runtime *runtime = substream->runtime; |
876 | struct audio_substream_data *rtd = runtime->private_data; | 879 | struct audio_substream_data *rtd = runtime->private_data; |
877 | 880 | ||
881 | if (!rtd) | ||
882 | return -EINVAL; | ||
878 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 883 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
879 | config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, | 884 | config_acp_dma_channel(rtd->acp_mmio, SYSRAM_TO_ACP_CH_NUM, |
880 | PLAYBACK_START_DMA_DESCR_CH12, | 885 | PLAYBACK_START_DMA_DESCR_CH12, |
@@ -1091,7 +1096,11 @@ static int acp_audio_probe(struct platform_device *pdev) | |||
1091 | dev_set_drvdata(&pdev->dev, audio_drv_data); | 1096 | dev_set_drvdata(&pdev->dev, audio_drv_data); |
1092 | 1097 | ||
1093 | /* Initialize the ACP */ | 1098 | /* Initialize the ACP */ |
1094 | acp_init(audio_drv_data->acp_mmio, audio_drv_data->asic_type); | 1099 | status = acp_init(audio_drv_data->acp_mmio, audio_drv_data->asic_type); |
1100 | if (status) { | ||
1101 | dev_err(&pdev->dev, "ACP Init failed status:%d\n", status); | ||
1102 | return status; | ||
1103 | } | ||
1095 | 1104 | ||
1096 | status = snd_soc_register_platform(&pdev->dev, &acp_asoc_platform); | 1105 | status = snd_soc_register_platform(&pdev->dev, &acp_asoc_platform); |
1097 | if (status != 0) { | 1106 | if (status != 0) { |
@@ -1108,9 +1117,12 @@ static int acp_audio_probe(struct platform_device *pdev) | |||
1108 | 1117 | ||
1109 | static int acp_audio_remove(struct platform_device *pdev) | 1118 | static int acp_audio_remove(struct platform_device *pdev) |
1110 | { | 1119 | { |
1120 | int status; | ||
1111 | struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev); | 1121 | struct audio_drv_data *adata = dev_get_drvdata(&pdev->dev); |
1112 | 1122 | ||
1113 | acp_deinit(adata->acp_mmio); | 1123 | status = acp_deinit(adata->acp_mmio); |
1124 | if (status) | ||
1125 | dev_err(&pdev->dev, "ACP Deinit failed status:%d\n", status); | ||
1114 | snd_soc_unregister_platform(&pdev->dev); | 1126 | snd_soc_unregister_platform(&pdev->dev); |
1115 | pm_runtime_disable(&pdev->dev); | 1127 | pm_runtime_disable(&pdev->dev); |
1116 | 1128 | ||
@@ -1120,9 +1132,14 @@ static int acp_audio_remove(struct platform_device *pdev) | |||
1120 | static int acp_pcm_resume(struct device *dev) | 1132 | static int acp_pcm_resume(struct device *dev) |
1121 | { | 1133 | { |
1122 | u16 bank; | 1134 | u16 bank; |
1135 | int status; | ||
1123 | struct audio_drv_data *adata = dev_get_drvdata(dev); | 1136 | struct audio_drv_data *adata = dev_get_drvdata(dev); |
1124 | 1137 | ||
1125 | acp_init(adata->acp_mmio, adata->asic_type); | 1138 | status = acp_init(adata->acp_mmio, adata->asic_type); |
1139 | if (status) { | ||
1140 | dev_err(dev, "ACP Init failed status:%d\n", status); | ||
1141 | return status; | ||
1142 | } | ||
1126 | 1143 | ||
1127 | if (adata->play_stream && adata->play_stream->runtime) { | 1144 | if (adata->play_stream && adata->play_stream->runtime) { |
1128 | /* For Stoney, Memory gating is disabled,i.e SRAM Banks | 1145 | /* For Stoney, Memory gating is disabled,i.e SRAM Banks |
@@ -1154,18 +1171,26 @@ static int acp_pcm_resume(struct device *dev) | |||
1154 | 1171 | ||
1155 | static int acp_pcm_runtime_suspend(struct device *dev) | 1172 | static int acp_pcm_runtime_suspend(struct device *dev) |
1156 | { | 1173 | { |
1174 | int status; | ||
1157 | struct audio_drv_data *adata = dev_get_drvdata(dev); | 1175 | struct audio_drv_data *adata = dev_get_drvdata(dev); |
1158 | 1176 | ||
1159 | acp_deinit(adata->acp_mmio); | 1177 | status = acp_deinit(adata->acp_mmio); |
1178 | if (status) | ||
1179 | dev_err(dev, "ACP Deinit failed status:%d\n", status); | ||
1160 | acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); | 1180 | acp_reg_write(0, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); |
1161 | return 0; | 1181 | return 0; |
1162 | } | 1182 | } |
1163 | 1183 | ||
1164 | static int acp_pcm_runtime_resume(struct device *dev) | 1184 | static int acp_pcm_runtime_resume(struct device *dev) |
1165 | { | 1185 | { |
1186 | int status; | ||
1166 | struct audio_drv_data *adata = dev_get_drvdata(dev); | 1187 | struct audio_drv_data *adata = dev_get_drvdata(dev); |
1167 | 1188 | ||
1168 | acp_init(adata->acp_mmio, adata->asic_type); | 1189 | status = acp_init(adata->acp_mmio, adata->asic_type); |
1190 | if (status) { | ||
1191 | dev_err(dev, "ACP Init failed status:%d\n", status); | ||
1192 | return status; | ||
1193 | } | ||
1169 | acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); | 1194 | acp_reg_write(1, adata->acp_mmio, mmACP_EXTERNAL_INTR_ENB); |
1170 | return 0; | 1195 | return 0; |
1171 | } | 1196 | } |
diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c index 8445edd06737..ebabed69f0e6 100644 --- a/sound/soc/atmel/atmel-classd.c +++ b/sound/soc/atmel/atmel-classd.c | |||
@@ -308,15 +308,9 @@ static int atmel_classd_codec_resume(struct snd_soc_codec *codec) | |||
308 | return regcache_sync(dd->regmap); | 308 | return regcache_sync(dd->regmap); |
309 | } | 309 | } |
310 | 310 | ||
311 | static struct regmap *atmel_classd_codec_get_remap(struct device *dev) | ||
312 | { | ||
313 | return dev_get_regmap(dev, NULL); | ||
314 | } | ||
315 | |||
316 | static struct snd_soc_codec_driver soc_codec_dev_classd = { | 311 | static struct snd_soc_codec_driver soc_codec_dev_classd = { |
317 | .probe = atmel_classd_codec_probe, | 312 | .probe = atmel_classd_codec_probe, |
318 | .resume = atmel_classd_codec_resume, | 313 | .resume = atmel_classd_codec_resume, |
319 | .get_regmap = atmel_classd_codec_get_remap, | ||
320 | .component_driver = { | 314 | .component_driver = { |
321 | .controls = atmel_classd_snd_controls, | 315 | .controls = atmel_classd_snd_controls, |
322 | .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), | 316 | .num_controls = ARRAY_SIZE(atmel_classd_snd_controls), |
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c index 29a97d52e8ad..66d6c52e7761 100644 --- a/sound/soc/au1x/ac97c.c +++ b/sound/soc/au1x/ac97c.c | |||
@@ -91,8 +91,8 @@ static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97, | |||
91 | do { | 91 | do { |
92 | mutex_lock(&ctx->lock); | 92 | mutex_lock(&ctx->lock); |
93 | 93 | ||
94 | tmo = 5; | 94 | tmo = 6; |
95 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--) | 95 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo) |
96 | udelay(21); /* wait an ac97 frame time */ | 96 | udelay(21); /* wait an ac97 frame time */ |
97 | if (!tmo) { | 97 | if (!tmo) { |
98 | pr_debug("ac97rd timeout #1\n"); | 98 | pr_debug("ac97rd timeout #1\n"); |
@@ -105,7 +105,7 @@ static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97, | |||
105 | * poll, Forrest, poll... | 105 | * poll, Forrest, poll... |
106 | */ | 106 | */ |
107 | tmo = 0x10000; | 107 | tmo = 0x10000; |
108 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--) | 108 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && --tmo) |
109 | asm volatile ("nop"); | 109 | asm volatile ("nop"); |
110 | data = RD(ctx, AC97_CMDRESP); | 110 | data = RD(ctx, AC97_CMDRESP); |
111 | 111 | ||
diff --git a/sound/soc/bcm/bcm2835-i2s.c b/sound/soc/bcm/bcm2835-i2s.c index 2e449d7173fc..d5f73a8ab893 100644 --- a/sound/soc/bcm/bcm2835-i2s.c +++ b/sound/soc/bcm/bcm2835-i2s.c | |||
@@ -130,6 +130,7 @@ struct bcm2835_i2s_dev { | |||
130 | struct regmap *i2s_regmap; | 130 | struct regmap *i2s_regmap; |
131 | struct clk *clk; | 131 | struct clk *clk; |
132 | bool clk_prepared; | 132 | bool clk_prepared; |
133 | int clk_rate; | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) | 136 | static void bcm2835_i2s_start_clock(struct bcm2835_i2s_dev *dev) |
@@ -419,10 +420,19 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream, | |||
419 | } | 420 | } |
420 | 421 | ||
421 | /* Clock should only be set up here if CPU is clock master */ | 422 | /* Clock should only be set up here if CPU is clock master */ |
422 | if (bit_clock_master) { | 423 | if (bit_clock_master && |
423 | ret = clk_set_rate(dev->clk, bclk_rate); | 424 | (!dev->clk_prepared || dev->clk_rate != bclk_rate)) { |
424 | if (ret) | 425 | if (dev->clk_prepared) |
425 | return ret; | 426 | bcm2835_i2s_stop_clock(dev); |
427 | |||
428 | if (dev->clk_rate != bclk_rate) { | ||
429 | ret = clk_set_rate(dev->clk, bclk_rate); | ||
430 | if (ret) | ||
431 | return ret; | ||
432 | dev->clk_rate = bclk_rate; | ||
433 | } | ||
434 | |||
435 | bcm2835_i2s_start_clock(dev); | ||
426 | } | 436 | } |
427 | 437 | ||
428 | /* Setup the frame format */ | 438 | /* Setup the frame format */ |
@@ -618,8 +628,6 @@ static int bcm2835_i2s_prepare(struct snd_pcm_substream *substream, | |||
618 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); | 628 | struct bcm2835_i2s_dev *dev = snd_soc_dai_get_drvdata(dai); |
619 | uint32_t cs_reg; | 629 | uint32_t cs_reg; |
620 | 630 | ||
621 | bcm2835_i2s_start_clock(dev); | ||
622 | |||
623 | /* | 631 | /* |
624 | * Clear both FIFOs if the one that should be started | 632 | * Clear both FIFOs if the one that should be started |
625 | * is not empty at the moment. This should only happen | 633 | * is not empty at the moment. This should only happen |
diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c index bbf7a9266a99..cd5a939ad608 100644 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ b/sound/soc/cirrus/ep93xx-ac97.c | |||
@@ -365,7 +365,7 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) | |||
365 | { | 365 | { |
366 | struct ep93xx_ac97_info *info; | 366 | struct ep93xx_ac97_info *info; |
367 | struct resource *res; | 367 | struct resource *res; |
368 | unsigned int irq; | 368 | int irq; |
369 | int ret; | 369 | int ret; |
370 | 370 | ||
371 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 371 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
@@ -378,8 +378,8 @@ static int ep93xx_ac97_probe(struct platform_device *pdev) | |||
378 | return PTR_ERR(info->regs); | 378 | return PTR_ERR(info->regs); |
379 | 379 | ||
380 | irq = platform_get_irq(pdev, 0); | 380 | irq = platform_get_irq(pdev, 0); |
381 | if (!irq) | 381 | if (irq <= 0) |
382 | return -ENODEV; | 382 | return irq < 0 ? irq : -ENODEV; |
383 | 383 | ||
384 | ret = devm_request_irq(&pdev->dev, irq, ep93xx_ac97_interrupt, | 384 | ret = devm_request_irq(&pdev->dev, irq, ep93xx_ac97_interrupt, |
385 | IRQF_TRIGGER_HIGH, pdev->name, info); | 385 | IRQF_TRIGGER_HIGH, pdev->name, info); |
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 848c5fe49bc7..be8ea723dff9 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -1319,6 +1319,7 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1319 | int i, ret; | 1319 | int i, ret; |
1320 | 1320 | ||
1321 | pm860x->codec = codec; | 1321 | pm860x->codec = codec; |
1322 | snd_soc_codec_init_regmap(codec, pm860x->regmap); | ||
1322 | 1323 | ||
1323 | for (i = 0; i < 4; i++) { | 1324 | for (i = 0; i < 4; i++) { |
1324 | ret = request_threaded_irq(pm860x->irq[i], NULL, | 1325 | ret = request_threaded_irq(pm860x->irq[i], NULL, |
@@ -1348,18 +1349,10 @@ static int pm860x_remove(struct snd_soc_codec *codec) | |||
1348 | return 0; | 1349 | return 0; |
1349 | } | 1350 | } |
1350 | 1351 | ||
1351 | static struct regmap *pm860x_get_regmap(struct device *dev) | ||
1352 | { | ||
1353 | struct pm860x_priv *pm860x = dev_get_drvdata(dev); | ||
1354 | |||
1355 | return pm860x->regmap; | ||
1356 | } | ||
1357 | |||
1358 | static const struct snd_soc_codec_driver soc_codec_dev_pm860x = { | 1352 | static const struct snd_soc_codec_driver soc_codec_dev_pm860x = { |
1359 | .probe = pm860x_probe, | 1353 | .probe = pm860x_probe, |
1360 | .remove = pm860x_remove, | 1354 | .remove = pm860x_remove, |
1361 | .set_bias_level = pm860x_set_bias_level, | 1355 | .set_bias_level = pm860x_set_bias_level, |
1362 | .get_regmap = pm860x_get_regmap, | ||
1363 | 1356 | ||
1364 | .component_driver = { | 1357 | .component_driver = { |
1365 | .controls = pm860x_snd_controls, | 1358 | .controls = pm860x_snd_controls, |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index a42ddbc93f3d..2b331f7266ab 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS | |||
95 | select SND_SOC_MAX98925 if I2C | 95 | select SND_SOC_MAX98925 if I2C |
96 | select SND_SOC_MAX98926 if I2C | 96 | select SND_SOC_MAX98926 if I2C |
97 | select SND_SOC_MAX98927 if I2C | 97 | select SND_SOC_MAX98927 if I2C |
98 | select SND_SOC_MAX98373 if I2C | ||
98 | select SND_SOC_MAX9850 if I2C | 99 | select SND_SOC_MAX9850 if I2C |
99 | select SND_SOC_MAX9860 if I2C | 100 | select SND_SOC_MAX9860 if I2C |
100 | select SND_SOC_MAX9768 if I2C | 101 | select SND_SOC_MAX9768 if I2C |
@@ -109,6 +110,8 @@ config SND_SOC_ALL_CODECS | |||
109 | select SND_SOC_PCM1681 if I2C | 110 | select SND_SOC_PCM1681 if I2C |
110 | select SND_SOC_PCM179X_I2C if I2C | 111 | select SND_SOC_PCM179X_I2C if I2C |
111 | select SND_SOC_PCM179X_SPI if SPI_MASTER | 112 | select SND_SOC_PCM179X_SPI if SPI_MASTER |
113 | select SND_SOC_PCM186X_I2C if I2C | ||
114 | select SND_SOC_PCM186X_SPI if SPI_MASTER | ||
112 | select SND_SOC_PCM3008 | 115 | select SND_SOC_PCM3008 |
113 | select SND_SOC_PCM3168A_I2C if I2C | 116 | select SND_SOC_PCM3168A_I2C if I2C |
114 | select SND_SOC_PCM3168A_SPI if SPI_MASTER | 117 | select SND_SOC_PCM3168A_SPI if SPI_MASTER |
@@ -133,7 +136,6 @@ config SND_SOC_ALL_CODECS | |||
133 | select SND_SOC_SGTL5000 if I2C | 136 | select SND_SOC_SGTL5000 if I2C |
134 | select SND_SOC_SI476X if MFD_SI476X_CORE | 137 | select SND_SOC_SI476X if MFD_SI476X_CORE |
135 | select SND_SOC_SIRF_AUDIO_CODEC | 138 | select SND_SOC_SIRF_AUDIO_CODEC |
136 | select SND_SOC_SN95031 if INTEL_SCU_IPC | ||
137 | select SND_SOC_SPDIF | 139 | select SND_SOC_SPDIF |
138 | select SND_SOC_SSM2518 if I2C | 140 | select SND_SOC_SSM2518 if I2C |
139 | select SND_SOC_SSM2602_SPI if SPI_MASTER | 141 | select SND_SOC_SSM2602_SPI if SPI_MASTER |
@@ -148,6 +150,7 @@ config SND_SOC_ALL_CODECS | |||
148 | select SND_SOC_TAS5086 if I2C | 150 | select SND_SOC_TAS5086 if I2C |
149 | select SND_SOC_TAS571X if I2C | 151 | select SND_SOC_TAS571X if I2C |
150 | select SND_SOC_TAS5720 if I2C | 152 | select SND_SOC_TAS5720 if I2C |
153 | select SND_SOC_TAS6424 if I2C | ||
151 | select SND_SOC_TFA9879 if I2C | 154 | select SND_SOC_TFA9879 if I2C |
152 | select SND_SOC_TLV320AIC23_I2C if I2C | 155 | select SND_SOC_TLV320AIC23_I2C if I2C |
153 | select SND_SOC_TLV320AIC23_SPI if SPI_MASTER | 156 | select SND_SOC_TLV320AIC23_SPI if SPI_MASTER |
@@ -158,6 +161,7 @@ config SND_SOC_ALL_CODECS | |||
158 | select SND_SOC_TLV320AIC3X if I2C | 161 | select SND_SOC_TLV320AIC3X if I2C |
159 | select SND_SOC_TPA6130A2 if I2C | 162 | select SND_SOC_TPA6130A2 if I2C |
160 | select SND_SOC_TLV320DAC33 if I2C | 163 | select SND_SOC_TLV320DAC33 if I2C |
164 | select SND_SOC_TSCS42XX if I2C | ||
161 | select SND_SOC_TS3A227E if I2C | 165 | select SND_SOC_TS3A227E if I2C |
162 | select SND_SOC_TWL4030 if TWL4030_CORE | 166 | select SND_SOC_TWL4030 if TWL4030_CORE |
163 | select SND_SOC_TWL6040 if TWL6040_CORE | 167 | select SND_SOC_TWL6040 if TWL6040_CORE |
@@ -623,6 +627,10 @@ config SND_SOC_MAX98927 | |||
623 | tristate "Maxim Integrated MAX98927 Speaker Amplifier" | 627 | tristate "Maxim Integrated MAX98927 Speaker Amplifier" |
624 | depends on I2C | 628 | depends on I2C |
625 | 629 | ||
630 | config SND_SOC_MAX98373 | ||
631 | tristate "Maxim Integrated MAX98373 Speaker Amplifier" | ||
632 | depends on I2C | ||
633 | |||
626 | config SND_SOC_MAX9850 | 634 | config SND_SOC_MAX9850 |
627 | tristate | 635 | tristate |
628 | 636 | ||
@@ -661,6 +669,21 @@ config SND_SOC_PCM179X_SPI | |||
661 | Enable support for Texas Instruments PCM179x CODEC. | 669 | Enable support for Texas Instruments PCM179x CODEC. |
662 | Select this if your PCM179x is connected via an SPI bus. | 670 | Select this if your PCM179x is connected via an SPI bus. |
663 | 671 | ||
672 | config SND_SOC_PCM186X | ||
673 | tristate | ||
674 | |||
675 | config SND_SOC_PCM186X_I2C | ||
676 | tristate "Texas Instruments PCM186x CODECs - I2C" | ||
677 | depends on I2C | ||
678 | select SND_SOC_PCM186X | ||
679 | select REGMAP_I2C | ||
680 | |||
681 | config SND_SOC_PCM186X_SPI | ||
682 | tristate "Texas Instruments PCM186x CODECs - SPI" | ||
683 | depends on SPI_MASTER | ||
684 | select SND_SOC_PCM186X | ||
685 | select REGMAP_SPI | ||
686 | |||
664 | config SND_SOC_PCM3008 | 687 | config SND_SOC_PCM3008 |
665 | tristate | 688 | tristate |
666 | 689 | ||
@@ -818,9 +841,6 @@ config SND_SOC_SIRF_AUDIO_CODEC | |||
818 | tristate "SiRF SoC internal audio codec" | 841 | tristate "SiRF SoC internal audio codec" |
819 | select REGMAP_MMIO | 842 | select REGMAP_MMIO |
820 | 843 | ||
821 | config SND_SOC_SN95031 | ||
822 | tristate | ||
823 | |||
824 | config SND_SOC_SPDIF | 844 | config SND_SOC_SPDIF |
825 | tristate "S/PDIF CODEC" | 845 | tristate "S/PDIF CODEC" |
826 | 846 | ||
@@ -883,6 +903,13 @@ config SND_SOC_TAS5720 | |||
883 | Enable support for Texas Instruments TAS5720L/M high-efficiency mono | 903 | Enable support for Texas Instruments TAS5720L/M high-efficiency mono |
884 | Class-D audio power amplifiers. | 904 | Class-D audio power amplifiers. |
885 | 905 | ||
906 | config SND_SOC_TAS6424 | ||
907 | tristate "Texas Instruments TAS6424 Quad-Channel Audio amplifier" | ||
908 | depends on I2C | ||
909 | help | ||
910 | Enable support for Texas Instruments TAS6424 high-efficiency | ||
911 | digital input quad-channel Class-D audio power amplifiers. | ||
912 | |||
886 | config SND_SOC_TFA9879 | 913 | config SND_SOC_TFA9879 |
887 | tristate "NXP Semiconductors TFA9879 amplifier" | 914 | tristate "NXP Semiconductors TFA9879 amplifier" |
888 | depends on I2C | 915 | depends on I2C |
@@ -913,12 +940,12 @@ config SND_SOC_TLV320AIC32X4 | |||
913 | tristate | 940 | tristate |
914 | 941 | ||
915 | config SND_SOC_TLV320AIC32X4_I2C | 942 | config SND_SOC_TLV320AIC32X4_I2C |
916 | tristate | 943 | tristate "Texas Instruments TLV320AIC32x4 audio CODECs - I2C" |
917 | depends on I2C | 944 | depends on I2C |
918 | select SND_SOC_TLV320AIC32X4 | 945 | select SND_SOC_TLV320AIC32X4 |
919 | 946 | ||
920 | config SND_SOC_TLV320AIC32X4_SPI | 947 | config SND_SOC_TLV320AIC32X4_SPI |
921 | tristate | 948 | tristate "Texas Instruments TLV320AIC32x4 audio CODECs - SPI" |
922 | depends on SPI_MASTER | 949 | depends on SPI_MASTER |
923 | select SND_SOC_TLV320AIC32X4 | 950 | select SND_SOC_TLV320AIC32X4 |
924 | 951 | ||
@@ -933,6 +960,13 @@ config SND_SOC_TS3A227E | |||
933 | tristate "TI Headset/Mic detect and keypress chip" | 960 | tristate "TI Headset/Mic detect and keypress chip" |
934 | depends on I2C | 961 | depends on I2C |
935 | 962 | ||
963 | config SND_SOC_TSCS42XX | ||
964 | tristate "Tempo Semiconductor TSCS42xx CODEC" | ||
965 | depends on I2C | ||
966 | select REGMAP_I2C | ||
967 | help | ||
968 | Add support for Tempo Semiconductor's TSCS42xx audio CODEC. | ||
969 | |||
936 | config SND_SOC_TWL4030 | 970 | config SND_SOC_TWL4030 |
937 | select MFD_TWL4030_AUDIO | 971 | select MFD_TWL4030_AUDIO |
938 | tristate | 972 | tristate |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 0001069ce2a7..da1571336f1e 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -90,6 +90,7 @@ snd-soc-max9867-objs := max9867.o | |||
90 | snd-soc-max98925-objs := max98925.o | 90 | snd-soc-max98925-objs := max98925.o |
91 | snd-soc-max98926-objs := max98926.o | 91 | snd-soc-max98926-objs := max98926.o |
92 | snd-soc-max98927-objs := max98927.o | 92 | snd-soc-max98927-objs := max98927.o |
93 | snd-soc-max98373-objs := max98373.o | ||
93 | snd-soc-max9850-objs := max9850.o | 94 | snd-soc-max9850-objs := max9850.o |
94 | snd-soc-max9860-objs := max9860.o | 95 | snd-soc-max9860-objs := max9860.o |
95 | snd-soc-mc13783-objs := mc13783.o | 96 | snd-soc-mc13783-objs := mc13783.o |
@@ -105,6 +106,9 @@ snd-soc-pcm1681-objs := pcm1681.o | |||
105 | snd-soc-pcm179x-codec-objs := pcm179x.o | 106 | snd-soc-pcm179x-codec-objs := pcm179x.o |
106 | snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o | 107 | snd-soc-pcm179x-i2c-objs := pcm179x-i2c.o |
107 | snd-soc-pcm179x-spi-objs := pcm179x-spi.o | 108 | snd-soc-pcm179x-spi-objs := pcm179x-spi.o |
109 | snd-soc-pcm186x-objs := pcm186x.o | ||
110 | snd-soc-pcm186x-i2c-objs := pcm186x-i2c.o | ||
111 | snd-soc-pcm186x-spi-objs := pcm186x-spi.o | ||
108 | snd-soc-pcm3008-objs := pcm3008.o | 112 | snd-soc-pcm3008-objs := pcm3008.o |
109 | snd-soc-pcm3168a-objs := pcm3168a.o | 113 | snd-soc-pcm3168a-objs := pcm3168a.o |
110 | snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o | 114 | snd-soc-pcm3168a-i2c-objs := pcm3168a-i2c.o |
@@ -140,7 +144,6 @@ snd-soc-sigmadsp-i2c-objs := sigmadsp-i2c.o | |||
140 | snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o | 144 | snd-soc-sigmadsp-regmap-objs := sigmadsp-regmap.o |
141 | snd-soc-si476x-objs := si476x.o | 145 | snd-soc-si476x-objs := si476x.o |
142 | snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o | 146 | snd-soc-sirf-audio-codec-objs := sirf-audio-codec.o |
143 | snd-soc-sn95031-objs := sn95031.o | ||
144 | snd-soc-spdif-tx-objs := spdif_transmitter.o | 147 | snd-soc-spdif-tx-objs := spdif_transmitter.o |
145 | snd-soc-spdif-rx-objs := spdif_receiver.o | 148 | snd-soc-spdif-rx-objs := spdif_receiver.o |
146 | snd-soc-ssm2518-objs := ssm2518.o | 149 | snd-soc-ssm2518-objs := ssm2518.o |
@@ -156,6 +159,7 @@ snd-soc-sti-sas-objs := sti-sas.o | |||
156 | snd-soc-tas5086-objs := tas5086.o | 159 | snd-soc-tas5086-objs := tas5086.o |
157 | snd-soc-tas571x-objs := tas571x.o | 160 | snd-soc-tas571x-objs := tas571x.o |
158 | snd-soc-tas5720-objs := tas5720.o | 161 | snd-soc-tas5720-objs := tas5720.o |
162 | snd-soc-tas6424-objs := tas6424.o | ||
159 | snd-soc-tfa9879-objs := tfa9879.o | 163 | snd-soc-tfa9879-objs := tfa9879.o |
160 | snd-soc-tlv320aic23-objs := tlv320aic23.o | 164 | snd-soc-tlv320aic23-objs := tlv320aic23.o |
161 | snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o | 165 | snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o |
@@ -167,6 +171,7 @@ snd-soc-tlv320aic32x4-i2c-objs := tlv320aic32x4-i2c.o | |||
167 | snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o | 171 | snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o |
168 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o | 172 | snd-soc-tlv320aic3x-objs := tlv320aic3x.o |
169 | snd-soc-tlv320dac33-objs := tlv320dac33.o | 173 | snd-soc-tlv320dac33-objs := tlv320dac33.o |
174 | snd-soc-tscs42xx-objs := tscs42xx.o | ||
170 | snd-soc-ts3a227e-objs := ts3a227e.o | 175 | snd-soc-ts3a227e-objs := ts3a227e.o |
171 | snd-soc-twl4030-objs := twl4030.o | 176 | snd-soc-twl4030-objs := twl4030.o |
172 | snd-soc-twl6040-objs := twl6040.o | 177 | snd-soc-twl6040-objs := twl6040.o |
@@ -330,6 +335,7 @@ obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o | |||
330 | obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o | 335 | obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o |
331 | obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o | 336 | obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o |
332 | obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o | 337 | obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o |
338 | obj-$(CONFIG_SND_SOC_MAX98373) += snd-soc-max98373.o | ||
333 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | 339 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o |
334 | obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o | 340 | obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o |
335 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o | 341 | obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o |
@@ -345,6 +351,9 @@ obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o | |||
345 | obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o | 351 | obj-$(CONFIG_SND_SOC_PCM179X) += snd-soc-pcm179x-codec.o |
346 | obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o | 352 | obj-$(CONFIG_SND_SOC_PCM179X_I2C) += snd-soc-pcm179x-i2c.o |
347 | obj-$(CONFIG_SND_SOC_PCM179X_SPI) += snd-soc-pcm179x-spi.o | 353 | obj-$(CONFIG_SND_SOC_PCM179X_SPI) += snd-soc-pcm179x-spi.o |
354 | obj-$(CONFIG_SND_SOC_PCM186X) += snd-soc-pcm186x.o | ||
355 | obj-$(CONFIG_SND_SOC_PCM186X_I2C) += snd-soc-pcm186x-i2c.o | ||
356 | obj-$(CONFIG_SND_SOC_PCM186X_SPI) += snd-soc-pcm186x-spi.o | ||
348 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o | 357 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o |
349 | obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o | 358 | obj-$(CONFIG_SND_SOC_PCM3168A) += snd-soc-pcm3168a.o |
350 | obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o | 359 | obj-$(CONFIG_SND_SOC_PCM3168A_I2C) += snd-soc-pcm3168a-i2c.o |
@@ -395,6 +404,7 @@ obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o | |||
395 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o | 404 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o |
396 | obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o | 405 | obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o |
397 | obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o | 406 | obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o |
407 | obj-$(CONFIG_SND_SOC_TAS6424) += snd-soc-tas6424.o | ||
398 | obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o | 408 | obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o |
399 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o | 409 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o |
400 | obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o | 410 | obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o |
@@ -406,6 +416,7 @@ obj-$(CONFIG_SND_SOC_TLV320AIC32X4_I2C) += snd-soc-tlv320aic32x4-i2c.o | |||
406 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4_SPI) += snd-soc-tlv320aic32x4-spi.o | 416 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4_SPI) += snd-soc-tlv320aic32x4-spi.o |
407 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | 417 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o |
408 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o | 418 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o |
419 | obj-$(CONFIG_SND_SOC_TSCS42XX) += snd-soc-tscs42xx.o | ||
409 | obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o | 420 | obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o |
410 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o | 421 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o |
411 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o | 422 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 6ed2cc374768..3bf93652bb31 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -121,17 +121,19 @@ static struct snd_soc_dai_driver cq93vc_dai = { | |||
121 | .ops = &cq93vc_dai_ops, | 121 | .ops = &cq93vc_dai_ops, |
122 | }; | 122 | }; |
123 | 123 | ||
124 | static struct regmap *cq93vc_get_regmap(struct device *dev) | 124 | static int cq93vc_probe(struct snd_soc_component *component) |
125 | { | 125 | { |
126 | struct davinci_vc *davinci_vc = dev->platform_data; | 126 | struct davinci_vc *davinci_vc = component->dev->platform_data; |
127 | 127 | ||
128 | return davinci_vc->regmap; | 128 | snd_soc_component_init_regmap(component, davinci_vc->regmap); |
129 | |||
130 | return 0; | ||
129 | } | 131 | } |
130 | 132 | ||
131 | static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = { | 133 | static const struct snd_soc_codec_driver soc_codec_dev_cq93vc = { |
132 | .set_bias_level = cq93vc_set_bias_level, | 134 | .set_bias_level = cq93vc_set_bias_level, |
133 | .get_regmap = cq93vc_get_regmap, | ||
134 | .component_driver = { | 135 | .component_driver = { |
136 | .probe = cq93vc_probe, | ||
135 | .controls = cq93vc_snd_controls, | 137 | .controls = cq93vc_snd_controls, |
136 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), | 138 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), |
137 | }, | 139 | }, |
diff --git a/sound/soc/codecs/cs35l32.c b/sound/soc/codecs/cs35l32.c index 7e9806206648..bc3a72e4c4ed 100644 --- a/sound/soc/codecs/cs35l32.c +++ b/sound/soc/codecs/cs35l32.c | |||
@@ -355,13 +355,9 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client, | |||
355 | unsigned int devid = 0; | 355 | unsigned int devid = 0; |
356 | unsigned int reg; | 356 | unsigned int reg; |
357 | 357 | ||
358 | 358 | cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l32), GFP_KERNEL); | |
359 | cs35l32 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs35l32_private), | 359 | if (!cs35l32) |
360 | GFP_KERNEL); | ||
361 | if (!cs35l32) { | ||
362 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
363 | return -ENOMEM; | 360 | return -ENOMEM; |
364 | } | ||
365 | 361 | ||
366 | i2c_set_clientdata(i2c_client, cs35l32); | 362 | i2c_set_clientdata(i2c_client, cs35l32); |
367 | 363 | ||
@@ -375,13 +371,11 @@ static int cs35l32_i2c_probe(struct i2c_client *i2c_client, | |||
375 | if (pdata) { | 371 | if (pdata) { |
376 | cs35l32->pdata = *pdata; | 372 | cs35l32->pdata = *pdata; |
377 | } else { | 373 | } else { |
378 | pdata = devm_kzalloc(&i2c_client->dev, | 374 | pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), |
379 | sizeof(struct cs35l32_platform_data), | 375 | GFP_KERNEL); |
380 | GFP_KERNEL); | 376 | if (!pdata) |
381 | if (!pdata) { | ||
382 | dev_err(&i2c_client->dev, "could not allocate pdata\n"); | ||
383 | return -ENOMEM; | 377 | return -ENOMEM; |
384 | } | 378 | |
385 | if (i2c_client->dev.of_node) { | 379 | if (i2c_client->dev.of_node) { |
386 | ret = cs35l32_handle_of_data(i2c_client, | 380 | ret = cs35l32_handle_of_data(i2c_client, |
387 | &cs35l32->pdata); | 381 | &cs35l32->pdata); |
diff --git a/sound/soc/codecs/cs35l34.c b/sound/soc/codecs/cs35l34.c index 1e05026bedca..0600d5264c4c 100644 --- a/sound/soc/codecs/cs35l34.c +++ b/sound/soc/codecs/cs35l34.c | |||
@@ -1004,13 +1004,9 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client, | |||
1004 | unsigned int devid = 0; | 1004 | unsigned int devid = 0; |
1005 | unsigned int reg; | 1005 | unsigned int reg; |
1006 | 1006 | ||
1007 | cs35l34 = devm_kzalloc(&i2c_client->dev, | 1007 | cs35l34 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l34), GFP_KERNEL); |
1008 | sizeof(struct cs35l34_private), | 1008 | if (!cs35l34) |
1009 | GFP_KERNEL); | ||
1010 | if (!cs35l34) { | ||
1011 | dev_err(&i2c_client->dev, "could not allocate codec\n"); | ||
1012 | return -ENOMEM; | 1009 | return -ENOMEM; |
1013 | } | ||
1014 | 1010 | ||
1015 | i2c_set_clientdata(i2c_client, cs35l34); | 1011 | i2c_set_clientdata(i2c_client, cs35l34); |
1016 | cs35l34->regmap = devm_regmap_init_i2c(i2c_client, &cs35l34_regmap); | 1012 | cs35l34->regmap = devm_regmap_init_i2c(i2c_client, &cs35l34_regmap); |
@@ -1044,14 +1040,11 @@ static int cs35l34_i2c_probe(struct i2c_client *i2c_client, | |||
1044 | if (pdata) { | 1040 | if (pdata) { |
1045 | cs35l34->pdata = *pdata; | 1041 | cs35l34->pdata = *pdata; |
1046 | } else { | 1042 | } else { |
1047 | pdata = devm_kzalloc(&i2c_client->dev, | 1043 | pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), |
1048 | sizeof(struct cs35l34_platform_data), | 1044 | GFP_KERNEL); |
1049 | GFP_KERNEL); | 1045 | if (!pdata) |
1050 | if (!pdata) { | ||
1051 | dev_err(&i2c_client->dev, | ||
1052 | "could not allocate pdata\n"); | ||
1053 | return -ENOMEM; | 1046 | return -ENOMEM; |
1054 | } | 1047 | |
1055 | if (i2c_client->dev.of_node) { | 1048 | if (i2c_client->dev.of_node) { |
1056 | ret = cs35l34_handle_of_data(i2c_client, pdata); | 1049 | ret = cs35l34_handle_of_data(i2c_client, pdata); |
1057 | if (ret != 0) | 1050 | if (ret != 0) |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 0d9c4a57301b..9731e5dff291 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -1100,8 +1100,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | |||
1100 | unsigned int reg; | 1100 | unsigned int reg; |
1101 | u32 val32; | 1101 | u32 val32; |
1102 | 1102 | ||
1103 | cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l52_private), | 1103 | cs42l52 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l52), GFP_KERNEL); |
1104 | GFP_KERNEL); | ||
1105 | if (cs42l52 == NULL) | 1104 | if (cs42l52 == NULL) |
1106 | return -ENOMEM; | 1105 | return -ENOMEM; |
1107 | cs42l52->dev = &i2c_client->dev; | 1106 | cs42l52->dev = &i2c_client->dev; |
@@ -1115,13 +1114,11 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client, | |||
1115 | if (pdata) { | 1114 | if (pdata) { |
1116 | cs42l52->pdata = *pdata; | 1115 | cs42l52->pdata = *pdata; |
1117 | } else { | 1116 | } else { |
1118 | pdata = devm_kzalloc(&i2c_client->dev, | 1117 | pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), |
1119 | sizeof(struct cs42l52_platform_data), | 1118 | GFP_KERNEL); |
1120 | GFP_KERNEL); | 1119 | if (!pdata) |
1121 | if (!pdata) { | ||
1122 | dev_err(&i2c_client->dev, "could not allocate pdata\n"); | ||
1123 | return -ENOMEM; | 1120 | return -ENOMEM; |
1124 | } | 1121 | |
1125 | if (i2c_client->dev.of_node) { | 1122 | if (i2c_client->dev.of_node) { |
1126 | if (of_property_read_bool(i2c_client->dev.of_node, | 1123 | if (of_property_read_bool(i2c_client->dev.of_node, |
1127 | "cirrus,mica-differential-cfg")) | 1124 | "cirrus,mica-differential-cfg")) |
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index cb6ca85f1536..fd7b8d32c2b2 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c | |||
@@ -1190,9 +1190,7 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, | |||
1190 | unsigned int alpha_rev, metal_rev; | 1190 | unsigned int alpha_rev, metal_rev; |
1191 | unsigned int reg; | 1191 | unsigned int reg; |
1192 | 1192 | ||
1193 | cs42l56 = devm_kzalloc(&i2c_client->dev, | 1193 | cs42l56 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l56), GFP_KERNEL); |
1194 | sizeof(struct cs42l56_private), | ||
1195 | GFP_KERNEL); | ||
1196 | if (cs42l56 == NULL) | 1194 | if (cs42l56 == NULL) |
1197 | return -ENOMEM; | 1195 | return -ENOMEM; |
1198 | cs42l56->dev = &i2c_client->dev; | 1196 | cs42l56->dev = &i2c_client->dev; |
@@ -1207,14 +1205,11 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client, | |||
1207 | if (pdata) { | 1205 | if (pdata) { |
1208 | cs42l56->pdata = *pdata; | 1206 | cs42l56->pdata = *pdata; |
1209 | } else { | 1207 | } else { |
1210 | pdata = devm_kzalloc(&i2c_client->dev, | 1208 | pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), |
1211 | sizeof(struct cs42l56_platform_data), | ||
1212 | GFP_KERNEL); | 1209 | GFP_KERNEL); |
1213 | if (!pdata) { | 1210 | if (!pdata) |
1214 | dev_err(&i2c_client->dev, | ||
1215 | "could not allocate pdata\n"); | ||
1216 | return -ENOMEM; | 1211 | return -ENOMEM; |
1217 | } | 1212 | |
1218 | if (i2c_client->dev.of_node) { | 1213 | if (i2c_client->dev.of_node) { |
1219 | ret = cs42l56_handle_of_data(i2c_client, | 1214 | ret = cs42l56_handle_of_data(i2c_client, |
1220 | &cs42l56->pdata); | 1215 | &cs42l56->pdata); |
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c index 3df2c473ab88..aebaa97490b6 100644 --- a/sound/soc/codecs/cs42l73.c +++ b/sound/soc/codecs/cs42l73.c | |||
@@ -1289,8 +1289,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1289 | unsigned int reg; | 1289 | unsigned int reg; |
1290 | u32 val32; | 1290 | u32 val32; |
1291 | 1291 | ||
1292 | cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l73_private), | 1292 | cs42l73 = devm_kzalloc(&i2c_client->dev, sizeof(*cs42l73), GFP_KERNEL); |
1293 | GFP_KERNEL); | ||
1294 | if (!cs42l73) | 1293 | if (!cs42l73) |
1295 | return -ENOMEM; | 1294 | return -ENOMEM; |
1296 | 1295 | ||
@@ -1304,13 +1303,11 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1304 | if (pdata) { | 1303 | if (pdata) { |
1305 | cs42l73->pdata = *pdata; | 1304 | cs42l73->pdata = *pdata; |
1306 | } else { | 1305 | } else { |
1307 | pdata = devm_kzalloc(&i2c_client->dev, | 1306 | pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), |
1308 | sizeof(struct cs42l73_platform_data), | 1307 | GFP_KERNEL); |
1309 | GFP_KERNEL); | 1308 | if (!pdata) |
1310 | if (!pdata) { | ||
1311 | dev_err(&i2c_client->dev, "could not allocate pdata\n"); | ||
1312 | return -ENOMEM; | 1309 | return -ENOMEM; |
1313 | } | 1310 | |
1314 | if (i2c_client->dev.of_node) { | 1311 | if (i2c_client->dev.of_node) { |
1315 | if (of_property_read_u32(i2c_client->dev.of_node, | 1312 | if (of_property_read_u32(i2c_client->dev.of_node, |
1316 | "chgfreq", &val32) >= 0) | 1313 | "chgfreq", &val32) >= 0) |
@@ -1358,7 +1355,7 @@ static int cs42l73_i2c_probe(struct i2c_client *i2c_client, | |||
1358 | ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); | 1355 | ret = regmap_read(cs42l73->regmap, CS42L73_REVID, ®); |
1359 | if (ret < 0) { | 1356 | if (ret < 0) { |
1360 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); | 1357 | dev_err(&i2c_client->dev, "Get Revision ID failed\n"); |
1361 | return ret;; | 1358 | return ret; |
1362 | } | 1359 | } |
1363 | 1360 | ||
1364 | dev_info(&i2c_client->dev, | 1361 | dev_info(&i2c_client->dev, |
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c index 94c0209977d0..be2750680838 100644 --- a/sound/soc/codecs/cs47l24.c +++ b/sound/soc/codecs/cs47l24.c | |||
@@ -1120,9 +1120,11 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec) | |||
1120 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 1120 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); |
1121 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); | 1121 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); |
1122 | struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec); | 1122 | struct cs47l24_priv *priv = snd_soc_codec_get_drvdata(codec); |
1123 | struct arizona *arizona = priv->core.arizona; | ||
1123 | int ret; | 1124 | int ret; |
1124 | 1125 | ||
1125 | priv->core.arizona->dapm = dapm; | 1126 | arizona->dapm = dapm; |
1127 | snd_soc_codec_init_regmap(codec, arizona->regmap); | ||
1126 | 1128 | ||
1127 | ret = arizona_init_spk(codec); | 1129 | ret = arizona_init_spk(codec); |
1128 | if (ret < 0) | 1130 | if (ret < 0) |
@@ -1175,17 +1177,9 @@ static unsigned int cs47l24_digital_vu[] = { | |||
1175 | ARIZONA_DAC_DIGITAL_VOLUME_4L, | 1177 | ARIZONA_DAC_DIGITAL_VOLUME_4L, |
1176 | }; | 1178 | }; |
1177 | 1179 | ||
1178 | static struct regmap *cs47l24_get_regmap(struct device *dev) | ||
1179 | { | ||
1180 | struct cs47l24_priv *priv = dev_get_drvdata(dev); | ||
1181 | |||
1182 | return priv->core.arizona->regmap; | ||
1183 | } | ||
1184 | |||
1185 | static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { | 1180 | static const struct snd_soc_codec_driver soc_codec_dev_cs47l24 = { |
1186 | .probe = cs47l24_codec_probe, | 1181 | .probe = cs47l24_codec_probe, |
1187 | .remove = cs47l24_codec_remove, | 1182 | .remove = cs47l24_codec_remove, |
1188 | .get_regmap = cs47l24_get_regmap, | ||
1189 | 1183 | ||
1190 | .idle_bias_off = true, | 1184 | .idle_bias_off = true, |
1191 | 1185 | ||
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 46b1fbb66eba..95bb10ba80dc 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
@@ -26,8 +26,9 @@ | |||
26 | 26 | ||
27 | 27 | ||
28 | struct cx20442_priv { | 28 | struct cx20442_priv { |
29 | void *control_data; | 29 | struct tty_struct *tty; |
30 | struct regulator *por; | 30 | struct regulator *por; |
31 | u8 reg_cache; | ||
31 | }; | 32 | }; |
32 | 33 | ||
33 | #define CX20442_PM 0x0 | 34 | #define CX20442_PM 0x0 |
@@ -89,14 +90,14 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = { | |||
89 | }; | 90 | }; |
90 | 91 | ||
91 | static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, | 92 | static unsigned int cx20442_read_reg_cache(struct snd_soc_codec *codec, |
92 | unsigned int reg) | 93 | unsigned int reg) |
93 | { | 94 | { |
94 | u8 *reg_cache = codec->reg_cache; | 95 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); |
95 | 96 | ||
96 | if (reg >= codec->driver->reg_cache_size) | 97 | if (reg >= 1) |
97 | return -EINVAL; | 98 | return -EINVAL; |
98 | 99 | ||
99 | return reg_cache[reg]; | 100 | return cx20442->reg_cache; |
100 | } | 101 | } |
101 | 102 | ||
102 | enum v253_vls { | 103 | enum v253_vls { |
@@ -156,20 +157,19 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, | |||
156 | unsigned int value) | 157 | unsigned int value) |
157 | { | 158 | { |
158 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); | 159 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); |
159 | u8 *reg_cache = codec->reg_cache; | ||
160 | int vls, vsp, old, len; | 160 | int vls, vsp, old, len; |
161 | char buf[18]; | 161 | char buf[18]; |
162 | 162 | ||
163 | if (reg >= codec->driver->reg_cache_size) | 163 | if (reg >= 1) |
164 | return -EINVAL; | 164 | return -EINVAL; |
165 | 165 | ||
166 | /* hw_write and control_data pointers required for talking to the modem | 166 | /* tty and write pointers required for talking to the modem |
167 | * are expected to be set by the line discipline initialization code */ | 167 | * are expected to be set by the line discipline initialization code */ |
168 | if (!codec->hw_write || !cx20442->control_data) | 168 | if (!cx20442->tty || !cx20442->tty->ops->write) |
169 | return -EIO; | 169 | return -EIO; |
170 | 170 | ||
171 | old = reg_cache[reg]; | 171 | old = cx20442->reg_cache; |
172 | reg_cache[reg] = value; | 172 | cx20442->reg_cache = value; |
173 | 173 | ||
174 | vls = cx20442_pm_to_v253_vls(value); | 174 | vls = cx20442_pm_to_v253_vls(value); |
175 | if (vls < 0) | 175 | if (vls < 0) |
@@ -194,13 +194,12 @@ static int cx20442_write(struct snd_soc_codec *codec, unsigned int reg, | |||
194 | return -ENOMEM; | 194 | return -ENOMEM; |
195 | 195 | ||
196 | dev_dbg(codec->dev, "%s: %s\n", __func__, buf); | 196 | dev_dbg(codec->dev, "%s: %s\n", __func__, buf); |
197 | if (codec->hw_write(cx20442->control_data, buf, len) != len) | 197 | if (cx20442->tty->ops->write(cx20442->tty, buf, len) != len) |
198 | return -EIO; | 198 | return -EIO; |
199 | 199 | ||
200 | return 0; | 200 | return 0; |
201 | } | 201 | } |
202 | 202 | ||
203 | |||
204 | /* | 203 | /* |
205 | * Line discpline related code | 204 | * Line discpline related code |
206 | * | 205 | * |
@@ -252,8 +251,7 @@ static void v253_close(struct tty_struct *tty) | |||
252 | cx20442 = snd_soc_codec_get_drvdata(codec); | 251 | cx20442 = snd_soc_codec_get_drvdata(codec); |
253 | 252 | ||
254 | /* Prevent the codec driver from further accessing the modem */ | 253 | /* Prevent the codec driver from further accessing the modem */ |
255 | codec->hw_write = NULL; | 254 | cx20442->tty = NULL; |
256 | cx20442->control_data = NULL; | ||
257 | codec->component.card->pop_time = 0; | 255 | codec->component.card->pop_time = 0; |
258 | } | 256 | } |
259 | 257 | ||
@@ -276,12 +274,11 @@ static void v253_receive(struct tty_struct *tty, | |||
276 | 274 | ||
277 | cx20442 = snd_soc_codec_get_drvdata(codec); | 275 | cx20442 = snd_soc_codec_get_drvdata(codec); |
278 | 276 | ||
279 | if (!cx20442->control_data) { | 277 | if (!cx20442->tty) { |
280 | /* First modem response, complete setup procedure */ | 278 | /* First modem response, complete setup procedure */ |
281 | 279 | ||
282 | /* Set up codec driver access to modem controls */ | 280 | /* Set up codec driver access to modem controls */ |
283 | cx20442->control_data = tty; | 281 | cx20442->tty = tty; |
284 | codec->hw_write = (hw_write_t)tty->ops->write; | ||
285 | codec->component.card->pop_time = 1; | 282 | codec->component.card->pop_time = 1; |
286 | } | 283 | } |
287 | } | 284 | } |
@@ -367,10 +364,9 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) | |||
367 | cx20442->por = regulator_get(codec->dev, "POR"); | 364 | cx20442->por = regulator_get(codec->dev, "POR"); |
368 | if (IS_ERR(cx20442->por)) | 365 | if (IS_ERR(cx20442->por)) |
369 | dev_warn(codec->dev, "failed to get the regulator"); | 366 | dev_warn(codec->dev, "failed to get the regulator"); |
370 | cx20442->control_data = NULL; | 367 | cx20442->tty = NULL; |
371 | 368 | ||
372 | snd_soc_codec_set_drvdata(codec, cx20442); | 369 | snd_soc_codec_set_drvdata(codec, cx20442); |
373 | codec->hw_write = NULL; | ||
374 | codec->component.card->pop_time = 0; | 370 | codec->component.card->pop_time = 0; |
375 | 371 | ||
376 | return 0; | 372 | return 0; |
@@ -381,8 +377,8 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) | |||
381 | { | 377 | { |
382 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); | 378 | struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec); |
383 | 379 | ||
384 | if (cx20442->control_data) { | 380 | if (cx20442->tty) { |
385 | struct tty_struct *tty = cx20442->control_data; | 381 | struct tty_struct *tty = cx20442->tty; |
386 | tty_hangup(tty); | 382 | tty_hangup(tty); |
387 | } | 383 | } |
388 | 384 | ||
@@ -396,17 +392,13 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec) | |||
396 | return 0; | 392 | return 0; |
397 | } | 393 | } |
398 | 394 | ||
399 | static const u8 cx20442_reg; | ||
400 | |||
401 | static const struct snd_soc_codec_driver cx20442_codec_dev = { | 395 | static const struct snd_soc_codec_driver cx20442_codec_dev = { |
402 | .probe = cx20442_codec_probe, | 396 | .probe = cx20442_codec_probe, |
403 | .remove = cx20442_codec_remove, | 397 | .remove = cx20442_codec_remove, |
404 | .set_bias_level = cx20442_set_bias_level, | 398 | .set_bias_level = cx20442_set_bias_level, |
405 | .reg_cache_default = &cx20442_reg, | ||
406 | .reg_cache_size = 1, | ||
407 | .reg_word_size = sizeof(u8), | ||
408 | .read = cx20442_read_reg_cache, | 399 | .read = cx20442_read_reg_cache, |
409 | .write = cx20442_write, | 400 | .write = cx20442_write, |
401 | |||
410 | .component_driver = { | 402 | .component_driver = { |
411 | .dapm_widgets = cx20442_dapm_widgets, | 403 | .dapm_widgets = cx20442_dapm_widgets, |
412 | .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), | 404 | .num_dapm_widgets = ARRAY_SIZE(cx20442_dapm_widgets), |
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 41d9b1da27c2..b2b4e90fc02a 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c | |||
@@ -1654,10 +1654,8 @@ static struct da7213_platform_data | |||
1654 | u32 fw_val32; | 1654 | u32 fw_val32; |
1655 | 1655 | ||
1656 | pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL); | 1656 | pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL); |
1657 | if (!pdata) { | 1657 | if (!pdata) |
1658 | dev_warn(codec->dev, "Failed to allocate memory for pdata\n"); | ||
1659 | return NULL; | 1658 | return NULL; |
1660 | } | ||
1661 | 1659 | ||
1662 | if (device_property_read_u32(dev, "dlg,micbias1-lvl", &fw_val32) >= 0) | 1660 | if (device_property_read_u32(dev, "dlg,micbias1-lvl", &fw_val32) >= 0) |
1663 | pdata->micbias1_lvl = da7213_of_micbias_lvl(codec, fw_val32); | 1661 | pdata->micbias1_lvl = da7213_of_micbias_lvl(codec, fw_val32); |
@@ -1855,8 +1853,7 @@ static int da7213_i2c_probe(struct i2c_client *i2c, | |||
1855 | struct da7213_priv *da7213; | 1853 | struct da7213_priv *da7213; |
1856 | int ret; | 1854 | int ret; |
1857 | 1855 | ||
1858 | da7213 = devm_kzalloc(&i2c->dev, sizeof(struct da7213_priv), | 1856 | da7213 = devm_kzalloc(&i2c->dev, sizeof(*da7213), GFP_KERNEL); |
1859 | GFP_KERNEL); | ||
1860 | if (!da7213) | 1857 | if (!da7213) |
1861 | return -ENOMEM; | 1858 | return -ENOMEM; |
1862 | 1859 | ||
diff --git a/sound/soc/codecs/da7218.c b/sound/soc/codecs/da7218.c index 56564ce90cb6..96c644a15b11 100644 --- a/sound/soc/codecs/da7218.c +++ b/sound/soc/codecs/da7218.c | |||
@@ -2455,10 +2455,8 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec) | |||
2455 | u32 of_val32; | 2455 | u32 of_val32; |
2456 | 2456 | ||
2457 | pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL); | 2457 | pdata = devm_kzalloc(codec->dev, sizeof(*pdata), GFP_KERNEL); |
2458 | if (!pdata) { | 2458 | if (!pdata) |
2459 | dev_warn(codec->dev, "Failed to allocate memory for pdata\n"); | ||
2460 | return NULL; | 2459 | return NULL; |
2461 | } | ||
2462 | 2460 | ||
2463 | if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0) | 2461 | if (of_property_read_u32(np, "dlg,micbias1-lvl-millivolt", &of_val32) >= 0) |
2464 | pdata->micbias1_lvl = da7218_of_micbias_lvl(codec, of_val32); | 2462 | pdata->micbias1_lvl = da7218_of_micbias_lvl(codec, of_val32); |
@@ -2527,8 +2525,6 @@ static struct da7218_pdata *da7218_of_to_pdata(struct snd_soc_codec *codec) | |||
2527 | hpldet_pdata = devm_kzalloc(codec->dev, sizeof(*hpldet_pdata), | 2525 | hpldet_pdata = devm_kzalloc(codec->dev, sizeof(*hpldet_pdata), |
2528 | GFP_KERNEL); | 2526 | GFP_KERNEL); |
2529 | if (!hpldet_pdata) { | 2527 | if (!hpldet_pdata) { |
2530 | dev_warn(codec->dev, | ||
2531 | "Failed to allocate memory for hpldet pdata\n"); | ||
2532 | of_node_put(hpldet_np); | 2528 | of_node_put(hpldet_np); |
2533 | return pdata; | 2529 | return pdata; |
2534 | } | 2530 | } |
@@ -3273,8 +3269,7 @@ static int da7218_i2c_probe(struct i2c_client *i2c, | |||
3273 | struct da7218_priv *da7218; | 3269 | struct da7218_priv *da7218; |
3274 | int ret; | 3270 | int ret; |
3275 | 3271 | ||
3276 | da7218 = devm_kzalloc(&i2c->dev, sizeof(struct da7218_priv), | 3272 | da7218 = devm_kzalloc(&i2c->dev, sizeof(*da7218), GFP_KERNEL); |
3277 | GFP_KERNEL); | ||
3278 | if (!da7218) | 3273 | if (!da7218) |
3279 | return -ENOMEM; | 3274 | return -ENOMEM; |
3280 | 3275 | ||
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c index b88a1ee66f80..c88f974ebe3e 100644 --- a/sound/soc/codecs/dmic.c +++ b/sound/soc/codecs/dmic.c | |||
@@ -107,8 +107,30 @@ static const struct snd_soc_codec_driver soc_dmic = { | |||
107 | 107 | ||
108 | static int dmic_dev_probe(struct platform_device *pdev) | 108 | static int dmic_dev_probe(struct platform_device *pdev) |
109 | { | 109 | { |
110 | int err; | ||
111 | u32 chans; | ||
112 | struct snd_soc_dai_driver *dai_drv = &dmic_dai; | ||
113 | |||
114 | if (pdev->dev.of_node) { | ||
115 | err = of_property_read_u32(pdev->dev.of_node, "num-channels", &chans); | ||
116 | if (err && (err != -ENOENT)) | ||
117 | return err; | ||
118 | |||
119 | if (!err) { | ||
120 | if (chans < 1 || chans > 8) | ||
121 | return -EINVAL; | ||
122 | |||
123 | dai_drv = devm_kzalloc(&pdev->dev, sizeof(*dai_drv), GFP_KERNEL); | ||
124 | if (!dai_drv) | ||
125 | return -ENOMEM; | ||
126 | |||
127 | memcpy(dai_drv, &dmic_dai, sizeof(*dai_drv)); | ||
128 | dai_drv->capture.channels_max = chans; | ||
129 | } | ||
130 | } | ||
131 | |||
110 | return snd_soc_register_codec(&pdev->dev, | 132 | return snd_soc_register_codec(&pdev->dev, |
111 | &soc_dmic, &dmic_dai, 1); | 133 | &soc_dmic, dai_drv, 1); |
112 | } | 134 | } |
113 | 135 | ||
114 | static int dmic_dev_remove(struct platform_device *pdev) | 136 | static int dmic_dev_remove(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index f3b4f4dfae6a..dba6f4c5074a 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c | |||
@@ -136,8 +136,11 @@ struct hdac_hdmi_priv { | |||
136 | struct mutex pin_mutex; | 136 | struct mutex pin_mutex; |
137 | struct hdac_chmap chmap; | 137 | struct hdac_chmap chmap; |
138 | struct hdac_hdmi_drv_data *drv_data; | 138 | struct hdac_hdmi_drv_data *drv_data; |
139 | struct snd_soc_dai_driver *dai_drv; | ||
139 | }; | 140 | }; |
140 | 141 | ||
142 | #define hdev_to_hdmi_priv(_hdev) ((to_ehdac_device(_hdev))->private_data) | ||
143 | |||
141 | static struct hdac_hdmi_pcm * | 144 | static struct hdac_hdmi_pcm * |
142 | hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi, | 145 | hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi, |
143 | struct hdac_hdmi_cvt *cvt) | 146 | struct hdac_hdmi_cvt *cvt) |
@@ -169,7 +172,7 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm, | |||
169 | * ports. | 172 | * ports. |
170 | */ | 173 | */ |
171 | if (pcm->jack_event == 0) { | 174 | if (pcm->jack_event == 0) { |
172 | dev_dbg(&edev->hdac.dev, | 175 | dev_dbg(&edev->hdev.dev, |
173 | "jack report for pcm=%d\n", | 176 | "jack report for pcm=%d\n", |
174 | pcm->pcm_id); | 177 | pcm->pcm_id); |
175 | snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT, | 178 | snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT, |
@@ -195,18 +198,18 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm, | |||
195 | /* | 198 | /* |
196 | * Get the no devices that can be connected to a port on the Pin widget. | 199 | * Get the no devices that can be connected to a port on the Pin widget. |
197 | */ | 200 | */ |
198 | static int hdac_hdmi_get_port_len(struct hdac_ext_device *hdac, hda_nid_t nid) | 201 | static int hdac_hdmi_get_port_len(struct hdac_ext_device *edev, hda_nid_t nid) |
199 | { | 202 | { |
200 | unsigned int caps; | 203 | unsigned int caps; |
201 | unsigned int type, param; | 204 | unsigned int type, param; |
202 | 205 | ||
203 | caps = get_wcaps(&hdac->hdac, nid); | 206 | caps = get_wcaps(&edev->hdev, nid); |
204 | type = get_wcaps_type(caps); | 207 | type = get_wcaps_type(caps); |
205 | 208 | ||
206 | if (!(caps & AC_WCAP_DIGITAL) || (type != AC_WID_PIN)) | 209 | if (!(caps & AC_WCAP_DIGITAL) || (type != AC_WID_PIN)) |
207 | return 0; | 210 | return 0; |
208 | 211 | ||
209 | param = snd_hdac_read_parm_uncached(&hdac->hdac, nid, | 212 | param = snd_hdac_read_parm_uncached(&edev->hdev, nid, |
210 | AC_PAR_DEVLIST_LEN); | 213 | AC_PAR_DEVLIST_LEN); |
211 | if (param == -1) | 214 | if (param == -1) |
212 | return param; | 215 | return param; |
@@ -219,10 +222,10 @@ static int hdac_hdmi_get_port_len(struct hdac_ext_device *hdac, hda_nid_t nid) | |||
219 | * id selected on the pin. Return 0 means the first port entry | 222 | * id selected on the pin. Return 0 means the first port entry |
220 | * is selected or MST is not supported. | 223 | * is selected or MST is not supported. |
221 | */ | 224 | */ |
222 | static int hdac_hdmi_port_select_get(struct hdac_ext_device *hdac, | 225 | static int hdac_hdmi_port_select_get(struct hdac_ext_device *edev, |
223 | struct hdac_hdmi_port *port) | 226 | struct hdac_hdmi_port *port) |
224 | { | 227 | { |
225 | return snd_hdac_codec_read(&hdac->hdac, port->pin->nid, | 228 | return snd_hdac_codec_read(&edev->hdev, port->pin->nid, |
226 | 0, AC_VERB_GET_DEVICE_SEL, 0); | 229 | 0, AC_VERB_GET_DEVICE_SEL, 0); |
227 | } | 230 | } |
228 | 231 | ||
@@ -230,7 +233,7 @@ static int hdac_hdmi_port_select_get(struct hdac_ext_device *hdac, | |||
230 | * Sets the selected port entry for the configuring Pin widget verb. | 233 | * Sets the selected port entry for the configuring Pin widget verb. |
231 | * returns error if port set is not equal to port get otherwise success | 234 | * returns error if port set is not equal to port get otherwise success |
232 | */ | 235 | */ |
233 | static int hdac_hdmi_port_select_set(struct hdac_ext_device *hdac, | 236 | static int hdac_hdmi_port_select_set(struct hdac_ext_device *edev, |
234 | struct hdac_hdmi_port *port) | 237 | struct hdac_hdmi_port *port) |
235 | { | 238 | { |
236 | int num_ports; | 239 | int num_ports; |
@@ -239,7 +242,7 @@ static int hdac_hdmi_port_select_set(struct hdac_ext_device *hdac, | |||
239 | return 0; | 242 | return 0; |
240 | 243 | ||
241 | /* AC_PAR_DEVLIST_LEN is 0 based. */ | 244 | /* AC_PAR_DEVLIST_LEN is 0 based. */ |
242 | num_ports = hdac_hdmi_get_port_len(hdac, port->pin->nid); | 245 | num_ports = hdac_hdmi_get_port_len(edev, port->pin->nid); |
243 | 246 | ||
244 | if (num_ports < 0) | 247 | if (num_ports < 0) |
245 | return -EIO; | 248 | return -EIO; |
@@ -250,13 +253,13 @@ static int hdac_hdmi_port_select_set(struct hdac_ext_device *hdac, | |||
250 | if (num_ports + 1 < port->id) | 253 | if (num_ports + 1 < port->id) |
251 | return 0; | 254 | return 0; |
252 | 255 | ||
253 | snd_hdac_codec_write(&hdac->hdac, port->pin->nid, 0, | 256 | snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0, |
254 | AC_VERB_SET_DEVICE_SEL, port->id); | 257 | AC_VERB_SET_DEVICE_SEL, port->id); |
255 | 258 | ||
256 | if (port->id != hdac_hdmi_port_select_get(hdac, port)) | 259 | if (port->id != hdac_hdmi_port_select_get(edev, port)) |
257 | return -EIO; | 260 | return -EIO; |
258 | 261 | ||
259 | dev_dbg(&hdac->hdac.dev, "Selected the port=%d\n", port->id); | 262 | dev_dbg(&edev->hdev.dev, "Selected the port=%d\n", port->id); |
260 | 263 | ||
261 | return 0; | 264 | return 0; |
262 | } | 265 | } |
@@ -276,9 +279,9 @@ static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi, | |||
276 | 279 | ||
277 | static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev) | 280 | static inline struct hdac_ext_device *to_hda_ext_device(struct device *dev) |
278 | { | 281 | { |
279 | struct hdac_device *hdac = dev_to_hdac_dev(dev); | 282 | struct hdac_device *hdev = dev_to_hdac_dev(dev); |
280 | 283 | ||
281 | return to_ehdac_device(hdac); | 284 | return to_ehdac_device(hdev); |
282 | } | 285 | } |
283 | 286 | ||
284 | static unsigned int sad_format(const u8 *sad) | 287 | static unsigned int sad_format(const u8 *sad) |
@@ -321,14 +324,14 @@ format_constraint: | |||
321 | } | 324 | } |
322 | 325 | ||
323 | static void | 326 | static void |
324 | hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid, | 327 | hdac_hdmi_set_dip_index(struct hdac_ext_device *edev, hda_nid_t pin_nid, |
325 | int packet_index, int byte_index) | 328 | int packet_index, int byte_index) |
326 | { | 329 | { |
327 | int val; | 330 | int val; |
328 | 331 | ||
329 | val = (packet_index << 5) | (byte_index & 0x1f); | 332 | val = (packet_index << 5) | (byte_index & 0x1f); |
330 | 333 | ||
331 | snd_hdac_codec_write(&hdac->hdac, pin_nid, 0, | 334 | snd_hdac_codec_write(&edev->hdev, pin_nid, 0, |
332 | AC_VERB_SET_HDMI_DIP_INDEX, val); | 335 | AC_VERB_SET_HDMI_DIP_INDEX, val); |
333 | } | 336 | } |
334 | 337 | ||
@@ -344,14 +347,14 @@ struct dp_audio_infoframe { | |||
344 | u8 LFEPBL01_LSV36_DM_INH7; | 347 | u8 LFEPBL01_LSV36_DM_INH7; |
345 | }; | 348 | }; |
346 | 349 | ||
347 | static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac, | 350 | static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *edev, |
348 | struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port) | 351 | struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port) |
349 | { | 352 | { |
350 | uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE]; | 353 | uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE]; |
351 | struct hdmi_audio_infoframe frame; | 354 | struct hdmi_audio_infoframe frame; |
352 | struct hdac_hdmi_pin *pin = port->pin; | 355 | struct hdac_hdmi_pin *pin = port->pin; |
353 | struct dp_audio_infoframe dp_ai; | 356 | struct dp_audio_infoframe dp_ai; |
354 | struct hdac_hdmi_priv *hdmi = hdac->private_data; | 357 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
355 | struct hdac_hdmi_cvt *cvt = pcm->cvt; | 358 | struct hdac_hdmi_cvt *cvt = pcm->cvt; |
356 | u8 *dip; | 359 | u8 *dip; |
357 | int ret; | 360 | int ret; |
@@ -360,11 +363,11 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac, | |||
360 | u8 conn_type; | 363 | u8 conn_type; |
361 | int channels, ca; | 364 | int channels, ca; |
362 | 365 | ||
363 | ca = snd_hdac_channel_allocation(&hdac->hdac, port->eld.info.spk_alloc, | 366 | ca = snd_hdac_channel_allocation(&edev->hdev, port->eld.info.spk_alloc, |
364 | pcm->channels, pcm->chmap_set, true, pcm->chmap); | 367 | pcm->channels, pcm->chmap_set, true, pcm->chmap); |
365 | 368 | ||
366 | channels = snd_hdac_get_active_channels(ca); | 369 | channels = snd_hdac_get_active_channels(ca); |
367 | hdmi->chmap.ops.set_channel_count(&hdac->hdac, cvt->nid, channels); | 370 | hdmi->chmap.ops.set_channel_count(&edev->hdev, cvt->nid, channels); |
368 | 371 | ||
369 | snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca, | 372 | snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca, |
370 | pcm->channels, pcm->chmap, pcm->chmap_set); | 373 | pcm->channels, pcm->chmap, pcm->chmap_set); |
@@ -397,32 +400,32 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac, | |||
397 | break; | 400 | break; |
398 | 401 | ||
399 | default: | 402 | default: |
400 | dev_err(&hdac->hdac.dev, "Invalid connection type: %d\n", | 403 | dev_err(&edev->hdev.dev, "Invalid connection type: %d\n", |
401 | conn_type); | 404 | conn_type); |
402 | return -EIO; | 405 | return -EIO; |
403 | } | 406 | } |
404 | 407 | ||
405 | /* stop infoframe transmission */ | 408 | /* stop infoframe transmission */ |
406 | hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0); | 409 | hdac_hdmi_set_dip_index(edev, pin->nid, 0x0, 0x0); |
407 | snd_hdac_codec_write(&hdac->hdac, pin->nid, 0, | 410 | snd_hdac_codec_write(&edev->hdev, pin->nid, 0, |
408 | AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE); | 411 | AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE); |
409 | 412 | ||
410 | 413 | ||
411 | /* Fill infoframe. Index auto-incremented */ | 414 | /* Fill infoframe. Index auto-incremented */ |
412 | hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0); | 415 | hdac_hdmi_set_dip_index(edev, pin->nid, 0x0, 0x0); |
413 | if (conn_type == DRM_ELD_CONN_TYPE_HDMI) { | 416 | if (conn_type == DRM_ELD_CONN_TYPE_HDMI) { |
414 | for (i = 0; i < sizeof(buffer); i++) | 417 | for (i = 0; i < sizeof(buffer); i++) |
415 | snd_hdac_codec_write(&hdac->hdac, pin->nid, 0, | 418 | snd_hdac_codec_write(&edev->hdev, pin->nid, 0, |
416 | AC_VERB_SET_HDMI_DIP_DATA, buffer[i]); | 419 | AC_VERB_SET_HDMI_DIP_DATA, buffer[i]); |
417 | } else { | 420 | } else { |
418 | for (i = 0; i < sizeof(dp_ai); i++) | 421 | for (i = 0; i < sizeof(dp_ai); i++) |
419 | snd_hdac_codec_write(&hdac->hdac, pin->nid, 0, | 422 | snd_hdac_codec_write(&edev->hdev, pin->nid, 0, |
420 | AC_VERB_SET_HDMI_DIP_DATA, dip[i]); | 423 | AC_VERB_SET_HDMI_DIP_DATA, dip[i]); |
421 | } | 424 | } |
422 | 425 | ||
423 | /* Start infoframe */ | 426 | /* Start infoframe */ |
424 | hdac_hdmi_set_dip_index(hdac, pin->nid, 0x0, 0x0); | 427 | hdac_hdmi_set_dip_index(edev, pin->nid, 0x0, 0x0); |
425 | snd_hdac_codec_write(&hdac->hdac, pin->nid, 0, | 428 | snd_hdac_codec_write(&edev->hdev, pin->nid, 0, |
426 | AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST); | 429 | AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST); |
427 | 430 | ||
428 | return 0; | 431 | return 0; |
@@ -433,11 +436,11 @@ static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai, | |||
433 | int slots, int slot_width) | 436 | int slots, int slot_width) |
434 | { | 437 | { |
435 | struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai); | 438 | struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai); |
436 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 439 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
437 | struct hdac_hdmi_dai_port_map *dai_map; | 440 | struct hdac_hdmi_dai_port_map *dai_map; |
438 | struct hdac_hdmi_pcm *pcm; | 441 | struct hdac_hdmi_pcm *pcm; |
439 | 442 | ||
440 | dev_dbg(&edev->hdac.dev, "%s: strm_tag: %d\n", __func__, tx_mask); | 443 | dev_dbg(&edev->hdev.dev, "%s: strm_tag: %d\n", __func__, tx_mask); |
441 | 444 | ||
442 | dai_map = &hdmi->dai_map[dai->id]; | 445 | dai_map = &hdmi->dai_map[dai->id]; |
443 | 446 | ||
@@ -452,8 +455,8 @@ static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai, | |||
452 | static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream, | 455 | static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream, |
453 | struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai) | 456 | struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai) |
454 | { | 457 | { |
455 | struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai); | 458 | struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai); |
456 | struct hdac_hdmi_priv *hdmi = hdac->private_data; | 459 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
457 | struct hdac_hdmi_dai_port_map *dai_map; | 460 | struct hdac_hdmi_dai_port_map *dai_map; |
458 | struct hdac_hdmi_port *port; | 461 | struct hdac_hdmi_port *port; |
459 | struct hdac_hdmi_pcm *pcm; | 462 | struct hdac_hdmi_pcm *pcm; |
@@ -466,7 +469,7 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream, | |||
466 | return -ENODEV; | 469 | return -ENODEV; |
467 | 470 | ||
468 | if ((!port->eld.monitor_present) || (!port->eld.eld_valid)) { | 471 | if ((!port->eld.monitor_present) || (!port->eld.eld_valid)) { |
469 | dev_err(&hdac->hdac.dev, | 472 | dev_err(&edev->hdev.dev, |
470 | "device is not configured for this pin:port%d:%d\n", | 473 | "device is not configured for this pin:port%d:%d\n", |
471 | port->pin->nid, port->id); | 474 | port->pin->nid, port->id); |
472 | return -ENODEV; | 475 | return -ENODEV; |
@@ -486,28 +489,28 @@ static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream, | |||
486 | return 0; | 489 | return 0; |
487 | } | 490 | } |
488 | 491 | ||
489 | static int hdac_hdmi_query_port_connlist(struct hdac_ext_device *hdac, | 492 | static int hdac_hdmi_query_port_connlist(struct hdac_ext_device *edev, |
490 | struct hdac_hdmi_pin *pin, | 493 | struct hdac_hdmi_pin *pin, |
491 | struct hdac_hdmi_port *port) | 494 | struct hdac_hdmi_port *port) |
492 | { | 495 | { |
493 | if (!(get_wcaps(&hdac->hdac, pin->nid) & AC_WCAP_CONN_LIST)) { | 496 | if (!(get_wcaps(&edev->hdev, pin->nid) & AC_WCAP_CONN_LIST)) { |
494 | dev_warn(&hdac->hdac.dev, | 497 | dev_warn(&edev->hdev.dev, |
495 | "HDMI: pin %d wcaps %#x does not support connection list\n", | 498 | "HDMI: pin %d wcaps %#x does not support connection list\n", |
496 | pin->nid, get_wcaps(&hdac->hdac, pin->nid)); | 499 | pin->nid, get_wcaps(&edev->hdev, pin->nid)); |
497 | return -EINVAL; | 500 | return -EINVAL; |
498 | } | 501 | } |
499 | 502 | ||
500 | if (hdac_hdmi_port_select_set(hdac, port) < 0) | 503 | if (hdac_hdmi_port_select_set(edev, port) < 0) |
501 | return -EIO; | 504 | return -EIO; |
502 | 505 | ||
503 | port->num_mux_nids = snd_hdac_get_connections(&hdac->hdac, pin->nid, | 506 | port->num_mux_nids = snd_hdac_get_connections(&edev->hdev, pin->nid, |
504 | port->mux_nids, HDA_MAX_CONNECTIONS); | 507 | port->mux_nids, HDA_MAX_CONNECTIONS); |
505 | if (port->num_mux_nids == 0) | 508 | if (port->num_mux_nids == 0) |
506 | dev_warn(&hdac->hdac.dev, | 509 | dev_warn(&edev->hdev.dev, |
507 | "No connections found for pin:port %d:%d\n", | 510 | "No connections found for pin:port %d:%d\n", |
508 | pin->nid, port->id); | 511 | pin->nid, port->id); |
509 | 512 | ||
510 | dev_dbg(&hdac->hdac.dev, "num_mux_nids %d for pin:port %d:%d\n", | 513 | dev_dbg(&edev->hdev.dev, "num_mux_nids %d for pin:port %d:%d\n", |
511 | port->num_mux_nids, pin->nid, port->id); | 514 | port->num_mux_nids, pin->nid, port->id); |
512 | 515 | ||
513 | return port->num_mux_nids; | 516 | return port->num_mux_nids; |
@@ -565,8 +568,8 @@ static struct hdac_hdmi_port *hdac_hdmi_get_port_from_cvt( | |||
565 | static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, | 568 | static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, |
566 | struct snd_soc_dai *dai) | 569 | struct snd_soc_dai *dai) |
567 | { | 570 | { |
568 | struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai); | 571 | struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai); |
569 | struct hdac_hdmi_priv *hdmi = hdac->private_data; | 572 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
570 | struct hdac_hdmi_dai_port_map *dai_map; | 573 | struct hdac_hdmi_dai_port_map *dai_map; |
571 | struct hdac_hdmi_cvt *cvt; | 574 | struct hdac_hdmi_cvt *cvt; |
572 | struct hdac_hdmi_port *port; | 575 | struct hdac_hdmi_port *port; |
@@ -575,7 +578,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, | |||
575 | dai_map = &hdmi->dai_map[dai->id]; | 578 | dai_map = &hdmi->dai_map[dai->id]; |
576 | 579 | ||
577 | cvt = dai_map->cvt; | 580 | cvt = dai_map->cvt; |
578 | port = hdac_hdmi_get_port_from_cvt(hdac, hdmi, cvt); | 581 | port = hdac_hdmi_get_port_from_cvt(edev, hdmi, cvt); |
579 | 582 | ||
580 | /* | 583 | /* |
581 | * To make PA and other userland happy. | 584 | * To make PA and other userland happy. |
@@ -586,7 +589,7 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, | |||
586 | if ((!port->eld.monitor_present) || | 589 | if ((!port->eld.monitor_present) || |
587 | (!port->eld.eld_valid)) { | 590 | (!port->eld.eld_valid)) { |
588 | 591 | ||
589 | dev_warn(&hdac->hdac.dev, | 592 | dev_warn(&edev->hdev.dev, |
590 | "Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n", | 593 | "Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n", |
591 | port->eld.monitor_present, port->eld.eld_valid, | 594 | port->eld.monitor_present, port->eld.eld_valid, |
592 | port->pin->nid, port->id); | 595 | port->pin->nid, port->id); |
@@ -608,8 +611,8 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream, | |||
608 | static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream, | 611 | static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream, |
609 | struct snd_soc_dai *dai) | 612 | struct snd_soc_dai *dai) |
610 | { | 613 | { |
611 | struct hdac_ext_device *hdac = snd_soc_dai_get_drvdata(dai); | 614 | struct hdac_ext_device *edev = snd_soc_dai_get_drvdata(dai); |
612 | struct hdac_hdmi_priv *hdmi = hdac->private_data; | 615 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
613 | struct hdac_hdmi_dai_port_map *dai_map; | 616 | struct hdac_hdmi_dai_port_map *dai_map; |
614 | struct hdac_hdmi_pcm *pcm; | 617 | struct hdac_hdmi_pcm *pcm; |
615 | 618 | ||
@@ -630,14 +633,13 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream, | |||
630 | } | 633 | } |
631 | 634 | ||
632 | static int | 635 | static int |
633 | hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt) | 636 | hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt) |
634 | { | 637 | { |
635 | unsigned int chans; | 638 | unsigned int chans; |
636 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 639 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
637 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
638 | int err; | 640 | int err; |
639 | 641 | ||
640 | chans = get_wcaps(hdac, cvt->nid); | 642 | chans = get_wcaps(hdev, cvt->nid); |
641 | chans = get_wcaps_channels(chans); | 643 | chans = get_wcaps_channels(chans); |
642 | 644 | ||
643 | cvt->params.channels_min = 2; | 645 | cvt->params.channels_min = 2; |
@@ -646,12 +648,12 @@ hdac_hdmi_query_cvt_params(struct hdac_device *hdac, struct hdac_hdmi_cvt *cvt) | |||
646 | if (chans > hdmi->chmap.channels_max) | 648 | if (chans > hdmi->chmap.channels_max) |
647 | hdmi->chmap.channels_max = chans; | 649 | hdmi->chmap.channels_max = chans; |
648 | 650 | ||
649 | err = snd_hdac_query_supported_pcm(hdac, cvt->nid, | 651 | err = snd_hdac_query_supported_pcm(hdev, cvt->nid, |
650 | &cvt->params.rates, | 652 | &cvt->params.rates, |
651 | &cvt->params.formats, | 653 | &cvt->params.formats, |
652 | &cvt->params.maxbps); | 654 | &cvt->params.maxbps); |
653 | if (err < 0) | 655 | if (err < 0) |
654 | dev_err(&hdac->dev, | 656 | dev_err(&hdev->dev, |
655 | "Failed to query pcm params for nid %d: %d\n", | 657 | "Failed to query pcm params for nid %d: %d\n", |
656 | cvt->nid, err); | 658 | cvt->nid, err); |
657 | 659 | ||
@@ -696,7 +698,7 @@ static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route, | |||
696 | static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev, | 698 | static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev, |
697 | struct hdac_hdmi_port *port) | 699 | struct hdac_hdmi_port *port) |
698 | { | 700 | { |
699 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 701 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
700 | struct hdac_hdmi_pcm *pcm = NULL; | 702 | struct hdac_hdmi_pcm *pcm = NULL; |
701 | struct hdac_hdmi_port *p; | 703 | struct hdac_hdmi_port *p; |
702 | 704 | ||
@@ -716,9 +718,9 @@ static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_ext_device *edev, | |||
716 | static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev, | 718 | static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev, |
717 | hda_nid_t nid, unsigned int pwr_state) | 719 | hda_nid_t nid, unsigned int pwr_state) |
718 | { | 720 | { |
719 | if (get_wcaps(&edev->hdac, nid) & AC_WCAP_POWER) { | 721 | if (get_wcaps(&edev->hdev, nid) & AC_WCAP_POWER) { |
720 | if (!snd_hdac_check_power_state(&edev->hdac, nid, pwr_state)) | 722 | if (!snd_hdac_check_power_state(&edev->hdev, nid, pwr_state)) |
721 | snd_hdac_codec_write(&edev->hdac, nid, 0, | 723 | snd_hdac_codec_write(&edev->hdev, nid, 0, |
722 | AC_VERB_SET_POWER_STATE, pwr_state); | 724 | AC_VERB_SET_POWER_STATE, pwr_state); |
723 | } | 725 | } |
724 | } | 726 | } |
@@ -726,8 +728,8 @@ static void hdac_hdmi_set_power_state(struct hdac_ext_device *edev, | |||
726 | static void hdac_hdmi_set_amp(struct hdac_ext_device *edev, | 728 | static void hdac_hdmi_set_amp(struct hdac_ext_device *edev, |
727 | hda_nid_t nid, int val) | 729 | hda_nid_t nid, int val) |
728 | { | 730 | { |
729 | if (get_wcaps(&edev->hdac, nid) & AC_WCAP_OUT_AMP) | 731 | if (get_wcaps(&edev->hdev, nid) & AC_WCAP_OUT_AMP) |
730 | snd_hdac_codec_write(&edev->hdac, nid, 0, | 732 | snd_hdac_codec_write(&edev->hdev, nid, 0, |
731 | AC_VERB_SET_AMP_GAIN_MUTE, val); | 733 | AC_VERB_SET_AMP_GAIN_MUTE, val); |
732 | } | 734 | } |
733 | 735 | ||
@@ -739,7 +741,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w, | |||
739 | struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev); | 741 | struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev); |
740 | struct hdac_hdmi_pcm *pcm; | 742 | struct hdac_hdmi_pcm *pcm; |
741 | 743 | ||
742 | dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n", | 744 | dev_dbg(&edev->hdev.dev, "%s: widget: %s event: %x\n", |
743 | __func__, w->name, event); | 745 | __func__, w->name, event); |
744 | 746 | ||
745 | pcm = hdac_hdmi_get_pcm(edev, port); | 747 | pcm = hdac_hdmi_get_pcm(edev, port); |
@@ -755,7 +757,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w, | |||
755 | hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D0); | 757 | hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D0); |
756 | 758 | ||
757 | /* Enable out path for this pin widget */ | 759 | /* Enable out path for this pin widget */ |
758 | snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0, | 760 | snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0, |
759 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 761 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
760 | 762 | ||
761 | hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_UNMUTE); | 763 | hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_UNMUTE); |
@@ -766,7 +768,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w, | |||
766 | hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_MUTE); | 768 | hdac_hdmi_set_amp(edev, port->pin->nid, AMP_OUT_MUTE); |
767 | 769 | ||
768 | /* Disable out path for this pin widget */ | 770 | /* Disable out path for this pin widget */ |
769 | snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0, | 771 | snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0, |
770 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | 772 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); |
771 | 773 | ||
772 | hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D3); | 774 | hdac_hdmi_set_power_state(edev, port->pin->nid, AC_PWRST_D3); |
@@ -782,10 +784,10 @@ static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w, | |||
782 | { | 784 | { |
783 | struct hdac_hdmi_cvt *cvt = w->priv; | 785 | struct hdac_hdmi_cvt *cvt = w->priv; |
784 | struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev); | 786 | struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev); |
785 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 787 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
786 | struct hdac_hdmi_pcm *pcm; | 788 | struct hdac_hdmi_pcm *pcm; |
787 | 789 | ||
788 | dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n", | 790 | dev_dbg(&edev->hdev.dev, "%s: widget: %s event: %x\n", |
789 | __func__, w->name, event); | 791 | __func__, w->name, event); |
790 | 792 | ||
791 | pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt); | 793 | pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt); |
@@ -797,23 +799,23 @@ static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w, | |||
797 | hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D0); | 799 | hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D0); |
798 | 800 | ||
799 | /* Enable transmission */ | 801 | /* Enable transmission */ |
800 | snd_hdac_codec_write(&edev->hdac, cvt->nid, 0, | 802 | snd_hdac_codec_write(&edev->hdev, cvt->nid, 0, |
801 | AC_VERB_SET_DIGI_CONVERT_1, 1); | 803 | AC_VERB_SET_DIGI_CONVERT_1, 1); |
802 | 804 | ||
803 | /* Category Code (CC) to zero */ | 805 | /* Category Code (CC) to zero */ |
804 | snd_hdac_codec_write(&edev->hdac, cvt->nid, 0, | 806 | snd_hdac_codec_write(&edev->hdev, cvt->nid, 0, |
805 | AC_VERB_SET_DIGI_CONVERT_2, 0); | 807 | AC_VERB_SET_DIGI_CONVERT_2, 0); |
806 | 808 | ||
807 | snd_hdac_codec_write(&edev->hdac, cvt->nid, 0, | 809 | snd_hdac_codec_write(&edev->hdev, cvt->nid, 0, |
808 | AC_VERB_SET_CHANNEL_STREAMID, pcm->stream_tag); | 810 | AC_VERB_SET_CHANNEL_STREAMID, pcm->stream_tag); |
809 | snd_hdac_codec_write(&edev->hdac, cvt->nid, 0, | 811 | snd_hdac_codec_write(&edev->hdev, cvt->nid, 0, |
810 | AC_VERB_SET_STREAM_FORMAT, pcm->format); | 812 | AC_VERB_SET_STREAM_FORMAT, pcm->format); |
811 | break; | 813 | break; |
812 | 814 | ||
813 | case SND_SOC_DAPM_POST_PMD: | 815 | case SND_SOC_DAPM_POST_PMD: |
814 | snd_hdac_codec_write(&edev->hdac, cvt->nid, 0, | 816 | snd_hdac_codec_write(&edev->hdev, cvt->nid, 0, |
815 | AC_VERB_SET_CHANNEL_STREAMID, 0); | 817 | AC_VERB_SET_CHANNEL_STREAMID, 0); |
816 | snd_hdac_codec_write(&edev->hdac, cvt->nid, 0, | 818 | snd_hdac_codec_write(&edev->hdev, cvt->nid, 0, |
817 | AC_VERB_SET_STREAM_FORMAT, 0); | 819 | AC_VERB_SET_STREAM_FORMAT, 0); |
818 | 820 | ||
819 | hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D3); | 821 | hdac_hdmi_set_power_state(edev, cvt->nid, AC_PWRST_D3); |
@@ -831,7 +833,7 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w, | |||
831 | struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev); | 833 | struct hdac_ext_device *edev = to_hda_ext_device(w->dapm->dev); |
832 | int mux_idx; | 834 | int mux_idx; |
833 | 835 | ||
834 | dev_dbg(&edev->hdac.dev, "%s: widget: %s event: %x\n", | 836 | dev_dbg(&edev->hdev.dev, "%s: widget: %s event: %x\n", |
835 | __func__, w->name, event); | 837 | __func__, w->name, event); |
836 | 838 | ||
837 | if (!kc) | 839 | if (!kc) |
@@ -844,7 +846,7 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w, | |||
844 | return -EIO; | 846 | return -EIO; |
845 | 847 | ||
846 | if (mux_idx > 0) { | 848 | if (mux_idx > 0) { |
847 | snd_hdac_codec_write(&edev->hdac, port->pin->nid, 0, | 849 | snd_hdac_codec_write(&edev->hdev, port->pin->nid, 0, |
848 | AC_VERB_SET_CONNECT_SEL, (mux_idx - 1)); | 850 | AC_VERB_SET_CONNECT_SEL, (mux_idx - 1)); |
849 | } | 851 | } |
850 | 852 | ||
@@ -864,7 +866,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol, | |||
864 | struct snd_soc_dapm_context *dapm = w->dapm; | 866 | struct snd_soc_dapm_context *dapm = w->dapm; |
865 | struct hdac_hdmi_port *port = w->priv; | 867 | struct hdac_hdmi_port *port = w->priv; |
866 | struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev); | 868 | struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev); |
867 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 869 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
868 | struct hdac_hdmi_pcm *pcm = NULL; | 870 | struct hdac_hdmi_pcm *pcm = NULL; |
869 | const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]]; | 871 | const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]]; |
870 | 872 | ||
@@ -922,7 +924,7 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev, | |||
922 | struct snd_soc_dapm_widget *widget, | 924 | struct snd_soc_dapm_widget *widget, |
923 | const char *widget_name) | 925 | const char *widget_name) |
924 | { | 926 | { |
925 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 927 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
926 | struct hdac_hdmi_pin *pin = port->pin; | 928 | struct hdac_hdmi_pin *pin = port->pin; |
927 | struct snd_kcontrol_new *kc; | 929 | struct snd_kcontrol_new *kc; |
928 | struct hdac_hdmi_cvt *cvt; | 930 | struct hdac_hdmi_cvt *cvt; |
@@ -934,17 +936,17 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev, | |||
934 | int i = 0; | 936 | int i = 0; |
935 | int num_items = hdmi->num_cvt + 1; | 937 | int num_items = hdmi->num_cvt + 1; |
936 | 938 | ||
937 | kc = devm_kzalloc(&edev->hdac.dev, sizeof(*kc), GFP_KERNEL); | 939 | kc = devm_kzalloc(&edev->hdev.dev, sizeof(*kc), GFP_KERNEL); |
938 | if (!kc) | 940 | if (!kc) |
939 | return -ENOMEM; | 941 | return -ENOMEM; |
940 | 942 | ||
941 | se = devm_kzalloc(&edev->hdac.dev, sizeof(*se), GFP_KERNEL); | 943 | se = devm_kzalloc(&edev->hdev.dev, sizeof(*se), GFP_KERNEL); |
942 | if (!se) | 944 | if (!se) |
943 | return -ENOMEM; | 945 | return -ENOMEM; |
944 | 946 | ||
945 | snprintf(kc_name, NAME_SIZE, "Pin %d port %d Input", | 947 | snprintf(kc_name, NAME_SIZE, "Pin %d port %d Input", |
946 | pin->nid, port->id); | 948 | pin->nid, port->id); |
947 | kc->name = devm_kstrdup(&edev->hdac.dev, kc_name, GFP_KERNEL); | 949 | kc->name = devm_kstrdup(&edev->hdev.dev, kc_name, GFP_KERNEL); |
948 | if (!kc->name) | 950 | if (!kc->name) |
949 | return -ENOMEM; | 951 | return -ENOMEM; |
950 | 952 | ||
@@ -962,24 +964,24 @@ static int hdac_hdmi_create_pin_port_muxs(struct hdac_ext_device *edev, | |||
962 | se->mask = roundup_pow_of_two(se->items) - 1; | 964 | se->mask = roundup_pow_of_two(se->items) - 1; |
963 | 965 | ||
964 | sprintf(mux_items, "NONE"); | 966 | sprintf(mux_items, "NONE"); |
965 | items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL); | 967 | items[i] = devm_kstrdup(&edev->hdev.dev, mux_items, GFP_KERNEL); |
966 | if (!items[i]) | 968 | if (!items[i]) |
967 | return -ENOMEM; | 969 | return -ENOMEM; |
968 | 970 | ||
969 | list_for_each_entry(cvt, &hdmi->cvt_list, head) { | 971 | list_for_each_entry(cvt, &hdmi->cvt_list, head) { |
970 | i++; | 972 | i++; |
971 | sprintf(mux_items, "cvt %d", cvt->nid); | 973 | sprintf(mux_items, "cvt %d", cvt->nid); |
972 | items[i] = devm_kstrdup(&edev->hdac.dev, mux_items, GFP_KERNEL); | 974 | items[i] = devm_kstrdup(&edev->hdev.dev, mux_items, GFP_KERNEL); |
973 | if (!items[i]) | 975 | if (!items[i]) |
974 | return -ENOMEM; | 976 | return -ENOMEM; |
975 | } | 977 | } |
976 | 978 | ||
977 | se->texts = devm_kmemdup(&edev->hdac.dev, items, | 979 | se->texts = devm_kmemdup(&edev->hdev.dev, items, |
978 | (num_items * sizeof(char *)), GFP_KERNEL); | 980 | (num_items * sizeof(char *)), GFP_KERNEL); |
979 | if (!se->texts) | 981 | if (!se->texts) |
980 | return -ENOMEM; | 982 | return -ENOMEM; |
981 | 983 | ||
982 | return hdac_hdmi_fill_widget_info(&edev->hdac.dev, widget, | 984 | return hdac_hdmi_fill_widget_info(&edev->hdev.dev, widget, |
983 | snd_soc_dapm_mux, port, widget_name, NULL, kc, 1, | 985 | snd_soc_dapm_mux, port, widget_name, NULL, kc, 1, |
984 | hdac_hdmi_pin_mux_widget_event, | 986 | hdac_hdmi_pin_mux_widget_event, |
985 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_REG); | 987 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_REG); |
@@ -990,7 +992,7 @@ static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_ext_device *edev, | |||
990 | struct snd_soc_dapm_widget *widgets, | 992 | struct snd_soc_dapm_widget *widgets, |
991 | struct snd_soc_dapm_route *route, int rindex) | 993 | struct snd_soc_dapm_route *route, int rindex) |
992 | { | 994 | { |
993 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 995 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
994 | const struct snd_kcontrol_new *kc; | 996 | const struct snd_kcontrol_new *kc; |
995 | struct soc_enum *se; | 997 | struct soc_enum *se; |
996 | int mux_index = hdmi->num_cvt + hdmi->num_ports; | 998 | int mux_index = hdmi->num_cvt + hdmi->num_ports; |
@@ -1033,8 +1035,8 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) | |||
1033 | struct snd_soc_dapm_widget *widgets; | 1035 | struct snd_soc_dapm_widget *widgets; |
1034 | struct snd_soc_dapm_route *route; | 1036 | struct snd_soc_dapm_route *route; |
1035 | struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev); | 1037 | struct hdac_ext_device *edev = to_hda_ext_device(dapm->dev); |
1036 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1038 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1037 | struct snd_soc_dai_driver *dai_drv = dapm->component->dai_drv; | 1039 | struct snd_soc_dai_driver *dai_drv = hdmi->dai_drv; |
1038 | char widget_name[NAME_SIZE]; | 1040 | char widget_name[NAME_SIZE]; |
1039 | struct hdac_hdmi_cvt *cvt; | 1041 | struct hdac_hdmi_cvt *cvt; |
1040 | struct hdac_hdmi_pin *pin; | 1042 | struct hdac_hdmi_pin *pin; |
@@ -1134,7 +1136,7 @@ static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm) | |||
1134 | 1136 | ||
1135 | static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev) | 1137 | static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev) |
1136 | { | 1138 | { |
1137 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1139 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1138 | struct hdac_hdmi_dai_port_map *dai_map; | 1140 | struct hdac_hdmi_dai_port_map *dai_map; |
1139 | struct hdac_hdmi_cvt *cvt; | 1141 | struct hdac_hdmi_cvt *cvt; |
1140 | int dai_id = 0; | 1142 | int dai_id = 0; |
@@ -1150,7 +1152,7 @@ static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev) | |||
1150 | dai_id++; | 1152 | dai_id++; |
1151 | 1153 | ||
1152 | if (dai_id == HDA_MAX_CVTS) { | 1154 | if (dai_id == HDA_MAX_CVTS) { |
1153 | dev_warn(&edev->hdac.dev, | 1155 | dev_warn(&edev->hdev.dev, |
1154 | "Max dais supported: %d\n", dai_id); | 1156 | "Max dais supported: %d\n", dai_id); |
1155 | break; | 1157 | break; |
1156 | } | 1158 | } |
@@ -1161,7 +1163,7 @@ static int hdac_hdmi_init_dai_map(struct hdac_ext_device *edev) | |||
1161 | 1163 | ||
1162 | static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid) | 1164 | static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid) |
1163 | { | 1165 | { |
1164 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1166 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1165 | struct hdac_hdmi_cvt *cvt; | 1167 | struct hdac_hdmi_cvt *cvt; |
1166 | char name[NAME_SIZE]; | 1168 | char name[NAME_SIZE]; |
1167 | 1169 | ||
@@ -1176,7 +1178,7 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid) | |||
1176 | list_add_tail(&cvt->head, &hdmi->cvt_list); | 1178 | list_add_tail(&cvt->head, &hdmi->cvt_list); |
1177 | hdmi->num_cvt++; | 1179 | hdmi->num_cvt++; |
1178 | 1180 | ||
1179 | return hdac_hdmi_query_cvt_params(&edev->hdac, cvt); | 1181 | return hdac_hdmi_query_cvt_params(&edev->hdev, cvt); |
1180 | } | 1182 | } |
1181 | 1183 | ||
1182 | static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev, | 1184 | static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev, |
@@ -1188,7 +1190,7 @@ static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev, | |||
1188 | >> DRM_ELD_VER_SHIFT; | 1190 | >> DRM_ELD_VER_SHIFT; |
1189 | 1191 | ||
1190 | if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) { | 1192 | if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) { |
1191 | dev_err(&edev->hdac.dev, "HDMI: Unknown ELD version %d\n", ver); | 1193 | dev_err(&edev->hdev.dev, "HDMI: Unknown ELD version %d\n", ver); |
1192 | return -EINVAL; | 1194 | return -EINVAL; |
1193 | } | 1195 | } |
1194 | 1196 | ||
@@ -1196,7 +1198,7 @@ static int hdac_hdmi_parse_eld(struct hdac_ext_device *edev, | |||
1196 | DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT; | 1198 | DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT; |
1197 | 1199 | ||
1198 | if (mnl > ELD_MAX_MNL) { | 1200 | if (mnl > ELD_MAX_MNL) { |
1199 | dev_err(&edev->hdac.dev, "HDMI: MNL Invalid %d\n", mnl); | 1201 | dev_err(&edev->hdev.dev, "HDMI: MNL Invalid %d\n", mnl); |
1200 | return -EINVAL; | 1202 | return -EINVAL; |
1201 | } | 1203 | } |
1202 | 1204 | ||
@@ -1209,7 +1211,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, | |||
1209 | struct hdac_hdmi_port *port) | 1211 | struct hdac_hdmi_port *port) |
1210 | { | 1212 | { |
1211 | struct hdac_ext_device *edev = pin->edev; | 1213 | struct hdac_ext_device *edev = pin->edev; |
1212 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1214 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1213 | struct hdac_hdmi_pcm *pcm; | 1215 | struct hdac_hdmi_pcm *pcm; |
1214 | int size = 0; | 1216 | int size = 0; |
1215 | int port_id = -1; | 1217 | int port_id = -1; |
@@ -1227,7 +1229,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, | |||
1227 | if (pin->mst_capable) | 1229 | if (pin->mst_capable) |
1228 | port_id = port->id; | 1230 | port_id = port->id; |
1229 | 1231 | ||
1230 | size = snd_hdac_acomp_get_eld(&edev->hdac, pin->nid, port_id, | 1232 | size = snd_hdac_acomp_get_eld(&edev->hdev, pin->nid, port_id, |
1231 | &port->eld.monitor_present, | 1233 | &port->eld.monitor_present, |
1232 | port->eld.eld_buffer, | 1234 | port->eld.eld_buffer, |
1233 | ELD_MAX_SIZE); | 1235 | ELD_MAX_SIZE); |
@@ -1250,7 +1252,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, | |||
1250 | 1252 | ||
1251 | if (!port->eld.monitor_present || !port->eld.eld_valid) { | 1253 | if (!port->eld.monitor_present || !port->eld.eld_valid) { |
1252 | 1254 | ||
1253 | dev_err(&edev->hdac.dev, "%s: disconnect for pin:port %d:%d\n", | 1255 | dev_err(&edev->hdev.dev, "%s: disconnect for pin:port %d:%d\n", |
1254 | __func__, pin->nid, port->id); | 1256 | __func__, pin->nid, port->id); |
1255 | 1257 | ||
1256 | /* | 1258 | /* |
@@ -1304,7 +1306,7 @@ static int hdac_hdmi_add_ports(struct hdac_hdmi_priv *hdmi, | |||
1304 | 1306 | ||
1305 | static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) | 1307 | static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) |
1306 | { | 1308 | { |
1307 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1309 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1308 | struct hdac_hdmi_pin *pin; | 1310 | struct hdac_hdmi_pin *pin; |
1309 | int ret; | 1311 | int ret; |
1310 | 1312 | ||
@@ -1333,40 +1335,38 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid) | |||
1333 | #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ | 1335 | #define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */ |
1334 | #define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */ | 1336 | #define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */ |
1335 | 1337 | ||
1336 | static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdac) | 1338 | static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdev) |
1337 | { | 1339 | { |
1338 | unsigned int vendor_param; | 1340 | unsigned int vendor_param; |
1339 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 1341 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
1340 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
1341 | unsigned int vendor_nid = hdmi->drv_data->vendor_nid; | 1342 | unsigned int vendor_nid = hdmi->drv_data->vendor_nid; |
1342 | 1343 | ||
1343 | vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, | 1344 | vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0, |
1344 | INTEL_GET_VENDOR_VERB, 0); | 1345 | INTEL_GET_VENDOR_VERB, 0); |
1345 | if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) | 1346 | if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS) |
1346 | return; | 1347 | return; |
1347 | 1348 | ||
1348 | vendor_param |= INTEL_EN_ALL_PIN_CVTS; | 1349 | vendor_param |= INTEL_EN_ALL_PIN_CVTS; |
1349 | vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, | 1350 | vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0, |
1350 | INTEL_SET_VENDOR_VERB, vendor_param); | 1351 | INTEL_SET_VENDOR_VERB, vendor_param); |
1351 | if (vendor_param == -1) | 1352 | if (vendor_param == -1) |
1352 | return; | 1353 | return; |
1353 | } | 1354 | } |
1354 | 1355 | ||
1355 | static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdac) | 1356 | static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdev) |
1356 | { | 1357 | { |
1357 | unsigned int vendor_param; | 1358 | unsigned int vendor_param; |
1358 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 1359 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
1359 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
1360 | unsigned int vendor_nid = hdmi->drv_data->vendor_nid; | 1360 | unsigned int vendor_nid = hdmi->drv_data->vendor_nid; |
1361 | 1361 | ||
1362 | vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, | 1362 | vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0, |
1363 | INTEL_GET_VENDOR_VERB, 0); | 1363 | INTEL_GET_VENDOR_VERB, 0); |
1364 | if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) | 1364 | if (vendor_param == -1 || vendor_param & INTEL_EN_DP12) |
1365 | return; | 1365 | return; |
1366 | 1366 | ||
1367 | /* enable DP1.2 mode */ | 1367 | /* enable DP1.2 mode */ |
1368 | vendor_param |= INTEL_EN_DP12; | 1368 | vendor_param |= INTEL_EN_DP12; |
1369 | vendor_param = snd_hdac_codec_read(hdac, vendor_nid, 0, | 1369 | vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0, |
1370 | INTEL_SET_VENDOR_VERB, vendor_param); | 1370 | INTEL_SET_VENDOR_VERB, vendor_param); |
1371 | if (vendor_param == -1) | 1371 | if (vendor_param == -1) |
1372 | return; | 1372 | return; |
@@ -1384,7 +1384,7 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = { | |||
1384 | * Each converter can support a stream independently. So a dai is created | 1384 | * Each converter can support a stream independently. So a dai is created |
1385 | * based on the number of converter queried. | 1385 | * based on the number of converter queried. |
1386 | */ | 1386 | */ |
1387 | static int hdac_hdmi_create_dais(struct hdac_device *hdac, | 1387 | static int hdac_hdmi_create_dais(struct hdac_device *hdev, |
1388 | struct snd_soc_dai_driver **dais, | 1388 | struct snd_soc_dai_driver **dais, |
1389 | struct hdac_hdmi_priv *hdmi, int num_dais) | 1389 | struct hdac_hdmi_priv *hdmi, int num_dais) |
1390 | { | 1390 | { |
@@ -1397,20 +1397,20 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac, | |||
1397 | u64 formats; | 1397 | u64 formats; |
1398 | int ret; | 1398 | int ret; |
1399 | 1399 | ||
1400 | hdmi_dais = devm_kzalloc(&hdac->dev, | 1400 | hdmi_dais = devm_kzalloc(&hdev->dev, |
1401 | (sizeof(*hdmi_dais) * num_dais), | 1401 | (sizeof(*hdmi_dais) * num_dais), |
1402 | GFP_KERNEL); | 1402 | GFP_KERNEL); |
1403 | if (!hdmi_dais) | 1403 | if (!hdmi_dais) |
1404 | return -ENOMEM; | 1404 | return -ENOMEM; |
1405 | 1405 | ||
1406 | list_for_each_entry(cvt, &hdmi->cvt_list, head) { | 1406 | list_for_each_entry(cvt, &hdmi->cvt_list, head) { |
1407 | ret = snd_hdac_query_supported_pcm(hdac, cvt->nid, | 1407 | ret = snd_hdac_query_supported_pcm(hdev, cvt->nid, |
1408 | &rates, &formats, &bps); | 1408 | &rates, &formats, &bps); |
1409 | if (ret) | 1409 | if (ret) |
1410 | return ret; | 1410 | return ret; |
1411 | 1411 | ||
1412 | sprintf(dai_name, "intel-hdmi-hifi%d", i+1); | 1412 | sprintf(dai_name, "intel-hdmi-hifi%d", i+1); |
1413 | hdmi_dais[i].name = devm_kstrdup(&hdac->dev, | 1413 | hdmi_dais[i].name = devm_kstrdup(&hdev->dev, |
1414 | dai_name, GFP_KERNEL); | 1414 | dai_name, GFP_KERNEL); |
1415 | 1415 | ||
1416 | if (!hdmi_dais[i].name) | 1416 | if (!hdmi_dais[i].name) |
@@ -1418,7 +1418,7 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac, | |||
1418 | 1418 | ||
1419 | snprintf(name, sizeof(name), "hifi%d", i+1); | 1419 | snprintf(name, sizeof(name), "hifi%d", i+1); |
1420 | hdmi_dais[i].playback.stream_name = | 1420 | hdmi_dais[i].playback.stream_name = |
1421 | devm_kstrdup(&hdac->dev, name, GFP_KERNEL); | 1421 | devm_kstrdup(&hdev->dev, name, GFP_KERNEL); |
1422 | if (!hdmi_dais[i].playback.stream_name) | 1422 | if (!hdmi_dais[i].playback.stream_name) |
1423 | return -ENOMEM; | 1423 | return -ENOMEM; |
1424 | 1424 | ||
@@ -1438,6 +1438,7 @@ static int hdac_hdmi_create_dais(struct hdac_device *hdac, | |||
1438 | } | 1438 | } |
1439 | 1439 | ||
1440 | *dais = hdmi_dais; | 1440 | *dais = hdmi_dais; |
1441 | hdmi->dai_drv = hdmi_dais; | ||
1441 | 1442 | ||
1442 | return 0; | 1443 | return 0; |
1443 | } | 1444 | } |
@@ -1451,29 +1452,26 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev, | |||
1451 | { | 1452 | { |
1452 | hda_nid_t nid; | 1453 | hda_nid_t nid; |
1453 | int i, num_nodes; | 1454 | int i, num_nodes; |
1454 | struct hdac_device *hdac = &edev->hdac; | ||
1455 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
1456 | struct hdac_hdmi_cvt *temp_cvt, *cvt_next; | 1455 | struct hdac_hdmi_cvt *temp_cvt, *cvt_next; |
1457 | struct hdac_hdmi_pin *temp_pin, *pin_next; | 1456 | struct hdac_hdmi_pin *temp_pin, *pin_next; |
1457 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); | ||
1458 | struct hdac_device *hdev = &edev->hdev; | ||
1458 | int ret; | 1459 | int ret; |
1459 | 1460 | ||
1460 | hdac_hdmi_skl_enable_all_pins(hdac); | 1461 | hdac_hdmi_skl_enable_all_pins(hdev); |
1461 | hdac_hdmi_skl_enable_dp12(hdac); | 1462 | hdac_hdmi_skl_enable_dp12(hdev); |
1462 | 1463 | ||
1463 | num_nodes = snd_hdac_get_sub_nodes(hdac, hdac->afg, &nid); | 1464 | num_nodes = snd_hdac_get_sub_nodes(hdev, hdev->afg, &nid); |
1464 | if (!nid || num_nodes <= 0) { | 1465 | if (!nid || num_nodes <= 0) { |
1465 | dev_warn(&hdac->dev, "HDMI: failed to get afg sub nodes\n"); | 1466 | dev_warn(&hdev->dev, "HDMI: failed to get afg sub nodes\n"); |
1466 | return -EINVAL; | 1467 | return -EINVAL; |
1467 | } | 1468 | } |
1468 | 1469 | ||
1469 | hdac->num_nodes = num_nodes; | 1470 | for (i = 0; i < num_nodes; i++, nid++) { |
1470 | hdac->start_nid = nid; | ||
1471 | |||
1472 | for (i = 0; i < hdac->num_nodes; i++, nid++) { | ||
1473 | unsigned int caps; | 1471 | unsigned int caps; |
1474 | unsigned int type; | 1472 | unsigned int type; |
1475 | 1473 | ||
1476 | caps = get_wcaps(hdac, nid); | 1474 | caps = get_wcaps(hdev, nid); |
1477 | type = get_wcaps_type(caps); | 1475 | type = get_wcaps_type(caps); |
1478 | 1476 | ||
1479 | if (!(caps & AC_WCAP_DIGITAL)) | 1477 | if (!(caps & AC_WCAP_DIGITAL)) |
@@ -1495,16 +1493,14 @@ static int hdac_hdmi_parse_and_map_nid(struct hdac_ext_device *edev, | |||
1495 | } | 1493 | } |
1496 | } | 1494 | } |
1497 | 1495 | ||
1498 | hdac->end_nid = nid; | ||
1499 | |||
1500 | if (!hdmi->num_pin || !hdmi->num_cvt) { | 1496 | if (!hdmi->num_pin || !hdmi->num_cvt) { |
1501 | ret = -EIO; | 1497 | ret = -EIO; |
1502 | goto free_widgets; | 1498 | goto free_widgets; |
1503 | } | 1499 | } |
1504 | 1500 | ||
1505 | ret = hdac_hdmi_create_dais(hdac, dais, hdmi, hdmi->num_cvt); | 1501 | ret = hdac_hdmi_create_dais(hdev, dais, hdmi, hdmi->num_cvt); |
1506 | if (ret) { | 1502 | if (ret) { |
1507 | dev_err(&hdac->dev, "Failed to create dais with err: %d\n", | 1503 | dev_err(&hdev->dev, "Failed to create dais with err: %d\n", |
1508 | ret); | 1504 | ret); |
1509 | goto free_widgets; | 1505 | goto free_widgets; |
1510 | } | 1506 | } |
@@ -1537,7 +1533,7 @@ free_widgets: | |||
1537 | static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) | 1533 | static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) |
1538 | { | 1534 | { |
1539 | struct hdac_ext_device *edev = aptr; | 1535 | struct hdac_ext_device *edev = aptr; |
1540 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1536 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1541 | struct hdac_hdmi_pin *pin = NULL; | 1537 | struct hdac_hdmi_pin *pin = NULL; |
1542 | struct hdac_hdmi_port *hport = NULL; | 1538 | struct hdac_hdmi_port *hport = NULL; |
1543 | struct snd_soc_codec *codec = edev->scodec; | 1539 | struct snd_soc_codec *codec = edev->scodec; |
@@ -1546,7 +1542,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) | |||
1546 | /* Don't know how this mapping is derived */ | 1542 | /* Don't know how this mapping is derived */ |
1547 | hda_nid_t pin_nid = port + 0x04; | 1543 | hda_nid_t pin_nid = port + 0x04; |
1548 | 1544 | ||
1549 | dev_dbg(&edev->hdac.dev, "%s: for pin:%d port=%d\n", __func__, | 1545 | dev_dbg(&edev->hdev.dev, "%s: for pin:%d port=%d\n", __func__, |
1550 | pin_nid, pipe); | 1546 | pin_nid, pipe); |
1551 | 1547 | ||
1552 | /* | 1548 | /* |
@@ -1559,7 +1555,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe) | |||
1559 | SNDRV_CTL_POWER_D0) | 1555 | SNDRV_CTL_POWER_D0) |
1560 | return; | 1556 | return; |
1561 | 1557 | ||
1562 | if (atomic_read(&edev->hdac.in_pm)) | 1558 | if (atomic_read(&edev->hdev.in_pm)) |
1563 | return; | 1559 | return; |
1564 | 1560 | ||
1565 | list_for_each_entry(pin, &hdmi->pin_list, head) { | 1561 | list_for_each_entry(pin, &hdmi->pin_list, head) { |
@@ -1614,7 +1610,7 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card, | |||
1614 | char *name; | 1610 | char *name; |
1615 | int i = 0, j; | 1611 | int i = 0, j; |
1616 | struct snd_soc_codec *codec = edev->scodec; | 1612 | struct snd_soc_codec *codec = edev->scodec; |
1617 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1613 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1618 | 1614 | ||
1619 | kc = devm_kcalloc(codec->dev, hdmi->num_ports, | 1615 | kc = devm_kcalloc(codec->dev, hdmi->num_ports, |
1620 | sizeof(*kc), GFP_KERNEL); | 1616 | sizeof(*kc), GFP_KERNEL); |
@@ -1652,7 +1648,7 @@ int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec, | |||
1652 | struct snd_soc_dapm_context *dapm) | 1648 | struct snd_soc_dapm_context *dapm) |
1653 | { | 1649 | { |
1654 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); | 1650 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); |
1655 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1651 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1656 | struct hdac_hdmi_pin *pin; | 1652 | struct hdac_hdmi_pin *pin; |
1657 | struct snd_soc_dapm_widget *widgets; | 1653 | struct snd_soc_dapm_widget *widgets; |
1658 | struct snd_soc_dapm_route *route; | 1654 | struct snd_soc_dapm_route *route; |
@@ -1728,7 +1724,7 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device, | |||
1728 | { | 1724 | { |
1729 | struct snd_soc_codec *codec = dai->codec; | 1725 | struct snd_soc_codec *codec = dai->codec; |
1730 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); | 1726 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); |
1731 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1727 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1732 | struct hdac_hdmi_pcm *pcm; | 1728 | struct hdac_hdmi_pcm *pcm; |
1733 | struct snd_pcm *snd_pcm; | 1729 | struct snd_pcm *snd_pcm; |
1734 | int err; | 1730 | int err; |
@@ -1750,7 +1746,7 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device, | |||
1750 | if (snd_pcm) { | 1746 | if (snd_pcm) { |
1751 | err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap); | 1747 | err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap); |
1752 | if (err < 0) { | 1748 | if (err < 0) { |
1753 | dev_err(&edev->hdac.dev, | 1749 | dev_err(&edev->hdev.dev, |
1754 | "chmap control add failed with err: %d for pcm: %d\n", | 1750 | "chmap control add failed with err: %d for pcm: %d\n", |
1755 | err, device); | 1751 | err, device); |
1756 | kfree(pcm); | 1752 | kfree(pcm); |
@@ -1791,7 +1787,7 @@ static void hdac_hdmi_present_sense_all_pins(struct hdac_ext_device *edev, | |||
1791 | static int hdmi_codec_probe(struct snd_soc_codec *codec) | 1787 | static int hdmi_codec_probe(struct snd_soc_codec *codec) |
1792 | { | 1788 | { |
1793 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); | 1789 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); |
1794 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1790 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1795 | struct snd_soc_dapm_context *dapm = | 1791 | struct snd_soc_dapm_context *dapm = |
1796 | snd_soc_component_get_dapm(&codec->component); | 1792 | snd_soc_component_get_dapm(&codec->component); |
1797 | struct hdac_ext_link *hlink = NULL; | 1793 | struct hdac_ext_link *hlink = NULL; |
@@ -1803,9 +1799,9 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec) | |||
1803 | * hold the ref while we probe, also no need to drop the ref on | 1799 | * hold the ref while we probe, also no need to drop the ref on |
1804 | * exit, we call pm_runtime_suspend() so that will do for us | 1800 | * exit, we call pm_runtime_suspend() so that will do for us |
1805 | */ | 1801 | */ |
1806 | hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); | 1802 | hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdev.dev)); |
1807 | if (!hlink) { | 1803 | if (!hlink) { |
1808 | dev_err(&edev->hdac.dev, "hdac link not found\n"); | 1804 | dev_err(&edev->hdev.dev, "hdac link not found\n"); |
1809 | return -EIO; | 1805 | return -EIO; |
1810 | } | 1806 | } |
1811 | 1807 | ||
@@ -1818,7 +1814,7 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec) | |||
1818 | aops.audio_ptr = edev; | 1814 | aops.audio_ptr = edev; |
1819 | ret = snd_hdac_i915_register_notifier(&aops); | 1815 | ret = snd_hdac_i915_register_notifier(&aops); |
1820 | if (ret < 0) { | 1816 | if (ret < 0) { |
1821 | dev_err(&edev->hdac.dev, "notifier register failed: err: %d\n", | 1817 | dev_err(&edev->hdev.dev, "notifier register failed: err: %d\n", |
1822 | ret); | 1818 | ret); |
1823 | return ret; | 1819 | return ret; |
1824 | } | 1820 | } |
@@ -1831,9 +1827,9 @@ static int hdmi_codec_probe(struct snd_soc_codec *codec) | |||
1831 | * hdac_device core already sets the state to active and calls | 1827 | * hdac_device core already sets the state to active and calls |
1832 | * get_noresume. So enable runtime and set the device to suspend. | 1828 | * get_noresume. So enable runtime and set the device to suspend. |
1833 | */ | 1829 | */ |
1834 | pm_runtime_enable(&edev->hdac.dev); | 1830 | pm_runtime_enable(&edev->hdev.dev); |
1835 | pm_runtime_put(&edev->hdac.dev); | 1831 | pm_runtime_put(&edev->hdev.dev); |
1836 | pm_runtime_suspend(&edev->hdac.dev); | 1832 | pm_runtime_suspend(&edev->hdev.dev); |
1837 | 1833 | ||
1838 | return 0; | 1834 | return 0; |
1839 | } | 1835 | } |
@@ -1842,7 +1838,7 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec) | |||
1842 | { | 1838 | { |
1843 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); | 1839 | struct hdac_ext_device *edev = snd_soc_codec_get_drvdata(codec); |
1844 | 1840 | ||
1845 | pm_runtime_disable(&edev->hdac.dev); | 1841 | pm_runtime_disable(&edev->hdev.dev); |
1846 | return 0; | 1842 | return 0; |
1847 | } | 1843 | } |
1848 | 1844 | ||
@@ -1850,9 +1846,9 @@ static int hdmi_codec_remove(struct snd_soc_codec *codec) | |||
1850 | static int hdmi_codec_prepare(struct device *dev) | 1846 | static int hdmi_codec_prepare(struct device *dev) |
1851 | { | 1847 | { |
1852 | struct hdac_ext_device *edev = to_hda_ext_device(dev); | 1848 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
1853 | struct hdac_device *hdac = &edev->hdac; | 1849 | struct hdac_device *hdev = &edev->hdev; |
1854 | 1850 | ||
1855 | pm_runtime_get_sync(&edev->hdac.dev); | 1851 | pm_runtime_get_sync(&edev->hdev.dev); |
1856 | 1852 | ||
1857 | /* | 1853 | /* |
1858 | * Power down afg. | 1854 | * Power down afg. |
@@ -1861,7 +1857,7 @@ static int hdmi_codec_prepare(struct device *dev) | |||
1861 | * is received. So setting power state is ensured without using loop | 1857 | * is received. So setting power state is ensured without using loop |
1862 | * to read the state. | 1858 | * to read the state. |
1863 | */ | 1859 | */ |
1864 | snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | 1860 | snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, |
1865 | AC_PWRST_D3); | 1861 | AC_PWRST_D3); |
1866 | 1862 | ||
1867 | return 0; | 1863 | return 0; |
@@ -1870,15 +1866,15 @@ static int hdmi_codec_prepare(struct device *dev) | |||
1870 | static void hdmi_codec_complete(struct device *dev) | 1866 | static void hdmi_codec_complete(struct device *dev) |
1871 | { | 1867 | { |
1872 | struct hdac_ext_device *edev = to_hda_ext_device(dev); | 1868 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
1873 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1869 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
1874 | struct hdac_device *hdac = &edev->hdac; | 1870 | struct hdac_device *hdev = &edev->hdev; |
1875 | 1871 | ||
1876 | /* Power up afg */ | 1872 | /* Power up afg */ |
1877 | snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | 1873 | snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, |
1878 | AC_PWRST_D0); | 1874 | AC_PWRST_D0); |
1879 | 1875 | ||
1880 | hdac_hdmi_skl_enable_all_pins(&edev->hdac); | 1876 | hdac_hdmi_skl_enable_all_pins(&edev->hdev); |
1881 | hdac_hdmi_skl_enable_dp12(&edev->hdac); | 1877 | hdac_hdmi_skl_enable_dp12(&edev->hdev); |
1882 | 1878 | ||
1883 | /* | 1879 | /* |
1884 | * As the ELD notify callback request is not entertained while the | 1880 | * As the ELD notify callback request is not entertained while the |
@@ -1888,7 +1884,7 @@ static void hdmi_codec_complete(struct device *dev) | |||
1888 | */ | 1884 | */ |
1889 | hdac_hdmi_present_sense_all_pins(edev, hdmi, false); | 1885 | hdac_hdmi_present_sense_all_pins(edev, hdmi, false); |
1890 | 1886 | ||
1891 | pm_runtime_put_sync(&edev->hdac.dev); | 1887 | pm_runtime_put_sync(&edev->hdev.dev); |
1892 | } | 1888 | } |
1893 | #else | 1889 | #else |
1894 | #define hdmi_codec_prepare NULL | 1890 | #define hdmi_codec_prepare NULL |
@@ -1901,21 +1897,20 @@ static const struct snd_soc_codec_driver hdmi_hda_codec = { | |||
1901 | .idle_bias_off = true, | 1897 | .idle_bias_off = true, |
1902 | }; | 1898 | }; |
1903 | 1899 | ||
1904 | static void hdac_hdmi_get_chmap(struct hdac_device *hdac, int pcm_idx, | 1900 | static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx, |
1905 | unsigned char *chmap) | 1901 | unsigned char *chmap) |
1906 | { | 1902 | { |
1907 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 1903 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
1908 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
1909 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | 1904 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); |
1910 | 1905 | ||
1911 | memcpy(chmap, pcm->chmap, ARRAY_SIZE(pcm->chmap)); | 1906 | memcpy(chmap, pcm->chmap, ARRAY_SIZE(pcm->chmap)); |
1912 | } | 1907 | } |
1913 | 1908 | ||
1914 | static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx, | 1909 | static void hdac_hdmi_set_chmap(struct hdac_device *hdev, int pcm_idx, |
1915 | unsigned char *chmap, int prepared) | 1910 | unsigned char *chmap, int prepared) |
1916 | { | 1911 | { |
1917 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 1912 | struct hdac_ext_device *edev = to_ehdac_device(hdev); |
1918 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 1913 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
1919 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | 1914 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); |
1920 | struct hdac_hdmi_port *port; | 1915 | struct hdac_hdmi_port *port; |
1921 | 1916 | ||
@@ -1934,10 +1929,9 @@ static void hdac_hdmi_set_chmap(struct hdac_device *hdac, int pcm_idx, | |||
1934 | mutex_unlock(&pcm->lock); | 1929 | mutex_unlock(&pcm->lock); |
1935 | } | 1930 | } |
1936 | 1931 | ||
1937 | static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx) | 1932 | static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdev, int pcm_idx) |
1938 | { | 1933 | { |
1939 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 1934 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
1940 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
1941 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | 1935 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); |
1942 | 1936 | ||
1943 | if (!pcm) | 1937 | if (!pcm) |
@@ -1949,10 +1943,9 @@ static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdac, int pcm_idx) | |||
1949 | return true; | 1943 | return true; |
1950 | } | 1944 | } |
1951 | 1945 | ||
1952 | static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdac, int pcm_idx) | 1946 | static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdev, int pcm_idx) |
1953 | { | 1947 | { |
1954 | struct hdac_ext_device *edev = to_ehdac_device(hdac); | 1948 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev); |
1955 | struct hdac_hdmi_priv *hdmi = edev->private_data; | ||
1956 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); | 1949 | struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx); |
1957 | struct hdac_hdmi_port *port; | 1950 | struct hdac_hdmi_port *port; |
1958 | 1951 | ||
@@ -1983,30 +1976,30 @@ static struct hdac_hdmi_drv_data intel_drv_data = { | |||
1983 | 1976 | ||
1984 | static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | 1977 | static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) |
1985 | { | 1978 | { |
1986 | struct hdac_device *codec = &edev->hdac; | 1979 | struct hdac_device *hdev = &edev->hdev; |
1987 | struct hdac_hdmi_priv *hdmi_priv; | 1980 | struct hdac_hdmi_priv *hdmi_priv; |
1988 | struct snd_soc_dai_driver *hdmi_dais = NULL; | 1981 | struct snd_soc_dai_driver *hdmi_dais = NULL; |
1989 | struct hdac_ext_link *hlink = NULL; | 1982 | struct hdac_ext_link *hlink = NULL; |
1990 | int num_dais = 0; | 1983 | int num_dais = 0; |
1991 | int ret = 0; | 1984 | int ret = 0; |
1992 | struct hdac_driver *hdrv = drv_to_hdac_driver(codec->dev.driver); | 1985 | struct hdac_driver *hdrv = drv_to_hdac_driver(hdev->dev.driver); |
1993 | const struct hda_device_id *hdac_id = hdac_get_device_id(codec, hdrv); | 1986 | const struct hda_device_id *hdac_id = hdac_get_device_id(hdev, hdrv); |
1994 | 1987 | ||
1995 | /* hold the ref while we probe */ | 1988 | /* hold the ref while we probe */ |
1996 | hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdac.dev)); | 1989 | hlink = snd_hdac_ext_bus_get_link(edev->ebus, dev_name(&edev->hdev.dev)); |
1997 | if (!hlink) { | 1990 | if (!hlink) { |
1998 | dev_err(&edev->hdac.dev, "hdac link not found\n"); | 1991 | dev_err(&edev->hdev.dev, "hdac link not found\n"); |
1999 | return -EIO; | 1992 | return -EIO; |
2000 | } | 1993 | } |
2001 | 1994 | ||
2002 | snd_hdac_ext_bus_link_get(edev->ebus, hlink); | 1995 | snd_hdac_ext_bus_link_get(edev->ebus, hlink); |
2003 | 1996 | ||
2004 | hdmi_priv = devm_kzalloc(&codec->dev, sizeof(*hdmi_priv), GFP_KERNEL); | 1997 | hdmi_priv = devm_kzalloc(&hdev->dev, sizeof(*hdmi_priv), GFP_KERNEL); |
2005 | if (hdmi_priv == NULL) | 1998 | if (hdmi_priv == NULL) |
2006 | return -ENOMEM; | 1999 | return -ENOMEM; |
2007 | 2000 | ||
2008 | edev->private_data = hdmi_priv; | 2001 | edev->private_data = hdmi_priv; |
2009 | snd_hdac_register_chmap_ops(codec, &hdmi_priv->chmap); | 2002 | snd_hdac_register_chmap_ops(hdev, &hdmi_priv->chmap); |
2010 | hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap; | 2003 | hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap; |
2011 | hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap; | 2004 | hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap; |
2012 | hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; | 2005 | hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached; |
@@ -2021,7 +2014,7 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | |||
2021 | else | 2014 | else |
2022 | hdmi_priv->drv_data = &intel_drv_data; | 2015 | hdmi_priv->drv_data = &intel_drv_data; |
2023 | 2016 | ||
2024 | dev_set_drvdata(&codec->dev, edev); | 2017 | dev_set_drvdata(&hdev->dev, edev); |
2025 | 2018 | ||
2026 | INIT_LIST_HEAD(&hdmi_priv->pin_list); | 2019 | INIT_LIST_HEAD(&hdmi_priv->pin_list); |
2027 | INIT_LIST_HEAD(&hdmi_priv->cvt_list); | 2020 | INIT_LIST_HEAD(&hdmi_priv->cvt_list); |
@@ -2032,9 +2025,9 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | |||
2032 | * Turned off in the runtime_suspend during the first explicit | 2025 | * Turned off in the runtime_suspend during the first explicit |
2033 | * pm_runtime_suspend call. | 2026 | * pm_runtime_suspend call. |
2034 | */ | 2027 | */ |
2035 | ret = snd_hdac_display_power(edev->hdac.bus, true); | 2028 | ret = snd_hdac_display_power(edev->hdev.bus, true); |
2036 | if (ret < 0) { | 2029 | if (ret < 0) { |
2037 | dev_err(&edev->hdac.dev, | 2030 | dev_err(&edev->hdev.dev, |
2038 | "Cannot turn on display power on i915 err: %d\n", | 2031 | "Cannot turn on display power on i915 err: %d\n", |
2039 | ret); | 2032 | ret); |
2040 | return ret; | 2033 | return ret; |
@@ -2042,13 +2035,14 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | |||
2042 | 2035 | ||
2043 | ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais); | 2036 | ret = hdac_hdmi_parse_and_map_nid(edev, &hdmi_dais, &num_dais); |
2044 | if (ret < 0) { | 2037 | if (ret < 0) { |
2045 | dev_err(&codec->dev, | 2038 | dev_err(&hdev->dev, |
2046 | "Failed in parse and map nid with err: %d\n", ret); | 2039 | "Failed in parse and map nid with err: %d\n", ret); |
2047 | return ret; | 2040 | return ret; |
2048 | } | 2041 | } |
2042 | snd_hdac_refresh_widgets(hdev, true); | ||
2049 | 2043 | ||
2050 | /* ASoC specific initialization */ | 2044 | /* ASoC specific initialization */ |
2051 | ret = snd_soc_register_codec(&codec->dev, &hdmi_hda_codec, | 2045 | ret = snd_soc_register_codec(&hdev->dev, &hdmi_hda_codec, |
2052 | hdmi_dais, num_dais); | 2046 | hdmi_dais, num_dais); |
2053 | 2047 | ||
2054 | snd_hdac_ext_bus_link_put(edev->ebus, hlink); | 2048 | snd_hdac_ext_bus_link_put(edev->ebus, hlink); |
@@ -2058,14 +2052,14 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev) | |||
2058 | 2052 | ||
2059 | static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) | 2053 | static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) |
2060 | { | 2054 | { |
2061 | struct hdac_hdmi_priv *hdmi = edev->private_data; | 2055 | struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(&edev->hdev); |
2062 | struct hdac_hdmi_pin *pin, *pin_next; | 2056 | struct hdac_hdmi_pin *pin, *pin_next; |
2063 | struct hdac_hdmi_cvt *cvt, *cvt_next; | 2057 | struct hdac_hdmi_cvt *cvt, *cvt_next; |
2064 | struct hdac_hdmi_pcm *pcm, *pcm_next; | 2058 | struct hdac_hdmi_pcm *pcm, *pcm_next; |
2065 | struct hdac_hdmi_port *port, *port_next; | 2059 | struct hdac_hdmi_port *port, *port_next; |
2066 | int i; | 2060 | int i; |
2067 | 2061 | ||
2068 | snd_soc_unregister_codec(&edev->hdac.dev); | 2062 | snd_soc_unregister_codec(&edev->hdev.dev); |
2069 | 2063 | ||
2070 | list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) { | 2064 | list_for_each_entry_safe(pcm, pcm_next, &hdmi->pcm_list, head) { |
2071 | pcm->cvt = NULL; | 2065 | pcm->cvt = NULL; |
@@ -2101,8 +2095,8 @@ static int hdac_hdmi_dev_remove(struct hdac_ext_device *edev) | |||
2101 | static int hdac_hdmi_runtime_suspend(struct device *dev) | 2095 | static int hdac_hdmi_runtime_suspend(struct device *dev) |
2102 | { | 2096 | { |
2103 | struct hdac_ext_device *edev = to_hda_ext_device(dev); | 2097 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
2104 | struct hdac_device *hdac = &edev->hdac; | 2098 | struct hdac_device *hdev = &edev->hdev; |
2105 | struct hdac_bus *bus = hdac->bus; | 2099 | struct hdac_bus *bus = hdev->bus; |
2106 | struct hdac_ext_bus *ebus = hbus_to_ebus(bus); | 2100 | struct hdac_ext_bus *ebus = hbus_to_ebus(bus); |
2107 | struct hdac_ext_link *hlink = NULL; | 2101 | struct hdac_ext_link *hlink = NULL; |
2108 | int err; | 2102 | int err; |
@@ -2120,7 +2114,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) | |||
2120 | * is received. So setting power state is ensured without using loop | 2114 | * is received. So setting power state is ensured without using loop |
2121 | * to read the state. | 2115 | * to read the state. |
2122 | */ | 2116 | */ |
2123 | snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | 2117 | snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, |
2124 | AC_PWRST_D3); | 2118 | AC_PWRST_D3); |
2125 | err = snd_hdac_display_power(bus, false); | 2119 | err = snd_hdac_display_power(bus, false); |
2126 | if (err < 0) { | 2120 | if (err < 0) { |
@@ -2142,8 +2136,8 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) | |||
2142 | static int hdac_hdmi_runtime_resume(struct device *dev) | 2136 | static int hdac_hdmi_runtime_resume(struct device *dev) |
2143 | { | 2137 | { |
2144 | struct hdac_ext_device *edev = to_hda_ext_device(dev); | 2138 | struct hdac_ext_device *edev = to_hda_ext_device(dev); |
2145 | struct hdac_device *hdac = &edev->hdac; | 2139 | struct hdac_device *hdev = &edev->hdev; |
2146 | struct hdac_bus *bus = hdac->bus; | 2140 | struct hdac_bus *bus = hdev->bus; |
2147 | struct hdac_ext_bus *ebus = hbus_to_ebus(bus); | 2141 | struct hdac_ext_bus *ebus = hbus_to_ebus(bus); |
2148 | struct hdac_ext_link *hlink = NULL; | 2142 | struct hdac_ext_link *hlink = NULL; |
2149 | int err; | 2143 | int err; |
@@ -2168,11 +2162,11 @@ static int hdac_hdmi_runtime_resume(struct device *dev) | |||
2168 | return err; | 2162 | return err; |
2169 | } | 2163 | } |
2170 | 2164 | ||
2171 | hdac_hdmi_skl_enable_all_pins(&edev->hdac); | 2165 | hdac_hdmi_skl_enable_all_pins(&edev->hdev); |
2172 | hdac_hdmi_skl_enable_dp12(&edev->hdac); | 2166 | hdac_hdmi_skl_enable_dp12(&edev->hdev); |
2173 | 2167 | ||
2174 | /* Power up afg */ | 2168 | /* Power up afg */ |
2175 | snd_hdac_codec_read(hdac, hdac->afg, 0, AC_VERB_SET_POWER_STATE, | 2169 | snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE, |
2176 | AC_PWRST_D0); | 2170 | AC_PWRST_D0); |
2177 | 2171 | ||
2178 | return 0; | 2172 | return 0; |
@@ -2192,6 +2186,8 @@ static const struct hda_device_id hdmi_list[] = { | |||
2192 | HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0), | 2186 | HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0), |
2193 | HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0), | 2187 | HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0), |
2194 | HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0), | 2188 | HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0), |
2189 | HDA_CODEC_EXT_ENTRY(0x8086280c, 0x100000, "Cannonlake HDMI", | ||
2190 | &intel_glk_drv_data), | ||
2195 | HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", | 2191 | HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI", |
2196 | &intel_glk_drv_data), | 2192 | &intel_glk_drv_data), |
2197 | {} | 2193 | {} |
diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c new file mode 100644 index 000000000000..31b0864583e8 --- /dev/null +++ b/sound/soc/codecs/max98373.c | |||
@@ -0,0 +1,976 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* Copyright (c) 2017, Maxim Integrated */ | ||
3 | |||
4 | #include <linux/acpi.h> | ||
5 | #include <linux/i2c.h> | ||
6 | #include <linux/module.h> | ||
7 | #include <linux/regmap.h> | ||
8 | #include <linux/slab.h> | ||
9 | #include <linux/cdev.h> | ||
10 | #include <sound/pcm.h> | ||
11 | #include <sound/pcm_params.h> | ||
12 | #include <sound/soc.h> | ||
13 | #include <linux/gpio.h> | ||
14 | #include <linux/of_gpio.h> | ||
15 | #include <sound/tlv.h> | ||
16 | #include "max98373.h" | ||
17 | |||
18 | static struct reg_default max98373_reg[] = { | ||
19 | {MAX98373_R2000_SW_RESET, 0x00}, | ||
20 | {MAX98373_R2001_INT_RAW1, 0x00}, | ||
21 | {MAX98373_R2002_INT_RAW2, 0x00}, | ||
22 | {MAX98373_R2003_INT_RAW3, 0x00}, | ||
23 | {MAX98373_R2004_INT_STATE1, 0x00}, | ||
24 | {MAX98373_R2005_INT_STATE2, 0x00}, | ||
25 | {MAX98373_R2006_INT_STATE3, 0x00}, | ||
26 | {MAX98373_R2007_INT_FLAG1, 0x00}, | ||
27 | {MAX98373_R2008_INT_FLAG2, 0x00}, | ||
28 | {MAX98373_R2009_INT_FLAG3, 0x00}, | ||
29 | {MAX98373_R200A_INT_EN1, 0x00}, | ||
30 | {MAX98373_R200B_INT_EN2, 0x00}, | ||
31 | {MAX98373_R200C_INT_EN3, 0x00}, | ||
32 | {MAX98373_R200D_INT_FLAG_CLR1, 0x00}, | ||
33 | {MAX98373_R200E_INT_FLAG_CLR2, 0x00}, | ||
34 | {MAX98373_R200F_INT_FLAG_CLR3, 0x00}, | ||
35 | {MAX98373_R2010_IRQ_CTRL, 0x00}, | ||
36 | {MAX98373_R2014_THERM_WARN_THRESH, 0x10}, | ||
37 | {MAX98373_R2015_THERM_SHDN_THRESH, 0x27}, | ||
38 | {MAX98373_R2016_THERM_HYSTERESIS, 0x01}, | ||
39 | {MAX98373_R2017_THERM_FOLDBACK_SET, 0xC0}, | ||
40 | {MAX98373_R2018_THERM_FOLDBACK_EN, 0x00}, | ||
41 | {MAX98373_R201E_PIN_DRIVE_STRENGTH, 0x55}, | ||
42 | {MAX98373_R2020_PCM_TX_HIZ_EN_1, 0xFE}, | ||
43 | {MAX98373_R2021_PCM_TX_HIZ_EN_2, 0xFF}, | ||
44 | {MAX98373_R2022_PCM_TX_SRC_1, 0x00}, | ||
45 | {MAX98373_R2023_PCM_TX_SRC_2, 0x00}, | ||
46 | {MAX98373_R2024_PCM_DATA_FMT_CFG, 0xC0}, | ||
47 | {MAX98373_R2025_AUDIO_IF_MODE, 0x00}, | ||
48 | {MAX98373_R2026_PCM_CLOCK_RATIO, 0x04}, | ||
49 | {MAX98373_R2027_PCM_SR_SETUP_1, 0x08}, | ||
50 | {MAX98373_R2028_PCM_SR_SETUP_2, 0x88}, | ||
51 | {MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1, 0x00}, | ||
52 | {MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, 0x00}, | ||
53 | {MAX98373_R202B_PCM_RX_EN, 0x00}, | ||
54 | {MAX98373_R202C_PCM_TX_EN, 0x00}, | ||
55 | {MAX98373_R202E_ICC_RX_CH_EN_1, 0x00}, | ||
56 | {MAX98373_R202F_ICC_RX_CH_EN_2, 0x00}, | ||
57 | {MAX98373_R2030_ICC_TX_HIZ_EN_1, 0xFF}, | ||
58 | {MAX98373_R2031_ICC_TX_HIZ_EN_2, 0xFF}, | ||
59 | {MAX98373_R2032_ICC_LINK_EN_CFG, 0x30}, | ||
60 | {MAX98373_R2034_ICC_TX_CNTL, 0x00}, | ||
61 | {MAX98373_R2035_ICC_TX_EN, 0x00}, | ||
62 | {MAX98373_R2036_SOUNDWIRE_CTRL, 0x05}, | ||
63 | {MAX98373_R203D_AMP_DIG_VOL_CTRL, 0x00}, | ||
64 | {MAX98373_R203E_AMP_PATH_GAIN, 0x08}, | ||
65 | {MAX98373_R203F_AMP_DSP_CFG, 0x02}, | ||
66 | {MAX98373_R2040_TONE_GEN_CFG, 0x00}, | ||
67 | {MAX98373_R2041_AMP_CFG, 0x03}, | ||
68 | {MAX98373_R2042_AMP_EDGE_RATE_CFG, 0x00}, | ||
69 | {MAX98373_R2043_AMP_EN, 0x00}, | ||
70 | {MAX98373_R2046_IV_SENSE_ADC_DSP_CFG, 0x04}, | ||
71 | {MAX98373_R2047_IV_SENSE_ADC_EN, 0x00}, | ||
72 | {MAX98373_R2051_MEAS_ADC_SAMPLING_RATE, 0x00}, | ||
73 | {MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG, 0x00}, | ||
74 | {MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG, 0x00}, | ||
75 | {MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0x00}, | ||
76 | {MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0x00}, | ||
77 | {MAX98373_R2056_MEAS_ADC_PVDD_CH_EN, 0x00}, | ||
78 | {MAX98373_R2090_BDE_LVL_HOLD, 0x00}, | ||
79 | {MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 0x00}, | ||
80 | {MAX98373_R2092_BDE_CLIPPER_MODE, 0x00}, | ||
81 | {MAX98373_R2097_BDE_L1_THRESH, 0x00}, | ||
82 | {MAX98373_R2098_BDE_L2_THRESH, 0x00}, | ||
83 | {MAX98373_R2099_BDE_L3_THRESH, 0x00}, | ||
84 | {MAX98373_R209A_BDE_L4_THRESH, 0x00}, | ||
85 | {MAX98373_R209B_BDE_THRESH_HYST, 0x00}, | ||
86 | {MAX98373_R20A8_BDE_L1_CFG_1, 0x00}, | ||
87 | {MAX98373_R20A9_BDE_L1_CFG_2, 0x00}, | ||
88 | {MAX98373_R20AA_BDE_L1_CFG_3, 0x00}, | ||
89 | {MAX98373_R20AB_BDE_L2_CFG_1, 0x00}, | ||
90 | {MAX98373_R20AC_BDE_L2_CFG_2, 0x00}, | ||
91 | {MAX98373_R20AD_BDE_L2_CFG_3, 0x00}, | ||
92 | {MAX98373_R20AE_BDE_L3_CFG_1, 0x00}, | ||
93 | {MAX98373_R20AF_BDE_L3_CFG_2, 0x00}, | ||
94 | {MAX98373_R20B0_BDE_L3_CFG_3, 0x00}, | ||
95 | {MAX98373_R20B1_BDE_L4_CFG_1, 0x00}, | ||
96 | {MAX98373_R20B2_BDE_L4_CFG_2, 0x00}, | ||
97 | {MAX98373_R20B3_BDE_L4_CFG_3, 0x00}, | ||
98 | {MAX98373_R20B4_BDE_INFINITE_HOLD_RELEASE, 0x00}, | ||
99 | {MAX98373_R20B5_BDE_EN, 0x00}, | ||
100 | {MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0x00}, | ||
101 | {MAX98373_R20D1_DHT_CFG, 0x01}, | ||
102 | {MAX98373_R20D2_DHT_ATTACK_CFG, 0x02}, | ||
103 | {MAX98373_R20D3_DHT_RELEASE_CFG, 0x03}, | ||
104 | {MAX98373_R20D4_DHT_EN, 0x00}, | ||
105 | {MAX98373_R20E0_LIMITER_THRESH_CFG, 0x00}, | ||
106 | {MAX98373_R20E1_LIMITER_ATK_REL_RATES, 0x00}, | ||
107 | {MAX98373_R20E2_LIMITER_EN, 0x00}, | ||
108 | {MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG, 0x00}, | ||
109 | {MAX98373_R20FF_GLOBAL_SHDN, 0x00}, | ||
110 | {MAX98373_R21FF_REV_ID, 0x42}, | ||
111 | }; | ||
112 | |||
113 | static int max98373_dai_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | ||
114 | { | ||
115 | struct snd_soc_codec *codec = codec_dai->codec; | ||
116 | struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec); | ||
117 | unsigned int format = 0; | ||
118 | unsigned int invert = 0; | ||
119 | |||
120 | dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt); | ||
121 | |||
122 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
123 | case SND_SOC_DAIFMT_NB_NF: | ||
124 | break; | ||
125 | case SND_SOC_DAIFMT_IB_NF: | ||
126 | invert = MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE; | ||
127 | break; | ||
128 | default: | ||
129 | dev_err(codec->dev, "DAI invert mode unsupported\n"); | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | |||
133 | regmap_update_bits(max98373->regmap, | ||
134 | MAX98373_R2026_PCM_CLOCK_RATIO, | ||
135 | MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE, | ||
136 | invert); | ||
137 | |||
138 | /* interface format */ | ||
139 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
140 | case SND_SOC_DAIFMT_I2S: | ||
141 | format = MAX98373_PCM_FORMAT_I2S; | ||
142 | break; | ||
143 | case SND_SOC_DAIFMT_LEFT_J: | ||
144 | format = MAX98373_PCM_FORMAT_LJ; | ||
145 | break; | ||
146 | case SND_SOC_DAIFMT_DSP_A: | ||
147 | format = MAX98373_PCM_FORMAT_TDM_MODE1; | ||
148 | break; | ||
149 | case SND_SOC_DAIFMT_DSP_B: | ||
150 | format = MAX98373_PCM_FORMAT_TDM_MODE0; | ||
151 | break; | ||
152 | default: | ||
153 | return -EINVAL; | ||
154 | } | ||
155 | |||
156 | regmap_update_bits(max98373->regmap, | ||
157 | MAX98373_R2024_PCM_DATA_FMT_CFG, | ||
158 | MAX98373_PCM_MODE_CFG_FORMAT_MASK, | ||
159 | format << MAX98373_PCM_MODE_CFG_FORMAT_SHIFT); | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | /* BCLKs per LRCLK */ | ||
165 | static const int bclk_sel_table[] = { | ||
166 | 32, 48, 64, 96, 128, 192, 256, 384, 512, 320, | ||
167 | }; | ||
168 | |||
169 | static int max98373_get_bclk_sel(int bclk) | ||
170 | { | ||
171 | int i; | ||
172 | /* match BCLKs per LRCLK */ | ||
173 | for (i = 0; i < ARRAY_SIZE(bclk_sel_table); i++) { | ||
174 | if (bclk_sel_table[i] == bclk) | ||
175 | return i + 2; | ||
176 | } | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int max98373_set_clock(struct snd_soc_codec *codec, | ||
181 | struct snd_pcm_hw_params *params) | ||
182 | { | ||
183 | struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec); | ||
184 | /* BCLK/LRCLK ratio calculation */ | ||
185 | int blr_clk_ratio = params_channels(params) * max98373->ch_size; | ||
186 | int value; | ||
187 | |||
188 | if (!max98373->tdm_mode) { | ||
189 | /* BCLK configuration */ | ||
190 | value = max98373_get_bclk_sel(blr_clk_ratio); | ||
191 | if (!value) { | ||
192 | dev_err(codec->dev, "format unsupported %d\n", | ||
193 | params_format(params)); | ||
194 | return -EINVAL; | ||
195 | } | ||
196 | |||
197 | regmap_update_bits(max98373->regmap, | ||
198 | MAX98373_R2026_PCM_CLOCK_RATIO, | ||
199 | MAX98373_PCM_CLK_SETUP_BSEL_MASK, | ||
200 | value); | ||
201 | } | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int max98373_dai_hw_params(struct snd_pcm_substream *substream, | ||
206 | struct snd_pcm_hw_params *params, | ||
207 | struct snd_soc_dai *dai) | ||
208 | { | ||
209 | struct snd_soc_codec *codec = dai->codec; | ||
210 | struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec); | ||
211 | unsigned int sampling_rate = 0; | ||
212 | unsigned int chan_sz = 0; | ||
213 | |||
214 | /* pcm mode configuration */ | ||
215 | switch (snd_pcm_format_width(params_format(params))) { | ||
216 | case 16: | ||
217 | chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_16; | ||
218 | break; | ||
219 | case 24: | ||
220 | chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_24; | ||
221 | break; | ||
222 | case 32: | ||
223 | chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32; | ||
224 | break; | ||
225 | default: | ||
226 | dev_err(codec->dev, "format unsupported %d\n", | ||
227 | params_format(params)); | ||
228 | goto err; | ||
229 | } | ||
230 | |||
231 | max98373->ch_size = snd_pcm_format_width(params_format(params)); | ||
232 | |||
233 | regmap_update_bits(max98373->regmap, | ||
234 | MAX98373_R2024_PCM_DATA_FMT_CFG, | ||
235 | MAX98373_PCM_MODE_CFG_CHANSZ_MASK, chan_sz); | ||
236 | |||
237 | dev_dbg(codec->dev, "format supported %d", | ||
238 | params_format(params)); | ||
239 | |||
240 | /* sampling rate configuration */ | ||
241 | switch (params_rate(params)) { | ||
242 | case 8000: | ||
243 | sampling_rate = MAX98373_PCM_SR_SET1_SR_8000; | ||
244 | break; | ||
245 | case 11025: | ||
246 | sampling_rate = MAX98373_PCM_SR_SET1_SR_11025; | ||
247 | break; | ||
248 | case 12000: | ||
249 | sampling_rate = MAX98373_PCM_SR_SET1_SR_12000; | ||
250 | break; | ||
251 | case 16000: | ||
252 | sampling_rate = MAX98373_PCM_SR_SET1_SR_16000; | ||
253 | break; | ||
254 | case 22050: | ||
255 | sampling_rate = MAX98373_PCM_SR_SET1_SR_22050; | ||
256 | break; | ||
257 | case 24000: | ||
258 | sampling_rate = MAX98373_PCM_SR_SET1_SR_24000; | ||
259 | break; | ||
260 | case 32000: | ||
261 | sampling_rate = MAX98373_PCM_SR_SET1_SR_32000; | ||
262 | break; | ||
263 | case 44100: | ||
264 | sampling_rate = MAX98373_PCM_SR_SET1_SR_44100; | ||
265 | break; | ||
266 | case 48000: | ||
267 | sampling_rate = MAX98373_PCM_SR_SET1_SR_48000; | ||
268 | break; | ||
269 | default: | ||
270 | dev_err(codec->dev, "rate %d not supported\n", | ||
271 | params_rate(params)); | ||
272 | goto err; | ||
273 | } | ||
274 | |||
275 | /* set DAI_SR to correct LRCLK frequency */ | ||
276 | regmap_update_bits(max98373->regmap, | ||
277 | MAX98373_R2027_PCM_SR_SETUP_1, | ||
278 | MAX98373_PCM_SR_SET1_SR_MASK, | ||
279 | sampling_rate); | ||
280 | regmap_update_bits(max98373->regmap, | ||
281 | MAX98373_R2028_PCM_SR_SETUP_2, | ||
282 | MAX98373_PCM_SR_SET2_SR_MASK, | ||
283 | sampling_rate << MAX98373_PCM_SR_SET2_SR_SHIFT); | ||
284 | |||
285 | /* set sampling rate of IV */ | ||
286 | if (max98373->interleave_mode && | ||
287 | sampling_rate > MAX98373_PCM_SR_SET1_SR_16000) | ||
288 | regmap_update_bits(max98373->regmap, | ||
289 | MAX98373_R2028_PCM_SR_SETUP_2, | ||
290 | MAX98373_PCM_SR_SET2_IVADC_SR_MASK, | ||
291 | sampling_rate - 3); | ||
292 | else | ||
293 | regmap_update_bits(max98373->regmap, | ||
294 | MAX98373_R2028_PCM_SR_SETUP_2, | ||
295 | MAX98373_PCM_SR_SET2_IVADC_SR_MASK, | ||
296 | sampling_rate); | ||
297 | |||
298 | return max98373_set_clock(codec, params); | ||
299 | err: | ||
300 | return -EINVAL; | ||
301 | } | ||
302 | |||
303 | static int max98373_dai_tdm_slot(struct snd_soc_dai *dai, | ||
304 | unsigned int tx_mask, unsigned int rx_mask, | ||
305 | int slots, int slot_width) | ||
306 | { | ||
307 | struct snd_soc_codec *codec = dai->codec; | ||
308 | struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec); | ||
309 | int bsel = 0; | ||
310 | unsigned int chan_sz = 0; | ||
311 | unsigned int mask; | ||
312 | int x, slot_found; | ||
313 | |||
314 | if (!tx_mask && !rx_mask && !slots && !slot_width) | ||
315 | max98373->tdm_mode = false; | ||
316 | else | ||
317 | max98373->tdm_mode = true; | ||
318 | |||
319 | /* BCLK configuration */ | ||
320 | bsel = max98373_get_bclk_sel(slots * slot_width); | ||
321 | if (bsel == 0) { | ||
322 | dev_err(codec->dev, "BCLK %d not supported\n", | ||
323 | slots * slot_width); | ||
324 | return -EINVAL; | ||
325 | } | ||
326 | |||
327 | regmap_update_bits(max98373->regmap, | ||
328 | MAX98373_R2026_PCM_CLOCK_RATIO, | ||
329 | MAX98373_PCM_CLK_SETUP_BSEL_MASK, | ||
330 | bsel); | ||
331 | |||
332 | /* Channel size configuration */ | ||
333 | switch (slot_width) { | ||
334 | case 16: | ||
335 | chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_16; | ||
336 | break; | ||
337 | case 24: | ||
338 | chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_24; | ||
339 | break; | ||
340 | case 32: | ||
341 | chan_sz = MAX98373_PCM_MODE_CFG_CHANSZ_32; | ||
342 | break; | ||
343 | default: | ||
344 | dev_err(codec->dev, "format unsupported %d\n", | ||
345 | slot_width); | ||
346 | return -EINVAL; | ||
347 | } | ||
348 | |||
349 | regmap_update_bits(max98373->regmap, | ||
350 | MAX98373_R2024_PCM_DATA_FMT_CFG, | ||
351 | MAX98373_PCM_MODE_CFG_CHANSZ_MASK, chan_sz); | ||
352 | |||
353 | /* Rx slot configuration */ | ||
354 | slot_found = 0; | ||
355 | mask = rx_mask; | ||
356 | for (x = 0 ; x < 16 ; x++, mask >>= 1) { | ||
357 | if (mask & 0x1) { | ||
358 | if (slot_found == 0) | ||
359 | regmap_update_bits(max98373->regmap, | ||
360 | MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1, | ||
361 | MAX98373_PCM_TO_SPK_CH0_SRC_MASK, x); | ||
362 | else | ||
363 | regmap_write(max98373->regmap, | ||
364 | MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, | ||
365 | x); | ||
366 | slot_found++; | ||
367 | if (slot_found > 1) | ||
368 | break; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | /* Tx slot Hi-Z configuration */ | ||
373 | regmap_write(max98373->regmap, | ||
374 | MAX98373_R2020_PCM_TX_HIZ_EN_1, | ||
375 | ~tx_mask & 0xFF); | ||
376 | regmap_write(max98373->regmap, | ||
377 | MAX98373_R2021_PCM_TX_HIZ_EN_2, | ||
378 | (~tx_mask & 0xFF00) >> 8); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | #define MAX98373_RATES SNDRV_PCM_RATE_8000_96000 | ||
384 | |||
385 | #define MAX98373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
386 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
387 | |||
388 | static const struct snd_soc_dai_ops max98373_dai_ops = { | ||
389 | .set_fmt = max98373_dai_set_fmt, | ||
390 | .hw_params = max98373_dai_hw_params, | ||
391 | .set_tdm_slot = max98373_dai_tdm_slot, | ||
392 | }; | ||
393 | |||
394 | static int max98373_dac_event(struct snd_soc_dapm_widget *w, | ||
395 | struct snd_kcontrol *kcontrol, int event) | ||
396 | { | ||
397 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
398 | struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec); | ||
399 | |||
400 | switch (event) { | ||
401 | case SND_SOC_DAPM_POST_PMU: | ||
402 | regmap_update_bits(max98373->regmap, | ||
403 | MAX98373_R20FF_GLOBAL_SHDN, | ||
404 | MAX98373_GLOBAL_EN_MASK, 1); | ||
405 | break; | ||
406 | case SND_SOC_DAPM_POST_PMD: | ||
407 | regmap_update_bits(max98373->regmap, | ||
408 | MAX98373_R20FF_GLOBAL_SHDN, | ||
409 | MAX98373_GLOBAL_EN_MASK, 0); | ||
410 | max98373->tdm_mode = 0; | ||
411 | break; | ||
412 | default: | ||
413 | return 0; | ||
414 | } | ||
415 | return 0; | ||
416 | } | ||
417 | |||
418 | static const char * const max98373_switch_text[] = { | ||
419 | "Left", "Right", "LeftRight"}; | ||
420 | |||
421 | static const struct soc_enum dai_sel_enum = | ||
422 | SOC_ENUM_SINGLE(MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1, | ||
423 | MAX98373_PCM_TO_SPK_MONOMIX_CFG_SHIFT, | ||
424 | 3, max98373_switch_text); | ||
425 | |||
426 | static const struct snd_kcontrol_new max98373_dai_controls = | ||
427 | SOC_DAPM_ENUM("DAI Sel", dai_sel_enum); | ||
428 | |||
429 | static const struct snd_kcontrol_new max98373_vi_control = | ||
430 | SOC_DAPM_SINGLE("Switch", MAX98373_R202C_PCM_TX_EN, 0, 1, 0); | ||
431 | |||
432 | static const struct snd_kcontrol_new max98373_spkfb_control = | ||
433 | SOC_DAPM_SINGLE("Switch", MAX98373_R2043_AMP_EN, 1, 1, 0); | ||
434 | |||
435 | static const struct snd_soc_dapm_widget max98373_dapm_widgets[] = { | ||
436 | SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", | ||
437 | MAX98373_R202B_PCM_RX_EN, 0, 0, max98373_dac_event, | ||
438 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
439 | SND_SOC_DAPM_MUX("DAI Sel Mux", SND_SOC_NOPM, 0, 0, | ||
440 | &max98373_dai_controls), | ||
441 | SND_SOC_DAPM_OUTPUT("BE_OUT"), | ||
442 | SND_SOC_DAPM_AIF_OUT("Voltage Sense", "HiFi Capture", 0, | ||
443 | MAX98373_R2047_IV_SENSE_ADC_EN, 0, 0), | ||
444 | SND_SOC_DAPM_AIF_OUT("Current Sense", "HiFi Capture", 0, | ||
445 | MAX98373_R2047_IV_SENSE_ADC_EN, 1, 0), | ||
446 | SND_SOC_DAPM_AIF_OUT("Speaker FB Sense", "HiFi Capture", 0, | ||
447 | SND_SOC_NOPM, 0, 0), | ||
448 | SND_SOC_DAPM_SWITCH("VI Sense", SND_SOC_NOPM, 0, 0, | ||
449 | &max98373_vi_control), | ||
450 | SND_SOC_DAPM_SWITCH("SpkFB Sense", SND_SOC_NOPM, 0, 0, | ||
451 | &max98373_spkfb_control), | ||
452 | SND_SOC_DAPM_SIGGEN("VMON"), | ||
453 | SND_SOC_DAPM_SIGGEN("IMON"), | ||
454 | SND_SOC_DAPM_SIGGEN("FBMON"), | ||
455 | }; | ||
456 | |||
457 | static DECLARE_TLV_DB_SCALE(max98373_digital_tlv, 0, -50, 0); | ||
458 | static const DECLARE_TLV_DB_RANGE(max98373_spk_tlv, | ||
459 | 0, 8, TLV_DB_SCALE_ITEM(0, 50, 0), | ||
460 | 9, 10, TLV_DB_SCALE_ITEM(500, 100, 0), | ||
461 | ); | ||
462 | static const DECLARE_TLV_DB_RANGE(max98373_spkgain_max_tlv, | ||
463 | 0, 9, TLV_DB_SCALE_ITEM(800, 100, 0), | ||
464 | ); | ||
465 | static const DECLARE_TLV_DB_RANGE(max98373_dht_step_size_tlv, | ||
466 | 0, 1, TLV_DB_SCALE_ITEM(25, 25, 0), | ||
467 | 2, 4, TLV_DB_SCALE_ITEM(100, 100, 0), | ||
468 | ); | ||
469 | static const DECLARE_TLV_DB_RANGE(max98373_dht_spkgain_min_tlv, | ||
470 | 0, 9, TLV_DB_SCALE_ITEM(800, 100, 0), | ||
471 | ); | ||
472 | static const DECLARE_TLV_DB_RANGE(max98373_dht_rotation_point_tlv, | ||
473 | 0, 1, TLV_DB_SCALE_ITEM(-50, -50, 0), | ||
474 | 2, 7, TLV_DB_SCALE_ITEM(-200, -100, 0), | ||
475 | 8, 9, TLV_DB_SCALE_ITEM(-1000, -200, 0), | ||
476 | 10, 11, TLV_DB_SCALE_ITEM(-1500, -300, 0), | ||
477 | 12, 13, TLV_DB_SCALE_ITEM(-2000, -200, 0), | ||
478 | 14, 15, TLV_DB_SCALE_ITEM(-2500, -500, 0), | ||
479 | ); | ||
480 | static const DECLARE_TLV_DB_RANGE(max98373_limiter_thresh_tlv, | ||
481 | 0, 15, TLV_DB_SCALE_ITEM(0, -100, 0), | ||
482 | ); | ||
483 | |||
484 | static const DECLARE_TLV_DB_RANGE(max98373_bde_gain_tlv, | ||
485 | 0, 60, TLV_DB_SCALE_ITEM(0, -25, 0), | ||
486 | ); | ||
487 | |||
488 | static bool max98373_readable_register(struct device *dev, unsigned int reg) | ||
489 | { | ||
490 | switch (reg) { | ||
491 | case MAX98373_R2001_INT_RAW1 ... MAX98373_R200C_INT_EN3: | ||
492 | case MAX98373_R2010_IRQ_CTRL: | ||
493 | case MAX98373_R2014_THERM_WARN_THRESH | ||
494 | ... MAX98373_R2018_THERM_FOLDBACK_EN: | ||
495 | case MAX98373_R201E_PIN_DRIVE_STRENGTH | ||
496 | ... MAX98373_R2036_SOUNDWIRE_CTRL: | ||
497 | case MAX98373_R203D_AMP_DIG_VOL_CTRL ... MAX98373_R2043_AMP_EN: | ||
498 | case MAX98373_R2046_IV_SENSE_ADC_DSP_CFG | ||
499 | ... MAX98373_R2047_IV_SENSE_ADC_EN: | ||
500 | case MAX98373_R2051_MEAS_ADC_SAMPLING_RATE | ||
501 | ... MAX98373_R2056_MEAS_ADC_PVDD_CH_EN: | ||
502 | case MAX98373_R2090_BDE_LVL_HOLD ... MAX98373_R2092_BDE_CLIPPER_MODE: | ||
503 | case MAX98373_R2097_BDE_L1_THRESH | ||
504 | ... MAX98373_R209B_BDE_THRESH_HYST: | ||
505 | case MAX98373_R20A8_BDE_L1_CFG_1 ... MAX98373_R20B3_BDE_L4_CFG_3: | ||
506 | case MAX98373_R20B5_BDE_EN ... MAX98373_R20B6_BDE_CUR_STATE_READBACK: | ||
507 | case MAX98373_R20D1_DHT_CFG ... MAX98373_R20D4_DHT_EN: | ||
508 | case MAX98373_R20E0_LIMITER_THRESH_CFG ... MAX98373_R20E2_LIMITER_EN: | ||
509 | case MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG | ||
510 | ... MAX98373_R20FF_GLOBAL_SHDN: | ||
511 | case MAX98373_R21FF_REV_ID: | ||
512 | return true; | ||
513 | default: | ||
514 | return false; | ||
515 | } | ||
516 | }; | ||
517 | |||
518 | static bool max98373_volatile_reg(struct device *dev, unsigned int reg) | ||
519 | { | ||
520 | switch (reg) { | ||
521 | case MAX98373_R2000_SW_RESET ... MAX98373_R2009_INT_FLAG3: | ||
522 | case MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK: | ||
523 | case MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK: | ||
524 | case MAX98373_R20B6_BDE_CUR_STATE_READBACK: | ||
525 | case MAX98373_R21FF_REV_ID: | ||
526 | return true; | ||
527 | default: | ||
528 | return false; | ||
529 | } | ||
530 | } | ||
531 | |||
532 | static const char * const max98373_output_voltage_lvl_text[] = { | ||
533 | "5.43V", "6.09V", "6.83V", "7.67V", "8.60V", | ||
534 | "9.65V", "10.83V", "12.15V", "13.63V", "15.29V" | ||
535 | }; | ||
536 | |||
537 | static SOC_ENUM_SINGLE_DECL(max98373_out_volt_enum, | ||
538 | MAX98373_R203E_AMP_PATH_GAIN, 0, | ||
539 | max98373_output_voltage_lvl_text); | ||
540 | |||
541 | static const char * const max98373_dht_attack_rate_text[] = { | ||
542 | "17.5us", "35us", "70us", "140us", | ||
543 | "280us", "560us", "1120us", "2240us" | ||
544 | }; | ||
545 | |||
546 | static SOC_ENUM_SINGLE_DECL(max98373_dht_attack_rate_enum, | ||
547 | MAX98373_R20D2_DHT_ATTACK_CFG, 0, | ||
548 | max98373_dht_attack_rate_text); | ||
549 | |||
550 | static const char * const max98373_dht_release_rate_text[] = { | ||
551 | "45ms", "225ms", "450ms", "1150ms", | ||
552 | "2250ms", "3100ms", "4500ms", "6750ms" | ||
553 | }; | ||
554 | |||
555 | static SOC_ENUM_SINGLE_DECL(max98373_dht_release_rate_enum, | ||
556 | MAX98373_R20D3_DHT_RELEASE_CFG, 0, | ||
557 | max98373_dht_release_rate_text); | ||
558 | |||
559 | static const char * const max98373_limiter_attack_rate_text[] = { | ||
560 | "10us", "20us", "40us", "80us", | ||
561 | "160us", "320us", "640us", "1.28ms", | ||
562 | "2.56ms", "5.12ms", "10.24ms", "20.48ms", | ||
563 | "40.96ms", "81.92ms", "16.384ms", "32.768ms" | ||
564 | }; | ||
565 | |||
566 | static SOC_ENUM_SINGLE_DECL(max98373_limiter_attack_rate_enum, | ||
567 | MAX98373_R20E1_LIMITER_ATK_REL_RATES, 4, | ||
568 | max98373_limiter_attack_rate_text); | ||
569 | |||
570 | static const char * const max98373_limiter_release_rate_text[] = { | ||
571 | "40us", "80us", "160us", "320us", | ||
572 | "640us", "1.28ms", "2.56ms", "5.120ms", | ||
573 | "10.24ms", "20.48ms", "40.96ms", "81.92ms", | ||
574 | "163.84ms", "327.68ms", "655.36ms", "1310.72ms" | ||
575 | }; | ||
576 | |||
577 | static SOC_ENUM_SINGLE_DECL(max98373_limiter_release_rate_enum, | ||
578 | MAX98373_R20E1_LIMITER_ATK_REL_RATES, 0, | ||
579 | max98373_limiter_release_rate_text); | ||
580 | |||
581 | static const char * const max98373_ADC_samplerate_text[] = { | ||
582 | "333kHz", "192kHz", "64kHz", "48kHz" | ||
583 | }; | ||
584 | |||
585 | static SOC_ENUM_SINGLE_DECL(max98373_adc_samplerate_enum, | ||
586 | MAX98373_R2051_MEAS_ADC_SAMPLING_RATE, 0, | ||
587 | max98373_ADC_samplerate_text); | ||
588 | |||
589 | static const struct snd_kcontrol_new max98373_snd_controls[] = { | ||
590 | SOC_SINGLE("Digital Vol Sel Switch", MAX98373_R203F_AMP_DSP_CFG, | ||
591 | MAX98373_AMP_VOL_SEL_SHIFT, 1, 0), | ||
592 | SOC_SINGLE("Volume Location Switch", MAX98373_R203F_AMP_DSP_CFG, | ||
593 | MAX98373_AMP_VOL_SEL_SHIFT, 1, 0), | ||
594 | SOC_SINGLE("Ramp Up Switch", MAX98373_R203F_AMP_DSP_CFG, | ||
595 | MAX98373_AMP_DSP_CFG_RMP_UP_SHIFT, 1, 0), | ||
596 | SOC_SINGLE("Ramp Down Switch", MAX98373_R203F_AMP_DSP_CFG, | ||
597 | MAX98373_AMP_DSP_CFG_RMP_DN_SHIFT, 1, 0), | ||
598 | SOC_SINGLE("CLK Monitor Switch", MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG, | ||
599 | MAX98373_CLOCK_MON_SHIFT, 1, 0), | ||
600 | SOC_SINGLE("Dither Switch", MAX98373_R203F_AMP_DSP_CFG, | ||
601 | MAX98373_AMP_DSP_CFG_DITH_SHIFT, 1, 0), | ||
602 | SOC_SINGLE("DC Blocker Switch", MAX98373_R203F_AMP_DSP_CFG, | ||
603 | MAX98373_AMP_DSP_CFG_DCBLK_SHIFT, 1, 0), | ||
604 | SOC_SINGLE_TLV("Digital Volume", MAX98373_R203D_AMP_DIG_VOL_CTRL, | ||
605 | 0, 0x7F, 0, max98373_digital_tlv), | ||
606 | SOC_SINGLE_TLV("Speaker Volume", MAX98373_R203E_AMP_PATH_GAIN, | ||
607 | MAX98373_SPK_DIGI_GAIN_SHIFT, 10, 0, max98373_spk_tlv), | ||
608 | SOC_SINGLE_TLV("FS Max Volume", MAX98373_R203E_AMP_PATH_GAIN, | ||
609 | MAX98373_FS_GAIN_MAX_SHIFT, 9, 0, max98373_spkgain_max_tlv), | ||
610 | SOC_ENUM("Output Voltage", max98373_out_volt_enum), | ||
611 | /* Dynamic Headroom Tracking */ | ||
612 | SOC_SINGLE("DHT Switch", MAX98373_R20D4_DHT_EN, | ||
613 | MAX98373_DHT_EN_SHIFT, 1, 0), | ||
614 | SOC_SINGLE_TLV("DHT Min Volume", MAX98373_R20D1_DHT_CFG, | ||
615 | MAX98373_DHT_SPK_GAIN_MIN_SHIFT, 9, 0, max98373_dht_spkgain_min_tlv), | ||
616 | SOC_SINGLE_TLV("DHT Rot Pnt Volume", MAX98373_R20D1_DHT_CFG, | ||
617 | MAX98373_DHT_ROT_PNT_SHIFT, 15, 0, max98373_dht_rotation_point_tlv), | ||
618 | SOC_SINGLE_TLV("DHT Attack Step Volume", MAX98373_R20D2_DHT_ATTACK_CFG, | ||
619 | MAX98373_DHT_ATTACK_STEP_SHIFT, 4, 0, max98373_dht_step_size_tlv), | ||
620 | SOC_SINGLE_TLV("DHT Release Step Volume", MAX98373_R20D3_DHT_RELEASE_CFG, | ||
621 | MAX98373_DHT_RELEASE_STEP_SHIFT, 4, 0, max98373_dht_step_size_tlv), | ||
622 | SOC_ENUM("DHT Attack Rate", max98373_dht_attack_rate_enum), | ||
623 | SOC_ENUM("DHT Release Rate", max98373_dht_release_rate_enum), | ||
624 | /* ADC configuration */ | ||
625 | SOC_SINGLE("ADC PVDD CH Switch", MAX98373_R2056_MEAS_ADC_PVDD_CH_EN, 0, 1, 0), | ||
626 | SOC_SINGLE("ADC PVDD FLT Switch", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG, | ||
627 | MAX98373_FLT_EN_SHIFT, 1, 0), | ||
628 | SOC_SINGLE("ADC TEMP FLT Switch", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG, | ||
629 | MAX98373_FLT_EN_SHIFT, 1, 0), | ||
630 | SOC_SINGLE("ADC PVDD", MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK, 0, 0xFF, 0), | ||
631 | SOC_SINGLE("ADC TEMP", MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK, 0, 0xFF, 0), | ||
632 | SOC_SINGLE("ADC PVDD FLT Coeff", MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG, | ||
633 | 0, 0x3, 0), | ||
634 | SOC_SINGLE("ADC TEMP FLT Coeff", MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG, | ||
635 | 0, 0x3, 0), | ||
636 | SOC_ENUM("ADC SampleRate", max98373_adc_samplerate_enum), | ||
637 | /* Brownout Detection Engine */ | ||
638 | SOC_SINGLE("BDE Switch", MAX98373_R20B5_BDE_EN, MAX98373_BDE_EN_SHIFT, 1, 0), | ||
639 | SOC_SINGLE("BDE LVL4 Mute Switch", MAX98373_R20B2_BDE_L4_CFG_2, | ||
640 | MAX98373_LVL4_MUTE_EN_SHIFT, 1, 0), | ||
641 | SOC_SINGLE("BDE LVL4 Hold Switch", MAX98373_R20B2_BDE_L4_CFG_2, | ||
642 | MAX98373_LVL4_HOLD_EN_SHIFT, 1, 0), | ||
643 | SOC_SINGLE("BDE LVL1 Thresh", MAX98373_R2097_BDE_L1_THRESH, 0, 0xFF, 0), | ||
644 | SOC_SINGLE("BDE LVL2 Thresh", MAX98373_R2098_BDE_L2_THRESH, 0, 0xFF, 0), | ||
645 | SOC_SINGLE("BDE LVL3 Thresh", MAX98373_R2099_BDE_L3_THRESH, 0, 0xFF, 0), | ||
646 | SOC_SINGLE("BDE LVL4 Thresh", MAX98373_R209A_BDE_L4_THRESH, 0, 0xFF, 0), | ||
647 | SOC_SINGLE("BDE Active Level", MAX98373_R20B6_BDE_CUR_STATE_READBACK, 0, 8, 0), | ||
648 | SOC_SINGLE("BDE Clip Mode Switch", MAX98373_R2092_BDE_CLIPPER_MODE, 0, 1, 0), | ||
649 | SOC_SINGLE("BDE Thresh Hysteresis", MAX98373_R209B_BDE_THRESH_HYST, 0, 0xFF, 0), | ||
650 | SOC_SINGLE("BDE Hold Time", MAX98373_R2090_BDE_LVL_HOLD, 0, 0xFF, 0), | ||
651 | SOC_SINGLE("BDE Attack Rate", MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 4, 0xF, 0), | ||
652 | SOC_SINGLE("BDE Release Rate", MAX98373_R2091_BDE_GAIN_ATK_REL_RATE, 0, 0xF, 0), | ||
653 | SOC_SINGLE_TLV("BDE LVL1 Clip Thresh Volume", MAX98373_R20A9_BDE_L1_CFG_2, | ||
654 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
655 | SOC_SINGLE_TLV("BDE LVL2 Clip Thresh Volume", MAX98373_R20AC_BDE_L2_CFG_2, | ||
656 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
657 | SOC_SINGLE_TLV("BDE LVL3 Clip Thresh Volume", MAX98373_R20AF_BDE_L3_CFG_2, | ||
658 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
659 | SOC_SINGLE_TLV("BDE LVL4 Clip Thresh Volume", MAX98373_R20B2_BDE_L4_CFG_2, | ||
660 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
661 | SOC_SINGLE_TLV("BDE LVL1 Clip Reduction Volume", MAX98373_R20AA_BDE_L1_CFG_3, | ||
662 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
663 | SOC_SINGLE_TLV("BDE LVL2 Clip Reduction Volume", MAX98373_R20AD_BDE_L2_CFG_3, | ||
664 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
665 | SOC_SINGLE_TLV("BDE LVL3 Clip Reduction Volume", MAX98373_R20B0_BDE_L3_CFG_3, | ||
666 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
667 | SOC_SINGLE_TLV("BDE LVL4 Clip Reduction Volume", MAX98373_R20B3_BDE_L4_CFG_3, | ||
668 | 0, 0x3C, 0, max98373_bde_gain_tlv), | ||
669 | SOC_SINGLE_TLV("BDE LVL1 Limiter Thresh Volume", MAX98373_R20A8_BDE_L1_CFG_1, | ||
670 | 0, 0xF, 0, max98373_limiter_thresh_tlv), | ||
671 | SOC_SINGLE_TLV("BDE LVL2 Limiter Thresh Volume", MAX98373_R20AB_BDE_L2_CFG_1, | ||
672 | 0, 0xF, 0, max98373_limiter_thresh_tlv), | ||
673 | SOC_SINGLE_TLV("BDE LVL3 Limiter Thresh Volume", MAX98373_R20AE_BDE_L3_CFG_1, | ||
674 | 0, 0xF, 0, max98373_limiter_thresh_tlv), | ||
675 | SOC_SINGLE_TLV("BDE LVL4 Limiter Thresh Volume", MAX98373_R20B1_BDE_L4_CFG_1, | ||
676 | 0, 0xF, 0, max98373_limiter_thresh_tlv), | ||
677 | /* Limiter */ | ||
678 | SOC_SINGLE("Limiter Switch", MAX98373_R20E2_LIMITER_EN, | ||
679 | MAX98373_LIMITER_EN_SHIFT, 1, 0), | ||
680 | SOC_SINGLE("Limiter Src Switch", MAX98373_R20E0_LIMITER_THRESH_CFG, | ||
681 | MAX98373_LIMITER_THRESH_SRC_SHIFT, 1, 0), | ||
682 | SOC_SINGLE_TLV("Limiter Thresh Volume", MAX98373_R20E0_LIMITER_THRESH_CFG, | ||
683 | MAX98373_LIMITER_THRESH_SHIFT, 15, 0, max98373_limiter_thresh_tlv), | ||
684 | SOC_ENUM("Limiter Attack Rate", max98373_limiter_attack_rate_enum), | ||
685 | SOC_ENUM("Limiter Release Rate", max98373_limiter_release_rate_enum), | ||
686 | }; | ||
687 | |||
688 | static const struct snd_soc_dapm_route max98373_audio_map[] = { | ||
689 | /* Plabyack */ | ||
690 | {"DAI Sel Mux", "Left", "Amp Enable"}, | ||
691 | {"DAI Sel Mux", "Right", "Amp Enable"}, | ||
692 | {"DAI Sel Mux", "LeftRight", "Amp Enable"}, | ||
693 | {"BE_OUT", NULL, "DAI Sel Mux"}, | ||
694 | /* Capture */ | ||
695 | { "VI Sense", "Switch", "VMON" }, | ||
696 | { "VI Sense", "Switch", "IMON" }, | ||
697 | { "SpkFB Sense", "Switch", "FBMON" }, | ||
698 | { "Voltage Sense", NULL, "VI Sense" }, | ||
699 | { "Current Sense", NULL, "VI Sense" }, | ||
700 | { "Speaker FB Sense", NULL, "SpkFB Sense" }, | ||
701 | }; | ||
702 | |||
703 | static struct snd_soc_dai_driver max98373_dai[] = { | ||
704 | { | ||
705 | .name = "max98373-aif1", | ||
706 | .playback = { | ||
707 | .stream_name = "HiFi Playback", | ||
708 | .channels_min = 1, | ||
709 | .channels_max = 2, | ||
710 | .rates = MAX98373_RATES, | ||
711 | .formats = MAX98373_FORMATS, | ||
712 | }, | ||
713 | .capture = { | ||
714 | .stream_name = "HiFi Capture", | ||
715 | .channels_min = 1, | ||
716 | .channels_max = 2, | ||
717 | .rates = MAX98373_RATES, | ||
718 | .formats = MAX98373_FORMATS, | ||
719 | }, | ||
720 | .ops = &max98373_dai_ops, | ||
721 | } | ||
722 | }; | ||
723 | |||
724 | static int max98373_probe(struct snd_soc_codec *codec) | ||
725 | { | ||
726 | struct max98373_priv *max98373 = snd_soc_codec_get_drvdata(codec); | ||
727 | |||
728 | codec->control_data = max98373->regmap; | ||
729 | |||
730 | /* Software Reset */ | ||
731 | regmap_write(max98373->regmap, | ||
732 | MAX98373_R2000_SW_RESET, MAX98373_SOFT_RESET); | ||
733 | |||
734 | /* IV default slot configuration */ | ||
735 | regmap_write(max98373->regmap, | ||
736 | MAX98373_R2020_PCM_TX_HIZ_EN_1, | ||
737 | 0xFF); | ||
738 | regmap_write(max98373->regmap, | ||
739 | MAX98373_R2021_PCM_TX_HIZ_EN_2, | ||
740 | 0xFF); | ||
741 | /* L/R mix configuration */ | ||
742 | regmap_write(max98373->regmap, | ||
743 | MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1, | ||
744 | 0x80); | ||
745 | regmap_write(max98373->regmap, | ||
746 | MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2, | ||
747 | 0x1); | ||
748 | /* Set inital volume (0dB) */ | ||
749 | regmap_write(max98373->regmap, | ||
750 | MAX98373_R203D_AMP_DIG_VOL_CTRL, | ||
751 | 0x00); | ||
752 | regmap_write(max98373->regmap, | ||
753 | MAX98373_R203E_AMP_PATH_GAIN, | ||
754 | 0x00); | ||
755 | /* Enable DC blocker */ | ||
756 | regmap_write(max98373->regmap, | ||
757 | MAX98373_R203F_AMP_DSP_CFG, | ||
758 | 0x3); | ||
759 | /* Enable IMON VMON DC blocker */ | ||
760 | regmap_write(max98373->regmap, | ||
761 | MAX98373_R2046_IV_SENSE_ADC_DSP_CFG, | ||
762 | 0x7); | ||
763 | /* voltage, current slot configuration */ | ||
764 | regmap_write(max98373->regmap, | ||
765 | MAX98373_R2022_PCM_TX_SRC_1, | ||
766 | (max98373->i_slot << MAX98373_PCM_TX_CH_SRC_A_I_SHIFT | | ||
767 | max98373->v_slot) & 0xFF); | ||
768 | if (max98373->v_slot < 8) | ||
769 | regmap_update_bits(max98373->regmap, | ||
770 | MAX98373_R2020_PCM_TX_HIZ_EN_1, | ||
771 | 1 << max98373->v_slot, 0); | ||
772 | else | ||
773 | regmap_update_bits(max98373->regmap, | ||
774 | MAX98373_R2021_PCM_TX_HIZ_EN_2, | ||
775 | 1 << (max98373->v_slot - 8), 0); | ||
776 | |||
777 | if (max98373->i_slot < 8) | ||
778 | regmap_update_bits(max98373->regmap, | ||
779 | MAX98373_R2020_PCM_TX_HIZ_EN_1, | ||
780 | 1 << max98373->i_slot, 0); | ||
781 | else | ||
782 | regmap_update_bits(max98373->regmap, | ||
783 | MAX98373_R2021_PCM_TX_HIZ_EN_2, | ||
784 | 1 << (max98373->i_slot - 8), 0); | ||
785 | |||
786 | /* speaker feedback slot configuration */ | ||
787 | regmap_write(max98373->regmap, | ||
788 | MAX98373_R2023_PCM_TX_SRC_2, | ||
789 | max98373->spkfb_slot & 0xFF); | ||
790 | |||
791 | /* Set interleave mode */ | ||
792 | if (max98373->interleave_mode) | ||
793 | regmap_update_bits(max98373->regmap, | ||
794 | MAX98373_R2024_PCM_DATA_FMT_CFG, | ||
795 | MAX98373_PCM_TX_CH_INTERLEAVE_MASK, | ||
796 | MAX98373_PCM_TX_CH_INTERLEAVE_MASK); | ||
797 | |||
798 | /* Speaker enable */ | ||
799 | regmap_update_bits(max98373->regmap, | ||
800 | MAX98373_R2043_AMP_EN, | ||
801 | MAX98373_SPK_EN_MASK, 1); | ||
802 | |||
803 | return 0; | ||
804 | } | ||
805 | |||
806 | #ifdef CONFIG_PM_SLEEP | ||
807 | static int max98373_suspend(struct device *dev) | ||
808 | { | ||
809 | struct max98373_priv *max98373 = dev_get_drvdata(dev); | ||
810 | |||
811 | regcache_cache_only(max98373->regmap, true); | ||
812 | regcache_mark_dirty(max98373->regmap); | ||
813 | return 0; | ||
814 | } | ||
815 | static int max98373_resume(struct device *dev) | ||
816 | { | ||
817 | struct max98373_priv *max98373 = dev_get_drvdata(dev); | ||
818 | |||
819 | regmap_write(max98373->regmap, | ||
820 | MAX98373_R2000_SW_RESET, MAX98373_SOFT_RESET); | ||
821 | regcache_cache_only(max98373->regmap, false); | ||
822 | regcache_sync(max98373->regmap); | ||
823 | return 0; | ||
824 | } | ||
825 | #endif | ||
826 | |||
827 | static const struct dev_pm_ops max98373_pm = { | ||
828 | SET_SYSTEM_SLEEP_PM_OPS(max98373_suspend, max98373_resume) | ||
829 | }; | ||
830 | |||
831 | static const struct snd_soc_codec_driver soc_codec_dev_max98373 = { | ||
832 | .probe = max98373_probe, | ||
833 | .component_driver = { | ||
834 | .controls = max98373_snd_controls, | ||
835 | .num_controls = ARRAY_SIZE(max98373_snd_controls), | ||
836 | .dapm_widgets = max98373_dapm_widgets, | ||
837 | .num_dapm_widgets = ARRAY_SIZE(max98373_dapm_widgets), | ||
838 | .dapm_routes = max98373_audio_map, | ||
839 | .num_dapm_routes = ARRAY_SIZE(max98373_audio_map), | ||
840 | }, | ||
841 | }; | ||
842 | |||
843 | static const struct regmap_config max98373_regmap = { | ||
844 | .reg_bits = 16, | ||
845 | .val_bits = 8, | ||
846 | .max_register = MAX98373_R21FF_REV_ID, | ||
847 | .reg_defaults = max98373_reg, | ||
848 | .num_reg_defaults = ARRAY_SIZE(max98373_reg), | ||
849 | .readable_reg = max98373_readable_register, | ||
850 | .volatile_reg = max98373_volatile_reg, | ||
851 | .cache_type = REGCACHE_RBTREE, | ||
852 | }; | ||
853 | |||
854 | static void max98373_slot_config(struct i2c_client *i2c, | ||
855 | struct max98373_priv *max98373) | ||
856 | { | ||
857 | int value; | ||
858 | struct device *dev = &i2c->dev; | ||
859 | |||
860 | if (!device_property_read_u32(dev, "maxim,vmon-slot-no", &value)) | ||
861 | max98373->v_slot = value & 0xF; | ||
862 | else | ||
863 | max98373->v_slot = 0; | ||
864 | |||
865 | if (!device_property_read_u32(dev, "maxim,imon-slot-no", &value)) | ||
866 | max98373->i_slot = value & 0xF; | ||
867 | else | ||
868 | max98373->i_slot = 1; | ||
869 | |||
870 | if (!device_property_read_u32(dev, "maxim,spkfb-slot-no", &value)) | ||
871 | max98373->spkfb_slot = value & 0xF; | ||
872 | else | ||
873 | max98373->spkfb_slot = 2; | ||
874 | } | ||
875 | |||
876 | static int max98373_i2c_probe(struct i2c_client *i2c, | ||
877 | const struct i2c_device_id *id) | ||
878 | { | ||
879 | |||
880 | int ret = 0; | ||
881 | int reg = 0; | ||
882 | struct max98373_priv *max98373 = NULL; | ||
883 | |||
884 | max98373 = devm_kzalloc(&i2c->dev, sizeof(*max98373), GFP_KERNEL); | ||
885 | |||
886 | if (!max98373) { | ||
887 | ret = -ENOMEM; | ||
888 | return ret; | ||
889 | } | ||
890 | i2c_set_clientdata(i2c, max98373); | ||
891 | |||
892 | /* update interleave mode info */ | ||
893 | if (device_property_read_bool(&i2c->dev, "maxim,interleave_mode")) | ||
894 | max98373->interleave_mode = 1; | ||
895 | else | ||
896 | max98373->interleave_mode = 0; | ||
897 | |||
898 | |||
899 | /* regmap initialization */ | ||
900 | max98373->regmap | ||
901 | = devm_regmap_init_i2c(i2c, &max98373_regmap); | ||
902 | if (IS_ERR(max98373->regmap)) { | ||
903 | ret = PTR_ERR(max98373->regmap); | ||
904 | dev_err(&i2c->dev, | ||
905 | "Failed to allocate regmap: %d\n", ret); | ||
906 | return ret; | ||
907 | } | ||
908 | |||
909 | /* Check Revision ID */ | ||
910 | ret = regmap_read(max98373->regmap, | ||
911 | MAX98373_R21FF_REV_ID, ®); | ||
912 | if (ret < 0) { | ||
913 | dev_err(&i2c->dev, | ||
914 | "Failed to read: 0x%02X\n", MAX98373_R21FF_REV_ID); | ||
915 | return ret; | ||
916 | } | ||
917 | dev_info(&i2c->dev, "MAX98373 revisionID: 0x%02X\n", reg); | ||
918 | |||
919 | /* voltage/current slot configuration */ | ||
920 | max98373_slot_config(i2c, max98373); | ||
921 | |||
922 | /* codec registeration */ | ||
923 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98373, | ||
924 | max98373_dai, ARRAY_SIZE(max98373_dai)); | ||
925 | if (ret < 0) | ||
926 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | ||
927 | |||
928 | return ret; | ||
929 | } | ||
930 | |||
931 | static int max98373_i2c_remove(struct i2c_client *client) | ||
932 | { | ||
933 | snd_soc_unregister_codec(&client->dev); | ||
934 | return 0; | ||
935 | } | ||
936 | |||
937 | static const struct i2c_device_id max98373_i2c_id[] = { | ||
938 | { "max98373", 0}, | ||
939 | { }, | ||
940 | }; | ||
941 | |||
942 | MODULE_DEVICE_TABLE(i2c, max98373_i2c_id); | ||
943 | |||
944 | #if defined(CONFIG_OF) | ||
945 | static const struct of_device_id max98373_of_match[] = { | ||
946 | { .compatible = "maxim,max98373", }, | ||
947 | { } | ||
948 | }; | ||
949 | MODULE_DEVICE_TABLE(of, max98373_of_match); | ||
950 | #endif | ||
951 | |||
952 | #ifdef CONFIG_ACPI | ||
953 | static const struct acpi_device_id max98373_acpi_match[] = { | ||
954 | { "MX98373", 0 }, | ||
955 | {}, | ||
956 | }; | ||
957 | MODULE_DEVICE_TABLE(acpi, max98373_acpi_match); | ||
958 | #endif | ||
959 | |||
960 | static struct i2c_driver max98373_i2c_driver = { | ||
961 | .driver = { | ||
962 | .name = "max98373", | ||
963 | .of_match_table = of_match_ptr(max98373_of_match), | ||
964 | .acpi_match_table = ACPI_PTR(max98373_acpi_match), | ||
965 | .pm = &max98373_pm, | ||
966 | }, | ||
967 | .probe = max98373_i2c_probe, | ||
968 | .remove = max98373_i2c_remove, | ||
969 | .id_table = max98373_i2c_id, | ||
970 | }; | ||
971 | |||
972 | module_i2c_driver(max98373_i2c_driver) | ||
973 | |||
974 | MODULE_DESCRIPTION("ALSA SoC MAX98373 driver"); | ||
975 | MODULE_AUTHOR("Ryan Lee <ryans.lee@maximintegrated.com>"); | ||
976 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/max98373.h b/sound/soc/codecs/max98373.h new file mode 100644 index 000000000000..d0b359d0cf8c --- /dev/null +++ b/sound/soc/codecs/max98373.h | |||
@@ -0,0 +1,212 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* Copyright (c) 2017, Maxim Integrated */ | ||
3 | #ifndef _MAX98373_H | ||
4 | #define _MAX98373_H | ||
5 | |||
6 | #define MAX98373_R2000_SW_RESET 0x2000 | ||
7 | #define MAX98373_R2001_INT_RAW1 0x2001 | ||
8 | #define MAX98373_R2002_INT_RAW2 0x2002 | ||
9 | #define MAX98373_R2003_INT_RAW3 0x2003 | ||
10 | #define MAX98373_R2004_INT_STATE1 0x2004 | ||
11 | #define MAX98373_R2005_INT_STATE2 0x2005 | ||
12 | #define MAX98373_R2006_INT_STATE3 0x2006 | ||
13 | #define MAX98373_R2007_INT_FLAG1 0x2007 | ||
14 | #define MAX98373_R2008_INT_FLAG2 0x2008 | ||
15 | #define MAX98373_R2009_INT_FLAG3 0x2009 | ||
16 | #define MAX98373_R200A_INT_EN1 0x200A | ||
17 | #define MAX98373_R200B_INT_EN2 0x200B | ||
18 | #define MAX98373_R200C_INT_EN3 0x200C | ||
19 | #define MAX98373_R200D_INT_FLAG_CLR1 0x200D | ||
20 | #define MAX98373_R200E_INT_FLAG_CLR2 0x200E | ||
21 | #define MAX98373_R200F_INT_FLAG_CLR3 0x200F | ||
22 | #define MAX98373_R2010_IRQ_CTRL 0x2010 | ||
23 | #define MAX98373_R2014_THERM_WARN_THRESH 0x2014 | ||
24 | #define MAX98373_R2015_THERM_SHDN_THRESH 0x2015 | ||
25 | #define MAX98373_R2016_THERM_HYSTERESIS 0x2016 | ||
26 | #define MAX98373_R2017_THERM_FOLDBACK_SET 0x2017 | ||
27 | #define MAX98373_R2018_THERM_FOLDBACK_EN 0x2018 | ||
28 | #define MAX98373_R201E_PIN_DRIVE_STRENGTH 0x201E | ||
29 | #define MAX98373_R2020_PCM_TX_HIZ_EN_1 0x2020 | ||
30 | #define MAX98373_R2021_PCM_TX_HIZ_EN_2 0x2021 | ||
31 | #define MAX98373_R2022_PCM_TX_SRC_1 0x2022 | ||
32 | #define MAX98373_R2023_PCM_TX_SRC_2 0x2023 | ||
33 | #define MAX98373_R2024_PCM_DATA_FMT_CFG 0x2024 | ||
34 | #define MAX98373_R2025_AUDIO_IF_MODE 0x2025 | ||
35 | #define MAX98373_R2026_PCM_CLOCK_RATIO 0x2026 | ||
36 | #define MAX98373_R2027_PCM_SR_SETUP_1 0x2027 | ||
37 | #define MAX98373_R2028_PCM_SR_SETUP_2 0x2028 | ||
38 | #define MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1 0x2029 | ||
39 | #define MAX98373_R202A_PCM_TO_SPK_MONO_MIX_2 0x202A | ||
40 | #define MAX98373_R202B_PCM_RX_EN 0x202B | ||
41 | #define MAX98373_R202C_PCM_TX_EN 0x202C | ||
42 | #define MAX98373_R202E_ICC_RX_CH_EN_1 0x202E | ||
43 | #define MAX98373_R202F_ICC_RX_CH_EN_2 0x202F | ||
44 | #define MAX98373_R2030_ICC_TX_HIZ_EN_1 0x2030 | ||
45 | #define MAX98373_R2031_ICC_TX_HIZ_EN_2 0x2031 | ||
46 | #define MAX98373_R2032_ICC_LINK_EN_CFG 0x2032 | ||
47 | #define MAX98373_R2034_ICC_TX_CNTL 0x2034 | ||
48 | #define MAX98373_R2035_ICC_TX_EN 0x2035 | ||
49 | #define MAX98373_R2036_SOUNDWIRE_CTRL 0x2036 | ||
50 | #define MAX98373_R203D_AMP_DIG_VOL_CTRL 0x203D | ||
51 | #define MAX98373_R203E_AMP_PATH_GAIN 0x203E | ||
52 | #define MAX98373_R203F_AMP_DSP_CFG 0x203F | ||
53 | #define MAX98373_R2040_TONE_GEN_CFG 0x2040 | ||
54 | #define MAX98373_R2041_AMP_CFG 0x2041 | ||
55 | #define MAX98373_R2042_AMP_EDGE_RATE_CFG 0x2042 | ||
56 | #define MAX98373_R2043_AMP_EN 0x2043 | ||
57 | #define MAX98373_R2046_IV_SENSE_ADC_DSP_CFG 0x2046 | ||
58 | #define MAX98373_R2047_IV_SENSE_ADC_EN 0x2047 | ||
59 | #define MAX98373_R2051_MEAS_ADC_SAMPLING_RATE 0x2051 | ||
60 | #define MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG 0x2052 | ||
61 | #define MAX98373_R2053_MEAS_ADC_THERM_FLT_CFG 0x2053 | ||
62 | #define MAX98373_R2054_MEAS_ADC_PVDD_CH_READBACK 0x2054 | ||
63 | #define MAX98373_R2055_MEAS_ADC_THERM_CH_READBACK 0x2055 | ||
64 | #define MAX98373_R2056_MEAS_ADC_PVDD_CH_EN 0x2056 | ||
65 | #define MAX98373_R2090_BDE_LVL_HOLD 0x2090 | ||
66 | #define MAX98373_R2091_BDE_GAIN_ATK_REL_RATE 0x2091 | ||
67 | #define MAX98373_R2092_BDE_CLIPPER_MODE 0x2092 | ||
68 | #define MAX98373_R2097_BDE_L1_THRESH 0x2097 | ||
69 | #define MAX98373_R2098_BDE_L2_THRESH 0x2098 | ||
70 | #define MAX98373_R2099_BDE_L3_THRESH 0x2099 | ||
71 | #define MAX98373_R209A_BDE_L4_THRESH 0x209A | ||
72 | #define MAX98373_R209B_BDE_THRESH_HYST 0x209B | ||
73 | #define MAX98373_R20A8_BDE_L1_CFG_1 0x20A8 | ||
74 | #define MAX98373_R20A9_BDE_L1_CFG_2 0x20A9 | ||
75 | #define MAX98373_R20AA_BDE_L1_CFG_3 0x20AA | ||
76 | #define MAX98373_R20AB_BDE_L2_CFG_1 0x20AB | ||
77 | #define MAX98373_R20AC_BDE_L2_CFG_2 0x20AC | ||
78 | #define MAX98373_R20AD_BDE_L2_CFG_3 0x20AD | ||
79 | #define MAX98373_R20AE_BDE_L3_CFG_1 0x20AE | ||
80 | #define MAX98373_R20AF_BDE_L3_CFG_2 0x20AF | ||
81 | #define MAX98373_R20B0_BDE_L3_CFG_3 0x20B0 | ||
82 | #define MAX98373_R20B1_BDE_L4_CFG_1 0x20B1 | ||
83 | #define MAX98373_R20B2_BDE_L4_CFG_2 0x20B2 | ||
84 | #define MAX98373_R20B3_BDE_L4_CFG_3 0x20B3 | ||
85 | #define MAX98373_R20B4_BDE_INFINITE_HOLD_RELEASE 0x20B4 | ||
86 | #define MAX98373_R20B5_BDE_EN 0x20B5 | ||
87 | #define MAX98373_R20B6_BDE_CUR_STATE_READBACK 0x20B6 | ||
88 | #define MAX98373_R20D1_DHT_CFG 0x20D1 | ||
89 | #define MAX98373_R20D2_DHT_ATTACK_CFG 0x20D2 | ||
90 | #define MAX98373_R20D3_DHT_RELEASE_CFG 0x20D3 | ||
91 | #define MAX98373_R20D4_DHT_EN 0x20D4 | ||
92 | #define MAX98373_R20E0_LIMITER_THRESH_CFG 0x20E0 | ||
93 | #define MAX98373_R20E1_LIMITER_ATK_REL_RATES 0x20E1 | ||
94 | #define MAX98373_R20E2_LIMITER_EN 0x20E2 | ||
95 | #define MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG 0x20FE | ||
96 | #define MAX98373_R20FF_GLOBAL_SHDN 0x20FF | ||
97 | #define MAX98373_R21FF_REV_ID 0x21FF | ||
98 | |||
99 | /* MAX98373_R2022_PCM_TX_SRC_1 */ | ||
100 | #define MAX98373_PCM_TX_CH_SRC_A_V_SHIFT (0) | ||
101 | #define MAX98373_PCM_TX_CH_SRC_A_I_SHIFT (4) | ||
102 | |||
103 | /* MAX98373_R2024_PCM_DATA_FMT_CFG */ | ||
104 | #define MAX98373_PCM_MODE_CFG_FORMAT_MASK (0x7 << 3) | ||
105 | #define MAX98373_PCM_MODE_CFG_FORMAT_SHIFT (3) | ||
106 | #define MAX98373_PCM_TX_CH_INTERLEAVE_MASK (0x1 << 2) | ||
107 | #define MAX98373_PCM_FORMAT_I2S (0x0 << 0) | ||
108 | #define MAX98373_PCM_FORMAT_LJ (0x1 << 0) | ||
109 | #define MAX98373_PCM_FORMAT_TDM_MODE0 (0x3 << 0) | ||
110 | #define MAX98373_PCM_FORMAT_TDM_MODE1 (0x4 << 0) | ||
111 | #define MAX98373_PCM_FORMAT_TDM_MODE2 (0x5 << 0) | ||
112 | #define MAX98373_PCM_MODE_CFG_CHANSZ_MASK (0x3 << 6) | ||
113 | #define MAX98373_PCM_MODE_CFG_CHANSZ_16 (0x1 << 6) | ||
114 | #define MAX98373_PCM_MODE_CFG_CHANSZ_24 (0x2 << 6) | ||
115 | #define MAX98373_PCM_MODE_CFG_CHANSZ_32 (0x3 << 6) | ||
116 | |||
117 | /* MAX98373_R2026_PCM_CLOCK_RATIO */ | ||
118 | #define MAX98373_PCM_MODE_CFG_PCM_BCLKEDGE (0x1 << 4) | ||
119 | #define MAX98373_PCM_CLK_SETUP_BSEL_MASK (0xF << 0) | ||
120 | |||
121 | /* MAX98373_R2027_PCM_SR_SETUP_1 */ | ||
122 | #define MAX98373_PCM_SR_SET1_SR_MASK (0xF << 0) | ||
123 | #define MAX98373_PCM_SR_SET1_SR_8000 (0x0 << 0) | ||
124 | #define MAX98373_PCM_SR_SET1_SR_11025 (0x1 << 0) | ||
125 | #define MAX98373_PCM_SR_SET1_SR_12000 (0x2 << 0) | ||
126 | #define MAX98373_PCM_SR_SET1_SR_16000 (0x3 << 0) | ||
127 | #define MAX98373_PCM_SR_SET1_SR_22050 (0x4 << 0) | ||
128 | #define MAX98373_PCM_SR_SET1_SR_24000 (0x5 << 0) | ||
129 | #define MAX98373_PCM_SR_SET1_SR_32000 (0x6 << 0) | ||
130 | #define MAX98373_PCM_SR_SET1_SR_44100 (0x7 << 0) | ||
131 | #define MAX98373_PCM_SR_SET1_SR_48000 (0x8 << 0) | ||
132 | |||
133 | /* MAX98373_R2028_PCM_SR_SETUP_2 */ | ||
134 | #define MAX98373_PCM_SR_SET2_SR_MASK (0xF << 4) | ||
135 | #define MAX98373_PCM_SR_SET2_SR_SHIFT (4) | ||
136 | #define MAX98373_PCM_SR_SET2_IVADC_SR_MASK (0xF << 0) | ||
137 | |||
138 | /* MAX98373_R2029_PCM_TO_SPK_MONO_MIX_1 */ | ||
139 | #define MAX98373_PCM_TO_SPK_MONOMIX_CFG_MASK (0x3 << 6) | ||
140 | #define MAX98373_PCM_TO_SPK_MONOMIX_CFG_SHIFT (6) | ||
141 | #define MAX98373_PCM_TO_SPK_CH0_SRC_MASK (0xF << 0) | ||
142 | |||
143 | /* MAX98373_R203E_AMP_PATH_GAIN */ | ||
144 | #define MAX98373_SPK_DIGI_GAIN_MASK (0xF << 4) | ||
145 | #define MAX98373_SPK_DIGI_GAIN_SHIFT (4) | ||
146 | #define MAX98373_FS_GAIN_MAX_MASK (0xF << 0) | ||
147 | #define MAX98373_FS_GAIN_MAX_SHIFT (0) | ||
148 | |||
149 | /* MAX98373_R203F_AMP_DSP_CFG */ | ||
150 | #define MAX98373_AMP_DSP_CFG_DCBLK_SHIFT (0) | ||
151 | #define MAX98373_AMP_DSP_CFG_DITH_SHIFT (1) | ||
152 | #define MAX98373_AMP_DSP_CFG_RMP_UP_SHIFT (2) | ||
153 | #define MAX98373_AMP_DSP_CFG_RMP_DN_SHIFT (3) | ||
154 | #define MAX98373_AMP_DSP_CFG_DAC_INV_SHIFT (5) | ||
155 | #define MAX98373_AMP_VOL_SEL_SHIFT (7) | ||
156 | |||
157 | /* MAX98373_R2043_AMP_EN */ | ||
158 | #define MAX98373_SPKFB_EN_MASK (0x1 << 1) | ||
159 | #define MAX98373_SPK_EN_MASK (0x1 << 0) | ||
160 | #define MAX98373_SPKFB_EN_SHIFT (1) | ||
161 | |||
162 | /*MAX98373_R2052_MEAS_ADC_PVDD_FLT_CFG */ | ||
163 | #define MAX98373_FLT_EN_SHIFT (4) | ||
164 | |||
165 | /* MAX98373_R20B2_BDE_L4_CFG_2 */ | ||
166 | #define MAX98373_LVL4_MUTE_EN_SHIFT (7) | ||
167 | #define MAX98373_LVL4_HOLD_EN_SHIFT (6) | ||
168 | |||
169 | /* MAX98373_R20B5_BDE_EN */ | ||
170 | #define MAX98373_BDE_EN_SHIFT (0) | ||
171 | |||
172 | /* MAX98373_R20D1_DHT_CFG */ | ||
173 | #define MAX98373_DHT_SPK_GAIN_MIN_SHIFT (4) | ||
174 | #define MAX98373_DHT_ROT_PNT_SHIFT (0) | ||
175 | |||
176 | /* MAX98373_R20D2_DHT_ATTACK_CFG */ | ||
177 | #define MAX98373_DHT_ATTACK_STEP_SHIFT (3) | ||
178 | #define MAX98373_DHT_ATTACK_RATE_SHIFT (0) | ||
179 | |||
180 | /* MAX98373_R20D3_DHT_RELEASE_CFG */ | ||
181 | #define MAX98373_DHT_RELEASE_STEP_SHIFT (3) | ||
182 | #define MAX98373_DHT_RELEASE_RATE_SHIFT (0) | ||
183 | |||
184 | /* MAX98373_R20D4_DHT_EN */ | ||
185 | #define MAX98373_DHT_EN_SHIFT (0) | ||
186 | |||
187 | /* MAX98373_R20E0_LIMITER_THRESH_CFG */ | ||
188 | #define MAX98373_LIMITER_THRESH_SHIFT (2) | ||
189 | #define MAX98373_LIMITER_THRESH_SRC_SHIFT (0) | ||
190 | |||
191 | /* MAX98373_R20E2_LIMITER_EN */ | ||
192 | #define MAX98373_LIMITER_EN_SHIFT (0) | ||
193 | |||
194 | /* MAX98373_R20FE_DEVICE_AUTO_RESTART_CFG */ | ||
195 | #define MAX98373_CLOCK_MON_SHIFT (0) | ||
196 | |||
197 | /* MAX98373_R20FF_GLOBAL_SHDN */ | ||
198 | #define MAX98373_GLOBAL_EN_MASK (0x1 << 0) | ||
199 | |||
200 | /* MAX98373_R2000_SW_RESET */ | ||
201 | #define MAX98373_SOFT_RESET (0x1 << 0) | ||
202 | |||
203 | struct max98373_priv { | ||
204 | struct regmap *regmap; | ||
205 | unsigned int v_slot; | ||
206 | unsigned int i_slot; | ||
207 | unsigned int spkfb_slot; | ||
208 | bool interleave_mode; | ||
209 | unsigned int ch_size; | ||
210 | bool tdm_mode; | ||
211 | }; | ||
212 | #endif | ||
diff --git a/sound/soc/codecs/max98926.c b/sound/soc/codecs/max98926.c index 03d07bf4d942..7b1d1b0fa879 100644 --- a/sound/soc/codecs/max98926.c +++ b/sound/soc/codecs/max98926.c | |||
@@ -490,7 +490,7 @@ static int max98926_probe(struct snd_soc_codec *codec) | |||
490 | struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec); | 490 | struct max98926_priv *max98926 = snd_soc_codec_get_drvdata(codec); |
491 | 491 | ||
492 | max98926->codec = codec; | 492 | max98926->codec = codec; |
493 | codec->control_data = max98926->regmap; | 493 | |
494 | /* Hi-Z all the slots */ | 494 | /* Hi-Z all the slots */ |
495 | regmap_write(max98926->regmap, MAX98926_DOUT_HIZ_CFG4, 0xF0); | 495 | regmap_write(max98926->regmap, MAX98926_DOUT_HIZ_CFG4, 0xF0); |
496 | return 0; | 496 | return 0; |
diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c index a1d39353719d..f701fdc81175 100644 --- a/sound/soc/codecs/max98927.c +++ b/sound/soc/codecs/max98927.c | |||
@@ -682,7 +682,6 @@ static int max98927_probe(struct snd_soc_codec *codec) | |||
682 | struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); | 682 | struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec); |
683 | 683 | ||
684 | max98927->codec = codec; | 684 | max98927->codec = codec; |
685 | codec->control_data = max98927->regmap; | ||
686 | 685 | ||
687 | /* Software Reset */ | 686 | /* Software Reset */ |
688 | regmap_write(max98927->regmap, | 687 | regmap_write(max98927->regmap, |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 4fd8d1dc4eef..be7a45f05bbf 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -610,6 +610,9 @@ static int mc13783_probe(struct snd_soc_codec *codec) | |||
610 | { | 610 | { |
611 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); | 611 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); |
612 | 612 | ||
613 | snd_soc_codec_init_regmap(codec, | ||
614 | dev_get_regmap(codec->dev->parent, NULL)); | ||
615 | |||
613 | /* these are the reset values */ | 616 | /* these are the reset values */ |
614 | mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); | 617 | mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); |
615 | mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A); | 618 | mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX1, 0x00d35A); |
@@ -728,15 +731,9 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { | |||
728 | } | 731 | } |
729 | }; | 732 | }; |
730 | 733 | ||
731 | static struct regmap *mc13783_get_regmap(struct device *dev) | ||
732 | { | ||
733 | return dev_get_regmap(dev->parent, NULL); | ||
734 | } | ||
735 | |||
736 | static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = { | 734 | static const struct snd_soc_codec_driver soc_codec_dev_mc13783 = { |
737 | .probe = mc13783_probe, | 735 | .probe = mc13783_probe, |
738 | .remove = mc13783_remove, | 736 | .remove = mc13783_remove, |
739 | .get_regmap = mc13783_get_regmap, | ||
740 | .component_driver = { | 737 | .component_driver = { |
741 | .controls = mc13783_control_list, | 738 | .controls = mc13783_control_list, |
742 | .num_controls = ARRAY_SIZE(mc13783_control_list), | 739 | .num_controls = ARRAY_SIZE(mc13783_control_list), |
diff --git a/sound/soc/codecs/msm8916-wcd-analog.c b/sound/soc/codecs/msm8916-wcd-analog.c index 066ea2f4ce7b..44062bb7bf2f 100644 --- a/sound/soc/codecs/msm8916-wcd-analog.c +++ b/sound/soc/codecs/msm8916-wcd-analog.c | |||
@@ -712,6 +712,8 @@ static int pm8916_wcd_analog_probe(struct snd_soc_codec *codec) | |||
712 | return err; | 712 | return err; |
713 | } | 713 | } |
714 | 714 | ||
715 | snd_soc_codec_init_regmap(codec, | ||
716 | dev_get_regmap(codec->dev->parent, NULL)); | ||
715 | snd_soc_codec_set_drvdata(codec, priv); | 717 | snd_soc_codec_set_drvdata(codec, priv); |
716 | priv->pmic_rev = snd_soc_read(codec, CDC_D_REVISION1); | 718 | priv->pmic_rev = snd_soc_read(codec, CDC_D_REVISION1); |
717 | priv->codec_version = snd_soc_read(codec, CDC_D_PERPH_SUBTYPE); | 719 | priv->codec_version = snd_soc_read(codec, CDC_D_PERPH_SUBTYPE); |
@@ -943,11 +945,6 @@ static int pm8916_wcd_analog_set_jack(struct snd_soc_codec *codec, | |||
943 | return 0; | 945 | return 0; |
944 | } | 946 | } |
945 | 947 | ||
946 | static struct regmap *pm8916_get_regmap(struct device *dev) | ||
947 | { | ||
948 | return dev_get_regmap(dev->parent, NULL); | ||
949 | } | ||
950 | |||
951 | static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg) | 948 | static irqreturn_t mbhc_btn_release_irq_handler(int irq, void *arg) |
952 | { | 949 | { |
953 | struct pm8916_wcd_analog_priv *priv = arg; | 950 | struct pm8916_wcd_analog_priv *priv = arg; |
@@ -1082,7 +1079,6 @@ static const struct snd_soc_codec_driver pm8916_wcd_analog = { | |||
1082 | .probe = pm8916_wcd_analog_probe, | 1079 | .probe = pm8916_wcd_analog_probe, |
1083 | .remove = pm8916_wcd_analog_remove, | 1080 | .remove = pm8916_wcd_analog_remove, |
1084 | .set_jack = pm8916_wcd_analog_set_jack, | 1081 | .set_jack = pm8916_wcd_analog_set_jack, |
1085 | .get_regmap = pm8916_get_regmap, | ||
1086 | .component_driver = { | 1082 | .component_driver = { |
1087 | .controls = pm8916_wcd_analog_snd_controls, | 1083 | .controls = pm8916_wcd_analog_snd_controls, |
1088 | .num_controls = ARRAY_SIZE(pm8916_wcd_analog_snd_controls), | 1084 | .num_controls = ARRAY_SIZE(pm8916_wcd_analog_snd_controls), |
diff --git a/sound/soc/codecs/nau8540.c b/sound/soc/codecs/nau8540.c index f9c9933acffb..b08fb7e243c3 100644 --- a/sound/soc/codecs/nau8540.c +++ b/sound/soc/codecs/nau8540.c | |||
@@ -233,6 +233,41 @@ static SOC_ENUM_SINGLE_DECL( | |||
233 | static const struct snd_kcontrol_new digital_ch1_mux = | 233 | static const struct snd_kcontrol_new digital_ch1_mux = |
234 | SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum); | 234 | SOC_DAPM_ENUM("Digital CH1 Select", digital_ch1_enum); |
235 | 235 | ||
236 | static int adc_power_control(struct snd_soc_dapm_widget *w, | ||
237 | struct snd_kcontrol *k, int event) | ||
238 | { | ||
239 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
240 | struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); | ||
241 | |||
242 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
243 | msleep(300); | ||
244 | /* DO12 and DO34 pad output enable */ | ||
245 | regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, | ||
246 | NAU8540_I2S_DO12_TRI, 0); | ||
247 | regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, | ||
248 | NAU8540_I2S_DO34_TRI, 0); | ||
249 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
250 | regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL1, | ||
251 | NAU8540_I2S_DO12_TRI, NAU8540_I2S_DO12_TRI); | ||
252 | regmap_update_bits(nau8540->regmap, NAU8540_REG_PCM_CTRL2, | ||
253 | NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI); | ||
254 | } | ||
255 | return 0; | ||
256 | } | ||
257 | |||
258 | static int aiftx_power_control(struct snd_soc_dapm_widget *w, | ||
259 | struct snd_kcontrol *k, int event) | ||
260 | { | ||
261 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
262 | struct nau8540 *nau8540 = snd_soc_codec_get_drvdata(codec); | ||
263 | |||
264 | if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
265 | regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0001); | ||
266 | regmap_write(nau8540->regmap, NAU8540_REG_RST, 0x0000); | ||
267 | } | ||
268 | return 0; | ||
269 | } | ||
270 | |||
236 | static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { | 271 | static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { |
237 | SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0), | 272 | SND_SOC_DAPM_SUPPLY("MICBIAS2", NAU8540_REG_MIC_BIAS, 11, 0, NULL, 0), |
238 | SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0), | 273 | SND_SOC_DAPM_SUPPLY("MICBIAS1", NAU8540_REG_MIC_BIAS, 10, 0, NULL, 0), |
@@ -247,14 +282,18 @@ static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { | |||
247 | SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0), | 282 | SND_SOC_DAPM_PGA("Frontend PGA3", NAU8540_REG_PWR, 14, 0, NULL, 0), |
248 | SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0), | 283 | SND_SOC_DAPM_PGA("Frontend PGA4", NAU8540_REG_PWR, 15, 0, NULL, 0), |
249 | 284 | ||
250 | SND_SOC_DAPM_ADC("ADC1", NULL, | 285 | SND_SOC_DAPM_ADC_E("ADC1", NULL, |
251 | NAU8540_REG_POWER_MANAGEMENT, 0, 0), | 286 | NAU8540_REG_POWER_MANAGEMENT, 0, 0, adc_power_control, |
252 | SND_SOC_DAPM_ADC("ADC2", NULL, | 287 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
253 | NAU8540_REG_POWER_MANAGEMENT, 1, 0), | 288 | SND_SOC_DAPM_ADC_E("ADC2", NULL, |
254 | SND_SOC_DAPM_ADC("ADC3", NULL, | 289 | NAU8540_REG_POWER_MANAGEMENT, 1, 0, adc_power_control, |
255 | NAU8540_REG_POWER_MANAGEMENT, 2, 0), | 290 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
256 | SND_SOC_DAPM_ADC("ADC4", NULL, | 291 | SND_SOC_DAPM_ADC_E("ADC3", NULL, |
257 | NAU8540_REG_POWER_MANAGEMENT, 3, 0), | 292 | NAU8540_REG_POWER_MANAGEMENT, 2, 0, adc_power_control, |
293 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
294 | SND_SOC_DAPM_ADC_E("ADC4", NULL, | ||
295 | NAU8540_REG_POWER_MANAGEMENT, 3, 0, adc_power_control, | ||
296 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
258 | 297 | ||
259 | SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0), | 298 | SND_SOC_DAPM_PGA("ADC CH1", NAU8540_REG_ANALOG_PWR, 0, 0, NULL, 0), |
260 | SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0), | 299 | SND_SOC_DAPM_PGA("ADC CH2", NAU8540_REG_ANALOG_PWR, 1, 0, NULL, 0), |
@@ -270,7 +309,8 @@ static const struct snd_soc_dapm_widget nau8540_dapm_widgets[] = { | |||
270 | SND_SOC_DAPM_MUX("Digital CH1 Mux", | 309 | SND_SOC_DAPM_MUX("Digital CH1 Mux", |
271 | SND_SOC_NOPM, 0, 0, &digital_ch1_mux), | 310 | SND_SOC_NOPM, 0, 0, &digital_ch1_mux), |
272 | 311 | ||
273 | SND_SOC_DAPM_AIF_OUT("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0), | 312 | SND_SOC_DAPM_AIF_OUT_E("AIFTX", "Capture", 0, SND_SOC_NOPM, 0, 0, |
313 | aiftx_power_control, SND_SOC_DAPM_POST_PMD), | ||
274 | }; | 314 | }; |
275 | 315 | ||
276 | static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { | 316 | static const struct snd_soc_dapm_route nau8540_dapm_routes[] = { |
@@ -575,7 +615,8 @@ static void nau8540_fll_apply(struct regmap *regmap, | |||
575 | NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK, | 615 | NAU8540_CLK_SRC_MASK | NAU8540_CLK_MCLK_SRC_MASK, |
576 | NAU8540_CLK_SRC_MCLK | fll_param->mclk_src); | 616 | NAU8540_CLK_SRC_MCLK | fll_param->mclk_src); |
577 | regmap_update_bits(regmap, NAU8540_REG_FLL1, | 617 | regmap_update_bits(regmap, NAU8540_REG_FLL1, |
578 | NAU8540_FLL_RATIO_MASK, fll_param->ratio); | 618 | NAU8540_FLL_RATIO_MASK | NAU8540_ICTRL_LATCH_MASK, |
619 | fll_param->ratio | (0x6 << NAU8540_ICTRL_LATCH_SFT)); | ||
579 | /* FLL 16-bit fractional input */ | 620 | /* FLL 16-bit fractional input */ |
580 | regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac); | 621 | regmap_write(regmap, NAU8540_REG_FLL2, fll_param->fll_frac); |
581 | /* FLL 10-bit integer input */ | 622 | /* FLL 10-bit integer input */ |
@@ -596,13 +637,14 @@ static void nau8540_fll_apply(struct regmap *regmap, | |||
596 | NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | | 637 | NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | |
597 | NAU8540_FLL_FTR_SW_FILTER); | 638 | NAU8540_FLL_FTR_SW_FILTER); |
598 | regmap_update_bits(regmap, NAU8540_REG_FLL6, | 639 | regmap_update_bits(regmap, NAU8540_REG_FLL6, |
599 | NAU8540_SDM_EN, NAU8540_SDM_EN); | 640 | NAU8540_SDM_EN | NAU8540_CUTOFF500, |
641 | NAU8540_SDM_EN | NAU8540_CUTOFF500); | ||
600 | } else { | 642 | } else { |
601 | regmap_update_bits(regmap, NAU8540_REG_FLL5, | 643 | regmap_update_bits(regmap, NAU8540_REG_FLL5, |
602 | NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | | 644 | NAU8540_FLL_PDB_DAC_EN | NAU8540_FLL_LOOP_FTR_EN | |
603 | NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU); | 645 | NAU8540_FLL_FTR_SW_MASK, NAU8540_FLL_FTR_SW_ACCU); |
604 | regmap_update_bits(regmap, | 646 | regmap_update_bits(regmap, NAU8540_REG_FLL6, |
605 | NAU8540_REG_FLL6, NAU8540_SDM_EN, 0); | 647 | NAU8540_SDM_EN | NAU8540_CUTOFF500, 0); |
606 | } | 648 | } |
607 | } | 649 | } |
608 | 650 | ||
@@ -617,17 +659,22 @@ static int nau8540_set_pll(struct snd_soc_codec *codec, int pll_id, int source, | |||
617 | switch (pll_id) { | 659 | switch (pll_id) { |
618 | case NAU8540_CLK_FLL_MCLK: | 660 | case NAU8540_CLK_FLL_MCLK: |
619 | regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, | 661 | regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, |
620 | NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_MCLK); | 662 | NAU8540_FLL_CLK_SRC_MASK | NAU8540_GAIN_ERR_MASK, |
663 | NAU8540_FLL_CLK_SRC_MCLK | 0); | ||
621 | break; | 664 | break; |
622 | 665 | ||
623 | case NAU8540_CLK_FLL_BLK: | 666 | case NAU8540_CLK_FLL_BLK: |
624 | regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, | 667 | regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, |
625 | NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_BLK); | 668 | NAU8540_FLL_CLK_SRC_MASK | NAU8540_GAIN_ERR_MASK, |
669 | NAU8540_FLL_CLK_SRC_BLK | | ||
670 | (0xf << NAU8540_GAIN_ERR_SFT)); | ||
626 | break; | 671 | break; |
627 | 672 | ||
628 | case NAU8540_CLK_FLL_FS: | 673 | case NAU8540_CLK_FLL_FS: |
629 | regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, | 674 | regmap_update_bits(nau8540->regmap, NAU8540_REG_FLL3, |
630 | NAU8540_FLL_CLK_SRC_MASK, NAU8540_FLL_CLK_SRC_FS); | 675 | NAU8540_FLL_CLK_SRC_MASK | NAU8540_GAIN_ERR_MASK, |
676 | NAU8540_FLL_CLK_SRC_FS | | ||
677 | (0xf << NAU8540_GAIN_ERR_SFT)); | ||
631 | break; | 678 | break; |
632 | 679 | ||
633 | default: | 680 | default: |
@@ -710,9 +757,24 @@ static void nau8540_init_regs(struct nau8540 *nau8540) | |||
710 | regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL, | 757 | regmap_update_bits(regmap, NAU8540_REG_CLOCK_CTRL, |
711 | NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN, | 758 | NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN, |
712 | NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN); | 759 | NAU8540_CLK_ADC_EN | NAU8540_CLK_I2S_EN); |
713 | /* ADC OSR selection, CLK_ADC = Fs * OSR */ | 760 | /* ADC OSR selection, CLK_ADC = Fs * OSR; |
761 | * Channel time alignment enable. | ||
762 | */ | ||
714 | regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE, | 763 | regmap_update_bits(regmap, NAU8540_REG_ADC_SAMPLE_RATE, |
715 | NAU8540_ADC_OSR_MASK, NAU8540_ADC_OSR_64); | 764 | NAU8540_CH_SYNC | NAU8540_ADC_OSR_MASK, |
765 | NAU8540_CH_SYNC | NAU8540_ADC_OSR_64); | ||
766 | /* PGA input mode selection */ | ||
767 | regmap_update_bits(regmap, NAU8540_REG_FEPGA1, | ||
768 | NAU8540_FEPGA1_MODCH2_SHT | NAU8540_FEPGA1_MODCH1_SHT, | ||
769 | NAU8540_FEPGA1_MODCH2_SHT | NAU8540_FEPGA1_MODCH1_SHT); | ||
770 | regmap_update_bits(regmap, NAU8540_REG_FEPGA2, | ||
771 | NAU8540_FEPGA2_MODCH4_SHT | NAU8540_FEPGA2_MODCH3_SHT, | ||
772 | NAU8540_FEPGA2_MODCH4_SHT | NAU8540_FEPGA2_MODCH3_SHT); | ||
773 | /* DO12 and DO34 pad output disable */ | ||
774 | regmap_update_bits(regmap, NAU8540_REG_PCM_CTRL1, | ||
775 | NAU8540_I2S_DO12_TRI, NAU8540_I2S_DO12_TRI); | ||
776 | regmap_update_bits(regmap, NAU8540_REG_PCM_CTRL2, | ||
777 | NAU8540_I2S_DO34_TRI, NAU8540_I2S_DO34_TRI); | ||
716 | } | 778 | } |
717 | 779 | ||
718 | static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec) | 780 | static int __maybe_unused nau8540_suspend(struct snd_soc_codec *codec) |
diff --git a/sound/soc/codecs/nau8540.h b/sound/soc/codecs/nau8540.h index 5db5b224944d..732b490edf81 100644 --- a/sound/soc/codecs/nau8540.h +++ b/sound/soc/codecs/nau8540.h | |||
@@ -100,9 +100,13 @@ | |||
100 | #define NAU8540_CLK_MCLK_SRC_MASK 0xf | 100 | #define NAU8540_CLK_MCLK_SRC_MASK 0xf |
101 | 101 | ||
102 | /* FLL1 (0x04) */ | 102 | /* FLL1 (0x04) */ |
103 | #define NAU8540_ICTRL_LATCH_SFT 10 | ||
104 | #define NAU8540_ICTRL_LATCH_MASK (0x7 << NAU8540_ICTRL_LATCH_SFT) | ||
103 | #define NAU8540_FLL_RATIO_MASK 0x7f | 105 | #define NAU8540_FLL_RATIO_MASK 0x7f |
104 | 106 | ||
105 | /* FLL3 (0x06) */ | 107 | /* FLL3 (0x06) */ |
108 | #define NAU8540_GAIN_ERR_SFT 12 | ||
109 | #define NAU8540_GAIN_ERR_MASK (0xf << NAU8540_GAIN_ERR_SFT) | ||
106 | #define NAU8540_FLL_CLK_SRC_SFT 10 | 110 | #define NAU8540_FLL_CLK_SRC_SFT 10 |
107 | #define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT) | 111 | #define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT) |
108 | #define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT) | 112 | #define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT) |
@@ -127,6 +131,7 @@ | |||
127 | /* FLL6 (0x9) */ | 131 | /* FLL6 (0x9) */ |
128 | #define NAU8540_DCO_EN (0x1 << 15) | 132 | #define NAU8540_DCO_EN (0x1 << 15) |
129 | #define NAU8540_SDM_EN (0x1 << 14) | 133 | #define NAU8540_SDM_EN (0x1 << 14) |
134 | #define NAU8540_CUTOFF500 (0x1 << 13) | ||
130 | 135 | ||
131 | /* PCM_CTRL0 (0x10) */ | 136 | /* PCM_CTRL0 (0x10) */ |
132 | #define NAU8540_I2S_BP_SFT 7 | 137 | #define NAU8540_I2S_BP_SFT 7 |
@@ -146,6 +151,7 @@ | |||
146 | #define NAU8540_I2S_DF_PCM_AB 0x3 | 151 | #define NAU8540_I2S_DF_PCM_AB 0x3 |
147 | 152 | ||
148 | /* PCM_CTRL1 (0x11) */ | 153 | /* PCM_CTRL1 (0x11) */ |
154 | #define NAU8540_I2S_DO12_TRI (0x1 << 15) | ||
149 | #define NAU8540_I2S_LRC_DIV_SFT 12 | 155 | #define NAU8540_I2S_LRC_DIV_SFT 12 |
150 | #define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT) | 156 | #define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT) |
151 | #define NAU8540_I2S_DO12_OE (0x1 << 4) | 157 | #define NAU8540_I2S_DO12_OE (0x1 << 4) |
@@ -156,6 +162,7 @@ | |||
156 | #define NAU8540_I2S_BLK_DIV_MASK 0x7 | 162 | #define NAU8540_I2S_BLK_DIV_MASK 0x7 |
157 | 163 | ||
158 | /* PCM_CTRL1 (0x12) */ | 164 | /* PCM_CTRL1 (0x12) */ |
165 | #define NAU8540_I2S_DO34_TRI (0x1 << 15) | ||
159 | #define NAU8540_I2S_DO34_OE (0x1 << 11) | 166 | #define NAU8540_I2S_DO34_OE (0x1 << 11) |
160 | #define NAU8540_I2S_TSLOT_L_MASK 0x3ff | 167 | #define NAU8540_I2S_TSLOT_L_MASK 0x3ff |
161 | 168 | ||
@@ -165,6 +172,7 @@ | |||
165 | #define NAU8540_TDM_TX_MASK 0xf | 172 | #define NAU8540_TDM_TX_MASK 0xf |
166 | 173 | ||
167 | /* ADC_SAMPLE_RATE (0x3A) */ | 174 | /* ADC_SAMPLE_RATE (0x3A) */ |
175 | #define NAU8540_CH_SYNC (0x1 << 14) | ||
168 | #define NAU8540_ADC_OSR_MASK 0x3 | 176 | #define NAU8540_ADC_OSR_MASK 0x3 |
169 | #define NAU8540_ADC_OSR_256 0x3 | 177 | #define NAU8540_ADC_OSR_256 0x3 |
170 | #define NAU8540_ADC_OSR_128 0x2 | 178 | #define NAU8540_ADC_OSR_128 0x2 |
@@ -183,6 +191,18 @@ | |||
183 | #define NAU8540_PRECHARGE_DIS (0x1 << 13) | 191 | #define NAU8540_PRECHARGE_DIS (0x1 << 13) |
184 | #define NAU8540_GLOBAL_BIAS_EN (0x1 << 12) | 192 | #define NAU8540_GLOBAL_BIAS_EN (0x1 << 12) |
185 | 193 | ||
194 | /* FEPGA1 (0x69) */ | ||
195 | #define NAU8540_FEPGA1_MODCH2_SHT_SFT 7 | ||
196 | #define NAU8540_FEPGA1_MODCH2_SHT (0x1 << NAU8540_FEPGA1_MODCH2_SHT_SFT) | ||
197 | #define NAU8540_FEPGA1_MODCH1_SHT_SFT 3 | ||
198 | #define NAU8540_FEPGA1_MODCH1_SHT (0x1 << NAU8540_FEPGA1_MODCH1_SHT_SFT) | ||
199 | |||
200 | /* FEPGA2 (0x6A) */ | ||
201 | #define NAU8540_FEPGA2_MODCH4_SHT_SFT 7 | ||
202 | #define NAU8540_FEPGA2_MODCH4_SHT (0x1 << NAU8540_FEPGA2_MODCH4_SHT_SFT) | ||
203 | #define NAU8540_FEPGA2_MODCH3_SHT_SFT 3 | ||
204 | #define NAU8540_FEPGA2_MODCH3_SHT (0x1 << NAU8540_FEPGA2_MODCH3_SHT_SFT) | ||
205 | |||
186 | 206 | ||
187 | /* System Clock Source */ | 207 | /* System Clock Source */ |
188 | enum { | 208 | enum { |
diff --git a/sound/soc/codecs/nau8824.c b/sound/soc/codecs/nau8824.c index 0240759f951c..088e0cef4cb8 100644 --- a/sound/soc/codecs/nau8824.c +++ b/sound/soc/codecs/nau8824.c | |||
@@ -43,7 +43,7 @@ static bool nau8824_is_jack_inserted(struct nau8824 *nau8824); | |||
43 | 43 | ||
44 | /* the parameter threshold of FLL */ | 44 | /* the parameter threshold of FLL */ |
45 | #define NAU_FREF_MAX 13500000 | 45 | #define NAU_FREF_MAX 13500000 |
46 | #define NAU_FVCO_MAX 124000000 | 46 | #define NAU_FVCO_MAX 100000000 |
47 | #define NAU_FVCO_MIN 90000000 | 47 | #define NAU_FVCO_MIN 90000000 |
48 | 48 | ||
49 | /* scaling for mclk from sysclk_src output */ | 49 | /* scaling for mclk from sysclk_src output */ |
@@ -811,7 +811,8 @@ static void nau8824_eject_jack(struct nau8824 *nau8824) | |||
811 | NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE); | 811 | NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE); |
812 | 812 | ||
813 | /* Close clock for jack type detection at manual mode */ | 813 | /* Close clock for jack type detection at manual mode */ |
814 | nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0); | 814 | if (dapm->bias_level < SND_SOC_BIAS_PREPARE) |
815 | nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0); | ||
815 | } | 816 | } |
816 | 817 | ||
817 | static void nau8824_jdet_work(struct work_struct *work) | 818 | static void nau8824_jdet_work(struct work_struct *work) |
@@ -843,6 +844,11 @@ static void nau8824_jdet_work(struct work_struct *work) | |||
843 | event_mask |= SND_JACK_HEADSET; | 844 | event_mask |= SND_JACK_HEADSET; |
844 | snd_soc_jack_report(nau8824->jack, event, event_mask); | 845 | snd_soc_jack_report(nau8824->jack, event, event_mask); |
845 | 846 | ||
847 | /* Enable short key press and release interruption. */ | ||
848 | regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING, | ||
849 | NAU8824_IRQ_KEY_RELEASE_DIS | | ||
850 | NAU8824_IRQ_KEY_SHORT_PRESS_DIS, 0); | ||
851 | |||
846 | nau8824_sema_release(nau8824); | 852 | nau8824_sema_release(nau8824); |
847 | } | 853 | } |
848 | 854 | ||
@@ -850,15 +856,15 @@ static void nau8824_setup_auto_irq(struct nau8824 *nau8824) | |||
850 | { | 856 | { |
851 | struct regmap *regmap = nau8824->regmap; | 857 | struct regmap *regmap = nau8824->regmap; |
852 | 858 | ||
853 | /* Enable jack ejection, short key press and release interruption. */ | 859 | /* Enable jack ejection interruption. */ |
854 | regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1, | 860 | regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1, |
855 | NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN, | 861 | NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN, |
856 | NAU8824_IRQ_EJECT_EN); | 862 | NAU8824_IRQ_EJECT_EN); |
857 | regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING, | 863 | regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING, |
858 | NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_KEY_RELEASE_DIS | | 864 | NAU8824_IRQ_EJECT_DIS, 0); |
859 | NAU8824_IRQ_KEY_SHORT_PRESS_DIS, 0); | ||
860 | /* Enable internal VCO needed for interruptions */ | 865 | /* Enable internal VCO needed for interruptions */ |
861 | nau8824_config_sysclk(nau8824, NAU8824_CLK_INTERNAL, 0); | 866 | if (nau8824->dapm->bias_level < SND_SOC_BIAS_PREPARE) |
867 | nau8824_config_sysclk(nau8824, NAU8824_CLK_INTERNAL, 0); | ||
862 | regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL, | 868 | regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL, |
863 | NAU8824_JD_SLEEP_MODE, 0); | 869 | NAU8824_JD_SLEEP_MODE, 0); |
864 | } | 870 | } |
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c index e853a6dfd33b..a1b697b6fb64 100644 --- a/sound/soc/codecs/nau8825.c +++ b/sound/soc/codecs/nau8825.c | |||
@@ -194,10 +194,10 @@ static const struct reg_default nau8825_reg_defaults[] = { | |||
194 | 194 | ||
195 | /* register backup table when cross talk detection */ | 195 | /* register backup table when cross talk detection */ |
196 | static struct reg_default nau8825_xtalk_baktab[] = { | 196 | static struct reg_default nau8825_xtalk_baktab[] = { |
197 | { NAU8825_REG_ADC_DGAIN_CTRL, 0 }, | 197 | { NAU8825_REG_ADC_DGAIN_CTRL, 0x00cf }, |
198 | { NAU8825_REG_HSVOL_CTRL, 0 }, | 198 | { NAU8825_REG_HSVOL_CTRL, 0 }, |
199 | { NAU8825_REG_DACL_CTRL, 0 }, | 199 | { NAU8825_REG_DACL_CTRL, 0x00cf }, |
200 | { NAU8825_REG_DACR_CTRL, 0 }, | 200 | { NAU8825_REG_DACR_CTRL, 0x02cf }, |
201 | }; | 201 | }; |
202 | 202 | ||
203 | static const unsigned short logtable[256] = { | 203 | static const unsigned short logtable[256] = { |
@@ -245,13 +245,14 @@ static const unsigned short logtable[256] = { | |||
245 | * tasks are allowed to acquire the semaphore, calling this function will | 245 | * tasks are allowed to acquire the semaphore, calling this function will |
246 | * put the task to sleep. If the semaphore is not released within the | 246 | * put the task to sleep. If the semaphore is not released within the |
247 | * specified number of jiffies, this function returns. | 247 | * specified number of jiffies, this function returns. |
248 | * Acquires the semaphore without jiffies. If no more tasks are allowed | ||
249 | * to acquire the semaphore, calling this function will put the task to | ||
250 | * sleep until the semaphore is released. | ||
251 | * If the semaphore is not released within the specified number of jiffies, | 248 | * If the semaphore is not released within the specified number of jiffies, |
252 | * this function returns -ETIME. | 249 | * this function returns -ETIME. If the sleep is interrupted by a signal, |
253 | * If the sleep is interrupted by a signal, this function will return -EINTR. | 250 | * this function will return -EINTR. It returns 0 if the semaphore was |
254 | * It returns 0 if the semaphore was acquired successfully. | 251 | * acquired successfully. |
252 | * | ||
253 | * Acquires the semaphore without jiffies. Try to acquire the semaphore | ||
254 | * atomically. Returns 0 if the semaphore has been acquired successfully | ||
255 | * or 1 if it it cannot be acquired. | ||
255 | */ | 256 | */ |
256 | static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) | 257 | static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) |
257 | { | 258 | { |
@@ -262,8 +263,8 @@ static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) | |||
262 | if (ret < 0) | 263 | if (ret < 0) |
263 | dev_warn(nau8825->dev, "Acquire semaphore timeout\n"); | 264 | dev_warn(nau8825->dev, "Acquire semaphore timeout\n"); |
264 | } else { | 265 | } else { |
265 | ret = down_interruptible(&nau8825->xtalk_sem); | 266 | ret = down_trylock(&nau8825->xtalk_sem); |
266 | if (ret < 0) | 267 | if (ret) |
267 | dev_warn(nau8825->dev, "Acquire semaphore fail\n"); | 268 | dev_warn(nau8825->dev, "Acquire semaphore fail\n"); |
268 | } | 269 | } |
269 | 270 | ||
@@ -454,22 +455,32 @@ static void nau8825_xtalk_backup(struct nau8825 *nau8825) | |||
454 | { | 455 | { |
455 | int i; | 456 | int i; |
456 | 457 | ||
458 | if (nau8825->xtalk_baktab_initialized) | ||
459 | return; | ||
460 | |||
457 | /* Backup some register values to backup table */ | 461 | /* Backup some register values to backup table */ |
458 | for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++) | 462 | for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++) |
459 | regmap_read(nau8825->regmap, nau8825_xtalk_baktab[i].reg, | 463 | regmap_read(nau8825->regmap, nau8825_xtalk_baktab[i].reg, |
460 | &nau8825_xtalk_baktab[i].def); | 464 | &nau8825_xtalk_baktab[i].def); |
465 | |||
466 | nau8825->xtalk_baktab_initialized = true; | ||
461 | } | 467 | } |
462 | 468 | ||
463 | static void nau8825_xtalk_restore(struct nau8825 *nau8825) | 469 | static void nau8825_xtalk_restore(struct nau8825 *nau8825, bool cause_cancel) |
464 | { | 470 | { |
465 | int i, volume; | 471 | int i, volume; |
466 | 472 | ||
473 | if (!nau8825->xtalk_baktab_initialized) | ||
474 | return; | ||
475 | |||
467 | /* Restore register values from backup table; When the driver restores | 476 | /* Restore register values from backup table; When the driver restores |
468 | * the headphone volumem, it needs recover to original level gradually | 477 | * the headphone volume in XTALK_DONE state, it needs recover to |
469 | * with 3dB per step for less pop noise. | 478 | * original level gradually with 3dB per step for less pop noise. |
479 | * Otherwise, the restore should do ASAP. | ||
470 | */ | 480 | */ |
471 | for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++) { | 481 | for (i = 0; i < ARRAY_SIZE(nau8825_xtalk_baktab); i++) { |
472 | if (nau8825_xtalk_baktab[i].reg == NAU8825_REG_HSVOL_CTRL) { | 482 | if (!cause_cancel && nau8825_xtalk_baktab[i].reg == |
483 | NAU8825_REG_HSVOL_CTRL) { | ||
473 | /* Ramping up the volume change to reduce pop noise */ | 484 | /* Ramping up the volume change to reduce pop noise */ |
474 | volume = nau8825_xtalk_baktab[i].def & | 485 | volume = nau8825_xtalk_baktab[i].def & |
475 | NAU8825_HPR_VOL_MASK; | 486 | NAU8825_HPR_VOL_MASK; |
@@ -479,6 +490,8 @@ static void nau8825_xtalk_restore(struct nau8825 *nau8825) | |||
479 | regmap_write(nau8825->regmap, nau8825_xtalk_baktab[i].reg, | 490 | regmap_write(nau8825->regmap, nau8825_xtalk_baktab[i].reg, |
480 | nau8825_xtalk_baktab[i].def); | 491 | nau8825_xtalk_baktab[i].def); |
481 | } | 492 | } |
493 | |||
494 | nau8825->xtalk_baktab_initialized = false; | ||
482 | } | 495 | } |
483 | 496 | ||
484 | static void nau8825_xtalk_prepare_dac(struct nau8825 *nau8825) | 497 | static void nau8825_xtalk_prepare_dac(struct nau8825 *nau8825) |
@@ -644,7 +657,7 @@ static void nau8825_xtalk_clean_adc(struct nau8825 *nau8825) | |||
644 | NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_MASK, 0); | 657 | NAU8825_POWERUP_ADCL | NAU8825_ADC_VREFSEL_MASK, 0); |
645 | } | 658 | } |
646 | 659 | ||
647 | static void nau8825_xtalk_clean(struct nau8825 *nau8825) | 660 | static void nau8825_xtalk_clean(struct nau8825 *nau8825, bool cause_cancel) |
648 | { | 661 | { |
649 | /* Enable internal VCO needed for interruptions */ | 662 | /* Enable internal VCO needed for interruptions */ |
650 | nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0); | 663 | nau8825_configure_sysclk(nau8825, NAU8825_CLK_INTERNAL, 0); |
@@ -660,7 +673,7 @@ static void nau8825_xtalk_clean(struct nau8825 *nau8825) | |||
660 | NAU8825_I2S_MS_MASK | NAU8825_I2S_LRC_DIV_MASK | | 673 | NAU8825_I2S_MS_MASK | NAU8825_I2S_LRC_DIV_MASK | |
661 | NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_SLAVE); | 674 | NAU8825_I2S_BLK_DIV_MASK, NAU8825_I2S_MS_SLAVE); |
662 | /* Restore value of specific register for cross talk */ | 675 | /* Restore value of specific register for cross talk */ |
663 | nau8825_xtalk_restore(nau8825); | 676 | nau8825_xtalk_restore(nau8825, cause_cancel); |
664 | } | 677 | } |
665 | 678 | ||
666 | static void nau8825_xtalk_imm_start(struct nau8825 *nau8825, int vol) | 679 | static void nau8825_xtalk_imm_start(struct nau8825 *nau8825, int vol) |
@@ -779,7 +792,7 @@ static void nau8825_xtalk_measure(struct nau8825 *nau8825) | |||
779 | dev_dbg(nau8825->dev, "cross talk sidetone: %x\n", sidetone); | 792 | dev_dbg(nau8825->dev, "cross talk sidetone: %x\n", sidetone); |
780 | regmap_write(nau8825->regmap, NAU8825_REG_DAC_DGAIN_CTRL, | 793 | regmap_write(nau8825->regmap, NAU8825_REG_DAC_DGAIN_CTRL, |
781 | (sidetone << 8) | sidetone); | 794 | (sidetone << 8) | sidetone); |
782 | nau8825_xtalk_clean(nau8825); | 795 | nau8825_xtalk_clean(nau8825, false); |
783 | nau8825->xtalk_state = NAU8825_XTALK_DONE; | 796 | nau8825->xtalk_state = NAU8825_XTALK_DONE; |
784 | break; | 797 | break; |
785 | default: | 798 | default: |
@@ -815,13 +828,14 @@ static void nau8825_xtalk_work(struct work_struct *work) | |||
815 | 828 | ||
816 | static void nau8825_xtalk_cancel(struct nau8825 *nau8825) | 829 | static void nau8825_xtalk_cancel(struct nau8825 *nau8825) |
817 | { | 830 | { |
818 | /* If the xtalk_protect is true, that means the process is still | 831 | /* If the crosstalk is eanbled and the process is on going, |
819 | * on going. The driver forces to cancel the cross talk task and | 832 | * the driver forces to cancel the crosstalk task and |
820 | * restores the configuration to original status. | 833 | * restores the configuration to original status. |
821 | */ | 834 | */ |
822 | if (nau8825->xtalk_protect) { | 835 | if (nau8825->xtalk_enable && nau8825->xtalk_state != |
836 | NAU8825_XTALK_DONE) { | ||
823 | cancel_work_sync(&nau8825->xtalk_work); | 837 | cancel_work_sync(&nau8825->xtalk_work); |
824 | nau8825_xtalk_clean(nau8825); | 838 | nau8825_xtalk_clean(nau8825, true); |
825 | } | 839 | } |
826 | /* Reset parameters for cross talk suppression function */ | 840 | /* Reset parameters for cross talk suppression function */ |
827 | nau8825_sema_reset(nau8825); | 841 | nau8825_sema_reset(nau8825); |
@@ -1246,8 +1260,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, | |||
1246 | regmap_read(nau8825->regmap, NAU8825_REG_DAC_CTRL1, &osr); | 1260 | regmap_read(nau8825->regmap, NAU8825_REG_DAC_CTRL1, &osr); |
1247 | osr &= NAU8825_DAC_OVERSAMPLE_MASK; | 1261 | osr &= NAU8825_DAC_OVERSAMPLE_MASK; |
1248 | if (nau8825_clock_check(nau8825, substream->stream, | 1262 | if (nau8825_clock_check(nau8825, substream->stream, |
1249 | params_rate(params), osr)) | 1263 | params_rate(params), osr)) { |
1264 | nau8825_sema_release(nau8825); | ||
1250 | return -EINVAL; | 1265 | return -EINVAL; |
1266 | } | ||
1251 | regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, | 1267 | regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, |
1252 | NAU8825_CLK_DAC_SRC_MASK, | 1268 | NAU8825_CLK_DAC_SRC_MASK, |
1253 | osr_dac_sel[osr].clk_src << NAU8825_CLK_DAC_SRC_SFT); | 1269 | osr_dac_sel[osr].clk_src << NAU8825_CLK_DAC_SRC_SFT); |
@@ -1255,8 +1271,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, | |||
1255 | regmap_read(nau8825->regmap, NAU8825_REG_ADC_RATE, &osr); | 1271 | regmap_read(nau8825->regmap, NAU8825_REG_ADC_RATE, &osr); |
1256 | osr &= NAU8825_ADC_SYNC_DOWN_MASK; | 1272 | osr &= NAU8825_ADC_SYNC_DOWN_MASK; |
1257 | if (nau8825_clock_check(nau8825, substream->stream, | 1273 | if (nau8825_clock_check(nau8825, substream->stream, |
1258 | params_rate(params), osr)) | 1274 | params_rate(params), osr)) { |
1275 | nau8825_sema_release(nau8825); | ||
1259 | return -EINVAL; | 1276 | return -EINVAL; |
1277 | } | ||
1260 | regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, | 1278 | regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, |
1261 | NAU8825_CLK_ADC_SRC_MASK, | 1279 | NAU8825_CLK_ADC_SRC_MASK, |
1262 | osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT); | 1280 | osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT); |
@@ -1273,8 +1291,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, | |||
1273 | bclk_div = 1; | 1291 | bclk_div = 1; |
1274 | else if (bclk_fs <= 128) | 1292 | else if (bclk_fs <= 128) |
1275 | bclk_div = 0; | 1293 | bclk_div = 0; |
1276 | else | 1294 | else { |
1295 | nau8825_sema_release(nau8825); | ||
1277 | return -EINVAL; | 1296 | return -EINVAL; |
1297 | } | ||
1278 | regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, | 1298 | regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, |
1279 | NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK, | 1299 | NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK, |
1280 | ((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div); | 1300 | ((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div); |
@@ -1294,6 +1314,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream, | |||
1294 | val_len |= NAU8825_I2S_DL_32; | 1314 | val_len |= NAU8825_I2S_DL_32; |
1295 | break; | 1315 | break; |
1296 | default: | 1316 | default: |
1317 | nau8825_sema_release(nau8825); | ||
1297 | return -EINVAL; | 1318 | return -EINVAL; |
1298 | } | 1319 | } |
1299 | 1320 | ||
@@ -1312,8 +1333,6 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
1312 | struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); | 1333 | struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); |
1313 | unsigned int ctrl1_val = 0, ctrl2_val = 0; | 1334 | unsigned int ctrl1_val = 0, ctrl2_val = 0; |
1314 | 1335 | ||
1315 | nau8825_sema_acquire(nau8825, 3 * HZ); | ||
1316 | |||
1317 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 1336 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
1318 | case SND_SOC_DAIFMT_CBM_CFM: | 1337 | case SND_SOC_DAIFMT_CBM_CFM: |
1319 | ctrl2_val |= NAU8825_I2S_MS_MASTER; | 1338 | ctrl2_val |= NAU8825_I2S_MS_MASTER; |
@@ -1355,6 +1374,8 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
1355 | return -EINVAL; | 1374 | return -EINVAL; |
1356 | } | 1375 | } |
1357 | 1376 | ||
1377 | nau8825_sema_acquire(nau8825, 3 * HZ); | ||
1378 | |||
1358 | regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, | 1379 | regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, |
1359 | NAU8825_I2S_DL_MASK | NAU8825_I2S_DF_MASK | | 1380 | NAU8825_I2S_DL_MASK | NAU8825_I2S_DF_MASK | |
1360 | NAU8825_I2S_BP_MASK | NAU8825_I2S_PCMB_MASK, | 1381 | NAU8825_I2S_BP_MASK | NAU8825_I2S_PCMB_MASK, |
@@ -1687,7 +1708,7 @@ static irqreturn_t nau8825_interrupt(int irq, void *data) | |||
1687 | } else if (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) { | 1708 | } else if (active_irq & NAU8825_HEADSET_COMPLETION_IRQ) { |
1688 | if (nau8825_is_jack_inserted(regmap)) { | 1709 | if (nau8825_is_jack_inserted(regmap)) { |
1689 | event |= nau8825_jack_insert(nau8825); | 1710 | event |= nau8825_jack_insert(nau8825); |
1690 | if (!nau8825->xtalk_bypass && !nau8825->high_imped) { | 1711 | if (nau8825->xtalk_enable && !nau8825->high_imped) { |
1691 | /* Apply the cross talk suppression in the | 1712 | /* Apply the cross talk suppression in the |
1692 | * headset without high impedance. | 1713 | * headset without high impedance. |
1693 | */ | 1714 | */ |
@@ -1701,12 +1722,15 @@ static irqreturn_t nau8825_interrupt(int irq, void *data) | |||
1701 | int ret; | 1722 | int ret; |
1702 | nau8825->xtalk_protect = true; | 1723 | nau8825->xtalk_protect = true; |
1703 | ret = nau8825_sema_acquire(nau8825, 0); | 1724 | ret = nau8825_sema_acquire(nau8825, 0); |
1704 | if (ret < 0) | 1725 | if (ret) |
1705 | nau8825->xtalk_protect = false; | 1726 | nau8825->xtalk_protect = false; |
1706 | } | 1727 | } |
1707 | /* Startup cross talk detection process */ | 1728 | /* Startup cross talk detection process */ |
1708 | nau8825->xtalk_state = NAU8825_XTALK_PREPARE; | 1729 | if (nau8825->xtalk_protect) { |
1709 | schedule_work(&nau8825->xtalk_work); | 1730 | nau8825->xtalk_state = |
1731 | NAU8825_XTALK_PREPARE; | ||
1732 | schedule_work(&nau8825->xtalk_work); | ||
1733 | } | ||
1710 | } else { | 1734 | } else { |
1711 | /* The cross talk suppression shouldn't apply | 1735 | /* The cross talk suppression shouldn't apply |
1712 | * in the headset with high impedance. Thus, | 1736 | * in the headset with high impedance. Thus, |
@@ -1733,7 +1757,9 @@ static irqreturn_t nau8825_interrupt(int irq, void *data) | |||
1733 | nau8825->xtalk_event_mask = event_mask; | 1757 | nau8825->xtalk_event_mask = event_mask; |
1734 | } | 1758 | } |
1735 | } else if (active_irq & NAU8825_IMPEDANCE_MEAS_IRQ) { | 1759 | } else if (active_irq & NAU8825_IMPEDANCE_MEAS_IRQ) { |
1736 | schedule_work(&nau8825->xtalk_work); | 1760 | /* crosstalk detection enable and process on going */ |
1761 | if (nau8825->xtalk_enable && nau8825->xtalk_protect) | ||
1762 | schedule_work(&nau8825->xtalk_work); | ||
1737 | clear_irq = NAU8825_IMPEDANCE_MEAS_IRQ; | 1763 | clear_irq = NAU8825_IMPEDANCE_MEAS_IRQ; |
1738 | } else if ((active_irq & NAU8825_JACK_INSERTION_IRQ_MASK) == | 1764 | } else if ((active_irq & NAU8825_JACK_INSERTION_IRQ_MASK) == |
1739 | NAU8825_JACK_INSERTION_DETECTED) { | 1765 | NAU8825_JACK_INSERTION_DETECTED) { |
@@ -2382,7 +2408,7 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec) | |||
2382 | regcache_sync(nau8825->regmap); | 2408 | regcache_sync(nau8825->regmap); |
2383 | nau8825->xtalk_protect = true; | 2409 | nau8825->xtalk_protect = true; |
2384 | ret = nau8825_sema_acquire(nau8825, 0); | 2410 | ret = nau8825_sema_acquire(nau8825, 0); |
2385 | if (ret < 0) | 2411 | if (ret) |
2386 | nau8825->xtalk_protect = false; | 2412 | nau8825->xtalk_protect = false; |
2387 | enable_irq(nau8825->irq); | 2413 | enable_irq(nau8825->irq); |
2388 | 2414 | ||
@@ -2441,8 +2467,8 @@ static void nau8825_print_device_properties(struct nau8825 *nau8825) | |||
2441 | nau8825->jack_insert_debounce); | 2467 | nau8825->jack_insert_debounce); |
2442 | dev_dbg(dev, "jack-eject-debounce: %d\n", | 2468 | dev_dbg(dev, "jack-eject-debounce: %d\n", |
2443 | nau8825->jack_eject_debounce); | 2469 | nau8825->jack_eject_debounce); |
2444 | dev_dbg(dev, "crosstalk-bypass: %d\n", | 2470 | dev_dbg(dev, "crosstalk-enable: %d\n", |
2445 | nau8825->xtalk_bypass); | 2471 | nau8825->xtalk_enable); |
2446 | } | 2472 | } |
2447 | 2473 | ||
2448 | static int nau8825_read_device_properties(struct device *dev, | 2474 | static int nau8825_read_device_properties(struct device *dev, |
@@ -2507,8 +2533,8 @@ static int nau8825_read_device_properties(struct device *dev, | |||
2507 | &nau8825->jack_eject_debounce); | 2533 | &nau8825->jack_eject_debounce); |
2508 | if (ret) | 2534 | if (ret) |
2509 | nau8825->jack_eject_debounce = 0; | 2535 | nau8825->jack_eject_debounce = 0; |
2510 | nau8825->xtalk_bypass = device_property_read_bool(dev, | 2536 | nau8825->xtalk_enable = device_property_read_bool(dev, |
2511 | "nuvoton,crosstalk-bypass"); | 2537 | "nuvoton,crosstalk-enable"); |
2512 | 2538 | ||
2513 | nau8825->mclk = devm_clk_get(dev, "mclk"); | 2539 | nau8825->mclk = devm_clk_get(dev, "mclk"); |
2514 | if (PTR_ERR(nau8825->mclk) == -EPROBE_DEFER) { | 2540 | if (PTR_ERR(nau8825->mclk) == -EPROBE_DEFER) { |
@@ -2569,6 +2595,7 @@ static int nau8825_i2c_probe(struct i2c_client *i2c, | |||
2569 | */ | 2595 | */ |
2570 | nau8825->xtalk_state = NAU8825_XTALK_DONE; | 2596 | nau8825->xtalk_state = NAU8825_XTALK_DONE; |
2571 | nau8825->xtalk_protect = false; | 2597 | nau8825->xtalk_protect = false; |
2598 | nau8825->xtalk_baktab_initialized = false; | ||
2572 | sema_init(&nau8825->xtalk_sem, 1); | 2599 | sema_init(&nau8825->xtalk_sem, 1); |
2573 | INIT_WORK(&nau8825->xtalk_work, nau8825_xtalk_work); | 2600 | INIT_WORK(&nau8825->xtalk_work, nau8825_xtalk_work); |
2574 | 2601 | ||
diff --git a/sound/soc/codecs/nau8825.h b/sound/soc/codecs/nau8825.h index 8aee5c8647ae..f7e732125882 100644 --- a/sound/soc/codecs/nau8825.h +++ b/sound/soc/codecs/nau8825.h | |||
@@ -476,7 +476,8 @@ struct nau8825 { | |||
476 | int xtalk_event_mask; | 476 | int xtalk_event_mask; |
477 | bool xtalk_protect; | 477 | bool xtalk_protect; |
478 | int imp_rms[NAU8825_XTALK_IMM]; | 478 | int imp_rms[NAU8825_XTALK_IMM]; |
479 | int xtalk_bypass; | 479 | int xtalk_enable; |
480 | bool xtalk_baktab_initialized; /* True if initialized. */ | ||
480 | }; | 481 | }; |
481 | 482 | ||
482 | int nau8825_enable_jack_detect(struct snd_soc_codec *codec, | 483 | int nau8825_enable_jack_detect(struct snd_soc_codec *codec, |
diff --git a/sound/soc/codecs/pcm186x-i2c.c b/sound/soc/codecs/pcm186x-i2c.c new file mode 100644 index 000000000000..543621232d60 --- /dev/null +++ b/sound/soc/codecs/pcm186x-i2c.c | |||
@@ -0,0 +1,69 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Texas Instruments PCM186x Universal Audio ADC - I2C | ||
4 | * | ||
5 | * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com | ||
6 | * Andreas Dannenberg <dannenberg@ti.com> | ||
7 | * Andrew F. Davis <afd@ti.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/i2c.h> | ||
13 | |||
14 | #include "pcm186x.h" | ||
15 | |||
16 | static const struct of_device_id pcm186x_of_match[] = { | ||
17 | { .compatible = "ti,pcm1862", .data = (void *)PCM1862 }, | ||
18 | { .compatible = "ti,pcm1863", .data = (void *)PCM1863 }, | ||
19 | { .compatible = "ti,pcm1864", .data = (void *)PCM1864 }, | ||
20 | { .compatible = "ti,pcm1865", .data = (void *)PCM1865 }, | ||
21 | { } | ||
22 | }; | ||
23 | MODULE_DEVICE_TABLE(of, pcm186x_of_match); | ||
24 | |||
25 | static int pcm186x_i2c_probe(struct i2c_client *i2c, | ||
26 | const struct i2c_device_id *id) | ||
27 | { | ||
28 | const enum pcm186x_type type = (enum pcm186x_type)id->driver_data; | ||
29 | int irq = i2c->irq; | ||
30 | struct regmap *regmap; | ||
31 | |||
32 | regmap = devm_regmap_init_i2c(i2c, &pcm186x_regmap); | ||
33 | if (IS_ERR(regmap)) | ||
34 | return PTR_ERR(regmap); | ||
35 | |||
36 | return pcm186x_probe(&i2c->dev, type, irq, regmap); | ||
37 | } | ||
38 | |||
39 | static int pcm186x_i2c_remove(struct i2c_client *i2c) | ||
40 | { | ||
41 | pcm186x_remove(&i2c->dev); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static const struct i2c_device_id pcm186x_i2c_id[] = { | ||
47 | { "pcm1862", PCM1862 }, | ||
48 | { "pcm1863", PCM1863 }, | ||
49 | { "pcm1864", PCM1864 }, | ||
50 | { "pcm1865", PCM1865 }, | ||
51 | { } | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id); | ||
54 | |||
55 | static struct i2c_driver pcm186x_i2c_driver = { | ||
56 | .probe = pcm186x_i2c_probe, | ||
57 | .remove = pcm186x_i2c_remove, | ||
58 | .id_table = pcm186x_i2c_id, | ||
59 | .driver = { | ||
60 | .name = "pcm186x", | ||
61 | .of_match_table = pcm186x_of_match, | ||
62 | }, | ||
63 | }; | ||
64 | module_i2c_driver(pcm186x_i2c_driver); | ||
65 | |||
66 | MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>"); | ||
67 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); | ||
68 | MODULE_DESCRIPTION("PCM186x Universal Audio ADC I2C Interface Driver"); | ||
69 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm186x-spi.c b/sound/soc/codecs/pcm186x-spi.c new file mode 100644 index 000000000000..2366f8e4d4d4 --- /dev/null +++ b/sound/soc/codecs/pcm186x-spi.c | |||
@@ -0,0 +1,69 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Texas Instruments PCM186x Universal Audio ADC - SPI | ||
4 | * | ||
5 | * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com | ||
6 | * Andreas Dannenberg <dannenberg@ti.com> | ||
7 | * Andrew F. Davis <afd@ti.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/spi/spi.h> | ||
13 | |||
14 | #include "pcm186x.h" | ||
15 | |||
16 | static const struct of_device_id pcm186x_of_match[] = { | ||
17 | { .compatible = "ti,pcm1862", .data = (void *)PCM1862 }, | ||
18 | { .compatible = "ti,pcm1863", .data = (void *)PCM1863 }, | ||
19 | { .compatible = "ti,pcm1864", .data = (void *)PCM1864 }, | ||
20 | { .compatible = "ti,pcm1865", .data = (void *)PCM1865 }, | ||
21 | { } | ||
22 | }; | ||
23 | MODULE_DEVICE_TABLE(of, pcm186x_of_match); | ||
24 | |||
25 | static int pcm186x_spi_probe(struct spi_device *spi) | ||
26 | { | ||
27 | const enum pcm186x_type type = | ||
28 | (enum pcm186x_type)spi_get_device_id(spi)->driver_data; | ||
29 | int irq = spi->irq; | ||
30 | struct regmap *regmap; | ||
31 | |||
32 | regmap = devm_regmap_init_spi(spi, &pcm186x_regmap); | ||
33 | if (IS_ERR(regmap)) | ||
34 | return PTR_ERR(regmap); | ||
35 | |||
36 | return pcm186x_probe(&spi->dev, type, irq, regmap); | ||
37 | } | ||
38 | |||
39 | static int pcm186x_spi_remove(struct spi_device *spi) | ||
40 | { | ||
41 | pcm186x_remove(&spi->dev); | ||
42 | |||
43 | return 0; | ||
44 | } | ||
45 | |||
46 | static const struct spi_device_id pcm186x_spi_id[] = { | ||
47 | { "pcm1862", PCM1862 }, | ||
48 | { "pcm1863", PCM1863 }, | ||
49 | { "pcm1864", PCM1864 }, | ||
50 | { "pcm1865", PCM1865 }, | ||
51 | { } | ||
52 | }; | ||
53 | MODULE_DEVICE_TABLE(spi, pcm186x_spi_id); | ||
54 | |||
55 | static struct spi_driver pcm186x_spi_driver = { | ||
56 | .probe = pcm186x_spi_probe, | ||
57 | .remove = pcm186x_spi_remove, | ||
58 | .id_table = pcm186x_spi_id, | ||
59 | .driver = { | ||
60 | .name = "pcm186x", | ||
61 | .of_match_table = pcm186x_of_match, | ||
62 | }, | ||
63 | }; | ||
64 | module_spi_driver(pcm186x_spi_driver); | ||
65 | |||
66 | MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>"); | ||
67 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); | ||
68 | MODULE_DESCRIPTION("PCM186x Universal Audio ADC SPI Interface Driver"); | ||
69 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm186x.c b/sound/soc/codecs/pcm186x.c new file mode 100644 index 000000000000..cdb51427facc --- /dev/null +++ b/sound/soc/codecs/pcm186x.c | |||
@@ -0,0 +1,719 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Texas Instruments PCM186x Universal Audio ADC | ||
4 | * | ||
5 | * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com | ||
6 | * Andreas Dannenberg <dannenberg@ti.com> | ||
7 | * Andrew F. Davis <afd@ti.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/moduleparam.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/pm.h> | ||
15 | #include <linux/pm_runtime.h> | ||
16 | #include <linux/regulator/consumer.h> | ||
17 | #include <linux/regmap.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <sound/core.h> | ||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/pcm_params.h> | ||
22 | #include <sound/soc.h> | ||
23 | #include <sound/jack.h> | ||
24 | #include <sound/initval.h> | ||
25 | #include <sound/tlv.h> | ||
26 | |||
27 | #include "pcm186x.h" | ||
28 | |||
29 | static const char * const pcm186x_supply_names[] = { | ||
30 | "avdd", /* Analog power supply. Connect to 3.3-V supply. */ | ||
31 | "dvdd", /* Digital power supply. Connect to 3.3-V supply. */ | ||
32 | "iovdd", /* I/O power supply. Connect to 3.3-V or 1.8-V. */ | ||
33 | }; | ||
34 | #define PCM186x_NUM_SUPPLIES ARRAY_SIZE(pcm186x_supply_names) | ||
35 | |||
36 | struct pcm186x_priv { | ||
37 | struct regmap *regmap; | ||
38 | struct regulator_bulk_data supplies[PCM186x_NUM_SUPPLIES]; | ||
39 | unsigned int sysclk; | ||
40 | unsigned int tdm_offset; | ||
41 | bool is_tdm_mode; | ||
42 | bool is_master_mode; | ||
43 | }; | ||
44 | |||
45 | static const DECLARE_TLV_DB_SCALE(pcm186x_pga_tlv, -1200, 4000, 50); | ||
46 | |||
47 | static const struct snd_kcontrol_new pcm1863_snd_controls[] = { | ||
48 | SOC_DOUBLE_R_S_TLV("ADC Capture Volume", PCM186X_PGA_VAL_CH1_L, | ||
49 | PCM186X_PGA_VAL_CH1_R, 0, -24, 80, 7, 0, | ||
50 | pcm186x_pga_tlv), | ||
51 | }; | ||
52 | |||
53 | static const struct snd_kcontrol_new pcm1865_snd_controls[] = { | ||
54 | SOC_DOUBLE_R_S_TLV("ADC1 Capture Volume", PCM186X_PGA_VAL_CH1_L, | ||
55 | PCM186X_PGA_VAL_CH1_R, 0, -24, 80, 7, 0, | ||
56 | pcm186x_pga_tlv), | ||
57 | SOC_DOUBLE_R_S_TLV("ADC2 Capture Volume", PCM186X_PGA_VAL_CH2_L, | ||
58 | PCM186X_PGA_VAL_CH2_R, 0, -24, 80, 7, 0, | ||
59 | pcm186x_pga_tlv), | ||
60 | }; | ||
61 | |||
62 | static const unsigned int pcm186x_adc_input_channel_sel_value[] = { | ||
63 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | ||
64 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | ||
65 | 0x10, 0x20, 0x30 | ||
66 | }; | ||
67 | |||
68 | static const char * const pcm186x_adcl_input_channel_sel_text[] = { | ||
69 | "No Select", | ||
70 | "VINL1[SE]", /* Default for ADC1L */ | ||
71 | "VINL2[SE]", /* Default for ADC2L */ | ||
72 | "VINL2[SE] + VINL1[SE]", | ||
73 | "VINL3[SE]", | ||
74 | "VINL3[SE] + VINL1[SE]", | ||
75 | "VINL3[SE] + VINL2[SE]", | ||
76 | "VINL3[SE] + VINL2[SE] + VINL1[SE]", | ||
77 | "VINL4[SE]", | ||
78 | "VINL4[SE] + VINL1[SE]", | ||
79 | "VINL4[SE] + VINL2[SE]", | ||
80 | "VINL4[SE] + VINL2[SE] + VINL1[SE]", | ||
81 | "VINL4[SE] + VINL3[SE]", | ||
82 | "VINL4[SE] + VINL3[SE] + VINL1[SE]", | ||
83 | "VINL4[SE] + VINL3[SE] + VINL2[SE]", | ||
84 | "VINL4[SE] + VINL3[SE] + VINL2[SE] + VINL1[SE]", | ||
85 | "{VIN1P, VIN1M}[DIFF]", | ||
86 | "{VIN4P, VIN4M}[DIFF]", | ||
87 | "{VIN1P, VIN1M}[DIFF] + {VIN4P, VIN4M}[DIFF]" | ||
88 | }; | ||
89 | |||
90 | static const char * const pcm186x_adcr_input_channel_sel_text[] = { | ||
91 | "No Select", | ||
92 | "VINR1[SE]", /* Default for ADC1R */ | ||
93 | "VINR2[SE]", /* Default for ADC2R */ | ||
94 | "VINR2[SE] + VINR1[SE]", | ||
95 | "VINR3[SE]", | ||
96 | "VINR3[SE] + VINR1[SE]", | ||
97 | "VINR3[SE] + VINR2[SE]", | ||
98 | "VINR3[SE] + VINR2[SE] + VINR1[SE]", | ||
99 | "VINR4[SE]", | ||
100 | "VINR4[SE] + VINR1[SE]", | ||
101 | "VINR4[SE] + VINR2[SE]", | ||
102 | "VINR4[SE] + VINR2[SE] + VINR1[SE]", | ||
103 | "VINR4[SE] + VINR3[SE]", | ||
104 | "VINR4[SE] + VINR3[SE] + VINR1[SE]", | ||
105 | "VINR4[SE] + VINR3[SE] + VINR2[SE]", | ||
106 | "VINR4[SE] + VINR3[SE] + VINR2[SE] + VINR1[SE]", | ||
107 | "{VIN2P, VIN2M}[DIFF]", | ||
108 | "{VIN3P, VIN3M}[DIFF]", | ||
109 | "{VIN2P, VIN2M}[DIFF] + {VIN3P, VIN3M}[DIFF]" | ||
110 | }; | ||
111 | |||
112 | static const struct soc_enum pcm186x_adc_input_channel_sel[] = { | ||
113 | SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_L, 0, | ||
114 | PCM186X_ADC_INPUT_SEL_MASK, | ||
115 | ARRAY_SIZE(pcm186x_adcl_input_channel_sel_text), | ||
116 | pcm186x_adcl_input_channel_sel_text, | ||
117 | pcm186x_adc_input_channel_sel_value), | ||
118 | SOC_VALUE_ENUM_SINGLE(PCM186X_ADC1_INPUT_SEL_R, 0, | ||
119 | PCM186X_ADC_INPUT_SEL_MASK, | ||
120 | ARRAY_SIZE(pcm186x_adcr_input_channel_sel_text), | ||
121 | pcm186x_adcr_input_channel_sel_text, | ||
122 | pcm186x_adc_input_channel_sel_value), | ||
123 | SOC_VALUE_ENUM_SINGLE(PCM186X_ADC2_INPUT_SEL_L, 0, | ||
124 | PCM186X_ADC_INPUT_SEL_MASK, | ||
125 | ARRAY_SIZE(pcm186x_adcl_input_channel_sel_text), | ||
126 | pcm186x_adcl_input_channel_sel_text, | ||
127 | pcm186x_adc_input_channel_sel_value), | ||
128 | SOC_VALUE_ENUM_SINGLE(PCM186X_ADC2_INPUT_SEL_R, 0, | ||
129 | PCM186X_ADC_INPUT_SEL_MASK, | ||
130 | ARRAY_SIZE(pcm186x_adcr_input_channel_sel_text), | ||
131 | pcm186x_adcr_input_channel_sel_text, | ||
132 | pcm186x_adc_input_channel_sel_value), | ||
133 | }; | ||
134 | |||
135 | static const struct snd_kcontrol_new pcm186x_adc_mux_controls[] = { | ||
136 | SOC_DAPM_ENUM("ADC1 Left Input", pcm186x_adc_input_channel_sel[0]), | ||
137 | SOC_DAPM_ENUM("ADC1 Right Input", pcm186x_adc_input_channel_sel[1]), | ||
138 | SOC_DAPM_ENUM("ADC2 Left Input", pcm186x_adc_input_channel_sel[2]), | ||
139 | SOC_DAPM_ENUM("ADC2 Right Input", pcm186x_adc_input_channel_sel[3]), | ||
140 | }; | ||
141 | |||
142 | static const struct snd_soc_dapm_widget pcm1863_dapm_widgets[] = { | ||
143 | SND_SOC_DAPM_INPUT("VINL1"), | ||
144 | SND_SOC_DAPM_INPUT("VINR1"), | ||
145 | SND_SOC_DAPM_INPUT("VINL2"), | ||
146 | SND_SOC_DAPM_INPUT("VINR2"), | ||
147 | SND_SOC_DAPM_INPUT("VINL3"), | ||
148 | SND_SOC_DAPM_INPUT("VINR3"), | ||
149 | SND_SOC_DAPM_INPUT("VINL4"), | ||
150 | SND_SOC_DAPM_INPUT("VINR4"), | ||
151 | |||
152 | SND_SOC_DAPM_MUX("ADC Left Capture Source", SND_SOC_NOPM, 0, 0, | ||
153 | &pcm186x_adc_mux_controls[0]), | ||
154 | SND_SOC_DAPM_MUX("ADC Right Capture Source", SND_SOC_NOPM, 0, 0, | ||
155 | &pcm186x_adc_mux_controls[1]), | ||
156 | |||
157 | /* | ||
158 | * Put the codec into SLEEP mode when not in use, allowing the | ||
159 | * Energysense mechanism to operate. | ||
160 | */ | ||
161 | SND_SOC_DAPM_ADC("ADC", "HiFi Capture", PCM186X_POWER_CTRL, 1, 0), | ||
162 | }; | ||
163 | |||
164 | static const struct snd_soc_dapm_widget pcm1865_dapm_widgets[] = { | ||
165 | SND_SOC_DAPM_INPUT("VINL1"), | ||
166 | SND_SOC_DAPM_INPUT("VINR1"), | ||
167 | SND_SOC_DAPM_INPUT("VINL2"), | ||
168 | SND_SOC_DAPM_INPUT("VINR2"), | ||
169 | SND_SOC_DAPM_INPUT("VINL3"), | ||
170 | SND_SOC_DAPM_INPUT("VINR3"), | ||
171 | SND_SOC_DAPM_INPUT("VINL4"), | ||
172 | SND_SOC_DAPM_INPUT("VINR4"), | ||
173 | |||
174 | SND_SOC_DAPM_MUX("ADC1 Left Capture Source", SND_SOC_NOPM, 0, 0, | ||
175 | &pcm186x_adc_mux_controls[0]), | ||
176 | SND_SOC_DAPM_MUX("ADC1 Right Capture Source", SND_SOC_NOPM, 0, 0, | ||
177 | &pcm186x_adc_mux_controls[1]), | ||
178 | SND_SOC_DAPM_MUX("ADC2 Left Capture Source", SND_SOC_NOPM, 0, 0, | ||
179 | &pcm186x_adc_mux_controls[2]), | ||
180 | SND_SOC_DAPM_MUX("ADC2 Right Capture Source", SND_SOC_NOPM, 0, 0, | ||
181 | &pcm186x_adc_mux_controls[3]), | ||
182 | |||
183 | /* | ||
184 | * Put the codec into SLEEP mode when not in use, allowing the | ||
185 | * Energysense mechanism to operate. | ||
186 | */ | ||
187 | SND_SOC_DAPM_ADC("ADC1", "HiFi Capture 1", PCM186X_POWER_CTRL, 1, 0), | ||
188 | SND_SOC_DAPM_ADC("ADC2", "HiFi Capture 2", PCM186X_POWER_CTRL, 1, 0), | ||
189 | }; | ||
190 | |||
191 | static const struct snd_soc_dapm_route pcm1863_dapm_routes[] = { | ||
192 | { "ADC Left Capture Source", NULL, "VINL1" }, | ||
193 | { "ADC Left Capture Source", NULL, "VINR1" }, | ||
194 | { "ADC Left Capture Source", NULL, "VINL2" }, | ||
195 | { "ADC Left Capture Source", NULL, "VINR2" }, | ||
196 | { "ADC Left Capture Source", NULL, "VINL3" }, | ||
197 | { "ADC Left Capture Source", NULL, "VINR3" }, | ||
198 | { "ADC Left Capture Source", NULL, "VINL4" }, | ||
199 | { "ADC Left Capture Source", NULL, "VINR4" }, | ||
200 | |||
201 | { "ADC", NULL, "ADC Left Capture Source" }, | ||
202 | |||
203 | { "ADC Right Capture Source", NULL, "VINL1" }, | ||
204 | { "ADC Right Capture Source", NULL, "VINR1" }, | ||
205 | { "ADC Right Capture Source", NULL, "VINL2" }, | ||
206 | { "ADC Right Capture Source", NULL, "VINR2" }, | ||
207 | { "ADC Right Capture Source", NULL, "VINL3" }, | ||
208 | { "ADC Right Capture Source", NULL, "VINR3" }, | ||
209 | { "ADC Right Capture Source", NULL, "VINL4" }, | ||
210 | { "ADC Right Capture Source", NULL, "VINR4" }, | ||
211 | |||
212 | { "ADC", NULL, "ADC Right Capture Source" }, | ||
213 | }; | ||
214 | |||
215 | static const struct snd_soc_dapm_route pcm1865_dapm_routes[] = { | ||
216 | { "ADC1 Left Capture Source", NULL, "VINL1" }, | ||
217 | { "ADC1 Left Capture Source", NULL, "VINR1" }, | ||
218 | { "ADC1 Left Capture Source", NULL, "VINL2" }, | ||
219 | { "ADC1 Left Capture Source", NULL, "VINR2" }, | ||
220 | { "ADC1 Left Capture Source", NULL, "VINL3" }, | ||
221 | { "ADC1 Left Capture Source", NULL, "VINR3" }, | ||
222 | { "ADC1 Left Capture Source", NULL, "VINL4" }, | ||
223 | { "ADC1 Left Capture Source", NULL, "VINR4" }, | ||
224 | |||
225 | { "ADC1", NULL, "ADC1 Left Capture Source" }, | ||
226 | |||
227 | { "ADC1 Right Capture Source", NULL, "VINL1" }, | ||
228 | { "ADC1 Right Capture Source", NULL, "VINR1" }, | ||
229 | { "ADC1 Right Capture Source", NULL, "VINL2" }, | ||
230 | { "ADC1 Right Capture Source", NULL, "VINR2" }, | ||
231 | { "ADC1 Right Capture Source", NULL, "VINL3" }, | ||
232 | { "ADC1 Right Capture Source", NULL, "VINR3" }, | ||
233 | { "ADC1 Right Capture Source", NULL, "VINL4" }, | ||
234 | { "ADC1 Right Capture Source", NULL, "VINR4" }, | ||
235 | |||
236 | { "ADC1", NULL, "ADC1 Right Capture Source" }, | ||
237 | |||
238 | { "ADC2 Left Capture Source", NULL, "VINL1" }, | ||
239 | { "ADC2 Left Capture Source", NULL, "VINR1" }, | ||
240 | { "ADC2 Left Capture Source", NULL, "VINL2" }, | ||
241 | { "ADC2 Left Capture Source", NULL, "VINR2" }, | ||
242 | { "ADC2 Left Capture Source", NULL, "VINL3" }, | ||
243 | { "ADC2 Left Capture Source", NULL, "VINR3" }, | ||
244 | { "ADC2 Left Capture Source", NULL, "VINL4" }, | ||
245 | { "ADC2 Left Capture Source", NULL, "VINR4" }, | ||
246 | |||
247 | { "ADC2", NULL, "ADC2 Left Capture Source" }, | ||
248 | |||
249 | { "ADC2 Right Capture Source", NULL, "VINL1" }, | ||
250 | { "ADC2 Right Capture Source", NULL, "VINR1" }, | ||
251 | { "ADC2 Right Capture Source", NULL, "VINL2" }, | ||
252 | { "ADC2 Right Capture Source", NULL, "VINR2" }, | ||
253 | { "ADC2 Right Capture Source", NULL, "VINL3" }, | ||
254 | { "ADC2 Right Capture Source", NULL, "VINR3" }, | ||
255 | { "ADC2 Right Capture Source", NULL, "VINL4" }, | ||
256 | { "ADC2 Right Capture Source", NULL, "VINR4" }, | ||
257 | |||
258 | { "ADC2", NULL, "ADC2 Right Capture Source" }, | ||
259 | }; | ||
260 | |||
261 | static int pcm186x_hw_params(struct snd_pcm_substream *substream, | ||
262 | struct snd_pcm_hw_params *params, | ||
263 | struct snd_soc_dai *dai) | ||
264 | { | ||
265 | struct snd_soc_codec *codec = dai->codec; | ||
266 | |||
267 | struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
268 | unsigned int rate = params_rate(params); | ||
269 | unsigned int format = params_format(params); | ||
270 | unsigned int width = params_width(params); | ||
271 | unsigned int channels = params_channels(params); | ||
272 | unsigned int div_lrck; | ||
273 | unsigned int div_bck; | ||
274 | u8 tdm_tx_sel = 0; | ||
275 | u8 pcm_cfg = 0; | ||
276 | |||
277 | dev_dbg(codec->dev, "%s() rate=%u format=0x%x width=%u channels=%u\n", | ||
278 | __func__, rate, format, width, channels); | ||
279 | |||
280 | switch (width) { | ||
281 | case 16: | ||
282 | pcm_cfg = PCM186X_PCM_CFG_RX_WLEN_16 << | ||
283 | PCM186X_PCM_CFG_RX_WLEN_SHIFT | | ||
284 | PCM186X_PCM_CFG_TX_WLEN_16 << | ||
285 | PCM186X_PCM_CFG_TX_WLEN_SHIFT; | ||
286 | break; | ||
287 | case 20: | ||
288 | pcm_cfg = PCM186X_PCM_CFG_RX_WLEN_20 << | ||
289 | PCM186X_PCM_CFG_RX_WLEN_SHIFT | | ||
290 | PCM186X_PCM_CFG_TX_WLEN_20 << | ||
291 | PCM186X_PCM_CFG_TX_WLEN_SHIFT; | ||
292 | break; | ||
293 | case 24: | ||
294 | pcm_cfg = PCM186X_PCM_CFG_RX_WLEN_24 << | ||
295 | PCM186X_PCM_CFG_RX_WLEN_SHIFT | | ||
296 | PCM186X_PCM_CFG_TX_WLEN_24 << | ||
297 | PCM186X_PCM_CFG_TX_WLEN_SHIFT; | ||
298 | break; | ||
299 | case 32: | ||
300 | pcm_cfg = PCM186X_PCM_CFG_RX_WLEN_32 << | ||
301 | PCM186X_PCM_CFG_RX_WLEN_SHIFT | | ||
302 | PCM186X_PCM_CFG_TX_WLEN_32 << | ||
303 | PCM186X_PCM_CFG_TX_WLEN_SHIFT; | ||
304 | break; | ||
305 | default: | ||
306 | return -EINVAL; | ||
307 | } | ||
308 | |||
309 | snd_soc_update_bits(codec, PCM186X_PCM_CFG, | ||
310 | PCM186X_PCM_CFG_RX_WLEN_MASK | | ||
311 | PCM186X_PCM_CFG_TX_WLEN_MASK, | ||
312 | pcm_cfg); | ||
313 | |||
314 | div_lrck = width * channels; | ||
315 | |||
316 | if (priv->is_tdm_mode) { | ||
317 | /* Select TDM transmission data */ | ||
318 | switch (channels) { | ||
319 | case 2: | ||
320 | tdm_tx_sel = PCM186X_TDM_TX_SEL_2CH; | ||
321 | break; | ||
322 | case 4: | ||
323 | tdm_tx_sel = PCM186X_TDM_TX_SEL_4CH; | ||
324 | break; | ||
325 | case 6: | ||
326 | tdm_tx_sel = PCM186X_TDM_TX_SEL_6CH; | ||
327 | break; | ||
328 | default: | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | snd_soc_update_bits(codec, PCM186X_TDM_TX_SEL, | ||
333 | PCM186X_TDM_TX_SEL_MASK, tdm_tx_sel); | ||
334 | |||
335 | /* In DSP/TDM mode, the LRCLK divider must be 256 */ | ||
336 | div_lrck = 256; | ||
337 | |||
338 | /* Configure 1/256 duty cycle for LRCK */ | ||
339 | snd_soc_update_bits(codec, PCM186X_PCM_CFG, | ||
340 | PCM186X_PCM_CFG_TDM_LRCK_MODE, | ||
341 | PCM186X_PCM_CFG_TDM_LRCK_MODE); | ||
342 | } | ||
343 | |||
344 | /* Only configure clock dividers in master mode. */ | ||
345 | if (priv->is_master_mode) { | ||
346 | div_bck = priv->sysclk / (div_lrck * rate); | ||
347 | |||
348 | dev_dbg(codec->dev, | ||
349 | "%s() master_clk=%u div_bck=%u div_lrck=%u\n", | ||
350 | __func__, priv->sysclk, div_bck, div_lrck); | ||
351 | |||
352 | snd_soc_write(codec, PCM186X_BCK_DIV, div_bck - 1); | ||
353 | snd_soc_write(codec, PCM186X_LRK_DIV, div_lrck - 1); | ||
354 | } | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | static int pcm186x_set_fmt(struct snd_soc_dai *dai, unsigned int format) | ||
360 | { | ||
361 | struct snd_soc_codec *codec = dai->codec; | ||
362 | struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
363 | u8 clk_ctrl = 0; | ||
364 | u8 pcm_cfg = 0; | ||
365 | |||
366 | dev_dbg(codec->dev, "%s() format=0x%x\n", __func__, format); | ||
367 | |||
368 | /* set master/slave audio interface */ | ||
369 | switch (format & SND_SOC_DAIFMT_MASTER_MASK) { | ||
370 | case SND_SOC_DAIFMT_CBM_CFM: | ||
371 | if (!priv->sysclk) { | ||
372 | dev_err(codec->dev, "operating in master mode requires sysclock to be configured\n"); | ||
373 | return -EINVAL; | ||
374 | } | ||
375 | clk_ctrl |= PCM186X_CLK_CTRL_MST_MODE; | ||
376 | priv->is_master_mode = true; | ||
377 | break; | ||
378 | case SND_SOC_DAIFMT_CBS_CFS: | ||
379 | priv->is_master_mode = false; | ||
380 | break; | ||
381 | default: | ||
382 | dev_err(codec->dev, "Invalid DAI master/slave interface\n"); | ||
383 | return -EINVAL; | ||
384 | } | ||
385 | |||
386 | /* set interface polarity */ | ||
387 | switch (format & SND_SOC_DAIFMT_INV_MASK) { | ||
388 | case SND_SOC_DAIFMT_NB_NF: | ||
389 | break; | ||
390 | default: | ||
391 | dev_err(codec->dev, "Inverted DAI clocks not supported\n"); | ||
392 | return -EINVAL; | ||
393 | } | ||
394 | |||
395 | /* set interface format */ | ||
396 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
397 | case SND_SOC_DAIFMT_I2S: | ||
398 | pcm_cfg = PCM186X_PCM_CFG_FMT_I2S; | ||
399 | break; | ||
400 | case SND_SOC_DAIFMT_LEFT_J: | ||
401 | pcm_cfg = PCM186X_PCM_CFG_FMT_LEFTJ; | ||
402 | break; | ||
403 | case SND_SOC_DAIFMT_DSP_A: | ||
404 | priv->tdm_offset += 1; | ||
405 | /* Fall through... DSP_A uses the same basic config as DSP_B | ||
406 | * except we need to shift the TDM output by one BCK cycle | ||
407 | */ | ||
408 | case SND_SOC_DAIFMT_DSP_B: | ||
409 | priv->is_tdm_mode = true; | ||
410 | pcm_cfg = PCM186X_PCM_CFG_FMT_TDM; | ||
411 | break; | ||
412 | default: | ||
413 | dev_err(codec->dev, "Invalid DAI format\n"); | ||
414 | return -EINVAL; | ||
415 | } | ||
416 | |||
417 | snd_soc_update_bits(codec, PCM186X_CLK_CTRL, | ||
418 | PCM186X_CLK_CTRL_MST_MODE, clk_ctrl); | ||
419 | |||
420 | snd_soc_write(codec, PCM186X_TDM_TX_OFFSET, priv->tdm_offset); | ||
421 | |||
422 | snd_soc_update_bits(codec, PCM186X_PCM_CFG, | ||
423 | PCM186X_PCM_CFG_FMT_MASK, pcm_cfg); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static int pcm186x_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
429 | unsigned int rx_mask, int slots, int slot_width) | ||
430 | { | ||
431 | struct snd_soc_codec *codec = dai->codec; | ||
432 | struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
433 | unsigned int first_slot, last_slot, tdm_offset; | ||
434 | |||
435 | dev_dbg(codec->dev, | ||
436 | "%s() tx_mask=0x%x rx_mask=0x%x slots=%d slot_width=%d\n", | ||
437 | __func__, tx_mask, rx_mask, slots, slot_width); | ||
438 | |||
439 | if (!tx_mask) { | ||
440 | dev_err(codec->dev, "tdm tx mask must not be 0\n"); | ||
441 | return -EINVAL; | ||
442 | } | ||
443 | |||
444 | first_slot = __ffs(tx_mask); | ||
445 | last_slot = __fls(tx_mask); | ||
446 | |||
447 | if (last_slot - first_slot != hweight32(tx_mask) - 1) { | ||
448 | dev_err(codec->dev, "tdm tx mask must be contiguous\n"); | ||
449 | return -EINVAL; | ||
450 | } | ||
451 | |||
452 | tdm_offset = first_slot * slot_width; | ||
453 | |||
454 | if (tdm_offset > 255) { | ||
455 | dev_err(codec->dev, "tdm tx slot selection out of bounds\n"); | ||
456 | return -EINVAL; | ||
457 | } | ||
458 | |||
459 | priv->tdm_offset = tdm_offset; | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | |||
464 | static int pcm186x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
465 | unsigned int freq, int dir) | ||
466 | { | ||
467 | struct snd_soc_codec *codec = dai->codec; | ||
468 | struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
469 | |||
470 | dev_dbg(codec->dev, "%s() clk_id=%d freq=%u dir=%d\n", | ||
471 | __func__, clk_id, freq, dir); | ||
472 | |||
473 | priv->sysclk = freq; | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static const struct snd_soc_dai_ops pcm186x_dai_ops = { | ||
479 | .set_sysclk = pcm186x_set_dai_sysclk, | ||
480 | .set_tdm_slot = pcm186x_set_tdm_slot, | ||
481 | .set_fmt = pcm186x_set_fmt, | ||
482 | .hw_params = pcm186x_hw_params, | ||
483 | }; | ||
484 | |||
485 | static struct snd_soc_dai_driver pcm1863_dai = { | ||
486 | .name = "pcm1863-aif", | ||
487 | .capture = { | ||
488 | .stream_name = "Capture", | ||
489 | .channels_min = 1, | ||
490 | .channels_max = 2, | ||
491 | .rates = PCM186X_RATES, | ||
492 | .formats = PCM186X_FORMATS, | ||
493 | }, | ||
494 | .ops = &pcm186x_dai_ops, | ||
495 | }; | ||
496 | |||
497 | static struct snd_soc_dai_driver pcm1865_dai = { | ||
498 | .name = "pcm1865-aif", | ||
499 | .capture = { | ||
500 | .stream_name = "Capture", | ||
501 | .channels_min = 1, | ||
502 | .channels_max = 4, | ||
503 | .rates = PCM186X_RATES, | ||
504 | .formats = PCM186X_FORMATS, | ||
505 | }, | ||
506 | .ops = &pcm186x_dai_ops, | ||
507 | }; | ||
508 | |||
509 | static int pcm186x_power_on(struct snd_soc_codec *codec) | ||
510 | { | ||
511 | struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
512 | int ret = 0; | ||
513 | |||
514 | ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), | ||
515 | priv->supplies); | ||
516 | if (ret) | ||
517 | return ret; | ||
518 | |||
519 | regcache_cache_only(priv->regmap, false); | ||
520 | ret = regcache_sync(priv->regmap); | ||
521 | if (ret) { | ||
522 | dev_err(codec->dev, "Failed to restore cache\n"); | ||
523 | regcache_cache_only(priv->regmap, true); | ||
524 | regulator_bulk_disable(ARRAY_SIZE(priv->supplies), | ||
525 | priv->supplies); | ||
526 | return ret; | ||
527 | } | ||
528 | |||
529 | snd_soc_update_bits(codec, PCM186X_POWER_CTRL, | ||
530 | PCM186X_PWR_CTRL_PWRDN, 0); | ||
531 | |||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | static int pcm186x_power_off(struct snd_soc_codec *codec) | ||
536 | { | ||
537 | struct pcm186x_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
538 | int ret; | ||
539 | |||
540 | snd_soc_update_bits(codec, PCM186X_POWER_CTRL, | ||
541 | PCM186X_PWR_CTRL_PWRDN, PCM186X_PWR_CTRL_PWRDN); | ||
542 | |||
543 | regcache_cache_only(priv->regmap, true); | ||
544 | |||
545 | ret = regulator_bulk_disable(ARRAY_SIZE(priv->supplies), | ||
546 | priv->supplies); | ||
547 | if (ret) | ||
548 | return ret; | ||
549 | |||
550 | return 0; | ||
551 | } | ||
552 | |||
553 | static int pcm186x_set_bias_level(struct snd_soc_codec *codec, | ||
554 | enum snd_soc_bias_level level) | ||
555 | { | ||
556 | dev_dbg(codec->dev, "## %s: %d -> %d\n", __func__, | ||
557 | snd_soc_codec_get_bias_level(codec), level); | ||
558 | |||
559 | switch (level) { | ||
560 | case SND_SOC_BIAS_ON: | ||
561 | break; | ||
562 | case SND_SOC_BIAS_PREPARE: | ||
563 | break; | ||
564 | case SND_SOC_BIAS_STANDBY: | ||
565 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) | ||
566 | pcm186x_power_on(codec); | ||
567 | break; | ||
568 | case SND_SOC_BIAS_OFF: | ||
569 | pcm186x_power_off(codec); | ||
570 | break; | ||
571 | } | ||
572 | |||
573 | return 0; | ||
574 | } | ||
575 | |||
576 | static struct snd_soc_codec_driver soc_codec_dev_pcm1863 = { | ||
577 | .set_bias_level = pcm186x_set_bias_level, | ||
578 | |||
579 | .component_driver = { | ||
580 | .controls = pcm1863_snd_controls, | ||
581 | .num_controls = ARRAY_SIZE(pcm1863_snd_controls), | ||
582 | .dapm_widgets = pcm1863_dapm_widgets, | ||
583 | .num_dapm_widgets = ARRAY_SIZE(pcm1863_dapm_widgets), | ||
584 | .dapm_routes = pcm1863_dapm_routes, | ||
585 | .num_dapm_routes = ARRAY_SIZE(pcm1863_dapm_routes), | ||
586 | }, | ||
587 | }; | ||
588 | |||
589 | static struct snd_soc_codec_driver soc_codec_dev_pcm1865 = { | ||
590 | .set_bias_level = pcm186x_set_bias_level, | ||
591 | .suspend_bias_off = true, | ||
592 | |||
593 | .component_driver = { | ||
594 | .controls = pcm1865_snd_controls, | ||
595 | .num_controls = ARRAY_SIZE(pcm1865_snd_controls), | ||
596 | .dapm_widgets = pcm1865_dapm_widgets, | ||
597 | .num_dapm_widgets = ARRAY_SIZE(pcm1865_dapm_widgets), | ||
598 | .dapm_routes = pcm1865_dapm_routes, | ||
599 | .num_dapm_routes = ARRAY_SIZE(pcm1865_dapm_routes), | ||
600 | }, | ||
601 | }; | ||
602 | |||
603 | static bool pcm186x_volatile(struct device *dev, unsigned int reg) | ||
604 | { | ||
605 | switch (reg) { | ||
606 | case PCM186X_PAGE: | ||
607 | case PCM186X_DEVICE_STATUS: | ||
608 | case PCM186X_FSAMPLE_STATUS: | ||
609 | case PCM186X_DIV_STATUS: | ||
610 | case PCM186X_CLK_STATUS: | ||
611 | case PCM186X_SUPPLY_STATUS: | ||
612 | case PCM186X_MMAP_STAT_CTRL: | ||
613 | case PCM186X_MMAP_ADDRESS: | ||
614 | return true; | ||
615 | } | ||
616 | |||
617 | return false; | ||
618 | } | ||
619 | |||
620 | static const struct regmap_range_cfg pcm186x_range = { | ||
621 | .name = "Pages", | ||
622 | .range_max = PCM186X_MAX_REGISTER, | ||
623 | .selector_reg = PCM186X_PAGE, | ||
624 | .selector_mask = 0xff, | ||
625 | .window_len = PCM186X_PAGE_LEN, | ||
626 | }; | ||
627 | |||
628 | const struct regmap_config pcm186x_regmap = { | ||
629 | .reg_bits = 8, | ||
630 | .val_bits = 8, | ||
631 | |||
632 | .volatile_reg = pcm186x_volatile, | ||
633 | |||
634 | .ranges = &pcm186x_range, | ||
635 | .num_ranges = 1, | ||
636 | |||
637 | .max_register = PCM186X_MAX_REGISTER, | ||
638 | |||
639 | .cache_type = REGCACHE_RBTREE, | ||
640 | }; | ||
641 | EXPORT_SYMBOL_GPL(pcm186x_regmap); | ||
642 | |||
643 | int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq, | ||
644 | struct regmap *regmap) | ||
645 | { | ||
646 | struct pcm186x_priv *priv; | ||
647 | int i, ret; | ||
648 | |||
649 | priv = devm_kzalloc(dev, sizeof(struct pcm186x_priv), GFP_KERNEL); | ||
650 | if (!priv) | ||
651 | return -ENOMEM; | ||
652 | |||
653 | dev_set_drvdata(dev, priv); | ||
654 | priv->regmap = regmap; | ||
655 | |||
656 | for (i = 0; i < ARRAY_SIZE(priv->supplies); i++) | ||
657 | priv->supplies[i].supply = pcm186x_supply_names[i]; | ||
658 | |||
659 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(priv->supplies), | ||
660 | priv->supplies); | ||
661 | if (ret) { | ||
662 | dev_err(dev, "failed to request supplies: %d\n", ret); | ||
663 | return ret; | ||
664 | } | ||
665 | |||
666 | ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), | ||
667 | priv->supplies); | ||
668 | if (ret) { | ||
669 | dev_err(dev, "failed enable supplies: %d\n", ret); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | /* Reset device registers for a consistent power-on like state */ | ||
674 | ret = regmap_write(regmap, PCM186X_PAGE, PCM186X_RESET); | ||
675 | if (ret) { | ||
676 | dev_err(dev, "failed to write device: %d\n", ret); | ||
677 | return ret; | ||
678 | } | ||
679 | |||
680 | ret = regulator_bulk_disable(ARRAY_SIZE(priv->supplies), | ||
681 | priv->supplies); | ||
682 | if (ret) { | ||
683 | dev_err(dev, "failed disable supplies: %d\n", ret); | ||
684 | return ret; | ||
685 | } | ||
686 | |||
687 | switch (type) { | ||
688 | case PCM1865: | ||
689 | case PCM1864: | ||
690 | ret = snd_soc_register_codec(dev, &soc_codec_dev_pcm1865, | ||
691 | &pcm1865_dai, 1); | ||
692 | break; | ||
693 | case PCM1863: | ||
694 | case PCM1862: | ||
695 | default: | ||
696 | ret = snd_soc_register_codec(dev, &soc_codec_dev_pcm1863, | ||
697 | &pcm1863_dai, 1); | ||
698 | } | ||
699 | if (ret) { | ||
700 | dev_err(dev, "failed to register CODEC: %d\n", ret); | ||
701 | return ret; | ||
702 | } | ||
703 | |||
704 | return 0; | ||
705 | } | ||
706 | EXPORT_SYMBOL_GPL(pcm186x_probe); | ||
707 | |||
708 | int pcm186x_remove(struct device *dev) | ||
709 | { | ||
710 | snd_soc_unregister_codec(dev); | ||
711 | |||
712 | return 0; | ||
713 | } | ||
714 | EXPORT_SYMBOL_GPL(pcm186x_remove); | ||
715 | |||
716 | MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>"); | ||
717 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); | ||
718 | MODULE_DESCRIPTION("PCM186x Universal Audio ADC driver"); | ||
719 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/pcm186x.h b/sound/soc/codecs/pcm186x.h new file mode 100644 index 000000000000..b630111bb3c4 --- /dev/null +++ b/sound/soc/codecs/pcm186x.h | |||
@@ -0,0 +1,220 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Texas Instruments PCM186x Universal Audio ADC | ||
4 | * | ||
5 | * Copyright (C) 2015-2017 Texas Instruments Incorporated - http://www.ti.com | ||
6 | * Andreas Dannenberg <dannenberg@ti.com> | ||
7 | * Andrew F. Davis <afd@ti.com> | ||
8 | */ | ||
9 | |||
10 | #ifndef _PCM186X_H_ | ||
11 | #define _PCM186X_H_ | ||
12 | |||
13 | #include <linux/pm.h> | ||
14 | #include <linux/regmap.h> | ||
15 | |||
16 | enum pcm186x_type { | ||
17 | PCM1862, | ||
18 | PCM1863, | ||
19 | PCM1864, | ||
20 | PCM1865, | ||
21 | }; | ||
22 | |||
23 | #define PCM186X_RATES SNDRV_PCM_RATE_8000_192000 | ||
24 | #define PCM186X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
25 | SNDRV_PCM_FMTBIT_S20_3LE |\ | ||
26 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
27 | SNDRV_PCM_FMTBIT_S32_LE) | ||
28 | |||
29 | #define PCM186X_PAGE_LEN 0x0100 | ||
30 | #define PCM186X_PAGE_BASE(n) (PCM186X_PAGE_LEN * n) | ||
31 | |||
32 | /* The page selection register address is the same on all pages */ | ||
33 | #define PCM186X_PAGE 0 | ||
34 | |||
35 | /* Register Definitions - Page 0 */ | ||
36 | #define PCM186X_PGA_VAL_CH1_L (PCM186X_PAGE_BASE(0) + 1) | ||
37 | #define PCM186X_PGA_VAL_CH1_R (PCM186X_PAGE_BASE(0) + 2) | ||
38 | #define PCM186X_PGA_VAL_CH2_L (PCM186X_PAGE_BASE(0) + 3) | ||
39 | #define PCM186X_PGA_VAL_CH2_R (PCM186X_PAGE_BASE(0) + 4) | ||
40 | #define PCM186X_PGA_CTRL (PCM186X_PAGE_BASE(0) + 5) | ||
41 | #define PCM186X_ADC1_INPUT_SEL_L (PCM186X_PAGE_BASE(0) + 6) | ||
42 | #define PCM186X_ADC1_INPUT_SEL_R (PCM186X_PAGE_BASE(0) + 7) | ||
43 | #define PCM186X_ADC2_INPUT_SEL_L (PCM186X_PAGE_BASE(0) + 8) | ||
44 | #define PCM186X_ADC2_INPUT_SEL_R (PCM186X_PAGE_BASE(0) + 9) | ||
45 | #define PCM186X_AUXADC_INPUT_SEL (PCM186X_PAGE_BASE(0) + 10) | ||
46 | #define PCM186X_PCM_CFG (PCM186X_PAGE_BASE(0) + 11) | ||
47 | #define PCM186X_TDM_TX_SEL (PCM186X_PAGE_BASE(0) + 12) | ||
48 | #define PCM186X_TDM_TX_OFFSET (PCM186X_PAGE_BASE(0) + 13) | ||
49 | #define PCM186X_TDM_RX_OFFSET (PCM186X_PAGE_BASE(0) + 14) | ||
50 | #define PCM186X_DPGA_VAL_CH1_L (PCM186X_PAGE_BASE(0) + 15) | ||
51 | #define PCM186X_GPIO1_0_CTRL (PCM186X_PAGE_BASE(0) + 16) | ||
52 | #define PCM186X_GPIO3_2_CTRL (PCM186X_PAGE_BASE(0) + 17) | ||
53 | #define PCM186X_GPIO1_0_DIR_CTRL (PCM186X_PAGE_BASE(0) + 18) | ||
54 | #define PCM186X_GPIO3_2_DIR_CTRL (PCM186X_PAGE_BASE(0) + 19) | ||
55 | #define PCM186X_GPIO_IN_OUT (PCM186X_PAGE_BASE(0) + 20) | ||
56 | #define PCM186X_GPIO_PULL_CTRL (PCM186X_PAGE_BASE(0) + 21) | ||
57 | #define PCM186X_DPGA_VAL_CH1_R (PCM186X_PAGE_BASE(0) + 22) | ||
58 | #define PCM186X_DPGA_VAL_CH2_L (PCM186X_PAGE_BASE(0) + 23) | ||
59 | #define PCM186X_DPGA_VAL_CH2_R (PCM186X_PAGE_BASE(0) + 24) | ||
60 | #define PCM186X_DPGA_GAIN_CTRL (PCM186X_PAGE_BASE(0) + 25) | ||
61 | #define PCM186X_DPGA_MIC_CTRL (PCM186X_PAGE_BASE(0) + 26) | ||
62 | #define PCM186X_DIN_RESAMP_CTRL (PCM186X_PAGE_BASE(0) + 27) | ||
63 | #define PCM186X_CLK_CTRL (PCM186X_PAGE_BASE(0) + 32) | ||
64 | #define PCM186X_DSP1_CLK_DIV (PCM186X_PAGE_BASE(0) + 33) | ||
65 | #define PCM186X_DSP2_CLK_DIV (PCM186X_PAGE_BASE(0) + 34) | ||
66 | #define PCM186X_ADC_CLK_DIV (PCM186X_PAGE_BASE(0) + 35) | ||
67 | #define PCM186X_PLL_SCK_DIV (PCM186X_PAGE_BASE(0) + 37) | ||
68 | #define PCM186X_BCK_DIV (PCM186X_PAGE_BASE(0) + 38) | ||
69 | #define PCM186X_LRK_DIV (PCM186X_PAGE_BASE(0) + 39) | ||
70 | #define PCM186X_PLL_CTRL (PCM186X_PAGE_BASE(0) + 40) | ||
71 | #define PCM186X_PLL_P_DIV (PCM186X_PAGE_BASE(0) + 41) | ||
72 | #define PCM186X_PLL_R_DIV (PCM186X_PAGE_BASE(0) + 42) | ||
73 | #define PCM186X_PLL_J_DIV (PCM186X_PAGE_BASE(0) + 43) | ||
74 | #define PCM186X_PLL_D_DIV_LSB (PCM186X_PAGE_BASE(0) + 44) | ||
75 | #define PCM186X_PLL_D_DIV_MSB (PCM186X_PAGE_BASE(0) + 45) | ||
76 | #define PCM186X_SIGDET_MODE (PCM186X_PAGE_BASE(0) + 48) | ||
77 | #define PCM186X_SIGDET_MASK (PCM186X_PAGE_BASE(0) + 49) | ||
78 | #define PCM186X_SIGDET_STAT (PCM186X_PAGE_BASE(0) + 50) | ||
79 | #define PCM186X_SIGDET_LOSS_TIME (PCM186X_PAGE_BASE(0) + 52) | ||
80 | #define PCM186X_SIGDET_SCAN_TIME (PCM186X_PAGE_BASE(0) + 53) | ||
81 | #define PCM186X_SIGDET_INT_INTVL (PCM186X_PAGE_BASE(0) + 54) | ||
82 | #define PCM186X_SIGDET_DC_REF_CH1_L (PCM186X_PAGE_BASE(0) + 64) | ||
83 | #define PCM186X_SIGDET_DC_DIFF_CH1_L (PCM186X_PAGE_BASE(0) + 65) | ||
84 | #define PCM186X_SIGDET_DC_LEV_CH1_L (PCM186X_PAGE_BASE(0) + 66) | ||
85 | #define PCM186X_SIGDET_DC_REF_CH1_R (PCM186X_PAGE_BASE(0) + 67) | ||
86 | #define PCM186X_SIGDET_DC_DIFF_CH1_R (PCM186X_PAGE_BASE(0) + 68) | ||
87 | #define PCM186X_SIGDET_DC_LEV_CH1_R (PCM186X_PAGE_BASE(0) + 69) | ||
88 | #define PCM186X_SIGDET_DC_REF_CH2_L (PCM186X_PAGE_BASE(0) + 70) | ||
89 | #define PCM186X_SIGDET_DC_DIFF_CH2_L (PCM186X_PAGE_BASE(0) + 71) | ||
90 | #define PCM186X_SIGDET_DC_LEV_CH2_L (PCM186X_PAGE_BASE(0) + 72) | ||
91 | #define PCM186X_SIGDET_DC_REF_CH2_R (PCM186X_PAGE_BASE(0) + 73) | ||
92 | #define PCM186X_SIGDET_DC_DIFF_CH2_R (PCM186X_PAGE_BASE(0) + 74) | ||
93 | #define PCM186X_SIGDET_DC_LEV_CH2_R (PCM186X_PAGE_BASE(0) + 75) | ||
94 | #define PCM186X_SIGDET_DC_REF_CH3_L (PCM186X_PAGE_BASE(0) + 76) | ||
95 | #define PCM186X_SIGDET_DC_DIFF_CH3_L (PCM186X_PAGE_BASE(0) + 77) | ||
96 | #define PCM186X_SIGDET_DC_LEV_CH3_L (PCM186X_PAGE_BASE(0) + 78) | ||
97 | #define PCM186X_SIGDET_DC_REF_CH3_R (PCM186X_PAGE_BASE(0) + 79) | ||
98 | #define PCM186X_SIGDET_DC_DIFF_CH3_R (PCM186X_PAGE_BASE(0) + 80) | ||
99 | #define PCM186X_SIGDET_DC_LEV_CH3_R (PCM186X_PAGE_BASE(0) + 81) | ||
100 | #define PCM186X_SIGDET_DC_REF_CH4_L (PCM186X_PAGE_BASE(0) + 82) | ||
101 | #define PCM186X_SIGDET_DC_DIFF_CH4_L (PCM186X_PAGE_BASE(0) + 83) | ||
102 | #define PCM186X_SIGDET_DC_LEV_CH4_L (PCM186X_PAGE_BASE(0) + 84) | ||
103 | #define PCM186X_SIGDET_DC_REF_CH4_R (PCM186X_PAGE_BASE(0) + 85) | ||
104 | #define PCM186X_SIGDET_DC_DIFF_CH4_R (PCM186X_PAGE_BASE(0) + 86) | ||
105 | #define PCM186X_SIGDET_DC_LEV_CH4_R (PCM186X_PAGE_BASE(0) + 87) | ||
106 | #define PCM186X_AUXADC_DATA_CTRL (PCM186X_PAGE_BASE(0) + 88) | ||
107 | #define PCM186X_AUXADC_DATA_LSB (PCM186X_PAGE_BASE(0) + 89) | ||
108 | #define PCM186X_AUXADC_DATA_MSB (PCM186X_PAGE_BASE(0) + 90) | ||
109 | #define PCM186X_INT_ENABLE (PCM186X_PAGE_BASE(0) + 96) | ||
110 | #define PCM186X_INT_FLAG (PCM186X_PAGE_BASE(0) + 97) | ||
111 | #define PCM186X_INT_POL_WIDTH (PCM186X_PAGE_BASE(0) + 98) | ||
112 | #define PCM186X_POWER_CTRL (PCM186X_PAGE_BASE(0) + 112) | ||
113 | #define PCM186X_FILTER_MUTE_CTRL (PCM186X_PAGE_BASE(0) + 113) | ||
114 | #define PCM186X_DEVICE_STATUS (PCM186X_PAGE_BASE(0) + 114) | ||
115 | #define PCM186X_FSAMPLE_STATUS (PCM186X_PAGE_BASE(0) + 115) | ||
116 | #define PCM186X_DIV_STATUS (PCM186X_PAGE_BASE(0) + 116) | ||
117 | #define PCM186X_CLK_STATUS (PCM186X_PAGE_BASE(0) + 117) | ||
118 | #define PCM186X_SUPPLY_STATUS (PCM186X_PAGE_BASE(0) + 120) | ||
119 | |||
120 | /* Register Definitions - Page 1 */ | ||
121 | #define PCM186X_MMAP_STAT_CTRL (PCM186X_PAGE_BASE(1) + 1) | ||
122 | #define PCM186X_MMAP_ADDRESS (PCM186X_PAGE_BASE(1) + 2) | ||
123 | #define PCM186X_MEM_WDATA0 (PCM186X_PAGE_BASE(1) + 4) | ||
124 | #define PCM186X_MEM_WDATA1 (PCM186X_PAGE_BASE(1) + 5) | ||
125 | #define PCM186X_MEM_WDATA2 (PCM186X_PAGE_BASE(1) + 6) | ||
126 | #define PCM186X_MEM_WDATA3 (PCM186X_PAGE_BASE(1) + 7) | ||
127 | #define PCM186X_MEM_RDATA0 (PCM186X_PAGE_BASE(1) + 8) | ||
128 | #define PCM186X_MEM_RDATA1 (PCM186X_PAGE_BASE(1) + 9) | ||
129 | #define PCM186X_MEM_RDATA2 (PCM186X_PAGE_BASE(1) + 10) | ||
130 | #define PCM186X_MEM_RDATA3 (PCM186X_PAGE_BASE(1) + 11) | ||
131 | |||
132 | /* Register Definitions - Page 3 */ | ||
133 | #define PCM186X_OSC_PWR_DOWN_CTRL (PCM186X_PAGE_BASE(3) + 18) | ||
134 | #define PCM186X_MIC_BIAS_CTRL (PCM186X_PAGE_BASE(3) + 21) | ||
135 | |||
136 | /* Register Definitions - Page 253 */ | ||
137 | #define PCM186X_CURR_TRIM_CTRL (PCM186X_PAGE_BASE(253) + 20) | ||
138 | |||
139 | #define PCM186X_MAX_REGISTER PCM186X_CURR_TRIM_CTRL | ||
140 | |||
141 | /* PCM186X_PAGE */ | ||
142 | #define PCM186X_RESET 0xff | ||
143 | |||
144 | /* PCM186X_ADCX_INPUT_SEL_X */ | ||
145 | #define PCM186X_ADC_INPUT_SEL_POL BIT(7) | ||
146 | #define PCM186X_ADC_INPUT_SEL_MASK GENMASK(5, 0) | ||
147 | |||
148 | /* PCM186X_PCM_CFG */ | ||
149 | #define PCM186X_PCM_CFG_RX_WLEN_MASK GENMASK(7, 6) | ||
150 | #define PCM186X_PCM_CFG_RX_WLEN_SHIFT 6 | ||
151 | #define PCM186X_PCM_CFG_RX_WLEN_32 0x00 | ||
152 | #define PCM186X_PCM_CFG_RX_WLEN_24 0x01 | ||
153 | #define PCM186X_PCM_CFG_RX_WLEN_20 0x02 | ||
154 | #define PCM186X_PCM_CFG_RX_WLEN_16 0x03 | ||
155 | #define PCM186X_PCM_CFG_TDM_LRCK_MODE BIT(4) | ||
156 | #define PCM186X_PCM_CFG_TX_WLEN_MASK GENMASK(3, 2) | ||
157 | #define PCM186X_PCM_CFG_TX_WLEN_SHIFT 2 | ||
158 | #define PCM186X_PCM_CFG_TX_WLEN_32 0x00 | ||
159 | #define PCM186X_PCM_CFG_TX_WLEN_24 0x01 | ||
160 | #define PCM186X_PCM_CFG_TX_WLEN_20 0x02 | ||
161 | #define PCM186X_PCM_CFG_TX_WLEN_16 0x03 | ||
162 | #define PCM186X_PCM_CFG_FMT_MASK GENMASK(1, 0) | ||
163 | #define PCM186X_PCM_CFG_FMT_SHIFT 0 | ||
164 | #define PCM186X_PCM_CFG_FMT_I2S 0x00 | ||
165 | #define PCM186X_PCM_CFG_FMT_LEFTJ 0x01 | ||
166 | #define PCM186X_PCM_CFG_FMT_RIGHTJ 0x02 | ||
167 | #define PCM186X_PCM_CFG_FMT_TDM 0x03 | ||
168 | |||
169 | /* PCM186X_TDM_TX_SEL */ | ||
170 | #define PCM186X_TDM_TX_SEL_2CH 0x00 | ||
171 | #define PCM186X_TDM_TX_SEL_4CH 0x01 | ||
172 | #define PCM186X_TDM_TX_SEL_6CH 0x02 | ||
173 | #define PCM186X_TDM_TX_SEL_MASK 0x03 | ||
174 | |||
175 | /* PCM186X_CLK_CTRL */ | ||
176 | #define PCM186X_CLK_CTRL_SCK_XI_SEL1 BIT(7) | ||
177 | #define PCM186X_CLK_CTRL_SCK_XI_SEL0 BIT(6) | ||
178 | #define PCM186X_CLK_CTRL_SCK_SRC_PLL BIT(5) | ||
179 | #define PCM186X_CLK_CTRL_MST_MODE BIT(4) | ||
180 | #define PCM186X_CLK_CTRL_ADC_SRC_PLL BIT(3) | ||
181 | #define PCM186X_CLK_CTRL_DSP2_SRC_PLL BIT(2) | ||
182 | #define PCM186X_CLK_CTRL_DSP1_SRC_PLL BIT(1) | ||
183 | #define PCM186X_CLK_CTRL_CLKDET_EN BIT(0) | ||
184 | |||
185 | /* PCM186X_PLL_CTRL */ | ||
186 | #define PCM186X_PLL_CTRL_LOCK BIT(4) | ||
187 | #define PCM186X_PLL_CTRL_REF_SEL BIT(1) | ||
188 | #define PCM186X_PLL_CTRL_EN BIT(0) | ||
189 | |||
190 | /* PCM186X_POWER_CTRL */ | ||
191 | #define PCM186X_PWR_CTRL_PWRDN BIT(2) | ||
192 | #define PCM186X_PWR_CTRL_SLEEP BIT(1) | ||
193 | #define PCM186X_PWR_CTRL_STBY BIT(0) | ||
194 | |||
195 | /* PCM186X_CLK_STATUS */ | ||
196 | #define PCM186X_CLK_STATUS_LRCKHLT BIT(6) | ||
197 | #define PCM186X_CLK_STATUS_BCKHLT BIT(5) | ||
198 | #define PCM186X_CLK_STATUS_SCKHLT BIT(4) | ||
199 | #define PCM186X_CLK_STATUS_LRCKERR BIT(2) | ||
200 | #define PCM186X_CLK_STATUS_BCKERR BIT(1) | ||
201 | #define PCM186X_CLK_STATUS_SCKERR BIT(0) | ||
202 | |||
203 | /* PCM186X_SUPPLY_STATUS */ | ||
204 | #define PCM186X_SUPPLY_STATUS_DVDD BIT(2) | ||
205 | #define PCM186X_SUPPLY_STATUS_AVDD BIT(1) | ||
206 | #define PCM186X_SUPPLY_STATUS_LDO BIT(0) | ||
207 | |||
208 | /* PCM186X_MMAP_STAT_CTRL */ | ||
209 | #define PCM186X_MMAP_STAT_DONE BIT(4) | ||
210 | #define PCM186X_MMAP_STAT_BUSY BIT(2) | ||
211 | #define PCM186X_MMAP_STAT_R_REQ BIT(1) | ||
212 | #define PCM186X_MMAP_STAT_W_REQ BIT(0) | ||
213 | |||
214 | extern const struct regmap_config pcm186x_regmap; | ||
215 | |||
216 | int pcm186x_probe(struct device *dev, enum pcm186x_type type, int irq, | ||
217 | struct regmap *regmap); | ||
218 | int pcm186x_remove(struct device *dev); | ||
219 | |||
220 | #endif /* _PCM186X_H_ */ | ||
diff --git a/sound/soc/codecs/pcm512x-spi.c b/sound/soc/codecs/pcm512x-spi.c index 25c63510ae15..7cdd2dc4fd79 100644 --- a/sound/soc/codecs/pcm512x-spi.c +++ b/sound/soc/codecs/pcm512x-spi.c | |||
@@ -70,3 +70,7 @@ static struct spi_driver pcm512x_spi_driver = { | |||
70 | }; | 70 | }; |
71 | 71 | ||
72 | module_spi_driver(pcm512x_spi_driver); | 72 | module_spi_driver(pcm512x_spi_driver); |
73 | |||
74 | MODULE_DESCRIPTION("ASoC PCM512x codec driver - SPI"); | ||
75 | MODULE_AUTHOR("Mark Brown <broonie@kernel.org>"); | ||
76 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rl6231.c b/sound/soc/codecs/rl6231.c index 974a9040651d..7ef3b5476bcc 100644 --- a/sound/soc/codecs/rl6231.c +++ b/sound/soc/codecs/rl6231.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/regmap.h> | 14 | #include <linux/regmap.h> |
15 | 15 | ||
16 | #include <linux/gcd.h> | ||
16 | #include "rl6231.h" | 17 | #include "rl6231.h" |
17 | 18 | ||
18 | /** | 19 | /** |
@@ -106,6 +107,25 @@ static const struct pll_calc_map pll_preset_table[] = { | |||
106 | {19200000, 24576000, 3, 30, 3, false}, | 107 | {19200000, 24576000, 3, 30, 3, false}, |
107 | }; | 108 | }; |
108 | 109 | ||
110 | static unsigned int find_best_div(unsigned int in, | ||
111 | unsigned int max, unsigned int div) | ||
112 | { | ||
113 | unsigned int d; | ||
114 | |||
115 | if (in <= max) | ||
116 | return 1; | ||
117 | |||
118 | d = in / max; | ||
119 | if (in % max) | ||
120 | d++; | ||
121 | |||
122 | while (div % d != 0) | ||
123 | d++; | ||
124 | |||
125 | |||
126 | return d; | ||
127 | } | ||
128 | |||
109 | /** | 129 | /** |
110 | * rl6231_pll_calc - Calcualte PLL M/N/K code. | 130 | * rl6231_pll_calc - Calcualte PLL M/N/K code. |
111 | * @freq_in: external clock provided to codec. | 131 | * @freq_in: external clock provided to codec. |
@@ -120,9 +140,11 @@ int rl6231_pll_calc(const unsigned int freq_in, | |||
120 | const unsigned int freq_out, struct rl6231_pll_code *pll_code) | 140 | const unsigned int freq_out, struct rl6231_pll_code *pll_code) |
121 | { | 141 | { |
122 | int max_n = RL6231_PLL_N_MAX, max_m = RL6231_PLL_M_MAX; | 142 | int max_n = RL6231_PLL_N_MAX, max_m = RL6231_PLL_M_MAX; |
123 | int i, k, red, n_t, pll_out, in_t, out_t; | 143 | int i, k, n_t; |
124 | int n = 0, m = 0, m_t = 0; | 144 | int k_t, min_k, max_k, n = 0, m = 0, m_t = 0; |
125 | int red_t = abs(freq_out - freq_in); | 145 | unsigned int red, pll_out, in_t, out_t, div, div_t; |
146 | unsigned int red_t = abs(freq_out - freq_in); | ||
147 | unsigned int f_in, f_out, f_max; | ||
126 | bool bypass = false; | 148 | bool bypass = false; |
127 | 149 | ||
128 | if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in) | 150 | if (RL6231_PLL_INP_MAX < freq_in || RL6231_PLL_INP_MIN > freq_in) |
@@ -140,39 +162,52 @@ int rl6231_pll_calc(const unsigned int freq_in, | |||
140 | } | 162 | } |
141 | } | 163 | } |
142 | 164 | ||
143 | k = 100000000 / freq_out - 2; | 165 | min_k = 80000000 / freq_out - 2; |
144 | if (k > RL6231_PLL_K_MAX) | 166 | max_k = 150000000 / freq_out - 2; |
145 | k = RL6231_PLL_K_MAX; | 167 | if (max_k > RL6231_PLL_K_MAX) |
146 | for (n_t = 0; n_t <= max_n; n_t++) { | 168 | max_k = RL6231_PLL_K_MAX; |
147 | in_t = freq_in / (k + 2); | 169 | if (min_k > RL6231_PLL_K_MAX) |
148 | pll_out = freq_out / (n_t + 2); | 170 | min_k = max_k = RL6231_PLL_K_MAX; |
149 | if (in_t < 0) | 171 | div_t = gcd(freq_in, freq_out); |
150 | continue; | 172 | f_max = 0xffffffff / RL6231_PLL_N_MAX; |
151 | if (in_t == pll_out) { | 173 | div = find_best_div(freq_in, f_max, div_t); |
152 | bypass = true; | 174 | f_in = freq_in / div; |
153 | n = n_t; | 175 | f_out = freq_out / div; |
154 | goto code_find; | 176 | k = min_k; |
155 | } | 177 | for (k_t = min_k; k_t <= max_k; k_t++) { |
156 | red = abs(in_t - pll_out); | 178 | for (n_t = 0; n_t <= max_n; n_t++) { |
157 | if (red < red_t) { | 179 | in_t = f_in * (n_t + 2); |
158 | bypass = true; | 180 | pll_out = f_out * (k_t + 2); |
159 | n = n_t; | 181 | if (in_t == pll_out) { |
160 | m = m_t; | 182 | bypass = true; |
161 | if (red == 0) | 183 | n = n_t; |
184 | k = k_t; | ||
162 | goto code_find; | 185 | goto code_find; |
163 | red_t = red; | 186 | } |
164 | } | 187 | out_t = in_t / (k_t + 2); |
165 | for (m_t = 0; m_t <= max_m; m_t++) { | 188 | red = abs(f_out - out_t); |
166 | out_t = in_t / (m_t + 2); | ||
167 | red = abs(out_t - pll_out); | ||
168 | if (red < red_t) { | 189 | if (red < red_t) { |
169 | bypass = false; | 190 | bypass = true; |
170 | n = n_t; | 191 | n = n_t; |
171 | m = m_t; | 192 | m = 0; |
193 | k = k_t; | ||
172 | if (red == 0) | 194 | if (red == 0) |
173 | goto code_find; | 195 | goto code_find; |
174 | red_t = red; | 196 | red_t = red; |
175 | } | 197 | } |
198 | for (m_t = 0; m_t <= max_m; m_t++) { | ||
199 | out_t = in_t / ((m_t + 2) * (k_t + 2)); | ||
200 | red = abs(f_out - out_t); | ||
201 | if (red < red_t) { | ||
202 | bypass = false; | ||
203 | n = n_t; | ||
204 | m = m_t; | ||
205 | k = k_t; | ||
206 | if (red == 0) | ||
207 | goto code_find; | ||
208 | red_t = red; | ||
209 | } | ||
210 | } | ||
176 | } | 211 | } |
177 | } | 212 | } |
178 | pr_debug("Only get approximation about PLL\n"); | 213 | pr_debug("Only get approximation about PLL\n"); |
diff --git a/sound/soc/codecs/rt5514-spi.c b/sound/soc/codecs/rt5514-spi.c index 64bf26cec20d..2144edca97b0 100644 --- a/sound/soc/codecs/rt5514-spi.c +++ b/sound/soc/codecs/rt5514-spi.c | |||
@@ -381,6 +381,7 @@ int rt5514_spi_burst_read(unsigned int addr, u8 *rxbuf, size_t len) | |||
381 | 381 | ||
382 | return true; | 382 | return true; |
383 | } | 383 | } |
384 | EXPORT_SYMBOL_GPL(rt5514_spi_burst_read); | ||
384 | 385 | ||
385 | /** | 386 | /** |
386 | * rt5514_spi_burst_write - Write data to SPI by rt5514 address. | 387 | * rt5514_spi_burst_write - Write data to SPI by rt5514 address. |
diff --git a/sound/soc/codecs/rt5514.c b/sound/soc/codecs/rt5514.c index 2dd6e9f990a4..198df016802f 100644 --- a/sound/soc/codecs/rt5514.c +++ b/sound/soc/codecs/rt5514.c | |||
@@ -295,6 +295,33 @@ static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, | |||
295 | return 0; | 295 | return 0; |
296 | } | 296 | } |
297 | 297 | ||
298 | static int rt5514_calibration(struct rt5514_priv *rt5514, bool on) | ||
299 | { | ||
300 | if (on) { | ||
301 | regmap_write(rt5514->regmap, RT5514_ANA_CTRL_PLL3, 0x0000000a); | ||
302 | regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL, 0xf, | ||
303 | 0xa); | ||
304 | regmap_update_bits(rt5514->regmap, RT5514_PWR_ANA1, 0x301, | ||
305 | 0x301); | ||
306 | regmap_write(rt5514->regmap, RT5514_PLL3_CALIB_CTRL4, | ||
307 | 0x80000000 | rt5514->pll3_cal_value); | ||
308 | regmap_write(rt5514->regmap, RT5514_PLL3_CALIB_CTRL1, | ||
309 | 0x8bb80800); | ||
310 | regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5, | ||
311 | 0xc0000000, 0x80000000); | ||
312 | regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5, | ||
313 | 0xc0000000, 0xc0000000); | ||
314 | } else { | ||
315 | regmap_update_bits(rt5514->regmap, RT5514_PLL3_CALIB_CTRL5, | ||
316 | 0xc0000000, 0x40000000); | ||
317 | regmap_update_bits(rt5514->regmap, RT5514_PWR_ANA1, 0x301, 0); | ||
318 | regmap_update_bits(rt5514->regmap, RT5514_PLL_SOURCE_CTRL, 0xf, | ||
319 | 0x4); | ||
320 | } | ||
321 | |||
322 | return 0; | ||
323 | } | ||
324 | |||
298 | static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, | 325 | static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, |
299 | struct snd_ctl_elem_value *ucontrol) | 326 | struct snd_ctl_elem_value *ucontrol) |
300 | { | 327 | { |
@@ -302,6 +329,7 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, | |||
302 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); | 329 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(component); |
303 | struct snd_soc_codec *codec = rt5514->codec; | 330 | struct snd_soc_codec *codec = rt5514->codec; |
304 | const struct firmware *fw = NULL; | 331 | const struct firmware *fw = NULL; |
332 | u8 buf[8]; | ||
305 | 333 | ||
306 | if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled) | 334 | if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled) |
307 | return 0; | 335 | return 0; |
@@ -310,6 +338,35 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, | |||
310 | rt5514->dsp_enabled = ucontrol->value.integer.value[0]; | 338 | rt5514->dsp_enabled = ucontrol->value.integer.value[0]; |
311 | 339 | ||
312 | if (rt5514->dsp_enabled) { | 340 | if (rt5514->dsp_enabled) { |
341 | if (rt5514->pdata.dsp_calib_clk_name && | ||
342 | !IS_ERR(rt5514->dsp_calib_clk)) { | ||
343 | if (clk_set_rate(rt5514->dsp_calib_clk, | ||
344 | rt5514->pdata.dsp_calib_clk_rate)) | ||
345 | dev_err(codec->dev, | ||
346 | "Can't set rate for mclk"); | ||
347 | |||
348 | if (clk_prepare_enable(rt5514->dsp_calib_clk)) | ||
349 | dev_err(codec->dev, | ||
350 | "Can't enable dsp_calib_clk"); | ||
351 | |||
352 | rt5514_calibration(rt5514, true); | ||
353 | |||
354 | msleep(20); | ||
355 | #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) | ||
356 | rt5514_spi_burst_read(RT5514_PLL3_CALIB_CTRL6 | | ||
357 | RT5514_DSP_MAPPING, | ||
358 | (u8 *)&buf, sizeof(buf)); | ||
359 | #else | ||
360 | dev_err(codec->dev, "There is no SPI driver for" | ||
361 | " loading the firmware\n"); | ||
362 | #endif | ||
363 | rt5514->pll3_cal_value = buf[0] | buf[1] << 8 | | ||
364 | buf[2] << 16 | buf[3] << 24; | ||
365 | |||
366 | rt5514_calibration(rt5514, false); | ||
367 | clk_disable_unprepare(rt5514->dsp_calib_clk); | ||
368 | } | ||
369 | |||
313 | rt5514_enable_dsp_prepare(rt5514); | 370 | rt5514_enable_dsp_prepare(rt5514); |
314 | 371 | ||
315 | request_firmware(&fw, RT5514_FIRMWARE1, codec->dev); | 372 | request_firmware(&fw, RT5514_FIRMWARE1, codec->dev); |
@@ -341,6 +398,20 @@ static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, | |||
341 | /* DSP run */ | 398 | /* DSP run */ |
342 | regmap_write(rt5514->i2c_regmap, 0x18002f00, | 399 | regmap_write(rt5514->i2c_regmap, 0x18002f00, |
343 | 0x00055148); | 400 | 0x00055148); |
401 | |||
402 | if (rt5514->pdata.dsp_calib_clk_name && | ||
403 | !IS_ERR(rt5514->dsp_calib_clk)) { | ||
404 | msleep(20); | ||
405 | |||
406 | regmap_write(rt5514->i2c_regmap, 0x1800211c, | ||
407 | rt5514->pll3_cal_value); | ||
408 | regmap_write(rt5514->i2c_regmap, 0x18002124, | ||
409 | 0x00220012); | ||
410 | regmap_write(rt5514->i2c_regmap, 0x18002124, | ||
411 | 0x80220042); | ||
412 | regmap_write(rt5514->i2c_regmap, 0x18002124, | ||
413 | 0xe0220042); | ||
414 | } | ||
344 | } else { | 415 | } else { |
345 | regmap_multi_reg_write(rt5514->i2c_regmap, | 416 | regmap_multi_reg_write(rt5514->i2c_regmap, |
346 | rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); | 417 | rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); |
@@ -1024,12 +1095,22 @@ static int rt5514_set_bias_level(struct snd_soc_codec *codec, | |||
1024 | static int rt5514_probe(struct snd_soc_codec *codec) | 1095 | static int rt5514_probe(struct snd_soc_codec *codec) |
1025 | { | 1096 | { |
1026 | struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); | 1097 | struct rt5514_priv *rt5514 = snd_soc_codec_get_drvdata(codec); |
1098 | struct platform_device *pdev = container_of(codec->dev, | ||
1099 | struct platform_device, dev); | ||
1027 | 1100 | ||
1028 | rt5514->mclk = devm_clk_get(codec->dev, "mclk"); | 1101 | rt5514->mclk = devm_clk_get(codec->dev, "mclk"); |
1029 | if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER) | 1102 | if (PTR_ERR(rt5514->mclk) == -EPROBE_DEFER) |
1030 | return -EPROBE_DEFER; | 1103 | return -EPROBE_DEFER; |
1031 | 1104 | ||
1105 | if (rt5514->pdata.dsp_calib_clk_name) { | ||
1106 | rt5514->dsp_calib_clk = devm_clk_get(&pdev->dev, | ||
1107 | rt5514->pdata.dsp_calib_clk_name); | ||
1108 | if (PTR_ERR(rt5514->dsp_calib_clk) == -EPROBE_DEFER) | ||
1109 | return -EPROBE_DEFER; | ||
1110 | } | ||
1111 | |||
1032 | rt5514->codec = codec; | 1112 | rt5514->codec = codec; |
1113 | rt5514->pll3_cal_value = 0x0078b000; | ||
1033 | 1114 | ||
1034 | return 0; | 1115 | return 0; |
1035 | } | 1116 | } |
@@ -1147,6 +1228,10 @@ static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev) | |||
1147 | { | 1228 | { |
1148 | device_property_read_u32(dev, "realtek,dmic-init-delay-ms", | 1229 | device_property_read_u32(dev, "realtek,dmic-init-delay-ms", |
1149 | &rt5514->pdata.dmic_init_delay); | 1230 | &rt5514->pdata.dmic_init_delay); |
1231 | device_property_read_string(dev, "realtek,dsp-calib-clk-name", | ||
1232 | &rt5514->pdata.dsp_calib_clk_name); | ||
1233 | device_property_read_u32(dev, "realtek,dsp-calib-clk-rate", | ||
1234 | &rt5514->pdata.dsp_calib_clk_rate); | ||
1150 | 1235 | ||
1151 | return 0; | 1236 | return 0; |
1152 | } | 1237 | } |
diff --git a/sound/soc/codecs/rt5514.h b/sound/soc/codecs/rt5514.h index 2dc40e6d8b3f..f0f3400ce6b1 100644 --- a/sound/soc/codecs/rt5514.h +++ b/sound/soc/codecs/rt5514.h | |||
@@ -34,7 +34,9 @@ | |||
34 | #define RT5514_CLK_CTRL1 0x2104 | 34 | #define RT5514_CLK_CTRL1 0x2104 |
35 | #define RT5514_CLK_CTRL2 0x2108 | 35 | #define RT5514_CLK_CTRL2 0x2108 |
36 | #define RT5514_PLL3_CALIB_CTRL1 0x2110 | 36 | #define RT5514_PLL3_CALIB_CTRL1 0x2110 |
37 | #define RT5514_PLL3_CALIB_CTRL4 0x2120 | ||
37 | #define RT5514_PLL3_CALIB_CTRL5 0x2124 | 38 | #define RT5514_PLL3_CALIB_CTRL5 0x2124 |
39 | #define RT5514_PLL3_CALIB_CTRL6 0x2128 | ||
38 | #define RT5514_DELAY_BUF_CTRL1 0x2140 | 40 | #define RT5514_DELAY_BUF_CTRL1 0x2140 |
39 | #define RT5514_DELAY_BUF_CTRL3 0x2148 | 41 | #define RT5514_DELAY_BUF_CTRL3 0x2148 |
40 | #define RT5514_ASRC_IN_CTRL1 0x2180 | 42 | #define RT5514_ASRC_IN_CTRL1 0x2180 |
@@ -272,7 +274,7 @@ struct rt5514_priv { | |||
272 | struct rt5514_platform_data pdata; | 274 | struct rt5514_platform_data pdata; |
273 | struct snd_soc_codec *codec; | 275 | struct snd_soc_codec *codec; |
274 | struct regmap *i2c_regmap, *regmap; | 276 | struct regmap *i2c_regmap, *regmap; |
275 | struct clk *mclk; | 277 | struct clk *mclk, *dsp_calib_clk; |
276 | int sysclk; | 278 | int sysclk; |
277 | int sysclk_src; | 279 | int sysclk_src; |
278 | int lrck; | 280 | int lrck; |
@@ -281,6 +283,7 @@ struct rt5514_priv { | |||
281 | int pll_in; | 283 | int pll_in; |
282 | int pll_out; | 284 | int pll_out; |
283 | int dsp_enabled; | 285 | int dsp_enabled; |
286 | unsigned int pll3_cal_value; | ||
284 | }; | 287 | }; |
285 | 288 | ||
286 | #endif /* __RT5514_H__ */ | 289 | #endif /* __RT5514_H__ */ |
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c index edc152c8a1fe..8f140c8b93ac 100644 --- a/sound/soc/codecs/rt5645.c +++ b/sound/soc/codecs/rt5645.c | |||
@@ -1943,6 +1943,56 @@ static int rt5650_hp_event(struct snd_soc_dapm_widget *w, | |||
1943 | return 0; | 1943 | return 0; |
1944 | } | 1944 | } |
1945 | 1945 | ||
1946 | static int rt5645_set_micbias1_event(struct snd_soc_dapm_widget *w, | ||
1947 | struct snd_kcontrol *k, int event) | ||
1948 | { | ||
1949 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1950 | |||
1951 | switch (event) { | ||
1952 | case SND_SOC_DAPM_PRE_PMU: | ||
1953 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1954 | RT5645_MICBIAS1_POW_CTRL_SEL_MASK, | ||
1955 | RT5645_MICBIAS1_POW_CTRL_SEL_M); | ||
1956 | break; | ||
1957 | |||
1958 | case SND_SOC_DAPM_POST_PMD: | ||
1959 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1960 | RT5645_MICBIAS1_POW_CTRL_SEL_MASK, | ||
1961 | RT5645_MICBIAS1_POW_CTRL_SEL_A); | ||
1962 | break; | ||
1963 | |||
1964 | default: | ||
1965 | return 0; | ||
1966 | } | ||
1967 | |||
1968 | return 0; | ||
1969 | } | ||
1970 | |||
1971 | static int rt5645_set_micbias2_event(struct snd_soc_dapm_widget *w, | ||
1972 | struct snd_kcontrol *k, int event) | ||
1973 | { | ||
1974 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
1975 | |||
1976 | switch (event) { | ||
1977 | case SND_SOC_DAPM_PRE_PMU: | ||
1978 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1979 | RT5645_MICBIAS2_POW_CTRL_SEL_MASK, | ||
1980 | RT5645_MICBIAS2_POW_CTRL_SEL_M); | ||
1981 | break; | ||
1982 | |||
1983 | case SND_SOC_DAPM_POST_PMD: | ||
1984 | snd_soc_update_bits(codec, RT5645_GEN_CTRL2, | ||
1985 | RT5645_MICBIAS2_POW_CTRL_SEL_MASK, | ||
1986 | RT5645_MICBIAS2_POW_CTRL_SEL_A); | ||
1987 | break; | ||
1988 | |||
1989 | default: | ||
1990 | return 0; | ||
1991 | } | ||
1992 | |||
1993 | return 0; | ||
1994 | } | ||
1995 | |||
1946 | static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | 1996 | static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { |
1947 | SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER, | 1997 | SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER, |
1948 | RT5645_PWR_LDO2_BIT, 0, NULL, 0), | 1998 | RT5645_PWR_LDO2_BIT, 0, NULL, 0), |
@@ -1980,10 +2030,12 @@ static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | |||
1980 | 2030 | ||
1981 | /* Input Side */ | 2031 | /* Input Side */ |
1982 | /* micbias */ | 2032 | /* micbias */ |
1983 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, | 2033 | SND_SOC_DAPM_SUPPLY("micbias1", RT5645_PWR_ANLG2, |
1984 | RT5645_PWR_MB1_BIT, 0), | 2034 | RT5645_PWR_MB1_BIT, 0, rt5645_set_micbias1_event, |
1985 | SND_SOC_DAPM_MICBIAS("micbias2", RT5645_PWR_ANLG2, | 2035 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
1986 | RT5645_PWR_MB2_BIT, 0), | 2036 | SND_SOC_DAPM_SUPPLY("micbias2", RT5645_PWR_ANLG2, |
2037 | RT5645_PWR_MB2_BIT, 0, rt5645_set_micbias2_event, | ||
2038 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
1987 | /* Input Lines */ | 2039 | /* Input Lines */ |
1988 | SND_SOC_DAPM_INPUT("DMIC L1"), | 2040 | SND_SOC_DAPM_INPUT("DMIC L1"), |
1989 | SND_SOC_DAPM_INPUT("DMIC R1"), | 2041 | SND_SOC_DAPM_INPUT("DMIC R1"), |
@@ -3394,6 +3446,9 @@ static int rt5645_probe(struct snd_soc_codec *codec) | |||
3394 | snd_soc_dapm_sync(dapm); | 3446 | snd_soc_dapm_sync(dapm); |
3395 | } | 3447 | } |
3396 | 3448 | ||
3449 | if (rt5645->pdata.long_name) | ||
3450 | codec->component.card->long_name = rt5645->pdata.long_name; | ||
3451 | |||
3397 | rt5645->eq_param = devm_kzalloc(codec->dev, | 3452 | rt5645->eq_param = devm_kzalloc(codec->dev, |
3398 | RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); | 3453 | RT5645_HWEQ_NUM * sizeof(struct rt5645_eq_param_s), GFP_KERNEL); |
3399 | 3454 | ||
@@ -3570,63 +3625,74 @@ static const struct acpi_device_id rt5645_acpi_match[] = { | |||
3570 | MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); | 3625 | MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match); |
3571 | #endif | 3626 | #endif |
3572 | 3627 | ||
3573 | static const struct rt5645_platform_data general_platform_data = { | 3628 | static const struct rt5645_platform_data intel_braswell_platform_data = { |
3574 | .dmic1_data_pin = RT5645_DMIC1_DISABLE, | 3629 | .dmic1_data_pin = RT5645_DMIC1_DISABLE, |
3575 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | 3630 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, |
3576 | .jd_mode = 3, | 3631 | .jd_mode = 3, |
3577 | }; | 3632 | }; |
3578 | 3633 | ||
3579 | static const struct dmi_system_id dmi_platform_intel_braswell[] = { | 3634 | static const struct rt5645_platform_data buddy_platform_data = { |
3635 | .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, | ||
3636 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | ||
3637 | .jd_mode = 3, | ||
3638 | .level_trigger_irq = true, | ||
3639 | }; | ||
3640 | |||
3641 | static const struct rt5645_platform_data gpd_win_platform_data = { | ||
3642 | .jd_mode = 3, | ||
3643 | .inv_jd1_1 = true, | ||
3644 | .long_name = "gpd-win-pocket-rt5645", | ||
3645 | /* The GPD pocket has a diff. mic, for the win this does not matter. */ | ||
3646 | .in2_diff = true, | ||
3647 | }; | ||
3648 | |||
3649 | static const struct rt5645_platform_data asus_t100ha_platform_data = { | ||
3650 | .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, | ||
3651 | .dmic2_data_pin = RT5645_DMIC2_DISABLE, | ||
3652 | .jd_mode = 3, | ||
3653 | .inv_jd1_1 = true, | ||
3654 | }; | ||
3655 | |||
3656 | static const struct rt5645_platform_data jd_mode3_platform_data = { | ||
3657 | .jd_mode = 3, | ||
3658 | }; | ||
3659 | |||
3660 | static const struct dmi_system_id dmi_platform_data[] = { | ||
3661 | { | ||
3662 | .ident = "Chrome Buddy", | ||
3663 | .matches = { | ||
3664 | DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), | ||
3665 | }, | ||
3666 | .driver_data = (void *)&buddy_platform_data, | ||
3667 | }, | ||
3580 | { | 3668 | { |
3581 | .ident = "Intel Strago", | 3669 | .ident = "Intel Strago", |
3582 | .matches = { | 3670 | .matches = { |
3583 | DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), | 3671 | DMI_MATCH(DMI_PRODUCT_NAME, "Strago"), |
3584 | }, | 3672 | }, |
3673 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3585 | }, | 3674 | }, |
3586 | { | 3675 | { |
3587 | .ident = "Google Chrome", | 3676 | .ident = "Google Chrome", |
3588 | .matches = { | 3677 | .matches = { |
3589 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), | 3678 | DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"), |
3590 | }, | 3679 | }, |
3680 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3591 | }, | 3681 | }, |
3592 | { | 3682 | { |
3593 | .ident = "Google Setzer", | 3683 | .ident = "Google Setzer", |
3594 | .matches = { | 3684 | .matches = { |
3595 | DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), | 3685 | DMI_MATCH(DMI_PRODUCT_NAME, "Setzer"), |
3596 | }, | 3686 | }, |
3687 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3597 | }, | 3688 | }, |
3598 | { | 3689 | { |
3599 | .ident = "Microsoft Surface 3", | 3690 | .ident = "Microsoft Surface 3", |
3600 | .matches = { | 3691 | .matches = { |
3601 | DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), | 3692 | DMI_MATCH(DMI_PRODUCT_NAME, "Surface 3"), |
3602 | }, | 3693 | }, |
3694 | .driver_data = (void *)&intel_braswell_platform_data, | ||
3603 | }, | 3695 | }, |
3604 | { } | ||
3605 | }; | ||
3606 | |||
3607 | static const struct rt5645_platform_data buddy_platform_data = { | ||
3608 | .dmic1_data_pin = RT5645_DMIC_DATA_GPIO5, | ||
3609 | .dmic2_data_pin = RT5645_DMIC_DATA_IN2P, | ||
3610 | .jd_mode = 3, | ||
3611 | .level_trigger_irq = true, | ||
3612 | }; | ||
3613 | |||
3614 | static const struct dmi_system_id dmi_platform_intel_broadwell[] = { | ||
3615 | { | ||
3616 | .ident = "Chrome Buddy", | ||
3617 | .matches = { | ||
3618 | DMI_MATCH(DMI_PRODUCT_NAME, "Buddy"), | ||
3619 | }, | ||
3620 | }, | ||
3621 | { } | ||
3622 | }; | ||
3623 | |||
3624 | static const struct rt5645_platform_data gpd_win_platform_data = { | ||
3625 | .jd_mode = 3, | ||
3626 | .inv_jd1_1 = true, | ||
3627 | }; | ||
3628 | |||
3629 | static const struct dmi_system_id dmi_platform_gpd_win[] = { | ||
3630 | { | 3696 | { |
3631 | /* | 3697 | /* |
3632 | * Match for the GPDwin which unfortunately uses somewhat | 3698 | * Match for the GPDwin which unfortunately uses somewhat |
@@ -3637,46 +3703,38 @@ static const struct dmi_system_id dmi_platform_gpd_win[] = { | |||
3637 | * the same default product_name. Also the GPDwin is the | 3703 | * the same default product_name. Also the GPDwin is the |
3638 | * only device to have both board_ and product_name not set. | 3704 | * only device to have both board_ and product_name not set. |
3639 | */ | 3705 | */ |
3640 | .ident = "GPD Win", | 3706 | .ident = "GPD Win / Pocket", |
3641 | .matches = { | 3707 | .matches = { |
3642 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), | 3708 | DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
3643 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), | 3709 | DMI_MATCH(DMI_BOARD_NAME, "Default string"), |
3644 | DMI_MATCH(DMI_BOARD_SERIAL, "Default string"), | 3710 | DMI_MATCH(DMI_BOARD_SERIAL, "Default string"), |
3645 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), | 3711 | DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), |
3646 | }, | 3712 | }, |
3713 | .driver_data = (void *)&gpd_win_platform_data, | ||
3647 | }, | 3714 | }, |
3648 | {} | ||
3649 | }; | ||
3650 | |||
3651 | static const struct rt5645_platform_data general_platform_data2 = { | ||
3652 | .dmic1_data_pin = RT5645_DMIC_DATA_IN2N, | ||
3653 | .dmic2_data_pin = RT5645_DMIC2_DISABLE, | ||
3654 | .jd_mode = 3, | ||
3655 | .inv_jd1_1 = true, | ||
3656 | }; | ||
3657 | |||
3658 | static const struct dmi_system_id dmi_platform_asus_t100ha[] = { | ||
3659 | { | 3715 | { |
3660 | .ident = "ASUS T100HAN", | 3716 | .ident = "ASUS T100HAN", |
3661 | .matches = { | 3717 | .matches = { |
3662 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 3718 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
3663 | DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), | 3719 | DMI_MATCH(DMI_PRODUCT_NAME, "T100HAN"), |
3664 | }, | 3720 | }, |
3721 | .driver_data = (void *)&asus_t100ha_platform_data, | ||
3665 | }, | 3722 | }, |
3666 | { } | ||
3667 | }; | ||
3668 | |||
3669 | static const struct rt5645_platform_data minix_z83_4_platform_data = { | ||
3670 | .jd_mode = 3, | ||
3671 | }; | ||
3672 | |||
3673 | static const struct dmi_system_id dmi_platform_minix_z83_4[] = { | ||
3674 | { | 3723 | { |
3675 | .ident = "MINIX Z83-4", | 3724 | .ident = "MINIX Z83-4", |
3676 | .matches = { | 3725 | .matches = { |
3677 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), | 3726 | DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MINIX"), |
3678 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), | 3727 | DMI_MATCH(DMI_PRODUCT_NAME, "Z83-4"), |
3679 | }, | 3728 | }, |
3729 | .driver_data = (void *)&jd_mode3_platform_data, | ||
3730 | }, | ||
3731 | { | ||
3732 | .ident = "Teclast X80 Pro", | ||
3733 | .matches = { | ||
3734 | DMI_MATCH(DMI_SYS_VENDOR, "TECLAST"), | ||
3735 | DMI_MATCH(DMI_PRODUCT_NAME, "X80 Pro"), | ||
3736 | }, | ||
3737 | .driver_data = (void *)&jd_mode3_platform_data, | ||
3680 | }, | 3738 | }, |
3681 | { } | 3739 | { } |
3682 | }; | 3740 | }; |
@@ -3684,9 +3742,9 @@ static const struct dmi_system_id dmi_platform_minix_z83_4[] = { | |||
3684 | static bool rt5645_check_dp(struct device *dev) | 3742 | static bool rt5645_check_dp(struct device *dev) |
3685 | { | 3743 | { |
3686 | if (device_property_present(dev, "realtek,in2-differential") || | 3744 | if (device_property_present(dev, "realtek,in2-differential") || |
3687 | device_property_present(dev, "realtek,dmic1-data-pin") || | 3745 | device_property_present(dev, "realtek,dmic1-data-pin") || |
3688 | device_property_present(dev, "realtek,dmic2-data-pin") || | 3746 | device_property_present(dev, "realtek,dmic2-data-pin") || |
3689 | device_property_present(dev, "realtek,jd-mode")) | 3747 | device_property_present(dev, "realtek,jd-mode")) |
3690 | return true; | 3748 | return true; |
3691 | 3749 | ||
3692 | return false; | 3750 | return false; |
@@ -3710,6 +3768,7 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3710 | const struct i2c_device_id *id) | 3768 | const struct i2c_device_id *id) |
3711 | { | 3769 | { |
3712 | struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev); | 3770 | struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev); |
3771 | const struct dmi_system_id *dmi_data; | ||
3713 | struct rt5645_priv *rt5645; | 3772 | struct rt5645_priv *rt5645; |
3714 | int ret, i; | 3773 | int ret, i; |
3715 | unsigned int val; | 3774 | unsigned int val; |
@@ -3723,20 +3782,18 @@ static int rt5645_i2c_probe(struct i2c_client *i2c, | |||
3723 | rt5645->i2c = i2c; | 3782 | rt5645->i2c = i2c; |
3724 | i2c_set_clientdata(i2c, rt5645); | 3783 | i2c_set_clientdata(i2c, rt5645); |
3725 | 3784 | ||
3785 | dmi_data = dmi_first_match(dmi_platform_data); | ||
3786 | if (dmi_data) { | ||
3787 | dev_info(&i2c->dev, "Detected %s platform\n", dmi_data->ident); | ||
3788 | pdata = dmi_data->driver_data; | ||
3789 | } | ||
3790 | |||
3726 | if (pdata) | 3791 | if (pdata) |
3727 | rt5645->pdata = *pdata; | 3792 | rt5645->pdata = *pdata; |
3728 | else if (dmi_check_system(dmi_platform_intel_broadwell)) | ||
3729 | rt5645->pdata = buddy_platform_data; | ||
3730 | else if (rt5645_check_dp(&i2c->dev)) | 3793 | else if (rt5645_check_dp(&i2c->dev)) |
3731 | rt5645_parse_dt(rt5645, &i2c->dev); | 3794 | rt5645_parse_dt(rt5645, &i2c->dev); |
3732 | else if (dmi_check_system(dmi_platform_intel_braswell)) | 3795 | else |
3733 | rt5645->pdata = general_platform_data; | 3796 | rt5645->pdata = jd_mode3_platform_data; |
3734 | else if (dmi_check_system(dmi_platform_gpd_win)) | ||
3735 | rt5645->pdata = gpd_win_platform_data; | ||
3736 | else if (dmi_check_system(dmi_platform_asus_t100ha)) | ||
3737 | rt5645->pdata = general_platform_data2; | ||
3738 | else if (dmi_check_system(dmi_platform_minix_z83_4)) | ||
3739 | rt5645->pdata = minix_z83_4_platform_data; | ||
3740 | 3797 | ||
3741 | if (quirk != -1) { | 3798 | if (quirk != -1) { |
3742 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); | 3799 | rt5645->pdata.in2_diff = QUIRK_IN2_DIFF(quirk); |
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h index cfc5f97549eb..940325b28c29 100644 --- a/sound/soc/codecs/rt5645.h +++ b/sound/soc/codecs/rt5645.h | |||
@@ -2117,6 +2117,12 @@ enum { | |||
2117 | #define RT5645_RXDC_SRC_STO (0x0 << 7) | 2117 | #define RT5645_RXDC_SRC_STO (0x0 << 7) |
2118 | #define RT5645_RXDC_SRC_MONO (0x1 << 7) | 2118 | #define RT5645_RXDC_SRC_MONO (0x1 << 7) |
2119 | #define RT5645_RXDC_SRC_SFT (7) | 2119 | #define RT5645_RXDC_SRC_SFT (7) |
2120 | #define RT5645_MICBIAS1_POW_CTRL_SEL_MASK (0x1 << 5) | ||
2121 | #define RT5645_MICBIAS1_POW_CTRL_SEL_A (0x0 << 5) | ||
2122 | #define RT5645_MICBIAS1_POW_CTRL_SEL_M (0x1 << 5) | ||
2123 | #define RT5645_MICBIAS2_POW_CTRL_SEL_MASK (0x1 << 4) | ||
2124 | #define RT5645_MICBIAS2_POW_CTRL_SEL_A (0x0 << 4) | ||
2125 | #define RT5645_MICBIAS2_POW_CTRL_SEL_M (0x1 << 4) | ||
2120 | #define RT5645_RXDP2_SEL_MASK (0x1 << 3) | 2126 | #define RT5645_RXDP2_SEL_MASK (0x1 << 3) |
2121 | #define RT5645_RXDP2_SEL_IF2 (0x0 << 3) | 2127 | #define RT5645_RXDP2_SEL_IF2 (0x0 << 3) |
2122 | #define RT5645_RXDP2_SEL_ADC (0x1 << 3) | 2128 | #define RT5645_RXDP2_SEL_ADC (0x1 << 3) |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index f2bb4feba3b6..633cdcfc933d 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -1332,10 +1332,13 @@ static int sgtl5000_i2c_probe(struct i2c_client *client, | |||
1332 | sgtl5000->mclk = devm_clk_get(&client->dev, NULL); | 1332 | sgtl5000->mclk = devm_clk_get(&client->dev, NULL); |
1333 | if (IS_ERR(sgtl5000->mclk)) { | 1333 | if (IS_ERR(sgtl5000->mclk)) { |
1334 | ret = PTR_ERR(sgtl5000->mclk); | 1334 | ret = PTR_ERR(sgtl5000->mclk); |
1335 | dev_err(&client->dev, "Failed to get mclock: %d\n", ret); | ||
1336 | /* Defer the probe to see if the clk will be provided later */ | 1335 | /* Defer the probe to see if the clk will be provided later */ |
1337 | if (ret == -ENOENT) | 1336 | if (ret == -ENOENT) |
1338 | ret = -EPROBE_DEFER; | 1337 | ret = -EPROBE_DEFER; |
1338 | |||
1339 | if (ret != -EPROBE_DEFER) | ||
1340 | dev_err(&client->dev, "Failed to get mclock: %d\n", | ||
1341 | ret); | ||
1339 | goto disable_regs; | 1342 | goto disable_regs; |
1340 | } | 1343 | } |
1341 | 1344 | ||
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 354dc0d64f11..7b91ee267b4e 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -231,14 +231,17 @@ static struct snd_soc_dai_driver si476x_dai = { | |||
231 | .ops = &si476x_dai_ops, | 231 | .ops = &si476x_dai_ops, |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static struct regmap *si476x_get_regmap(struct device *dev) | 234 | static int si476x_probe(struct snd_soc_component *component) |
235 | { | 235 | { |
236 | return dev_get_regmap(dev->parent, NULL); | 236 | snd_soc_component_init_regmap(component, |
237 | dev_get_regmap(component->dev->parent, NULL)); | ||
238 | |||
239 | return 0; | ||
237 | } | 240 | } |
238 | 241 | ||
239 | static const struct snd_soc_codec_driver soc_codec_dev_si476x = { | 242 | static const struct snd_soc_codec_driver soc_codec_dev_si476x = { |
240 | .get_regmap = si476x_get_regmap, | ||
241 | .component_driver = { | 243 | .component_driver = { |
244 | .probe = si476x_probe, | ||
242 | .dapm_widgets = si476x_dapm_widgets, | 245 | .dapm_widgets = si476x_dapm_widgets, |
243 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), | 246 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), |
244 | .dapm_routes = si476x_dapm_routes, | 247 | .dapm_routes = si476x_dapm_routes, |
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c deleted file mode 100644 index 887923e68849..000000000000 --- a/sound/soc/codecs/sn95031.c +++ /dev/null | |||
@@ -1,936 +0,0 @@ | |||
1 | /* | ||
2 | * sn95031.c - TI sn95031 Codec driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Intel Corp | ||
5 | * Author: Vinod Koul <vinod.koul@intel.com> | ||
6 | * Author: Harsha Priya <priya.harsha@intel.com> | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | * | ||
24 | * | ||
25 | */ | ||
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
27 | |||
28 | #include <linux/platform_device.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/module.h> | ||
32 | |||
33 | #include <asm/intel_scu_ipc.h> | ||
34 | #include <sound/pcm.h> | ||
35 | #include <sound/pcm_params.h> | ||
36 | #include <sound/soc.h> | ||
37 | #include <sound/soc-dapm.h> | ||
38 | #include <sound/initval.h> | ||
39 | #include <sound/tlv.h> | ||
40 | #include <sound/jack.h> | ||
41 | #include "sn95031.h" | ||
42 | |||
43 | #define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) | ||
44 | #define SN95031_FORMATS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) | ||
45 | |||
46 | /* adc helper functions */ | ||
47 | |||
48 | /* enables mic bias voltage */ | ||
49 | static void sn95031_enable_mic_bias(struct snd_soc_codec *codec) | ||
50 | { | ||
51 | snd_soc_write(codec, SN95031_VAUD, BIT(2)|BIT(1)|BIT(0)); | ||
52 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(2), BIT(2)); | ||
53 | } | ||
54 | |||
55 | /* Enable/Disable the ADC depending on the argument */ | ||
56 | static void configure_adc(struct snd_soc_codec *sn95031_codec, int val) | ||
57 | { | ||
58 | int value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); | ||
59 | |||
60 | if (val) { | ||
61 | /* Enable and start the ADC */ | ||
62 | value |= (SN95031_ADC_ENBL | SN95031_ADC_START); | ||
63 | value &= (~SN95031_ADC_NO_LOOP); | ||
64 | } else { | ||
65 | /* Just stop the ADC */ | ||
66 | value &= (~SN95031_ADC_START); | ||
67 | } | ||
68 | snd_soc_write(sn95031_codec, SN95031_ADC1CNTL1, value); | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * finds an empty channel for conversion | ||
73 | * If the ADC is not enabled then start using 0th channel | ||
74 | * itself. Otherwise find an empty channel by looking for a | ||
75 | * channel in which the stopbit is set to 1. returns the index | ||
76 | * of the first free channel if succeeds or an error code. | ||
77 | * | ||
78 | * Context: can sleep | ||
79 | * | ||
80 | */ | ||
81 | static int find_free_channel(struct snd_soc_codec *sn95031_codec) | ||
82 | { | ||
83 | int i, value; | ||
84 | |||
85 | /* check whether ADC is enabled */ | ||
86 | value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); | ||
87 | |||
88 | if ((value & SN95031_ADC_ENBL) == 0) | ||
89 | return 0; | ||
90 | |||
91 | /* ADC is already enabled; Looking for an empty channel */ | ||
92 | for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { | ||
93 | value = snd_soc_read(sn95031_codec, | ||
94 | SN95031_ADC_CHNL_START_ADDR + i); | ||
95 | if (value & SN95031_STOPBIT_MASK) | ||
96 | break; | ||
97 | } | ||
98 | return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i; | ||
99 | } | ||
100 | |||
101 | /* Initialize the ADC for reading micbias values. Can sleep. */ | ||
102 | static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec) | ||
103 | { | ||
104 | int base_addr, chnl_addr; | ||
105 | int value; | ||
106 | int channel_index; | ||
107 | |||
108 | /* Index of the first channel in which the stop bit is set */ | ||
109 | channel_index = find_free_channel(sn95031_codec); | ||
110 | if (channel_index < 0) { | ||
111 | pr_err("No free ADC channels"); | ||
112 | return channel_index; | ||
113 | } | ||
114 | |||
115 | base_addr = SN95031_ADC_CHNL_START_ADDR + channel_index; | ||
116 | |||
117 | if (!(channel_index == 0 || channel_index == SN95031_ADC_LOOP_MAX)) { | ||
118 | /* Reset stop bit for channels other than 0 and 12 */ | ||
119 | value = snd_soc_read(sn95031_codec, base_addr); | ||
120 | /* Set the stop bit to zero */ | ||
121 | snd_soc_write(sn95031_codec, base_addr, value & 0xEF); | ||
122 | /* Index of the first free channel */ | ||
123 | base_addr++; | ||
124 | channel_index++; | ||
125 | } | ||
126 | |||
127 | /* Since this is the last channel, set the stop bit | ||
128 | to 1 by ORing the DIE_SENSOR_CODE with 0x10 */ | ||
129 | snd_soc_write(sn95031_codec, base_addr, | ||
130 | SN95031_AUDIO_DETECT_CODE | 0x10); | ||
131 | |||
132 | chnl_addr = SN95031_ADC_DATA_START_ADDR + 2 * channel_index; | ||
133 | pr_debug("mid_initialize : %x", chnl_addr); | ||
134 | configure_adc(sn95031_codec, 1); | ||
135 | return chnl_addr; | ||
136 | } | ||
137 | |||
138 | |||
139 | /* reads the ADC registers and gets the mic bias value in mV. */ | ||
140 | static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec) | ||
141 | { | ||
142 | u16 adc_adr = sn95031_initialize_adc(codec); | ||
143 | u16 adc_val1, adc_val2; | ||
144 | unsigned int mic_bias; | ||
145 | |||
146 | sn95031_enable_mic_bias(codec); | ||
147 | |||
148 | /* Enable the sound card for conversion before reading */ | ||
149 | snd_soc_write(codec, SN95031_ADC1CNTL3, 0x05); | ||
150 | /* Re-toggle the RRDATARD bit */ | ||
151 | snd_soc_write(codec, SN95031_ADC1CNTL3, 0x04); | ||
152 | |||
153 | /* Read the higher bits of data */ | ||
154 | msleep(1000); | ||
155 | adc_val1 = snd_soc_read(codec, adc_adr); | ||
156 | adc_adr++; | ||
157 | adc_val2 = snd_soc_read(codec, adc_adr); | ||
158 | |||
159 | /* Adding lower two bits to the higher bits */ | ||
160 | mic_bias = (adc_val1 << 2) + (adc_val2 & 3); | ||
161 | mic_bias = (mic_bias * SN95031_ADC_ONE_LSB_MULTIPLIER) / 1000; | ||
162 | pr_debug("mic bias = %dmV\n", mic_bias); | ||
163 | return mic_bias; | ||
164 | } | ||
165 | /*end - adc helper functions */ | ||
166 | |||
167 | static int sn95031_read(void *ctx, unsigned int reg, unsigned int *val) | ||
168 | { | ||
169 | u8 value = 0; | ||
170 | int ret; | ||
171 | |||
172 | ret = intel_scu_ipc_ioread8(reg, &value); | ||
173 | if (ret == 0) | ||
174 | *val = value; | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static int sn95031_write(void *ctx, unsigned int reg, unsigned int value) | ||
180 | { | ||
181 | return intel_scu_ipc_iowrite8(reg, value); | ||
182 | } | ||
183 | |||
184 | static const struct regmap_config sn95031_regmap = { | ||
185 | .reg_read = sn95031_read, | ||
186 | .reg_write = sn95031_write, | ||
187 | }; | ||
188 | |||
189 | static int sn95031_set_vaud_bias(struct snd_soc_codec *codec, | ||
190 | enum snd_soc_bias_level level) | ||
191 | { | ||
192 | switch (level) { | ||
193 | case SND_SOC_BIAS_ON: | ||
194 | break; | ||
195 | |||
196 | case SND_SOC_BIAS_PREPARE: | ||
197 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) { | ||
198 | pr_debug("vaud_bias powering up pll\n"); | ||
199 | /* power up the pll */ | ||
200 | snd_soc_write(codec, SN95031_AUDPLLCTRL, BIT(5)); | ||
201 | /* enable pcm 2 */ | ||
202 | snd_soc_update_bits(codec, SN95031_PCM2C2, | ||
203 | BIT(0), BIT(0)); | ||
204 | } | ||
205 | break; | ||
206 | |||
207 | case SND_SOC_BIAS_STANDBY: | ||
208 | switch (snd_soc_codec_get_bias_level(codec)) { | ||
209 | case SND_SOC_BIAS_OFF: | ||
210 | pr_debug("vaud_bias power up rail\n"); | ||
211 | /* power up the rail */ | ||
212 | snd_soc_write(codec, SN95031_VAUD, | ||
213 | BIT(2)|BIT(1)|BIT(0)); | ||
214 | msleep(1); | ||
215 | break; | ||
216 | case SND_SOC_BIAS_PREPARE: | ||
217 | /* turn off pcm */ | ||
218 | pr_debug("vaud_bias power dn pcm\n"); | ||
219 | snd_soc_update_bits(codec, SN95031_PCM2C2, BIT(0), 0); | ||
220 | snd_soc_write(codec, SN95031_AUDPLLCTRL, 0); | ||
221 | break; | ||
222 | default: | ||
223 | break; | ||
224 | } | ||
225 | break; | ||
226 | |||
227 | |||
228 | case SND_SOC_BIAS_OFF: | ||
229 | pr_debug("vaud_bias _OFF doing rail shutdown\n"); | ||
230 | snd_soc_write(codec, SN95031_VAUD, BIT(3)); | ||
231 | break; | ||
232 | } | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static int sn95031_vhs_event(struct snd_soc_dapm_widget *w, | ||
238 | struct snd_kcontrol *kcontrol, int event) | ||
239 | { | ||
240 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
241 | |||
242 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
243 | pr_debug("VHS SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); | ||
244 | /* power up the rail */ | ||
245 | snd_soc_write(codec, SN95031_VHSP, 0x3D); | ||
246 | snd_soc_write(codec, SN95031_VHSN, 0x3F); | ||
247 | msleep(1); | ||
248 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
249 | pr_debug("VHS SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); | ||
250 | snd_soc_write(codec, SN95031_VHSP, 0xC4); | ||
251 | snd_soc_write(codec, SN95031_VHSN, 0x04); | ||
252 | } | ||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int sn95031_vihf_event(struct snd_soc_dapm_widget *w, | ||
257 | struct snd_kcontrol *kcontrol, int event) | ||
258 | { | ||
259 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
260 | |||
261 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
262 | pr_debug("VIHF SND_SOC_DAPM_EVENT_ON doing rail startup now\n"); | ||
263 | /* power up the rail */ | ||
264 | snd_soc_write(codec, SN95031_VIHF, 0x27); | ||
265 | msleep(1); | ||
266 | } else if (SND_SOC_DAPM_EVENT_OFF(event)) { | ||
267 | pr_debug("VIHF SND_SOC_DAPM_EVENT_OFF doing rail shutdown\n"); | ||
268 | snd_soc_write(codec, SN95031_VIHF, 0x24); | ||
269 | } | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int sn95031_dmic12_event(struct snd_soc_dapm_widget *w, | ||
274 | struct snd_kcontrol *k, int event) | ||
275 | { | ||
276 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
277 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; | ||
278 | |||
279 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
280 | ldo = BIT(5)|BIT(4); | ||
281 | clk_dir = BIT(0); | ||
282 | data_dir = BIT(7); | ||
283 | } | ||
284 | /* program DMIC LDO, clock and set clock */ | ||
285 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); | ||
286 | snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(0), clk_dir); | ||
287 | snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(7), data_dir); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
291 | static int sn95031_dmic34_event(struct snd_soc_dapm_widget *w, | ||
292 | struct snd_kcontrol *k, int event) | ||
293 | { | ||
294 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
295 | unsigned int ldo = 0, clk_dir = 0, data_dir = 0; | ||
296 | |||
297 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
298 | ldo = BIT(5)|BIT(4); | ||
299 | clk_dir = BIT(2); | ||
300 | data_dir = BIT(1); | ||
301 | } | ||
302 | /* program DMIC LDO, clock and set clock */ | ||
303 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(5)|BIT(4), ldo); | ||
304 | snd_soc_update_bits(codec, SN95031_DMICBUF0123, BIT(2), clk_dir); | ||
305 | snd_soc_update_bits(codec, SN95031_DMICBUF45, BIT(1), data_dir); | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static int sn95031_dmic56_event(struct snd_soc_dapm_widget *w, | ||
310 | struct snd_kcontrol *k, int event) | ||
311 | { | ||
312 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
313 | unsigned int ldo = 0; | ||
314 | |||
315 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
316 | ldo = BIT(7)|BIT(6); | ||
317 | |||
318 | /* program DMIC LDO */ | ||
319 | snd_soc_update_bits(codec, SN95031_MICBIAS, BIT(7)|BIT(6), ldo); | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | /* mux controls */ | ||
324 | static const char *sn95031_mic_texts[] = { "AMIC", "LineIn" }; | ||
325 | |||
326 | static SOC_ENUM_SINGLE_DECL(sn95031_micl_enum, | ||
327 | SN95031_ADCCONFIG, 1, sn95031_mic_texts); | ||
328 | |||
329 | static const struct snd_kcontrol_new sn95031_micl_mux_control = | ||
330 | SOC_DAPM_ENUM("Route", sn95031_micl_enum); | ||
331 | |||
332 | static SOC_ENUM_SINGLE_DECL(sn95031_micr_enum, | ||
333 | SN95031_ADCCONFIG, 3, sn95031_mic_texts); | ||
334 | |||
335 | static const struct snd_kcontrol_new sn95031_micr_mux_control = | ||
336 | SOC_DAPM_ENUM("Route", sn95031_micr_enum); | ||
337 | |||
338 | static const char *sn95031_input_texts[] = { "DMIC1", "DMIC2", "DMIC3", | ||
339 | "DMIC4", "DMIC5", "DMIC6", | ||
340 | "ADC Left", "ADC Right" }; | ||
341 | |||
342 | static SOC_ENUM_SINGLE_DECL(sn95031_input1_enum, | ||
343 | SN95031_AUDIOMUX12, 0, sn95031_input_texts); | ||
344 | |||
345 | static const struct snd_kcontrol_new sn95031_input1_mux_control = | ||
346 | SOC_DAPM_ENUM("Route", sn95031_input1_enum); | ||
347 | |||
348 | static SOC_ENUM_SINGLE_DECL(sn95031_input2_enum, | ||
349 | SN95031_AUDIOMUX12, 4, sn95031_input_texts); | ||
350 | |||
351 | static const struct snd_kcontrol_new sn95031_input2_mux_control = | ||
352 | SOC_DAPM_ENUM("Route", sn95031_input2_enum); | ||
353 | |||
354 | static SOC_ENUM_SINGLE_DECL(sn95031_input3_enum, | ||
355 | SN95031_AUDIOMUX34, 0, sn95031_input_texts); | ||
356 | |||
357 | static const struct snd_kcontrol_new sn95031_input3_mux_control = | ||
358 | SOC_DAPM_ENUM("Route", sn95031_input3_enum); | ||
359 | |||
360 | static SOC_ENUM_SINGLE_DECL(sn95031_input4_enum, | ||
361 | SN95031_AUDIOMUX34, 4, sn95031_input_texts); | ||
362 | |||
363 | static const struct snd_kcontrol_new sn95031_input4_mux_control = | ||
364 | SOC_DAPM_ENUM("Route", sn95031_input4_enum); | ||
365 | |||
366 | /* capture path controls */ | ||
367 | |||
368 | static const char *sn95031_micmode_text[] = {"Single Ended", "Differential"}; | ||
369 | |||
370 | /* 0dB to 30dB in 10dB steps */ | ||
371 | static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 10, 0); | ||
372 | |||
373 | static SOC_ENUM_SINGLE_DECL(sn95031_micmode1_enum, | ||
374 | SN95031_MICAMP1, 1, sn95031_micmode_text); | ||
375 | static SOC_ENUM_SINGLE_DECL(sn95031_micmode2_enum, | ||
376 | SN95031_MICAMP2, 1, sn95031_micmode_text); | ||
377 | |||
378 | static const char *sn95031_dmic_cfg_text[] = {"GPO", "DMIC"}; | ||
379 | |||
380 | static SOC_ENUM_SINGLE_DECL(sn95031_dmic12_cfg_enum, | ||
381 | SN95031_DMICMUX, 0, sn95031_dmic_cfg_text); | ||
382 | static SOC_ENUM_SINGLE_DECL(sn95031_dmic34_cfg_enum, | ||
383 | SN95031_DMICMUX, 1, sn95031_dmic_cfg_text); | ||
384 | static SOC_ENUM_SINGLE_DECL(sn95031_dmic56_cfg_enum, | ||
385 | SN95031_DMICMUX, 2, sn95031_dmic_cfg_text); | ||
386 | |||
387 | static const struct snd_kcontrol_new sn95031_snd_controls[] = { | ||
388 | SOC_ENUM("Mic1Mode Capture Route", sn95031_micmode1_enum), | ||
389 | SOC_ENUM("Mic2Mode Capture Route", sn95031_micmode2_enum), | ||
390 | SOC_ENUM("DMIC12 Capture Route", sn95031_dmic12_cfg_enum), | ||
391 | SOC_ENUM("DMIC34 Capture Route", sn95031_dmic34_cfg_enum), | ||
392 | SOC_ENUM("DMIC56 Capture Route", sn95031_dmic56_cfg_enum), | ||
393 | SOC_SINGLE_TLV("Mic1 Capture Volume", SN95031_MICAMP1, | ||
394 | 2, 4, 0, mic_tlv), | ||
395 | SOC_SINGLE_TLV("Mic2 Capture Volume", SN95031_MICAMP2, | ||
396 | 2, 4, 0, mic_tlv), | ||
397 | }; | ||
398 | |||
399 | /* DAPM widgets */ | ||
400 | static const struct snd_soc_dapm_widget sn95031_dapm_widgets[] = { | ||
401 | |||
402 | /* all end points mic, hs etc */ | ||
403 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | ||
404 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | ||
405 | SND_SOC_DAPM_OUTPUT("EPOUT"), | ||
406 | SND_SOC_DAPM_OUTPUT("IHFOUTL"), | ||
407 | SND_SOC_DAPM_OUTPUT("IHFOUTR"), | ||
408 | SND_SOC_DAPM_OUTPUT("LINEOUTL"), | ||
409 | SND_SOC_DAPM_OUTPUT("LINEOUTR"), | ||
410 | SND_SOC_DAPM_OUTPUT("VIB1OUT"), | ||
411 | SND_SOC_DAPM_OUTPUT("VIB2OUT"), | ||
412 | |||
413 | SND_SOC_DAPM_INPUT("AMIC1"), /* headset mic */ | ||
414 | SND_SOC_DAPM_INPUT("AMIC2"), | ||
415 | SND_SOC_DAPM_INPUT("DMIC1"), | ||
416 | SND_SOC_DAPM_INPUT("DMIC2"), | ||
417 | SND_SOC_DAPM_INPUT("DMIC3"), | ||
418 | SND_SOC_DAPM_INPUT("DMIC4"), | ||
419 | SND_SOC_DAPM_INPUT("DMIC5"), | ||
420 | SND_SOC_DAPM_INPUT("DMIC6"), | ||
421 | SND_SOC_DAPM_INPUT("LINEINL"), | ||
422 | SND_SOC_DAPM_INPUT("LINEINR"), | ||
423 | |||
424 | SND_SOC_DAPM_MICBIAS("AMIC1Bias", SN95031_MICBIAS, 2, 0), | ||
425 | SND_SOC_DAPM_MICBIAS("AMIC2Bias", SN95031_MICBIAS, 3, 0), | ||
426 | SND_SOC_DAPM_MICBIAS("DMIC12Bias", SN95031_DMICMUX, 3, 0), | ||
427 | SND_SOC_DAPM_MICBIAS("DMIC34Bias", SN95031_DMICMUX, 4, 0), | ||
428 | SND_SOC_DAPM_MICBIAS("DMIC56Bias", SN95031_DMICMUX, 5, 0), | ||
429 | |||
430 | SND_SOC_DAPM_SUPPLY("DMIC12supply", SN95031_DMICLK, 0, 0, | ||
431 | sn95031_dmic12_event, | ||
432 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
433 | SND_SOC_DAPM_SUPPLY("DMIC34supply", SN95031_DMICLK, 1, 0, | ||
434 | sn95031_dmic34_event, | ||
435 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
436 | SND_SOC_DAPM_SUPPLY("DMIC56supply", SN95031_DMICLK, 2, 0, | ||
437 | sn95031_dmic56_event, | ||
438 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
439 | |||
440 | SND_SOC_DAPM_AIF_OUT("PCM_Out", "Capture", 0, | ||
441 | SND_SOC_NOPM, 0, 0), | ||
442 | |||
443 | SND_SOC_DAPM_SUPPLY("Headset Rail", SND_SOC_NOPM, 0, 0, | ||
444 | sn95031_vhs_event, | ||
445 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
446 | SND_SOC_DAPM_SUPPLY("Speaker Rail", SND_SOC_NOPM, 0, 0, | ||
447 | sn95031_vihf_event, | ||
448 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
449 | |||
450 | /* playback path driver enables */ | ||
451 | SND_SOC_DAPM_PGA("Headset Left Playback", | ||
452 | SN95031_DRIVEREN, 0, 0, NULL, 0), | ||
453 | SND_SOC_DAPM_PGA("Headset Right Playback", | ||
454 | SN95031_DRIVEREN, 1, 0, NULL, 0), | ||
455 | SND_SOC_DAPM_PGA("Speaker Left Playback", | ||
456 | SN95031_DRIVEREN, 2, 0, NULL, 0), | ||
457 | SND_SOC_DAPM_PGA("Speaker Right Playback", | ||
458 | SN95031_DRIVEREN, 3, 0, NULL, 0), | ||
459 | SND_SOC_DAPM_PGA("Vibra1 Playback", | ||
460 | SN95031_DRIVEREN, 4, 0, NULL, 0), | ||
461 | SND_SOC_DAPM_PGA("Vibra2 Playback", | ||
462 | SN95031_DRIVEREN, 5, 0, NULL, 0), | ||
463 | SND_SOC_DAPM_PGA("Earpiece Playback", | ||
464 | SN95031_DRIVEREN, 6, 0, NULL, 0), | ||
465 | SND_SOC_DAPM_PGA("Lineout Left Playback", | ||
466 | SN95031_LOCTL, 0, 0, NULL, 0), | ||
467 | SND_SOC_DAPM_PGA("Lineout Right Playback", | ||
468 | SN95031_LOCTL, 4, 0, NULL, 0), | ||
469 | |||
470 | /* playback path filter enable */ | ||
471 | SND_SOC_DAPM_PGA("Headset Left Filter", | ||
472 | SN95031_HSEPRXCTRL, 4, 0, NULL, 0), | ||
473 | SND_SOC_DAPM_PGA("Headset Right Filter", | ||
474 | SN95031_HSEPRXCTRL, 5, 0, NULL, 0), | ||
475 | SND_SOC_DAPM_PGA("Speaker Left Filter", | ||
476 | SN95031_IHFRXCTRL, 0, 0, NULL, 0), | ||
477 | SND_SOC_DAPM_PGA("Speaker Right Filter", | ||
478 | SN95031_IHFRXCTRL, 1, 0, NULL, 0), | ||
479 | |||
480 | /* DACs */ | ||
481 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset", | ||
482 | SN95031_DACCONFIG, 0, 0), | ||
483 | SND_SOC_DAPM_DAC("HSDAC Right", "Headset", | ||
484 | SN95031_DACCONFIG, 1, 0), | ||
485 | SND_SOC_DAPM_DAC("IHFDAC Left", "Speaker", | ||
486 | SN95031_DACCONFIG, 2, 0), | ||
487 | SND_SOC_DAPM_DAC("IHFDAC Right", "Speaker", | ||
488 | SN95031_DACCONFIG, 3, 0), | ||
489 | SND_SOC_DAPM_DAC("Vibra1 DAC", "Vibra1", | ||
490 | SN95031_VIB1C5, 1, 0), | ||
491 | SND_SOC_DAPM_DAC("Vibra2 DAC", "Vibra2", | ||
492 | SN95031_VIB2C5, 1, 0), | ||
493 | |||
494 | /* capture widgets */ | ||
495 | SND_SOC_DAPM_PGA("LineIn Enable Left", SN95031_MICAMP1, | ||
496 | 7, 0, NULL, 0), | ||
497 | SND_SOC_DAPM_PGA("LineIn Enable Right", SN95031_MICAMP2, | ||
498 | 7, 0, NULL, 0), | ||
499 | |||
500 | SND_SOC_DAPM_PGA("MIC1 Enable", SN95031_MICAMP1, 0, 0, NULL, 0), | ||
501 | SND_SOC_DAPM_PGA("MIC2 Enable", SN95031_MICAMP2, 0, 0, NULL, 0), | ||
502 | SND_SOC_DAPM_PGA("TX1 Enable", SN95031_AUDIOTXEN, 2, 0, NULL, 0), | ||
503 | SND_SOC_DAPM_PGA("TX2 Enable", SN95031_AUDIOTXEN, 3, 0, NULL, 0), | ||
504 | SND_SOC_DAPM_PGA("TX3 Enable", SN95031_AUDIOTXEN, 4, 0, NULL, 0), | ||
505 | SND_SOC_DAPM_PGA("TX4 Enable", SN95031_AUDIOTXEN, 5, 0, NULL, 0), | ||
506 | |||
507 | /* ADC have null stream as they will be turned ON by TX path */ | ||
508 | SND_SOC_DAPM_ADC("ADC Left", NULL, | ||
509 | SN95031_ADCCONFIG, 0, 0), | ||
510 | SND_SOC_DAPM_ADC("ADC Right", NULL, | ||
511 | SN95031_ADCCONFIG, 2, 0), | ||
512 | |||
513 | SND_SOC_DAPM_MUX("Mic_InputL Capture Route", | ||
514 | SND_SOC_NOPM, 0, 0, &sn95031_micl_mux_control), | ||
515 | SND_SOC_DAPM_MUX("Mic_InputR Capture Route", | ||
516 | SND_SOC_NOPM, 0, 0, &sn95031_micr_mux_control), | ||
517 | |||
518 | SND_SOC_DAPM_MUX("Txpath1 Capture Route", | ||
519 | SND_SOC_NOPM, 0, 0, &sn95031_input1_mux_control), | ||
520 | SND_SOC_DAPM_MUX("Txpath2 Capture Route", | ||
521 | SND_SOC_NOPM, 0, 0, &sn95031_input2_mux_control), | ||
522 | SND_SOC_DAPM_MUX("Txpath3 Capture Route", | ||
523 | SND_SOC_NOPM, 0, 0, &sn95031_input3_mux_control), | ||
524 | SND_SOC_DAPM_MUX("Txpath4 Capture Route", | ||
525 | SND_SOC_NOPM, 0, 0, &sn95031_input4_mux_control), | ||
526 | |||
527 | }; | ||
528 | |||
529 | static const struct snd_soc_dapm_route sn95031_audio_map[] = { | ||
530 | /* headset and earpiece map */ | ||
531 | { "HPOUTL", NULL, "Headset Rail"}, | ||
532 | { "HPOUTR", NULL, "Headset Rail"}, | ||
533 | { "HPOUTL", NULL, "Headset Left Playback" }, | ||
534 | { "HPOUTR", NULL, "Headset Right Playback" }, | ||
535 | { "EPOUT", NULL, "Earpiece Playback" }, | ||
536 | { "Headset Left Playback", NULL, "Headset Left Filter"}, | ||
537 | { "Headset Right Playback", NULL, "Headset Right Filter"}, | ||
538 | { "Earpiece Playback", NULL, "Headset Left Filter"}, | ||
539 | { "Headset Left Filter", NULL, "HSDAC Left"}, | ||
540 | { "Headset Right Filter", NULL, "HSDAC Right"}, | ||
541 | |||
542 | /* speaker map */ | ||
543 | { "IHFOUTL", NULL, "Speaker Rail"}, | ||
544 | { "IHFOUTR", NULL, "Speaker Rail"}, | ||
545 | { "IHFOUTL", NULL, "Speaker Left Playback"}, | ||
546 | { "IHFOUTR", NULL, "Speaker Right Playback"}, | ||
547 | { "Speaker Left Playback", NULL, "Speaker Left Filter"}, | ||
548 | { "Speaker Right Playback", NULL, "Speaker Right Filter"}, | ||
549 | { "Speaker Left Filter", NULL, "IHFDAC Left"}, | ||
550 | { "Speaker Right Filter", NULL, "IHFDAC Right"}, | ||
551 | |||
552 | /* vibra map */ | ||
553 | { "VIB1OUT", NULL, "Vibra1 Playback"}, | ||
554 | { "Vibra1 Playback", NULL, "Vibra1 DAC"}, | ||
555 | |||
556 | { "VIB2OUT", NULL, "Vibra2 Playback"}, | ||
557 | { "Vibra2 Playback", NULL, "Vibra2 DAC"}, | ||
558 | |||
559 | /* lineout */ | ||
560 | { "LINEOUTL", NULL, "Lineout Left Playback"}, | ||
561 | { "LINEOUTR", NULL, "Lineout Right Playback"}, | ||
562 | { "Lineout Left Playback", NULL, "Headset Left Filter"}, | ||
563 | { "Lineout Left Playback", NULL, "Speaker Left Filter"}, | ||
564 | { "Lineout Left Playback", NULL, "Vibra1 DAC"}, | ||
565 | { "Lineout Right Playback", NULL, "Headset Right Filter"}, | ||
566 | { "Lineout Right Playback", NULL, "Speaker Right Filter"}, | ||
567 | { "Lineout Right Playback", NULL, "Vibra2 DAC"}, | ||
568 | |||
569 | /* Headset (AMIC1) mic */ | ||
570 | { "AMIC1Bias", NULL, "AMIC1"}, | ||
571 | { "MIC1 Enable", NULL, "AMIC1Bias"}, | ||
572 | { "Mic_InputL Capture Route", "AMIC", "MIC1 Enable"}, | ||
573 | |||
574 | /* AMIC2 */ | ||
575 | { "AMIC2Bias", NULL, "AMIC2"}, | ||
576 | { "MIC2 Enable", NULL, "AMIC2Bias"}, | ||
577 | { "Mic_InputR Capture Route", "AMIC", "MIC2 Enable"}, | ||
578 | |||
579 | |||
580 | /* Linein */ | ||
581 | { "LineIn Enable Left", NULL, "LINEINL"}, | ||
582 | { "LineIn Enable Right", NULL, "LINEINR"}, | ||
583 | { "Mic_InputL Capture Route", "LineIn", "LineIn Enable Left"}, | ||
584 | { "Mic_InputR Capture Route", "LineIn", "LineIn Enable Right"}, | ||
585 | |||
586 | /* ADC connection */ | ||
587 | { "ADC Left", NULL, "Mic_InputL Capture Route"}, | ||
588 | { "ADC Right", NULL, "Mic_InputR Capture Route"}, | ||
589 | |||
590 | /*DMIC connections */ | ||
591 | { "DMIC1", NULL, "DMIC12supply"}, | ||
592 | { "DMIC2", NULL, "DMIC12supply"}, | ||
593 | { "DMIC3", NULL, "DMIC34supply"}, | ||
594 | { "DMIC4", NULL, "DMIC34supply"}, | ||
595 | { "DMIC5", NULL, "DMIC56supply"}, | ||
596 | { "DMIC6", NULL, "DMIC56supply"}, | ||
597 | |||
598 | { "DMIC12Bias", NULL, "DMIC1"}, | ||
599 | { "DMIC12Bias", NULL, "DMIC2"}, | ||
600 | { "DMIC34Bias", NULL, "DMIC3"}, | ||
601 | { "DMIC34Bias", NULL, "DMIC4"}, | ||
602 | { "DMIC56Bias", NULL, "DMIC5"}, | ||
603 | { "DMIC56Bias", NULL, "DMIC6"}, | ||
604 | |||
605 | /*TX path inputs*/ | ||
606 | { "Txpath1 Capture Route", "ADC Left", "ADC Left"}, | ||
607 | { "Txpath2 Capture Route", "ADC Left", "ADC Left"}, | ||
608 | { "Txpath3 Capture Route", "ADC Left", "ADC Left"}, | ||
609 | { "Txpath4 Capture Route", "ADC Left", "ADC Left"}, | ||
610 | { "Txpath1 Capture Route", "ADC Right", "ADC Right"}, | ||
611 | { "Txpath2 Capture Route", "ADC Right", "ADC Right"}, | ||
612 | { "Txpath3 Capture Route", "ADC Right", "ADC Right"}, | ||
613 | { "Txpath4 Capture Route", "ADC Right", "ADC Right"}, | ||
614 | { "Txpath1 Capture Route", "DMIC1", "DMIC1"}, | ||
615 | { "Txpath2 Capture Route", "DMIC1", "DMIC1"}, | ||
616 | { "Txpath3 Capture Route", "DMIC1", "DMIC1"}, | ||
617 | { "Txpath4 Capture Route", "DMIC1", "DMIC1"}, | ||
618 | { "Txpath1 Capture Route", "DMIC2", "DMIC2"}, | ||
619 | { "Txpath2 Capture Route", "DMIC2", "DMIC2"}, | ||
620 | { "Txpath3 Capture Route", "DMIC2", "DMIC2"}, | ||
621 | { "Txpath4 Capture Route", "DMIC2", "DMIC2"}, | ||
622 | { "Txpath1 Capture Route", "DMIC3", "DMIC3"}, | ||
623 | { "Txpath2 Capture Route", "DMIC3", "DMIC3"}, | ||
624 | { "Txpath3 Capture Route", "DMIC3", "DMIC3"}, | ||
625 | { "Txpath4 Capture Route", "DMIC3", "DMIC3"}, | ||
626 | { "Txpath1 Capture Route", "DMIC4", "DMIC4"}, | ||
627 | { "Txpath2 Capture Route", "DMIC4", "DMIC4"}, | ||
628 | { "Txpath3 Capture Route", "DMIC4", "DMIC4"}, | ||
629 | { "Txpath4 Capture Route", "DMIC4", "DMIC4"}, | ||
630 | { "Txpath1 Capture Route", "DMIC5", "DMIC5"}, | ||
631 | { "Txpath2 Capture Route", "DMIC5", "DMIC5"}, | ||
632 | { "Txpath3 Capture Route", "DMIC5", "DMIC5"}, | ||
633 | { "Txpath4 Capture Route", "DMIC5", "DMIC5"}, | ||
634 | { "Txpath1 Capture Route", "DMIC6", "DMIC6"}, | ||
635 | { "Txpath2 Capture Route", "DMIC6", "DMIC6"}, | ||
636 | { "Txpath3 Capture Route", "DMIC6", "DMIC6"}, | ||
637 | { "Txpath4 Capture Route", "DMIC6", "DMIC6"}, | ||
638 | |||
639 | /* tx path */ | ||
640 | { "TX1 Enable", NULL, "Txpath1 Capture Route"}, | ||
641 | { "TX2 Enable", NULL, "Txpath2 Capture Route"}, | ||
642 | { "TX3 Enable", NULL, "Txpath3 Capture Route"}, | ||
643 | { "TX4 Enable", NULL, "Txpath4 Capture Route"}, | ||
644 | { "PCM_Out", NULL, "TX1 Enable"}, | ||
645 | { "PCM_Out", NULL, "TX2 Enable"}, | ||
646 | { "PCM_Out", NULL, "TX3 Enable"}, | ||
647 | { "PCM_Out", NULL, "TX4 Enable"}, | ||
648 | |||
649 | }; | ||
650 | |||
651 | /* speaker and headset mutes, for audio pops and clicks */ | ||
652 | static int sn95031_pcm_hs_mute(struct snd_soc_dai *dai, int mute) | ||
653 | { | ||
654 | snd_soc_update_bits(dai->codec, | ||
655 | SN95031_HSLVOLCTRL, BIT(7), (!mute << 7)); | ||
656 | snd_soc_update_bits(dai->codec, | ||
657 | SN95031_HSRVOLCTRL, BIT(7), (!mute << 7)); | ||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute) | ||
662 | { | ||
663 | snd_soc_update_bits(dai->codec, | ||
664 | SN95031_IHFLVOLCTRL, BIT(7), (!mute << 7)); | ||
665 | snd_soc_update_bits(dai->codec, | ||
666 | SN95031_IHFRVOLCTRL, BIT(7), (!mute << 7)); | ||
667 | return 0; | ||
668 | } | ||
669 | |||
670 | static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, | ||
671 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
672 | { | ||
673 | unsigned int format, rate; | ||
674 | |||
675 | switch (params_width(params)) { | ||
676 | case 16: | ||
677 | format = BIT(4)|BIT(5); | ||
678 | break; | ||
679 | |||
680 | case 24: | ||
681 | format = 0; | ||
682 | break; | ||
683 | default: | ||
684 | return -EINVAL; | ||
685 | } | ||
686 | snd_soc_update_bits(dai->codec, SN95031_PCM2C2, | ||
687 | BIT(4)|BIT(5), format); | ||
688 | |||
689 | switch (params_rate(params)) { | ||
690 | case 48000: | ||
691 | pr_debug("RATE_48000\n"); | ||
692 | rate = 0; | ||
693 | break; | ||
694 | |||
695 | case 44100: | ||
696 | pr_debug("RATE_44100\n"); | ||
697 | rate = BIT(7); | ||
698 | break; | ||
699 | |||
700 | default: | ||
701 | pr_err("ERR rate %d\n", params_rate(params)); | ||
702 | return -EINVAL; | ||
703 | } | ||
704 | snd_soc_update_bits(dai->codec, SN95031_PCM1C1, BIT(7), rate); | ||
705 | |||
706 | return 0; | ||
707 | } | ||
708 | |||
709 | /* Codec DAI section */ | ||
710 | static const struct snd_soc_dai_ops sn95031_headset_dai_ops = { | ||
711 | .digital_mute = sn95031_pcm_hs_mute, | ||
712 | .hw_params = sn95031_pcm_hw_params, | ||
713 | }; | ||
714 | |||
715 | static const struct snd_soc_dai_ops sn95031_speaker_dai_ops = { | ||
716 | .digital_mute = sn95031_pcm_spkr_mute, | ||
717 | .hw_params = sn95031_pcm_hw_params, | ||
718 | }; | ||
719 | |||
720 | static const struct snd_soc_dai_ops sn95031_vib1_dai_ops = { | ||
721 | .hw_params = sn95031_pcm_hw_params, | ||
722 | }; | ||
723 | |||
724 | static const struct snd_soc_dai_ops sn95031_vib2_dai_ops = { | ||
725 | .hw_params = sn95031_pcm_hw_params, | ||
726 | }; | ||
727 | |||
728 | static struct snd_soc_dai_driver sn95031_dais[] = { | ||
729 | { | ||
730 | .name = "SN95031 Headset", | ||
731 | .playback = { | ||
732 | .stream_name = "Headset", | ||
733 | .channels_min = 2, | ||
734 | .channels_max = 2, | ||
735 | .rates = SN95031_RATES, | ||
736 | .formats = SN95031_FORMATS, | ||
737 | }, | ||
738 | .capture = { | ||
739 | .stream_name = "Capture", | ||
740 | .channels_min = 1, | ||
741 | .channels_max = 5, | ||
742 | .rates = SN95031_RATES, | ||
743 | .formats = SN95031_FORMATS, | ||
744 | }, | ||
745 | .ops = &sn95031_headset_dai_ops, | ||
746 | }, | ||
747 | { .name = "SN95031 Speaker", | ||
748 | .playback = { | ||
749 | .stream_name = "Speaker", | ||
750 | .channels_min = 2, | ||
751 | .channels_max = 2, | ||
752 | .rates = SN95031_RATES, | ||
753 | .formats = SN95031_FORMATS, | ||
754 | }, | ||
755 | .ops = &sn95031_speaker_dai_ops, | ||
756 | }, | ||
757 | { .name = "SN95031 Vibra1", | ||
758 | .playback = { | ||
759 | .stream_name = "Vibra1", | ||
760 | .channels_min = 1, | ||
761 | .channels_max = 1, | ||
762 | .rates = SN95031_RATES, | ||
763 | .formats = SN95031_FORMATS, | ||
764 | }, | ||
765 | .ops = &sn95031_vib1_dai_ops, | ||
766 | }, | ||
767 | { .name = "SN95031 Vibra2", | ||
768 | .playback = { | ||
769 | .stream_name = "Vibra2", | ||
770 | .channels_min = 1, | ||
771 | .channels_max = 1, | ||
772 | .rates = SN95031_RATES, | ||
773 | .formats = SN95031_FORMATS, | ||
774 | }, | ||
775 | .ops = &sn95031_vib2_dai_ops, | ||
776 | }, | ||
777 | }; | ||
778 | |||
779 | static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec) | ||
780 | { | ||
781 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x00); | ||
782 | } | ||
783 | |||
784 | static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec) | ||
785 | { | ||
786 | snd_soc_write(codec, SN95031_BTNCTRL1, 0x77); | ||
787 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x01); | ||
788 | } | ||
789 | |||
790 | static int sn95031_get_headset_state(struct snd_soc_codec *codec, | ||
791 | struct snd_soc_jack *mfld_jack) | ||
792 | { | ||
793 | int micbias = sn95031_get_mic_bias(codec); | ||
794 | |||
795 | int jack_type = snd_soc_jack_get_type(mfld_jack, micbias); | ||
796 | |||
797 | pr_debug("jack type detected = %d\n", jack_type); | ||
798 | if (jack_type == SND_JACK_HEADSET) | ||
799 | sn95031_enable_jack_btn(codec); | ||
800 | return jack_type; | ||
801 | } | ||
802 | |||
803 | void sn95031_jack_detection(struct snd_soc_codec *codec, | ||
804 | struct mfld_jack_data *jack_data) | ||
805 | { | ||
806 | unsigned int status; | ||
807 | unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET; | ||
808 | |||
809 | pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id); | ||
810 | if (jack_data->intr_id & 0x1) { | ||
811 | pr_debug("short_push detected\n"); | ||
812 | status = SND_JACK_HEADSET | SND_JACK_BTN_0; | ||
813 | } else if (jack_data->intr_id & 0x2) { | ||
814 | pr_debug("long_push detected\n"); | ||
815 | status = SND_JACK_HEADSET | SND_JACK_BTN_1; | ||
816 | } else if (jack_data->intr_id & 0x4) { | ||
817 | pr_debug("headset or headphones inserted\n"); | ||
818 | status = sn95031_get_headset_state(codec, jack_data->mfld_jack); | ||
819 | } else if (jack_data->intr_id & 0x8) { | ||
820 | pr_debug("headset or headphones removed\n"); | ||
821 | status = 0; | ||
822 | sn95031_disable_jack_btn(codec); | ||
823 | } else { | ||
824 | pr_err("unidentified interrupt\n"); | ||
825 | return; | ||
826 | } | ||
827 | |||
828 | snd_soc_jack_report(jack_data->mfld_jack, status, mask); | ||
829 | /*button pressed and released so we send explicit button release */ | ||
830 | if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1)) | ||
831 | snd_soc_jack_report(jack_data->mfld_jack, | ||
832 | SND_JACK_HEADSET, mask); | ||
833 | } | ||
834 | EXPORT_SYMBOL_GPL(sn95031_jack_detection); | ||
835 | |||
836 | /* codec registration */ | ||
837 | static int sn95031_codec_probe(struct snd_soc_codec *codec) | ||
838 | { | ||
839 | pr_debug("codec_probe called\n"); | ||
840 | |||
841 | /* PCM interface config | ||
842 | * This sets the pcm rx slot conguration to max 6 slots | ||
843 | * for max 4 dais (2 stereo and 2 mono) | ||
844 | */ | ||
845 | snd_soc_write(codec, SN95031_PCM2RXSLOT01, 0x10); | ||
846 | snd_soc_write(codec, SN95031_PCM2RXSLOT23, 0x32); | ||
847 | snd_soc_write(codec, SN95031_PCM2RXSLOT45, 0x54); | ||
848 | snd_soc_write(codec, SN95031_PCM2TXSLOT01, 0x10); | ||
849 | snd_soc_write(codec, SN95031_PCM2TXSLOT23, 0x32); | ||
850 | /* pcm port setting | ||
851 | * This sets the pcm port to slave and clock at 19.2Mhz which | ||
852 | * can support 6slots, sampling rate set per stream in hw-params | ||
853 | */ | ||
854 | snd_soc_write(codec, SN95031_PCM1C1, 0x00); | ||
855 | snd_soc_write(codec, SN95031_PCM2C1, 0x01); | ||
856 | snd_soc_write(codec, SN95031_PCM2C2, 0x0A); | ||
857 | snd_soc_write(codec, SN95031_HSMIXER, BIT(0)|BIT(4)); | ||
858 | /* vendor vibra workround, the vibras are muted by | ||
859 | * custom register so unmute them | ||
860 | */ | ||
861 | snd_soc_write(codec, SN95031_SSR5, 0x80); | ||
862 | snd_soc_write(codec, SN95031_SSR6, 0x80); | ||
863 | snd_soc_write(codec, SN95031_VIB1C5, 0x00); | ||
864 | snd_soc_write(codec, SN95031_VIB2C5, 0x00); | ||
865 | /* configure vibras for pcm port */ | ||
866 | snd_soc_write(codec, SN95031_VIB1C3, 0x00); | ||
867 | snd_soc_write(codec, SN95031_VIB2C3, 0x00); | ||
868 | |||
869 | /* soft mute ramp time */ | ||
870 | snd_soc_write(codec, SN95031_SOFTMUTE, 0x3); | ||
871 | /* fix the initial volume at 1dB, | ||
872 | * default in +9dB, | ||
873 | * 1dB give optimal swing on DAC, amps | ||
874 | */ | ||
875 | snd_soc_write(codec, SN95031_HSLVOLCTRL, 0x08); | ||
876 | snd_soc_write(codec, SN95031_HSRVOLCTRL, 0x08); | ||
877 | snd_soc_write(codec, SN95031_IHFLVOLCTRL, 0x08); | ||
878 | snd_soc_write(codec, SN95031_IHFRVOLCTRL, 0x08); | ||
879 | /* dac mode and lineout workaround */ | ||
880 | snd_soc_write(codec, SN95031_SSR2, 0x10); | ||
881 | snd_soc_write(codec, SN95031_SSR3, 0x40); | ||
882 | |||
883 | return 0; | ||
884 | } | ||
885 | |||
886 | static const struct snd_soc_codec_driver sn95031_codec = { | ||
887 | .probe = sn95031_codec_probe, | ||
888 | .set_bias_level = sn95031_set_vaud_bias, | ||
889 | .idle_bias_off = true, | ||
890 | |||
891 | .component_driver = { | ||
892 | .controls = sn95031_snd_controls, | ||
893 | .num_controls = ARRAY_SIZE(sn95031_snd_controls), | ||
894 | .dapm_widgets = sn95031_dapm_widgets, | ||
895 | .num_dapm_widgets = ARRAY_SIZE(sn95031_dapm_widgets), | ||
896 | .dapm_routes = sn95031_audio_map, | ||
897 | .num_dapm_routes = ARRAY_SIZE(sn95031_audio_map), | ||
898 | }, | ||
899 | }; | ||
900 | |||
901 | static int sn95031_device_probe(struct platform_device *pdev) | ||
902 | { | ||
903 | struct regmap *regmap; | ||
904 | |||
905 | pr_debug("codec device probe called for %s\n", dev_name(&pdev->dev)); | ||
906 | |||
907 | regmap = devm_regmap_init(&pdev->dev, NULL, NULL, &sn95031_regmap); | ||
908 | if (IS_ERR(regmap)) | ||
909 | return PTR_ERR(regmap); | ||
910 | |||
911 | return snd_soc_register_codec(&pdev->dev, &sn95031_codec, | ||
912 | sn95031_dais, ARRAY_SIZE(sn95031_dais)); | ||
913 | } | ||
914 | |||
915 | static int sn95031_device_remove(struct platform_device *pdev) | ||
916 | { | ||
917 | pr_debug("codec device remove called\n"); | ||
918 | snd_soc_unregister_codec(&pdev->dev); | ||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | static struct platform_driver sn95031_codec_driver = { | ||
923 | .driver = { | ||
924 | .name = "sn95031", | ||
925 | }, | ||
926 | .probe = sn95031_device_probe, | ||
927 | .remove = sn95031_device_remove, | ||
928 | }; | ||
929 | |||
930 | module_platform_driver(sn95031_codec_driver); | ||
931 | |||
932 | MODULE_DESCRIPTION("ASoC TI SN95031 codec driver"); | ||
933 | MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); | ||
934 | MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); | ||
935 | MODULE_LICENSE("GPL v2"); | ||
936 | MODULE_ALIAS("platform:sn95031"); | ||
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h deleted file mode 100644 index 7651fe4e6a45..000000000000 --- a/sound/soc/codecs/sn95031.h +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* | ||
2 | * sn95031.h - TI sn95031 Codec driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Intel Corp | ||
5 | * Author: Vinod Koul <vinod.koul@intel.com> | ||
6 | * Author: Harsha Priya <priya.harsha@intel.com> | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | * | ||
24 | * | ||
25 | */ | ||
26 | #ifndef _SN95031_H | ||
27 | #define _SN95031_H | ||
28 | |||
29 | /*register map*/ | ||
30 | #define SN95031_VAUD 0xDB | ||
31 | #define SN95031_VHSP 0xDC | ||
32 | #define SN95031_VHSN 0xDD | ||
33 | #define SN95031_VIHF 0xC9 | ||
34 | |||
35 | #define SN95031_AUDPLLCTRL 0x240 | ||
36 | #define SN95031_DMICBUF0123 0x241 | ||
37 | #define SN95031_DMICBUF45 0x242 | ||
38 | #define SN95031_DMICGPO 0x244 | ||
39 | #define SN95031_DMICMUX 0x245 | ||
40 | #define SN95031_DMICLK 0x246 | ||
41 | #define SN95031_MICBIAS 0x247 | ||
42 | #define SN95031_ADCCONFIG 0x248 | ||
43 | #define SN95031_MICAMP1 0x249 | ||
44 | #define SN95031_MICAMP2 0x24A | ||
45 | #define SN95031_NOISEMUX 0x24B | ||
46 | #define SN95031_AUDIOMUX12 0x24C | ||
47 | #define SN95031_AUDIOMUX34 0x24D | ||
48 | #define SN95031_AUDIOSINC 0x24E | ||
49 | #define SN95031_AUDIOTXEN 0x24F | ||
50 | #define SN95031_HSEPRXCTRL 0x250 | ||
51 | #define SN95031_IHFRXCTRL 0x251 | ||
52 | #define SN95031_HSMIXER 0x256 | ||
53 | #define SN95031_DACCONFIG 0x257 | ||
54 | #define SN95031_SOFTMUTE 0x258 | ||
55 | #define SN95031_HSLVOLCTRL 0x259 | ||
56 | #define SN95031_HSRVOLCTRL 0x25A | ||
57 | #define SN95031_IHFLVOLCTRL 0x25B | ||
58 | #define SN95031_IHFRVOLCTRL 0x25C | ||
59 | #define SN95031_DRIVEREN 0x25D | ||
60 | #define SN95031_LOCTL 0x25E | ||
61 | #define SN95031_VIB1C1 0x25F | ||
62 | #define SN95031_VIB1C2 0x260 | ||
63 | #define SN95031_VIB1C3 0x261 | ||
64 | #define SN95031_VIB1SPIPCM1 0x262 | ||
65 | #define SN95031_VIB1SPIPCM2 0x263 | ||
66 | #define SN95031_VIB1C5 0x264 | ||
67 | #define SN95031_VIB2C1 0x265 | ||
68 | #define SN95031_VIB2C2 0x266 | ||
69 | #define SN95031_VIB2C3 0x267 | ||
70 | #define SN95031_VIB2SPIPCM1 0x268 | ||
71 | #define SN95031_VIB2SPIPCM2 0x269 | ||
72 | #define SN95031_VIB2C5 0x26A | ||
73 | #define SN95031_BTNCTRL1 0x26B | ||
74 | #define SN95031_BTNCTRL2 0x26C | ||
75 | #define SN95031_PCM1TXSLOT01 0x26D | ||
76 | #define SN95031_PCM1TXSLOT23 0x26E | ||
77 | #define SN95031_PCM1TXSLOT45 0x26F | ||
78 | #define SN95031_PCM1RXSLOT0_3 0x270 | ||
79 | #define SN95031_PCM1RXSLOT45 0x271 | ||
80 | #define SN95031_PCM2TXSLOT01 0x272 | ||
81 | #define SN95031_PCM2TXSLOT23 0x273 | ||
82 | #define SN95031_PCM2TXSLOT45 0x274 | ||
83 | #define SN95031_PCM2RXSLOT01 0x275 | ||
84 | #define SN95031_PCM2RXSLOT23 0x276 | ||
85 | #define SN95031_PCM2RXSLOT45 0x277 | ||
86 | #define SN95031_PCM1C1 0x278 | ||
87 | #define SN95031_PCM1C2 0x279 | ||
88 | #define SN95031_PCM1C3 0x27A | ||
89 | #define SN95031_PCM2C1 0x27B | ||
90 | #define SN95031_PCM2C2 0x27C | ||
91 | /*end codec register defn*/ | ||
92 | |||
93 | /*vendor defn these are not part of avp*/ | ||
94 | #define SN95031_SSR2 0x381 | ||
95 | #define SN95031_SSR3 0x382 | ||
96 | #define SN95031_SSR5 0x384 | ||
97 | #define SN95031_SSR6 0x385 | ||
98 | |||
99 | /* ADC registers */ | ||
100 | |||
101 | #define SN95031_ADC1CNTL1 0x1C0 | ||
102 | #define SN95031_ADC_ENBL 0x10 | ||
103 | #define SN95031_ADC_START 0x08 | ||
104 | #define SN95031_ADC1CNTL3 0x1C2 | ||
105 | #define SN95031_ADCTHERM_ENBL 0x04 | ||
106 | #define SN95031_ADCRRDATA_ENBL 0x05 | ||
107 | #define SN95031_STOPBIT_MASK 16 | ||
108 | #define SN95031_ADCTHERM_MASK 4 | ||
109 | #define SN95031_ADC_CHANLS_MAX 15 /* Number of ADC channels */ | ||
110 | #define SN95031_ADC_LOOP_MAX (SN95031_ADC_CHANLS_MAX - 1) | ||
111 | #define SN95031_ADC_NO_LOOP 0x07 | ||
112 | #define SN95031_AUDIO_GPIO_CTRL 0x070 | ||
113 | |||
114 | /* ADC channel code values */ | ||
115 | #define SN95031_AUDIO_DETECT_CODE 0x06 | ||
116 | |||
117 | /* ADC base addresses */ | ||
118 | #define SN95031_ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */ | ||
119 | #define SN95031_ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */ | ||
120 | /* multipier to convert to mV */ | ||
121 | #define SN95031_ADC_ONE_LSB_MULTIPLIER 2346 | ||
122 | |||
123 | |||
124 | struct mfld_jack_data { | ||
125 | int intr_id; | ||
126 | int micbias_vol; | ||
127 | struct snd_soc_jack *mfld_jack; | ||
128 | }; | ||
129 | |||
130 | extern void sn95031_jack_detection(struct snd_soc_codec *codec, | ||
131 | struct mfld_jack_data *jack_data); | ||
132 | |||
133 | #endif | ||
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c index 7acd05140a81..c8fd6367f6c0 100644 --- a/sound/soc/codecs/spdif_receiver.c +++ b/sound/soc/codecs/spdif_receiver.c | |||
@@ -34,10 +34,11 @@ static const struct snd_soc_dapm_route dir_routes[] = { | |||
34 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 | 34 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 |
35 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | 35 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
36 | SNDRV_PCM_FMTBIT_S20_3LE | \ | 36 | SNDRV_PCM_FMTBIT_S20_3LE | \ |
37 | SNDRV_PCM_FMTBIT_S24_LE | \ | 37 | SNDRV_PCM_FMTBIT_S24_LE | \ |
38 | SNDRV_PCM_FMTBIT_S32_LE | \ | ||
38 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) | 39 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE) |
39 | 40 | ||
40 | static const struct snd_soc_codec_driver soc_codec_spdif_dir = { | 41 | static struct snd_soc_codec_driver soc_codec_spdif_dir = { |
41 | .component_driver = { | 42 | .component_driver = { |
42 | .dapm_widgets = dir_widgets, | 43 | .dapm_widgets = dir_widgets, |
43 | .num_dapm_widgets = ARRAY_SIZE(dir_widgets), | 44 | .num_dapm_widgets = ARRAY_SIZE(dir_widgets), |
diff --git a/sound/soc/codecs/spdif_transmitter.c b/sound/soc/codecs/spdif_transmitter.c index 063a64ff82d3..037aa1d45559 100644 --- a/sound/soc/codecs/spdif_transmitter.c +++ b/sound/soc/codecs/spdif_transmitter.c | |||
@@ -27,7 +27,8 @@ | |||
27 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 | 27 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 |
28 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | 28 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
29 | SNDRV_PCM_FMTBIT_S20_3LE | \ | 29 | SNDRV_PCM_FMTBIT_S20_3LE | \ |
30 | SNDRV_PCM_FMTBIT_S24_LE) | 30 | SNDRV_PCM_FMTBIT_S24_LE | \ |
31 | SNDRV_PCM_FMTBIT_S32_LE) | ||
31 | 32 | ||
32 | static const struct snd_soc_dapm_widget dit_widgets[] = { | 33 | static const struct snd_soc_dapm_widget dit_widgets[] = { |
33 | SND_SOC_DAPM_OUTPUT("spdif-out"), | 34 | SND_SOC_DAPM_OUTPUT("spdif-out"), |
@@ -37,7 +38,7 @@ static const struct snd_soc_dapm_route dit_routes[] = { | |||
37 | { "spdif-out", NULL, "Playback" }, | 38 | { "spdif-out", NULL, "Playback" }, |
38 | }; | 39 | }; |
39 | 40 | ||
40 | static const struct snd_soc_codec_driver soc_codec_spdif_dit = { | 41 | static struct snd_soc_codec_driver soc_codec_spdif_dit = { |
41 | .component_driver = { | 42 | .component_driver = { |
42 | .dapm_widgets = dit_widgets, | 43 | .dapm_widgets = dit_widgets, |
43 | .num_dapm_widgets = ARRAY_SIZE(dit_widgets), | 44 | .num_dapm_widgets = ARRAY_SIZE(dit_widgets), |
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c index a736a2a6976c..f3006f301fe8 100644 --- a/sound/soc/codecs/tas5720.c +++ b/sound/soc/codecs/tas5720.c | |||
@@ -36,6 +36,11 @@ | |||
36 | /* Define how often to check (and clear) the fault status register (in ms) */ | 36 | /* Define how often to check (and clear) the fault status register (in ms) */ |
37 | #define TAS5720_FAULT_CHECK_INTERVAL 200 | 37 | #define TAS5720_FAULT_CHECK_INTERVAL 200 |
38 | 38 | ||
39 | enum tas572x_type { | ||
40 | TAS5720, | ||
41 | TAS5722, | ||
42 | }; | ||
43 | |||
39 | static const char * const tas5720_supply_names[] = { | 44 | static const char * const tas5720_supply_names[] = { |
40 | "dvdd", /* Digital power supply. Connect to 3.3-V supply. */ | 45 | "dvdd", /* Digital power supply. Connect to 3.3-V supply. */ |
41 | "pvdd", /* Class-D amp and analog power supply (connected). */ | 46 | "pvdd", /* Class-D amp and analog power supply (connected). */ |
@@ -47,6 +52,7 @@ struct tas5720_data { | |||
47 | struct snd_soc_codec *codec; | 52 | struct snd_soc_codec *codec; |
48 | struct regmap *regmap; | 53 | struct regmap *regmap; |
49 | struct i2c_client *tas5720_client; | 54 | struct i2c_client *tas5720_client; |
55 | enum tas572x_type devtype; | ||
50 | struct regulator_bulk_data supplies[TAS5720_NUM_SUPPLIES]; | 56 | struct regulator_bulk_data supplies[TAS5720_NUM_SUPPLIES]; |
51 | struct delayed_work fault_check_work; | 57 | struct delayed_work fault_check_work; |
52 | unsigned int last_fault; | 58 | unsigned int last_fault; |
@@ -264,7 +270,7 @@ out: | |||
264 | static int tas5720_codec_probe(struct snd_soc_codec *codec) | 270 | static int tas5720_codec_probe(struct snd_soc_codec *codec) |
265 | { | 271 | { |
266 | struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec); | 272 | struct tas5720_data *tas5720 = snd_soc_codec_get_drvdata(codec); |
267 | unsigned int device_id; | 273 | unsigned int device_id, expected_device_id; |
268 | int ret; | 274 | int ret; |
269 | 275 | ||
270 | tas5720->codec = codec; | 276 | tas5720->codec = codec; |
@@ -276,6 +282,11 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec) | |||
276 | return ret; | 282 | return ret; |
277 | } | 283 | } |
278 | 284 | ||
285 | /* | ||
286 | * Take a liberal approach to checking the device ID to allow the | ||
287 | * driver to be used even if the device ID does not match, however | ||
288 | * issue a warning if there is a mismatch. | ||
289 | */ | ||
279 | ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id); | 290 | ret = regmap_read(tas5720->regmap, TAS5720_DEVICE_ID_REG, &device_id); |
280 | if (ret < 0) { | 291 | if (ret < 0) { |
281 | dev_err(codec->dev, "failed to read device ID register: %d\n", | 292 | dev_err(codec->dev, "failed to read device ID register: %d\n", |
@@ -283,13 +294,22 @@ static int tas5720_codec_probe(struct snd_soc_codec *codec) | |||
283 | goto probe_fail; | 294 | goto probe_fail; |
284 | } | 295 | } |
285 | 296 | ||
286 | if (device_id != TAS5720_DEVICE_ID) { | 297 | switch (tas5720->devtype) { |
287 | dev_err(codec->dev, "wrong device ID. expected: %u read: %u\n", | 298 | case TAS5720: |
288 | TAS5720_DEVICE_ID, device_id); | 299 | expected_device_id = TAS5720_DEVICE_ID; |
289 | ret = -ENODEV; | 300 | break; |
290 | goto probe_fail; | 301 | case TAS5722: |
302 | expected_device_id = TAS5722_DEVICE_ID; | ||
303 | break; | ||
304 | default: | ||
305 | dev_err(codec->dev, "unexpected private driver data\n"); | ||
306 | return -EINVAL; | ||
291 | } | 307 | } |
292 | 308 | ||
309 | if (device_id != expected_device_id) | ||
310 | dev_warn(codec->dev, "wrong device ID. expected: %u read: %u\n", | ||
311 | expected_device_id, device_id); | ||
312 | |||
293 | /* Set device to mute */ | 313 | /* Set device to mute */ |
294 | ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG, | 314 | ret = snd_soc_update_bits(codec, TAS5720_DIGITAL_CTRL2_REG, |
295 | TAS5720_MUTE, TAS5720_MUTE); | 315 | TAS5720_MUTE, TAS5720_MUTE); |
@@ -446,6 +466,15 @@ static const struct regmap_config tas5720_regmap_config = { | |||
446 | .volatile_reg = tas5720_is_volatile_reg, | 466 | .volatile_reg = tas5720_is_volatile_reg, |
447 | }; | 467 | }; |
448 | 468 | ||
469 | static const struct regmap_config tas5722_regmap_config = { | ||
470 | .reg_bits = 8, | ||
471 | .val_bits = 8, | ||
472 | |||
473 | .max_register = TAS5722_MAX_REG, | ||
474 | .cache_type = REGCACHE_RBTREE, | ||
475 | .volatile_reg = tas5720_is_volatile_reg, | ||
476 | }; | ||
477 | |||
449 | /* | 478 | /* |
450 | * DAC analog gain. There are four discrete values to select from, ranging | 479 | * DAC analog gain. There are four discrete values to select from, ranging |
451 | * from 19.2 dB to 26.3dB. | 480 | * from 19.2 dB to 26.3dB. |
@@ -544,6 +573,7 @@ static int tas5720_probe(struct i2c_client *client, | |||
544 | { | 573 | { |
545 | struct device *dev = &client->dev; | 574 | struct device *dev = &client->dev; |
546 | struct tas5720_data *data; | 575 | struct tas5720_data *data; |
576 | const struct regmap_config *regmap_config; | ||
547 | int ret; | 577 | int ret; |
548 | int i; | 578 | int i; |
549 | 579 | ||
@@ -552,7 +582,20 @@ static int tas5720_probe(struct i2c_client *client, | |||
552 | return -ENOMEM; | 582 | return -ENOMEM; |
553 | 583 | ||
554 | data->tas5720_client = client; | 584 | data->tas5720_client = client; |
555 | data->regmap = devm_regmap_init_i2c(client, &tas5720_regmap_config); | 585 | data->devtype = id->driver_data; |
586 | |||
587 | switch (id->driver_data) { | ||
588 | case TAS5720: | ||
589 | regmap_config = &tas5720_regmap_config; | ||
590 | break; | ||
591 | case TAS5722: | ||
592 | regmap_config = &tas5722_regmap_config; | ||
593 | break; | ||
594 | default: | ||
595 | dev_err(dev, "unexpected private driver data\n"); | ||
596 | return -EINVAL; | ||
597 | } | ||
598 | data->regmap = devm_regmap_init_i2c(client, regmap_config); | ||
556 | if (IS_ERR(data->regmap)) { | 599 | if (IS_ERR(data->regmap)) { |
557 | ret = PTR_ERR(data->regmap); | 600 | ret = PTR_ERR(data->regmap); |
558 | dev_err(dev, "failed to allocate register map: %d\n", ret); | 601 | dev_err(dev, "failed to allocate register map: %d\n", ret); |
@@ -592,7 +635,8 @@ static int tas5720_remove(struct i2c_client *client) | |||
592 | } | 635 | } |
593 | 636 | ||
594 | static const struct i2c_device_id tas5720_id[] = { | 637 | static const struct i2c_device_id tas5720_id[] = { |
595 | { "tas5720", 0 }, | 638 | { "tas5720", TAS5720 }, |
639 | { "tas5722", TAS5722 }, | ||
596 | { } | 640 | { } |
597 | }; | 641 | }; |
598 | MODULE_DEVICE_TABLE(i2c, tas5720_id); | 642 | MODULE_DEVICE_TABLE(i2c, tas5720_id); |
@@ -600,6 +644,7 @@ MODULE_DEVICE_TABLE(i2c, tas5720_id); | |||
600 | #if IS_ENABLED(CONFIG_OF) | 644 | #if IS_ENABLED(CONFIG_OF) |
601 | static const struct of_device_id tas5720_of_match[] = { | 645 | static const struct of_device_id tas5720_of_match[] = { |
602 | { .compatible = "ti,tas5720", }, | 646 | { .compatible = "ti,tas5720", }, |
647 | { .compatible = "ti,tas5722", }, | ||
603 | { }, | 648 | { }, |
604 | }; | 649 | }; |
605 | MODULE_DEVICE_TABLE(of, tas5720_of_match); | 650 | MODULE_DEVICE_TABLE(of, tas5720_of_match); |
diff --git a/sound/soc/codecs/tas5720.h b/sound/soc/codecs/tas5720.h index 3d077c779b12..1dda3095961d 100644 --- a/sound/soc/codecs/tas5720.h +++ b/sound/soc/codecs/tas5720.h | |||
@@ -30,8 +30,14 @@ | |||
30 | #define TAS5720_DIGITAL_CLIP1_REG 0x11 | 30 | #define TAS5720_DIGITAL_CLIP1_REG 0x11 |
31 | #define TAS5720_MAX_REG TAS5720_DIGITAL_CLIP1_REG | 31 | #define TAS5720_MAX_REG TAS5720_DIGITAL_CLIP1_REG |
32 | 32 | ||
33 | /* Additional TAS5722-specific Registers */ | ||
34 | #define TAS5722_DIGITAL_CTRL2_REG 0x13 | ||
35 | #define TAS5722_ANALOG_CTRL2_REG 0x14 | ||
36 | #define TAS5722_MAX_REG TAS5722_ANALOG_CTRL2_REG | ||
37 | |||
33 | /* TAS5720_DEVICE_ID_REG */ | 38 | /* TAS5720_DEVICE_ID_REG */ |
34 | #define TAS5720_DEVICE_ID 0x01 | 39 | #define TAS5720_DEVICE_ID 0x01 |
40 | #define TAS5722_DEVICE_ID 0x12 | ||
35 | 41 | ||
36 | /* TAS5720_POWER_CTRL_REG */ | 42 | /* TAS5720_POWER_CTRL_REG */ |
37 | #define TAS5720_DIG_CLIP_MASK GENMASK(7, 2) | 43 | #define TAS5720_DIG_CLIP_MASK GENMASK(7, 2) |
@@ -51,6 +57,7 @@ | |||
51 | #define TAS5720_SAIF_FORMAT_MASK GENMASK(2, 0) | 57 | #define TAS5720_SAIF_FORMAT_MASK GENMASK(2, 0) |
52 | 58 | ||
53 | /* TAS5720_DIGITAL_CTRL2_REG */ | 59 | /* TAS5720_DIGITAL_CTRL2_REG */ |
60 | #define TAS5722_VOL_RAMP_RATE BIT(6) | ||
54 | #define TAS5720_MUTE BIT(4) | 61 | #define TAS5720_MUTE BIT(4) |
55 | #define TAS5720_TDM_SLOT_SEL_MASK GENMASK(2, 0) | 62 | #define TAS5720_TDM_SLOT_SEL_MASK GENMASK(2, 0) |
56 | 63 | ||
@@ -87,4 +94,28 @@ | |||
87 | #define TAS5720_CLIP1_MASK GENMASK(7, 2) | 94 | #define TAS5720_CLIP1_MASK GENMASK(7, 2) |
88 | #define TAS5720_CLIP1_SHIFT (0x2) | 95 | #define TAS5720_CLIP1_SHIFT (0x2) |
89 | 96 | ||
97 | /* TAS5722_DIGITAL_CTRL2_REG */ | ||
98 | #define TAS5722_HPF_3_7HZ (0x0 << 5) | ||
99 | #define TAS5722_HPF_7_4HZ (0x1 << 5) | ||
100 | #define TAS5722_HPF_14_9HZ (0x2 << 5) | ||
101 | #define TAS5722_HPF_29_7HZ (0x3 << 5) | ||
102 | #define TAS5722_HPF_59_4HZ (0x4 << 5) | ||
103 | #define TAS5722_HPF_118_4HZ (0x5 << 5) | ||
104 | #define TAS5722_HPF_235_0HZ (0x6 << 5) | ||
105 | #define TAS5722_HPF_463_2HZ (0x7 << 5) | ||
106 | #define TAS5722_HPF_MASK GENMASK(7, 5) | ||
107 | #define TAS5722_AUTO_SLEEP_OFF (0x0 << 3) | ||
108 | #define TAS5722_AUTO_SLEEP_1024LR (0x1 << 3) | ||
109 | #define TAS5722_AUTO_SLEEP_65536LR (0x2 << 3) | ||
110 | #define TAS5722_AUTO_SLEEP_262144LR (0x3 << 3) | ||
111 | #define TAS5722_AUTO_SLEEP_MASK GENMASK(4, 3) | ||
112 | #define TAS5722_TDM_SLOT_16B BIT(2) | ||
113 | #define TAS5722_MCLK_PIN_CFG BIT(1) | ||
114 | #define TAS5722_VOL_CONTROL_LSB BIT(0) | ||
115 | |||
116 | /* TAS5722_ANALOG_CTRL2_REG */ | ||
117 | #define TAS5722_FAULTZ_PU BIT(3) | ||
118 | #define TAS5722_VREG_LVL BIT(2) | ||
119 | #define TAS5722_PWR_TUNE BIT(0) | ||
120 | |||
90 | #endif /* __TAS5720_H__ */ | 121 | #endif /* __TAS5720_H__ */ |
diff --git a/sound/soc/codecs/tas6424.c b/sound/soc/codecs/tas6424.c new file mode 100644 index 000000000000..49b87f6e85bf --- /dev/null +++ b/sound/soc/codecs/tas6424.c | |||
@@ -0,0 +1,707 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * ALSA SoC Texas Instruments TAS6424 Quad-Channel Audio Amplifier | ||
4 | * | ||
5 | * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/ | ||
6 | * Author: Andreas Dannenberg <dannenberg@ti.com> | ||
7 | * Andrew F. Davis <afd@ti.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/module.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/pm_runtime.h> | ||
15 | #include <linux/regmap.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/regulator/consumer.h> | ||
18 | #include <linux/delay.h> | ||
19 | |||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/pcm_params.h> | ||
22 | #include <sound/soc.h> | ||
23 | #include <sound/soc-dapm.h> | ||
24 | #include <sound/tlv.h> | ||
25 | |||
26 | #include "tas6424.h" | ||
27 | |||
28 | /* Define how often to check (and clear) the fault status register (in ms) */ | ||
29 | #define TAS6424_FAULT_CHECK_INTERVAL 200 | ||
30 | |||
31 | static const char * const tas6424_supply_names[] = { | ||
32 | "dvdd", /* Digital power supply. Connect to 3.3-V supply. */ | ||
33 | "vbat", /* Supply used for higher voltage analog circuits. */ | ||
34 | "pvdd", /* Class-D amp output FETs supply. */ | ||
35 | }; | ||
36 | #define TAS6424_NUM_SUPPLIES ARRAY_SIZE(tas6424_supply_names) | ||
37 | |||
38 | struct tas6424_data { | ||
39 | struct device *dev; | ||
40 | struct regmap *regmap; | ||
41 | struct regulator_bulk_data supplies[TAS6424_NUM_SUPPLIES]; | ||
42 | struct delayed_work fault_check_work; | ||
43 | unsigned int last_fault1; | ||
44 | unsigned int last_fault2; | ||
45 | unsigned int last_warn; | ||
46 | }; | ||
47 | |||
48 | /* | ||
49 | * DAC digital volumes. From -103.5 to 24 dB in 0.5 dB steps. Note that | ||
50 | * setting the gain below -100 dB (register value <0x7) is effectively a MUTE | ||
51 | * as per device datasheet. | ||
52 | */ | ||
53 | static DECLARE_TLV_DB_SCALE(dac_tlv, -10350, 50, 0); | ||
54 | |||
55 | static const struct snd_kcontrol_new tas6424_snd_controls[] = { | ||
56 | SOC_SINGLE_TLV("Speaker Driver CH1 Playback Volume", | ||
57 | TAS6424_CH1_VOL_CTRL, 0, 0xff, 0, dac_tlv), | ||
58 | SOC_SINGLE_TLV("Speaker Driver CH2 Playback Volume", | ||
59 | TAS6424_CH2_VOL_CTRL, 0, 0xff, 0, dac_tlv), | ||
60 | SOC_SINGLE_TLV("Speaker Driver CH3 Playback Volume", | ||
61 | TAS6424_CH3_VOL_CTRL, 0, 0xff, 0, dac_tlv), | ||
62 | SOC_SINGLE_TLV("Speaker Driver CH4 Playback Volume", | ||
63 | TAS6424_CH4_VOL_CTRL, 0, 0xff, 0, dac_tlv), | ||
64 | }; | ||
65 | |||
66 | static int tas6424_dac_event(struct snd_soc_dapm_widget *w, | ||
67 | struct snd_kcontrol *kcontrol, int event) | ||
68 | { | ||
69 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
70 | struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec); | ||
71 | |||
72 | dev_dbg(codec->dev, "%s() event=0x%0x\n", __func__, event); | ||
73 | |||
74 | if (event & SND_SOC_DAPM_POST_PMU) { | ||
75 | /* Observe codec shutdown-to-active time */ | ||
76 | msleep(12); | ||
77 | |||
78 | /* Turn on TAS6424 periodic fault checking/handling */ | ||
79 | tas6424->last_fault1 = 0; | ||
80 | tas6424->last_fault2 = 0; | ||
81 | tas6424->last_warn = 0; | ||
82 | schedule_delayed_work(&tas6424->fault_check_work, | ||
83 | msecs_to_jiffies(TAS6424_FAULT_CHECK_INTERVAL)); | ||
84 | } else if (event & SND_SOC_DAPM_PRE_PMD) { | ||
85 | /* Disable TAS6424 periodic fault checking/handling */ | ||
86 | cancel_delayed_work_sync(&tas6424->fault_check_work); | ||
87 | } | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static const struct snd_soc_dapm_widget tas6424_dapm_widgets[] = { | ||
93 | SND_SOC_DAPM_AIF_IN("DAC IN", "Playback", 0, SND_SOC_NOPM, 0, 0), | ||
94 | SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas6424_dac_event, | ||
95 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
96 | SND_SOC_DAPM_OUTPUT("OUT") | ||
97 | }; | ||
98 | |||
99 | static const struct snd_soc_dapm_route tas6424_audio_map[] = { | ||
100 | { "DAC", NULL, "DAC IN" }, | ||
101 | { "OUT", NULL, "DAC" }, | ||
102 | }; | ||
103 | |||
104 | static int tas6424_hw_params(struct snd_pcm_substream *substream, | ||
105 | struct snd_pcm_hw_params *params, | ||
106 | struct snd_soc_dai *dai) | ||
107 | { | ||
108 | struct snd_soc_codec *codec = dai->codec; | ||
109 | unsigned int rate = params_rate(params); | ||
110 | unsigned int width = params_width(params); | ||
111 | u8 sap_ctrl = 0; | ||
112 | |||
113 | dev_dbg(codec->dev, "%s() rate=%u width=%u\n", __func__, rate, width); | ||
114 | |||
115 | switch (rate) { | ||
116 | case 44100: | ||
117 | sap_ctrl |= TAS6424_SAP_RATE_44100; | ||
118 | break; | ||
119 | case 48000: | ||
120 | sap_ctrl |= TAS6424_SAP_RATE_48000; | ||
121 | break; | ||
122 | case 96000: | ||
123 | sap_ctrl |= TAS6424_SAP_RATE_96000; | ||
124 | break; | ||
125 | default: | ||
126 | dev_err(codec->dev, "unsupported sample rate: %u\n", rate); | ||
127 | return -EINVAL; | ||
128 | } | ||
129 | |||
130 | switch (width) { | ||
131 | case 16: | ||
132 | sap_ctrl |= TAS6424_SAP_TDM_SLOT_SZ_16; | ||
133 | break; | ||
134 | case 24: | ||
135 | break; | ||
136 | default: | ||
137 | dev_err(codec->dev, "unsupported sample width: %u\n", width); | ||
138 | return -EINVAL; | ||
139 | } | ||
140 | |||
141 | snd_soc_update_bits(codec, TAS6424_SAP_CTRL, | ||
142 | TAS6424_SAP_RATE_MASK | | ||
143 | TAS6424_SAP_TDM_SLOT_SZ_16, | ||
144 | sap_ctrl); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static int tas6424_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
150 | { | ||
151 | struct snd_soc_codec *codec = dai->codec; | ||
152 | u8 serial_format = 0; | ||
153 | |||
154 | dev_dbg(codec->dev, "%s() fmt=0x%0x\n", __func__, fmt); | ||
155 | |||
156 | /* clock masters */ | ||
157 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
158 | case SND_SOC_DAIFMT_CBS_CFS: | ||
159 | break; | ||
160 | default: | ||
161 | dev_err(codec->dev, "Invalid DAI master/slave interface\n"); | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | /* signal polarity */ | ||
166 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
167 | case SND_SOC_DAIFMT_NB_NF: | ||
168 | break; | ||
169 | default: | ||
170 | dev_err(codec->dev, "Invalid DAI clock signal polarity\n"); | ||
171 | return -EINVAL; | ||
172 | } | ||
173 | |||
174 | /* interface format */ | ||
175 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
176 | case SND_SOC_DAIFMT_I2S: | ||
177 | serial_format |= TAS6424_SAP_I2S; | ||
178 | break; | ||
179 | case SND_SOC_DAIFMT_DSP_A: | ||
180 | serial_format |= TAS6424_SAP_DSP; | ||
181 | break; | ||
182 | case SND_SOC_DAIFMT_DSP_B: | ||
183 | /* | ||
184 | * We can use the fact that the TAS6424 does not care about the | ||
185 | * LRCLK duty cycle during TDM to receive DSP_B formatted data | ||
186 | * in LEFTJ mode (no delaying of the 1st data bit). | ||
187 | */ | ||
188 | serial_format |= TAS6424_SAP_LEFTJ; | ||
189 | break; | ||
190 | case SND_SOC_DAIFMT_LEFT_J: | ||
191 | serial_format |= TAS6424_SAP_LEFTJ; | ||
192 | break; | ||
193 | default: | ||
194 | dev_err(codec->dev, "Invalid DAI interface format\n"); | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | |||
198 | snd_soc_update_bits(codec, TAS6424_SAP_CTRL, | ||
199 | TAS6424_SAP_FMT_MASK, serial_format); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int tas6424_set_dai_tdm_slot(struct snd_soc_dai *dai, | ||
205 | unsigned int tx_mask, unsigned int rx_mask, | ||
206 | int slots, int slot_width) | ||
207 | { | ||
208 | struct snd_soc_codec *codec = dai->codec; | ||
209 | unsigned int first_slot, last_slot; | ||
210 | bool sap_tdm_slot_last; | ||
211 | |||
212 | dev_dbg(codec->dev, "%s() tx_mask=%d rx_mask=%d\n", __func__, | ||
213 | tx_mask, rx_mask); | ||
214 | |||
215 | if (!tx_mask || !rx_mask) | ||
216 | return 0; /* nothing needed to disable TDM mode */ | ||
217 | |||
218 | /* | ||
219 | * Determine the first slot and last slot that is being requested so | ||
220 | * we'll be able to more easily enforce certain constraints as the | ||
221 | * TAS6424's TDM interface is not fully configurable. | ||
222 | */ | ||
223 | first_slot = __ffs(tx_mask); | ||
224 | last_slot = __fls(rx_mask); | ||
225 | |||
226 | if (last_slot - first_slot != 4) { | ||
227 | dev_err(codec->dev, "tdm mask must cover 4 contiguous slots\n"); | ||
228 | return -EINVAL; | ||
229 | } | ||
230 | |||
231 | switch (first_slot) { | ||
232 | case 0: | ||
233 | sap_tdm_slot_last = false; | ||
234 | break; | ||
235 | case 4: | ||
236 | sap_tdm_slot_last = true; | ||
237 | break; | ||
238 | default: | ||
239 | dev_err(codec->dev, "tdm mask must start at slot 0 or 4\n"); | ||
240 | return -EINVAL; | ||
241 | } | ||
242 | |||
243 | snd_soc_update_bits(codec, TAS6424_SAP_CTRL, TAS6424_SAP_TDM_SLOT_LAST, | ||
244 | sap_tdm_slot_last ? TAS6424_SAP_TDM_SLOT_LAST : 0); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int tas6424_mute(struct snd_soc_dai *dai, int mute) | ||
250 | { | ||
251 | struct snd_soc_codec *codec = dai->codec; | ||
252 | unsigned int val; | ||
253 | |||
254 | dev_dbg(codec->dev, "%s() mute=%d\n", __func__, mute); | ||
255 | |||
256 | if (mute) | ||
257 | val = TAS6424_ALL_STATE_MUTE; | ||
258 | else | ||
259 | val = TAS6424_ALL_STATE_PLAY; | ||
260 | |||
261 | snd_soc_write(codec, TAS6424_CH_STATE_CTRL, val); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int tas6424_power_off(struct snd_soc_codec *codec) | ||
267 | { | ||
268 | struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec); | ||
269 | int ret; | ||
270 | |||
271 | snd_soc_write(codec, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_HIZ); | ||
272 | |||
273 | regcache_cache_only(tas6424->regmap, true); | ||
274 | regcache_mark_dirty(tas6424->regmap); | ||
275 | |||
276 | ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies), | ||
277 | tas6424->supplies); | ||
278 | if (ret < 0) { | ||
279 | dev_err(codec->dev, "failed to disable supplies: %d\n", ret); | ||
280 | return ret; | ||
281 | } | ||
282 | |||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static int tas6424_power_on(struct snd_soc_codec *codec) | ||
287 | { | ||
288 | struct tas6424_data *tas6424 = snd_soc_codec_get_drvdata(codec); | ||
289 | int ret; | ||
290 | |||
291 | ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies), | ||
292 | tas6424->supplies); | ||
293 | if (ret < 0) { | ||
294 | dev_err(codec->dev, "failed to enable supplies: %d\n", ret); | ||
295 | return ret; | ||
296 | } | ||
297 | |||
298 | regcache_cache_only(tas6424->regmap, false); | ||
299 | |||
300 | ret = regcache_sync(tas6424->regmap); | ||
301 | if (ret < 0) { | ||
302 | dev_err(codec->dev, "failed to sync regcache: %d\n", ret); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | snd_soc_write(codec, TAS6424_CH_STATE_CTRL, TAS6424_ALL_STATE_MUTE); | ||
307 | |||
308 | /* any time we come out of HIZ, the output channels automatically run DC | ||
309 | * load diagnostics, wait here until this completes | ||
310 | */ | ||
311 | msleep(230); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static int tas6424_set_bias_level(struct snd_soc_codec *codec, | ||
317 | enum snd_soc_bias_level level) | ||
318 | { | ||
319 | dev_dbg(codec->dev, "%s() level=%d\n", __func__, level); | ||
320 | |||
321 | switch (level) { | ||
322 | case SND_SOC_BIAS_ON: | ||
323 | case SND_SOC_BIAS_PREPARE: | ||
324 | break; | ||
325 | case SND_SOC_BIAS_STANDBY: | ||
326 | if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) | ||
327 | tas6424_power_on(codec); | ||
328 | break; | ||
329 | case SND_SOC_BIAS_OFF: | ||
330 | tas6424_power_off(codec); | ||
331 | break; | ||
332 | } | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static struct snd_soc_codec_driver soc_codec_dev_tas6424 = { | ||
338 | .set_bias_level = tas6424_set_bias_level, | ||
339 | .idle_bias_off = true, | ||
340 | |||
341 | .component_driver = { | ||
342 | .controls = tas6424_snd_controls, | ||
343 | .num_controls = ARRAY_SIZE(tas6424_snd_controls), | ||
344 | .dapm_widgets = tas6424_dapm_widgets, | ||
345 | .num_dapm_widgets = ARRAY_SIZE(tas6424_dapm_widgets), | ||
346 | .dapm_routes = tas6424_audio_map, | ||
347 | .num_dapm_routes = ARRAY_SIZE(tas6424_audio_map), | ||
348 | }, | ||
349 | }; | ||
350 | |||
351 | static struct snd_soc_dai_ops tas6424_speaker_dai_ops = { | ||
352 | .hw_params = tas6424_hw_params, | ||
353 | .set_fmt = tas6424_set_dai_fmt, | ||
354 | .set_tdm_slot = tas6424_set_dai_tdm_slot, | ||
355 | .digital_mute = tas6424_mute, | ||
356 | }; | ||
357 | |||
358 | static struct snd_soc_dai_driver tas6424_dai[] = { | ||
359 | { | ||
360 | .name = "tas6424-amplifier", | ||
361 | .playback = { | ||
362 | .stream_name = "Playback", | ||
363 | .channels_min = 1, | ||
364 | .channels_max = 4, | ||
365 | .rates = TAS6424_RATES, | ||
366 | .formats = TAS6424_FORMATS, | ||
367 | }, | ||
368 | .ops = &tas6424_speaker_dai_ops, | ||
369 | }, | ||
370 | }; | ||
371 | |||
372 | static void tas6424_fault_check_work(struct work_struct *work) | ||
373 | { | ||
374 | struct tas6424_data *tas6424 = container_of(work, struct tas6424_data, | ||
375 | fault_check_work.work); | ||
376 | struct device *dev = tas6424->dev; | ||
377 | unsigned int reg; | ||
378 | int ret; | ||
379 | |||
380 | ret = regmap_read(tas6424->regmap, TAS6424_GLOB_FAULT1, ®); | ||
381 | if (ret < 0) { | ||
382 | dev_err(dev, "failed to read FAULT1 register: %d\n", ret); | ||
383 | goto out; | ||
384 | } | ||
385 | |||
386 | /* | ||
387 | * Ignore any clock faults as there is no clean way to check for them. | ||
388 | * We would need to start checking for those faults *after* the SAIF | ||
389 | * stream has been setup, and stop checking *before* the stream is | ||
390 | * stopped to avoid any false-positives. However there are no | ||
391 | * appropriate hooks to monitor these events. | ||
392 | */ | ||
393 | reg &= TAS6424_FAULT_PVDD_OV | | ||
394 | TAS6424_FAULT_VBAT_OV | | ||
395 | TAS6424_FAULT_PVDD_UV | | ||
396 | TAS6424_FAULT_VBAT_UV; | ||
397 | |||
398 | if (reg) | ||
399 | goto check_global_fault2_reg; | ||
400 | |||
401 | /* | ||
402 | * Only flag errors once for a given occurrence. This is needed as | ||
403 | * the TAS6424 will take time clearing the fault condition internally | ||
404 | * during which we don't want to bombard the system with the same | ||
405 | * error message over and over. | ||
406 | */ | ||
407 | if ((reg & TAS6424_FAULT_PVDD_OV) && !(tas6424->last_fault1 & TAS6424_FAULT_PVDD_OV)) | ||
408 | dev_crit(dev, "experienced a PVDD overvoltage fault\n"); | ||
409 | |||
410 | if ((reg & TAS6424_FAULT_VBAT_OV) && !(tas6424->last_fault1 & TAS6424_FAULT_VBAT_OV)) | ||
411 | dev_crit(dev, "experienced a VBAT overvoltage fault\n"); | ||
412 | |||
413 | if ((reg & TAS6424_FAULT_PVDD_UV) && !(tas6424->last_fault1 & TAS6424_FAULT_PVDD_UV)) | ||
414 | dev_crit(dev, "experienced a PVDD undervoltage fault\n"); | ||
415 | |||
416 | if ((reg & TAS6424_FAULT_VBAT_UV) && !(tas6424->last_fault1 & TAS6424_FAULT_VBAT_UV)) | ||
417 | dev_crit(dev, "experienced a VBAT undervoltage fault\n"); | ||
418 | |||
419 | /* Store current fault1 value so we can detect any changes next time */ | ||
420 | tas6424->last_fault1 = reg; | ||
421 | |||
422 | check_global_fault2_reg: | ||
423 | ret = regmap_read(tas6424->regmap, TAS6424_GLOB_FAULT2, ®); | ||
424 | if (ret < 0) { | ||
425 | dev_err(dev, "failed to read FAULT2 register: %d\n", ret); | ||
426 | goto out; | ||
427 | } | ||
428 | |||
429 | reg &= TAS6424_FAULT_OTSD | | ||
430 | TAS6424_FAULT_OTSD_CH1 | | ||
431 | TAS6424_FAULT_OTSD_CH2 | | ||
432 | TAS6424_FAULT_OTSD_CH3 | | ||
433 | TAS6424_FAULT_OTSD_CH4; | ||
434 | |||
435 | if (!reg) | ||
436 | goto check_warn_reg; | ||
437 | |||
438 | if ((reg & TAS6424_FAULT_OTSD) && !(tas6424->last_fault2 & TAS6424_FAULT_OTSD)) | ||
439 | dev_crit(dev, "experienced a global overtemp shutdown\n"); | ||
440 | |||
441 | if ((reg & TAS6424_FAULT_OTSD_CH1) && !(tas6424->last_fault2 & TAS6424_FAULT_OTSD_CH1)) | ||
442 | dev_crit(dev, "experienced an overtemp shutdown on CH1\n"); | ||
443 | |||
444 | if ((reg & TAS6424_FAULT_OTSD_CH2) && !(tas6424->last_fault2 & TAS6424_FAULT_OTSD_CH2)) | ||
445 | dev_crit(dev, "experienced an overtemp shutdown on CH2\n"); | ||
446 | |||
447 | if ((reg & TAS6424_FAULT_OTSD_CH3) && !(tas6424->last_fault2 & TAS6424_FAULT_OTSD_CH3)) | ||
448 | dev_crit(dev, "experienced an overtemp shutdown on CH3\n"); | ||
449 | |||
450 | if ((reg & TAS6424_FAULT_OTSD_CH4) && !(tas6424->last_fault2 & TAS6424_FAULT_OTSD_CH4)) | ||
451 | dev_crit(dev, "experienced an overtemp shutdown on CH4\n"); | ||
452 | |||
453 | /* Store current fault2 value so we can detect any changes next time */ | ||
454 | tas6424->last_fault2 = reg; | ||
455 | |||
456 | check_warn_reg: | ||
457 | ret = regmap_read(tas6424->regmap, TAS6424_WARN, ®); | ||
458 | if (ret < 0) { | ||
459 | dev_err(dev, "failed to read WARN register: %d\n", ret); | ||
460 | goto out; | ||
461 | } | ||
462 | |||
463 | reg &= TAS6424_WARN_VDD_UV | | ||
464 | TAS6424_WARN_VDD_POR | | ||
465 | TAS6424_WARN_VDD_OTW | | ||
466 | TAS6424_WARN_VDD_OTW_CH1 | | ||
467 | TAS6424_WARN_VDD_OTW_CH2 | | ||
468 | TAS6424_WARN_VDD_OTW_CH3 | | ||
469 | TAS6424_WARN_VDD_OTW_CH4; | ||
470 | |||
471 | if (!reg) | ||
472 | goto out; | ||
473 | |||
474 | if ((reg & TAS6424_WARN_VDD_UV) && !(tas6424->last_warn & TAS6424_WARN_VDD_UV)) | ||
475 | dev_warn(dev, "experienced a VDD under voltage condition\n"); | ||
476 | |||
477 | if ((reg & TAS6424_WARN_VDD_POR) && !(tas6424->last_warn & TAS6424_WARN_VDD_POR)) | ||
478 | dev_warn(dev, "experienced a VDD POR condition\n"); | ||
479 | |||
480 | if ((reg & TAS6424_WARN_VDD_OTW) && !(tas6424->last_warn & TAS6424_WARN_VDD_OTW)) | ||
481 | dev_warn(dev, "experienced a global overtemp warning\n"); | ||
482 | |||
483 | if ((reg & TAS6424_WARN_VDD_OTW_CH1) && !(tas6424->last_warn & TAS6424_WARN_VDD_OTW_CH1)) | ||
484 | dev_warn(dev, "experienced an overtemp warning on CH1\n"); | ||
485 | |||
486 | if ((reg & TAS6424_WARN_VDD_OTW_CH2) && !(tas6424->last_warn & TAS6424_WARN_VDD_OTW_CH2)) | ||
487 | dev_warn(dev, "experienced an overtemp warning on CH2\n"); | ||
488 | |||
489 | if ((reg & TAS6424_WARN_VDD_OTW_CH3) && !(tas6424->last_warn & TAS6424_WARN_VDD_OTW_CH3)) | ||
490 | dev_warn(dev, "experienced an overtemp warning on CH3\n"); | ||
491 | |||
492 | if ((reg & TAS6424_WARN_VDD_OTW_CH4) && !(tas6424->last_warn & TAS6424_WARN_VDD_OTW_CH4)) | ||
493 | dev_warn(dev, "experienced an overtemp warning on CH4\n"); | ||
494 | |||
495 | /* Store current warn value so we can detect any changes next time */ | ||
496 | tas6424->last_warn = reg; | ||
497 | |||
498 | /* Clear any faults by toggling the CLEAR_FAULT control bit */ | ||
499 | ret = regmap_write_bits(tas6424->regmap, TAS6424_MISC_CTRL3, | ||
500 | TAS6424_CLEAR_FAULT, TAS6424_CLEAR_FAULT); | ||
501 | if (ret < 0) | ||
502 | dev_err(dev, "failed to write MISC_CTRL3 register: %d\n", ret); | ||
503 | |||
504 | ret = regmap_write_bits(tas6424->regmap, TAS6424_MISC_CTRL3, | ||
505 | TAS6424_CLEAR_FAULT, 0); | ||
506 | if (ret < 0) | ||
507 | dev_err(dev, "failed to write MISC_CTRL3 register: %d\n", ret); | ||
508 | |||
509 | out: | ||
510 | /* Schedule the next fault check at the specified interval */ | ||
511 | schedule_delayed_work(&tas6424->fault_check_work, | ||
512 | msecs_to_jiffies(TAS6424_FAULT_CHECK_INTERVAL)); | ||
513 | } | ||
514 | |||
515 | static const struct reg_default tas6424_reg_defaults[] = { | ||
516 | { TAS6424_MODE_CTRL, 0x00 }, | ||
517 | { TAS6424_MISC_CTRL1, 0x32 }, | ||
518 | { TAS6424_MISC_CTRL2, 0x62 }, | ||
519 | { TAS6424_SAP_CTRL, 0x04 }, | ||
520 | { TAS6424_CH_STATE_CTRL, 0x55 }, | ||
521 | { TAS6424_CH1_VOL_CTRL, 0xcf }, | ||
522 | { TAS6424_CH2_VOL_CTRL, 0xcf }, | ||
523 | { TAS6424_CH3_VOL_CTRL, 0xcf }, | ||
524 | { TAS6424_CH4_VOL_CTRL, 0xcf }, | ||
525 | { TAS6424_DC_DIAG_CTRL1, 0x00 }, | ||
526 | { TAS6424_DC_DIAG_CTRL2, 0x11 }, | ||
527 | { TAS6424_DC_DIAG_CTRL3, 0x11 }, | ||
528 | { TAS6424_PIN_CTRL, 0xff }, | ||
529 | { TAS6424_AC_DIAG_CTRL1, 0x00 }, | ||
530 | { TAS6424_MISC_CTRL3, 0x00 }, | ||
531 | { TAS6424_CLIP_CTRL, 0x01 }, | ||
532 | { TAS6424_CLIP_WINDOW, 0x14 }, | ||
533 | { TAS6424_CLIP_WARN, 0x00 }, | ||
534 | { TAS6424_CBC_STAT, 0x00 }, | ||
535 | { TAS6424_MISC_CTRL4, 0x40 }, | ||
536 | }; | ||
537 | |||
538 | static bool tas6424_is_writable_reg(struct device *dev, unsigned int reg) | ||
539 | { | ||
540 | switch (reg) { | ||
541 | case TAS6424_MODE_CTRL: | ||
542 | case TAS6424_MISC_CTRL1: | ||
543 | case TAS6424_MISC_CTRL2: | ||
544 | case TAS6424_SAP_CTRL: | ||
545 | case TAS6424_CH_STATE_CTRL: | ||
546 | case TAS6424_CH1_VOL_CTRL: | ||
547 | case TAS6424_CH2_VOL_CTRL: | ||
548 | case TAS6424_CH3_VOL_CTRL: | ||
549 | case TAS6424_CH4_VOL_CTRL: | ||
550 | case TAS6424_DC_DIAG_CTRL1: | ||
551 | case TAS6424_DC_DIAG_CTRL2: | ||
552 | case TAS6424_DC_DIAG_CTRL3: | ||
553 | case TAS6424_PIN_CTRL: | ||
554 | case TAS6424_AC_DIAG_CTRL1: | ||
555 | case TAS6424_MISC_CTRL3: | ||
556 | case TAS6424_CLIP_CTRL: | ||
557 | case TAS6424_CLIP_WINDOW: | ||
558 | case TAS6424_CLIP_WARN: | ||
559 | case TAS6424_CBC_STAT: | ||
560 | case TAS6424_MISC_CTRL4: | ||
561 | return true; | ||
562 | default: | ||
563 | return false; | ||
564 | } | ||
565 | } | ||
566 | |||
567 | static bool tas6424_is_volatile_reg(struct device *dev, unsigned int reg) | ||
568 | { | ||
569 | switch (reg) { | ||
570 | case TAS6424_DC_LOAD_DIAG_REP12: | ||
571 | case TAS6424_DC_LOAD_DIAG_REP34: | ||
572 | case TAS6424_DC_LOAD_DIAG_REPLO: | ||
573 | case TAS6424_CHANNEL_STATE: | ||
574 | case TAS6424_CHANNEL_FAULT: | ||
575 | case TAS6424_GLOB_FAULT1: | ||
576 | case TAS6424_GLOB_FAULT2: | ||
577 | case TAS6424_WARN: | ||
578 | case TAS6424_AC_LOAD_DIAG_REP1: | ||
579 | case TAS6424_AC_LOAD_DIAG_REP2: | ||
580 | case TAS6424_AC_LOAD_DIAG_REP3: | ||
581 | case TAS6424_AC_LOAD_DIAG_REP4: | ||
582 | return true; | ||
583 | default: | ||
584 | return false; | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static const struct regmap_config tas6424_regmap_config = { | ||
589 | .reg_bits = 8, | ||
590 | .val_bits = 8, | ||
591 | |||
592 | .writeable_reg = tas6424_is_writable_reg, | ||
593 | .volatile_reg = tas6424_is_volatile_reg, | ||
594 | |||
595 | .max_register = TAS6424_MAX, | ||
596 | .reg_defaults = tas6424_reg_defaults, | ||
597 | .num_reg_defaults = ARRAY_SIZE(tas6424_reg_defaults), | ||
598 | .cache_type = REGCACHE_RBTREE, | ||
599 | }; | ||
600 | |||
601 | #if IS_ENABLED(CONFIG_OF) | ||
602 | static const struct of_device_id tas6424_of_ids[] = { | ||
603 | { .compatible = "ti,tas6424", }, | ||
604 | { }, | ||
605 | }; | ||
606 | MODULE_DEVICE_TABLE(of, tas6424_of_ids); | ||
607 | #endif | ||
608 | |||
609 | static int tas6424_i2c_probe(struct i2c_client *client, | ||
610 | const struct i2c_device_id *id) | ||
611 | { | ||
612 | struct device *dev = &client->dev; | ||
613 | struct tas6424_data *tas6424; | ||
614 | int ret; | ||
615 | int i; | ||
616 | |||
617 | tas6424 = devm_kzalloc(dev, sizeof(*tas6424), GFP_KERNEL); | ||
618 | if (!tas6424) | ||
619 | return -ENOMEM; | ||
620 | dev_set_drvdata(dev, tas6424); | ||
621 | |||
622 | tas6424->dev = dev; | ||
623 | |||
624 | tas6424->regmap = devm_regmap_init_i2c(client, &tas6424_regmap_config); | ||
625 | if (IS_ERR(tas6424->regmap)) { | ||
626 | ret = PTR_ERR(tas6424->regmap); | ||
627 | dev_err(dev, "unable to allocate register map: %d\n", ret); | ||
628 | return ret; | ||
629 | } | ||
630 | |||
631 | for (i = 0; i < ARRAY_SIZE(tas6424->supplies); i++) | ||
632 | tas6424->supplies[i].supply = tas6424_supply_names[i]; | ||
633 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(tas6424->supplies), | ||
634 | tas6424->supplies); | ||
635 | if (ret) { | ||
636 | dev_err(dev, "unable to request supplies: %d\n", ret); | ||
637 | return ret; | ||
638 | } | ||
639 | |||
640 | ret = regulator_bulk_enable(ARRAY_SIZE(tas6424->supplies), | ||
641 | tas6424->supplies); | ||
642 | if (ret) { | ||
643 | dev_err(dev, "unable to enable supplies: %d\n", ret); | ||
644 | return ret; | ||
645 | } | ||
646 | |||
647 | /* Reset device to establish well-defined startup state */ | ||
648 | ret = regmap_update_bits(tas6424->regmap, TAS6424_MODE_CTRL, | ||
649 | TAS6424_RESET, TAS6424_RESET); | ||
650 | if (ret) { | ||
651 | dev_err(dev, "unable to reset device: %d\n", ret); | ||
652 | return ret; | ||
653 | } | ||
654 | |||
655 | INIT_DELAYED_WORK(&tas6424->fault_check_work, tas6424_fault_check_work); | ||
656 | |||
657 | ret = snd_soc_register_codec(dev, &soc_codec_dev_tas6424, | ||
658 | tas6424_dai, ARRAY_SIZE(tas6424_dai)); | ||
659 | if (ret < 0) { | ||
660 | dev_err(dev, "unable to register codec: %d\n", ret); | ||
661 | return ret; | ||
662 | } | ||
663 | |||
664 | return 0; | ||
665 | } | ||
666 | |||
667 | static int tas6424_i2c_remove(struct i2c_client *client) | ||
668 | { | ||
669 | struct device *dev = &client->dev; | ||
670 | struct tas6424_data *tas6424 = dev_get_drvdata(dev); | ||
671 | int ret; | ||
672 | |||
673 | snd_soc_unregister_codec(dev); | ||
674 | |||
675 | cancel_delayed_work_sync(&tas6424->fault_check_work); | ||
676 | |||
677 | ret = regulator_bulk_disable(ARRAY_SIZE(tas6424->supplies), | ||
678 | tas6424->supplies); | ||
679 | if (ret < 0) { | ||
680 | dev_err(dev, "unable to disable supplies: %d\n", ret); | ||
681 | return ret; | ||
682 | } | ||
683 | |||
684 | return 0; | ||
685 | } | ||
686 | |||
687 | static const struct i2c_device_id tas6424_i2c_ids[] = { | ||
688 | { "tas6424", 0 }, | ||
689 | { } | ||
690 | }; | ||
691 | MODULE_DEVICE_TABLE(i2c, tas6424_i2c_ids); | ||
692 | |||
693 | static struct i2c_driver tas6424_i2c_driver = { | ||
694 | .driver = { | ||
695 | .name = "tas6424", | ||
696 | .of_match_table = of_match_ptr(tas6424_of_ids), | ||
697 | }, | ||
698 | .probe = tas6424_i2c_probe, | ||
699 | .remove = tas6424_i2c_remove, | ||
700 | .id_table = tas6424_i2c_ids, | ||
701 | }; | ||
702 | module_i2c_driver(tas6424_i2c_driver); | ||
703 | |||
704 | MODULE_AUTHOR("Andreas Dannenberg <dannenberg@ti.com>"); | ||
705 | MODULE_AUTHOR("Andrew F. Davis <afd@ti.com>"); | ||
706 | MODULE_DESCRIPTION("TAS6424 Audio amplifier driver"); | ||
707 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/tas6424.h b/sound/soc/codecs/tas6424.h new file mode 100644 index 000000000000..430588328a06 --- /dev/null +++ b/sound/soc/codecs/tas6424.h | |||
@@ -0,0 +1,144 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * ALSA SoC Texas Instruments TAS6424 Quad-Channel Audio Amplifier | ||
4 | * | ||
5 | * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/ | ||
6 | * Author: Andreas Dannenberg <dannenberg@ti.com> | ||
7 | * Andrew F. Davis <afd@ti.com> | ||
8 | */ | ||
9 | |||
10 | #ifndef __TAS6424_H__ | ||
11 | #define __TAS6424_H__ | ||
12 | |||
13 | #define TAS6424_RATES (SNDRV_PCM_RATE_44100 | \ | ||
14 | SNDRV_PCM_RATE_48000 | \ | ||
15 | SNDRV_PCM_RATE_96000) | ||
16 | |||
17 | #define TAS6424_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
18 | SNDRV_PCM_FMTBIT_S24_LE) | ||
19 | |||
20 | /* Register Address Map */ | ||
21 | #define TAS6424_MODE_CTRL 0x00 | ||
22 | #define TAS6424_MISC_CTRL1 0x01 | ||
23 | #define TAS6424_MISC_CTRL2 0x02 | ||
24 | #define TAS6424_SAP_CTRL 0x03 | ||
25 | #define TAS6424_CH_STATE_CTRL 0x04 | ||
26 | #define TAS6424_CH1_VOL_CTRL 0x05 | ||
27 | #define TAS6424_CH2_VOL_CTRL 0x06 | ||
28 | #define TAS6424_CH3_VOL_CTRL 0x07 | ||
29 | #define TAS6424_CH4_VOL_CTRL 0x08 | ||
30 | #define TAS6424_DC_DIAG_CTRL1 0x09 | ||
31 | #define TAS6424_DC_DIAG_CTRL2 0x0a | ||
32 | #define TAS6424_DC_DIAG_CTRL3 0x0b | ||
33 | #define TAS6424_DC_LOAD_DIAG_REP12 0x0c | ||
34 | #define TAS6424_DC_LOAD_DIAG_REP34 0x0d | ||
35 | #define TAS6424_DC_LOAD_DIAG_REPLO 0x0e | ||
36 | #define TAS6424_CHANNEL_STATE 0x0f | ||
37 | #define TAS6424_CHANNEL_FAULT 0x10 | ||
38 | #define TAS6424_GLOB_FAULT1 0x11 | ||
39 | #define TAS6424_GLOB_FAULT2 0x12 | ||
40 | #define TAS6424_WARN 0x13 | ||
41 | #define TAS6424_PIN_CTRL 0x14 | ||
42 | #define TAS6424_AC_DIAG_CTRL1 0x15 | ||
43 | #define TAS6424_AC_DIAG_CTRL2 0x16 | ||
44 | #define TAS6424_AC_LOAD_DIAG_REP1 0x17 | ||
45 | #define TAS6424_AC_LOAD_DIAG_REP2 0x18 | ||
46 | #define TAS6424_AC_LOAD_DIAG_REP3 0x19 | ||
47 | #define TAS6424_AC_LOAD_DIAG_REP4 0x1a | ||
48 | #define TAS6424_MISC_CTRL3 0x21 | ||
49 | #define TAS6424_CLIP_CTRL 0x22 | ||
50 | #define TAS6424_CLIP_WINDOW 0x23 | ||
51 | #define TAS6424_CLIP_WARN 0x24 | ||
52 | #define TAS6424_CBC_STAT 0x25 | ||
53 | #define TAS6424_MISC_CTRL4 0x26 | ||
54 | #define TAS6424_MAX TAS6424_MISC_CTRL4 | ||
55 | |||
56 | /* TAS6424_MODE_CTRL_REG */ | ||
57 | #define TAS6424_RESET BIT(7) | ||
58 | |||
59 | /* TAS6424_SAP_CTRL_REG */ | ||
60 | #define TAS6424_SAP_RATE_MASK GENMASK(7, 6) | ||
61 | #define TAS6424_SAP_RATE_44100 (0x00 << 6) | ||
62 | #define TAS6424_SAP_RATE_48000 (0x01 << 6) | ||
63 | #define TAS6424_SAP_RATE_96000 (0x02 << 6) | ||
64 | #define TAS6424_SAP_TDM_SLOT_LAST BIT(5) | ||
65 | #define TAS6424_SAP_TDM_SLOT_SZ_16 BIT(4) | ||
66 | #define TAS6424_SAP_TDM_SLOT_SWAP BIT(3) | ||
67 | #define TAS6424_SAP_FMT_MASK GENMASK(2, 0) | ||
68 | #define TAS6424_SAP_RIGHTJ_24 (0x00 << 0) | ||
69 | #define TAS6424_SAP_RIGHTJ_20 (0x01 << 0) | ||
70 | #define TAS6424_SAP_RIGHTJ_18 (0x02 << 0) | ||
71 | #define TAS6424_SAP_RIGHTJ_16 (0x03 << 0) | ||
72 | #define TAS6424_SAP_I2S (0x04 << 0) | ||
73 | #define TAS6424_SAP_LEFTJ (0x05 << 0) | ||
74 | #define TAS6424_SAP_DSP (0x06 << 0) | ||
75 | |||
76 | /* TAS6424_CH_STATE_CTRL_REG */ | ||
77 | #define TAS6424_CH1_STATE_MASK GENMASK(7, 6) | ||
78 | #define TAS6424_CH1_STATE_PLAY (0x00 << 6) | ||
79 | #define TAS6424_CH1_STATE_HIZ (0x01 << 6) | ||
80 | #define TAS6424_CH1_STATE_MUTE (0x02 << 6) | ||
81 | #define TAS6424_CH1_STATE_DIAG (0x03 << 6) | ||
82 | #define TAS6424_CH2_STATE_MASK GENMASK(5, 4) | ||
83 | #define TAS6424_CH2_STATE_PLAY (0x00 << 4) | ||
84 | #define TAS6424_CH2_STATE_HIZ (0x01 << 4) | ||
85 | #define TAS6424_CH2_STATE_MUTE (0x02 << 4) | ||
86 | #define TAS6424_CH2_STATE_DIAG (0x03 << 4) | ||
87 | #define TAS6424_CH3_STATE_MASK GENMASK(3, 2) | ||
88 | #define TAS6424_CH3_STATE_PLAY (0x00 << 2) | ||
89 | #define TAS6424_CH3_STATE_HIZ (0x01 << 2) | ||
90 | #define TAS6424_CH3_STATE_MUTE (0x02 << 2) | ||
91 | #define TAS6424_CH3_STATE_DIAG (0x03 << 2) | ||
92 | #define TAS6424_CH4_STATE_MASK GENMASK(1, 0) | ||
93 | #define TAS6424_CH4_STATE_PLAY (0x00 << 0) | ||
94 | #define TAS6424_CH4_STATE_HIZ (0x01 << 0) | ||
95 | #define TAS6424_CH4_STATE_MUTE (0x02 << 0) | ||
96 | #define TAS6424_CH4_STATE_DIAG (0x03 << 0) | ||
97 | #define TAS6424_ALL_STATE_PLAY (TAS6424_CH1_STATE_PLAY | \ | ||
98 | TAS6424_CH2_STATE_PLAY | \ | ||
99 | TAS6424_CH3_STATE_PLAY | \ | ||
100 | TAS6424_CH4_STATE_PLAY) | ||
101 | #define TAS6424_ALL_STATE_HIZ (TAS6424_CH1_STATE_HIZ | \ | ||
102 | TAS6424_CH2_STATE_HIZ | \ | ||
103 | TAS6424_CH3_STATE_HIZ | \ | ||
104 | TAS6424_CH4_STATE_HIZ) | ||
105 | #define TAS6424_ALL_STATE_MUTE (TAS6424_CH1_STATE_MUTE | \ | ||
106 | TAS6424_CH2_STATE_MUTE | \ | ||
107 | TAS6424_CH3_STATE_MUTE | \ | ||
108 | TAS6424_CH4_STATE_MUTE) | ||
109 | #define TAS6424_ALL_STATE_DIAG (TAS6424_CH1_STATE_DIAG | \ | ||
110 | TAS6424_CH2_STATE_DIAG | \ | ||
111 | TAS6424_CH3_STATE_DIAG | \ | ||
112 | TAS6424_CH4_STATE_DIAG) | ||
113 | |||
114 | /* TAS6424_GLOB_FAULT1_REG */ | ||
115 | #define TAS6424_FAULT_CLOCK BIT(4) | ||
116 | #define TAS6424_FAULT_PVDD_OV BIT(3) | ||
117 | #define TAS6424_FAULT_VBAT_OV BIT(2) | ||
118 | #define TAS6424_FAULT_PVDD_UV BIT(1) | ||
119 | #define TAS6424_FAULT_VBAT_UV BIT(0) | ||
120 | |||
121 | /* TAS6424_GLOB_FAULT2_REG */ | ||
122 | #define TAS6424_FAULT_OTSD BIT(4) | ||
123 | #define TAS6424_FAULT_OTSD_CH1 BIT(3) | ||
124 | #define TAS6424_FAULT_OTSD_CH2 BIT(2) | ||
125 | #define TAS6424_FAULT_OTSD_CH3 BIT(1) | ||
126 | #define TAS6424_FAULT_OTSD_CH4 BIT(0) | ||
127 | |||
128 | /* TAS6424_WARN_REG */ | ||
129 | #define TAS6424_WARN_VDD_UV BIT(6) | ||
130 | #define TAS6424_WARN_VDD_POR BIT(5) | ||
131 | #define TAS6424_WARN_VDD_OTW BIT(4) | ||
132 | #define TAS6424_WARN_VDD_OTW_CH1 BIT(3) | ||
133 | #define TAS6424_WARN_VDD_OTW_CH2 BIT(2) | ||
134 | #define TAS6424_WARN_VDD_OTW_CH3 BIT(1) | ||
135 | #define TAS6424_WARN_VDD_OTW_CH4 BIT(0) | ||
136 | |||
137 | /* TAS6424_MISC_CTRL3_REG */ | ||
138 | #define TAS6424_CLEAR_FAULT BIT(7) | ||
139 | #define TAS6424_PBTL_CH_SEL BIT(6) | ||
140 | #define TAS6424_MASK_CBC_WARN BIT(5) | ||
141 | #define TAS6424_MASK_VDD_UV BIT(4) | ||
142 | #define TAS6424_OTSD_AUTO_RECOVERY BIT(3) | ||
143 | |||
144 | #endif /* __TAS6424_H__ */ | ||
diff --git a/sound/soc/codecs/tfa9879.c b/sound/soc/codecs/tfa9879.c index f8dd67ca0744..e7ca764b5729 100644 --- a/sound/soc/codecs/tfa9879.c +++ b/sound/soc/codecs/tfa9879.c | |||
@@ -316,6 +316,7 @@ static const struct of_device_id tfa9879_of_match[] = { | |||
316 | { .compatible = "nxp,tfa9879", }, | 316 | { .compatible = "nxp,tfa9879", }, |
317 | { } | 317 | { } |
318 | }; | 318 | }; |
319 | MODULE_DEVICE_TABLE(of, tfa9879_of_match); | ||
319 | 320 | ||
320 | static struct i2c_driver tfa9879_i2c_driver = { | 321 | static struct i2c_driver tfa9879_i2c_driver = { |
321 | .driver = { | 322 | .driver = { |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index e2862372c26e..858cb8be445f 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -1,22 +1,14 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * ALSA SoC TLV320AIC31XX codec driver | 3 | * ALSA SoC TLV320AIC31xx CODEC Driver |
3 | * | 4 | * |
4 | * Copyright (C) 2014 Texas Instruments, Inc. | 5 | * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/ |
5 | * | 6 | * Jyri Sarha <jsarha@ti.com> |
6 | * Author: Jyri Sarha <jsarha@ti.com> | ||
7 | * | 7 | * |
8 | * Based on ground work by: Ajit Kulkarni <x0175765@ti.com> | 8 | * Based on ground work by: Ajit Kulkarni <x0175765@ti.com> |
9 | * | 9 | * |
10 | * This package is free software; you can redistribute it and/or modify | 10 | * The TLV320AIC31xx series of audio codecs are low-power, highly integrated |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * high performance codecs which provides a stereo DAC, a mono ADC, |
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * THIS PACKAGE IS PROVIDED AS IS AND WITHOUT ANY EXPRESS OR | ||
15 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
16 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
17 | * | ||
18 | * The TLV320AIC31xx series of audio codec is a low-power, highly integrated | ||
19 | * high performance codec which provides a stereo DAC, a mono ADC, | ||
20 | * and mono/stereo Class-D speaker driver. | 12 | * and mono/stereo Class-D speaker driver. |
21 | */ | 13 | */ |
22 | 14 | ||
@@ -26,7 +18,7 @@ | |||
26 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
27 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
28 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
29 | #include <linux/gpio.h> | 21 | #include <linux/gpio/consumer.h> |
30 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
31 | #include <linux/acpi.h> | 23 | #include <linux/acpi.h> |
32 | #include <linux/of.h> | 24 | #include <linux/of.h> |
@@ -144,8 +136,7 @@ static const struct regmap_config aic31xx_i2c_regmap = { | |||
144 | .max_register = 12 * 128, | 136 | .max_register = 12 * 128, |
145 | }; | 137 | }; |
146 | 138 | ||
147 | #define AIC31XX_NUM_SUPPLIES 6 | 139 | static const char * const aic31xx_supply_names[] = { |
148 | static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = { | ||
149 | "HPVDD", | 140 | "HPVDD", |
150 | "SPRVDD", | 141 | "SPRVDD", |
151 | "SPLVDD", | 142 | "SPLVDD", |
@@ -154,6 +145,8 @@ static const char * const aic31xx_supply_names[AIC31XX_NUM_SUPPLIES] = { | |||
154 | "DVDD", | 145 | "DVDD", |
155 | }; | 146 | }; |
156 | 147 | ||
148 | #define AIC31XX_NUM_SUPPLIES ARRAY_SIZE(aic31xx_supply_names) | ||
149 | |||
157 | struct aic31xx_disable_nb { | 150 | struct aic31xx_disable_nb { |
158 | struct notifier_block nb; | 151 | struct notifier_block nb; |
159 | struct aic31xx_priv *aic31xx; | 152 | struct aic31xx_priv *aic31xx; |
@@ -164,6 +157,9 @@ struct aic31xx_priv { | |||
164 | u8 i2c_regs_status; | 157 | u8 i2c_regs_status; |
165 | struct device *dev; | 158 | struct device *dev; |
166 | struct regmap *regmap; | 159 | struct regmap *regmap; |
160 | enum aic31xx_type codec_type; | ||
161 | struct gpio_desc *gpio_reset; | ||
162 | int micbias_vg; | ||
167 | struct aic31xx_pdata pdata; | 163 | struct aic31xx_pdata pdata; |
168 | struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; | 164 | struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES]; |
169 | struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; | 165 | struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES]; |
@@ -185,7 +181,7 @@ struct aic31xx_rate_divs { | |||
185 | u8 madc; | 181 | u8 madc; |
186 | }; | 182 | }; |
187 | 183 | ||
188 | /* ADC dividers can be disabled by cofiguring them to 0 */ | 184 | /* ADC dividers can be disabled by configuring them to 0 */ |
189 | static const struct aic31xx_rate_divs aic31xx_divs[] = { | 185 | static const struct aic31xx_rate_divs aic31xx_divs[] = { |
190 | /* mclk/p rate pll: j d dosr ndac mdac aors nadc madc */ | 186 | /* mclk/p rate pll: j d dosr ndac mdac aors nadc madc */ |
191 | /* 8k rate */ | 187 | /* 8k rate */ |
@@ -456,7 +452,7 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, | |||
456 | /* change mic bias voltage to user defined */ | 452 | /* change mic bias voltage to user defined */ |
457 | snd_soc_update_bits(codec, AIC31XX_MICBIAS, | 453 | snd_soc_update_bits(codec, AIC31XX_MICBIAS, |
458 | AIC31XX_MICBIAS_MASK, | 454 | AIC31XX_MICBIAS_MASK, |
459 | aic31xx->pdata.micbias_vg << | 455 | aic31xx->micbias_vg << |
460 | AIC31XX_MICBIAS_SHIFT); | 456 | AIC31XX_MICBIAS_SHIFT); |
461 | dev_dbg(codec->dev, "%s: turned on\n", __func__); | 457 | dev_dbg(codec->dev, "%s: turned on\n", __func__); |
462 | break; | 458 | break; |
@@ -679,14 +675,14 @@ static int aic31xx_add_controls(struct snd_soc_codec *codec) | |||
679 | int ret = 0; | 675 | int ret = 0; |
680 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 676 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
681 | 677 | ||
682 | if (!(aic31xx->pdata.codec_type & DAC31XX_BIT)) | 678 | if (!(aic31xx->codec_type & DAC31XX_BIT)) |
683 | ret = snd_soc_add_codec_controls( | 679 | ret = snd_soc_add_codec_controls( |
684 | codec, aic31xx_snd_controls, | 680 | codec, aic31xx_snd_controls, |
685 | ARRAY_SIZE(aic31xx_snd_controls)); | 681 | ARRAY_SIZE(aic31xx_snd_controls)); |
686 | if (ret) | 682 | if (ret) |
687 | return ret; | 683 | return ret; |
688 | 684 | ||
689 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) | 685 | if (aic31xx->codec_type & AIC31XX_STEREO_CLASS_D_BIT) |
690 | ret = snd_soc_add_codec_controls( | 686 | ret = snd_soc_add_codec_controls( |
691 | codec, aic311x_snd_controls, | 687 | codec, aic311x_snd_controls, |
692 | ARRAY_SIZE(aic311x_snd_controls)); | 688 | ARRAY_SIZE(aic311x_snd_controls)); |
@@ -704,7 +700,7 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec) | |||
704 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 700 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
705 | int ret = 0; | 701 | int ret = 0; |
706 | 702 | ||
707 | if (aic31xx->pdata.codec_type & DAC31XX_BIT) { | 703 | if (aic31xx->codec_type & DAC31XX_BIT) { |
708 | ret = snd_soc_dapm_new_controls( | 704 | ret = snd_soc_dapm_new_controls( |
709 | dapm, dac31xx_dapm_widgets, | 705 | dapm, dac31xx_dapm_widgets, |
710 | ARRAY_SIZE(dac31xx_dapm_widgets)); | 706 | ARRAY_SIZE(dac31xx_dapm_widgets)); |
@@ -728,7 +724,7 @@ static int aic31xx_add_widgets(struct snd_soc_codec *codec) | |||
728 | return ret; | 724 | return ret; |
729 | } | 725 | } |
730 | 726 | ||
731 | if (aic31xx->pdata.codec_type & AIC31XX_STEREO_CLASS_D_BIT) { | 727 | if (aic31xx->codec_type & AIC31XX_STEREO_CLASS_D_BIT) { |
732 | ret = snd_soc_dapm_new_controls( | 728 | ret = snd_soc_dapm_new_controls( |
733 | dapm, aic311x_dapm_widgets, | 729 | dapm, aic311x_dapm_widgets, |
734 | ARRAY_SIZE(aic311x_dapm_widgets)); | 730 | ARRAY_SIZE(aic311x_dapm_widgets)); |
@@ -760,11 +756,17 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, | |||
760 | { | 756 | { |
761 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 757 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
762 | int bclk_score = snd_soc_params_to_frame_size(params); | 758 | int bclk_score = snd_soc_params_to_frame_size(params); |
763 | int mclk_p = aic31xx->sysclk / aic31xx->p_div; | 759 | int mclk_p; |
764 | int bclk_n = 0; | 760 | int bclk_n = 0; |
765 | int match = -1; | 761 | int match = -1; |
766 | int i; | 762 | int i; |
767 | 763 | ||
764 | if (!aic31xx->sysclk || !aic31xx->p_div) { | ||
765 | dev_err(codec->dev, "Master clock not supplied\n"); | ||
766 | return -EINVAL; | ||
767 | } | ||
768 | mclk_p = aic31xx->sysclk / aic31xx->p_div; | ||
769 | |||
768 | /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ | 770 | /* Use PLL as CODEC_CLKIN and DAC_CLK as BDIV_CLKIN */ |
769 | snd_soc_update_bits(codec, AIC31XX_CLKMUX, | 771 | snd_soc_update_bits(codec, AIC31XX_CLKMUX, |
770 | AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL); | 772 | AIC31XX_CODEC_CLKIN_MASK, AIC31XX_CODEC_CLKIN_PLL); |
@@ -840,11 +842,17 @@ static int aic31xx_setup_pll(struct snd_soc_codec *codec, | |||
840 | 842 | ||
841 | dev_dbg(codec->dev, | 843 | dev_dbg(codec->dev, |
842 | "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", | 844 | "pll %d.%04d/%d dosr %d n %d m %d aosr %d n %d m %d bclk_n %d\n", |
843 | aic31xx_divs[i].pll_j, aic31xx_divs[i].pll_d, | 845 | aic31xx_divs[i].pll_j, |
844 | aic31xx->p_div, aic31xx_divs[i].dosr, | 846 | aic31xx_divs[i].pll_d, |
845 | aic31xx_divs[i].ndac, aic31xx_divs[i].mdac, | 847 | aic31xx->p_div, |
846 | aic31xx_divs[i].aosr, aic31xx_divs[i].nadc, | 848 | aic31xx_divs[i].dosr, |
847 | aic31xx_divs[i].madc, bclk_n); | 849 | aic31xx_divs[i].ndac, |
850 | aic31xx_divs[i].mdac, | ||
851 | aic31xx_divs[i].aosr, | ||
852 | aic31xx_divs[i].nadc, | ||
853 | aic31xx_divs[i].madc, | ||
854 | bclk_n | ||
855 | ); | ||
848 | 856 | ||
849 | return 0; | 857 | return 0; |
850 | } | 858 | } |
@@ -919,8 +927,28 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
919 | case SND_SOC_DAIFMT_CBM_CFM: | 927 | case SND_SOC_DAIFMT_CBM_CFM: |
920 | iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; | 928 | iface_reg1 |= AIC31XX_BCLK_MASTER | AIC31XX_WCLK_MASTER; |
921 | break; | 929 | break; |
930 | case SND_SOC_DAIFMT_CBS_CFM: | ||
931 | iface_reg1 |= AIC31XX_WCLK_MASTER; | ||
932 | break; | ||
933 | case SND_SOC_DAIFMT_CBM_CFS: | ||
934 | iface_reg1 |= AIC31XX_BCLK_MASTER; | ||
935 | break; | ||
936 | case SND_SOC_DAIFMT_CBS_CFS: | ||
937 | break; | ||
938 | default: | ||
939 | dev_err(codec->dev, "Invalid DAI master/slave interface\n"); | ||
940 | return -EINVAL; | ||
941 | } | ||
942 | |||
943 | /* signal polarity */ | ||
944 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
945 | case SND_SOC_DAIFMT_NB_NF: | ||
946 | break; | ||
947 | case SND_SOC_DAIFMT_IB_NF: | ||
948 | iface_reg2 |= AIC31XX_BCLKINV_MASK; | ||
949 | break; | ||
922 | default: | 950 | default: |
923 | dev_alert(codec->dev, "Invalid DAI master/slave interface\n"); | 951 | dev_err(codec->dev, "Invalid DAI clock signal polarity\n"); |
924 | return -EINVAL; | 952 | return -EINVAL; |
925 | } | 953 | } |
926 | 954 | ||
@@ -931,16 +959,12 @@ static int aic31xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
931 | case SND_SOC_DAIFMT_DSP_A: | 959 | case SND_SOC_DAIFMT_DSP_A: |
932 | dsp_a_val = 0x1; /* fall through */ | 960 | dsp_a_val = 0x1; /* fall through */ |
933 | case SND_SOC_DAIFMT_DSP_B: | 961 | case SND_SOC_DAIFMT_DSP_B: |
934 | /* NOTE: BCLKINV bit value 1 equas NB and 0 equals IB */ | 962 | /* |
935 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 963 | * NOTE: This CODEC samples on the falling edge of BCLK in |
936 | case SND_SOC_DAIFMT_NB_NF: | 964 | * DSP mode, this is inverted compared to what most DAIs |
937 | iface_reg2 |= AIC31XX_BCLKINV_MASK; | 965 | * expect, so we invert for this mode |
938 | break; | 966 | */ |
939 | case SND_SOC_DAIFMT_IB_NF: | 967 | iface_reg2 ^= AIC31XX_BCLKINV_MASK; |
940 | break; | ||
941 | default: | ||
942 | return -EINVAL; | ||
943 | } | ||
944 | iface_reg1 |= (AIC31XX_DSP_MODE << | 968 | iface_reg1 |= (AIC31XX_DSP_MODE << |
945 | AIC31XX_IFACE1_DATATYPE_SHIFT); | 969 | AIC31XX_IFACE1_DATATYPE_SHIFT); |
946 | break; | 970 | break; |
@@ -981,8 +1005,9 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
981 | dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", | 1005 | dev_dbg(codec->dev, "## %s: clk_id = %d, freq = %d, dir = %d\n", |
982 | __func__, clk_id, freq, dir); | 1006 | __func__, clk_id, freq, dir); |
983 | 1007 | ||
984 | for (i = 1; freq/i > 20000000 && i < 8; i++) | 1008 | for (i = 1; i < 8; i++) |
985 | ; | 1009 | if (freq / i <= 20000000) |
1010 | break; | ||
986 | if (freq/i > 20000000) { | 1011 | if (freq/i > 20000000) { |
987 | dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n", | 1012 | dev_err(aic31xx->dev, "%s: Too high mclk frequency %u\n", |
988 | __func__, freq); | 1013 | __func__, freq); |
@@ -990,9 +1015,9 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
990 | } | 1015 | } |
991 | aic31xx->p_div = i; | 1016 | aic31xx->p_div = i; |
992 | 1017 | ||
993 | for (i = 0; i < ARRAY_SIZE(aic31xx_divs) && | 1018 | for (i = 0; i < ARRAY_SIZE(aic31xx_divs); i++) |
994 | aic31xx_divs[i].mclk_p != freq/aic31xx->p_div; i++) | 1019 | if (aic31xx_divs[i].mclk_p == freq / aic31xx->p_div) |
995 | ; | 1020 | break; |
996 | if (i == ARRAY_SIZE(aic31xx_divs)) { | 1021 | if (i == ARRAY_SIZE(aic31xx_divs)) { |
997 | dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", | 1022 | dev_err(aic31xx->dev, "%s: Unsupported frequency %d\n", |
998 | __func__, freq); | 1023 | __func__, freq); |
@@ -1004,6 +1029,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
1004 | clk_id << AIC31XX_PLL_CLKIN_SHIFT); | 1029 | clk_id << AIC31XX_PLL_CLKIN_SHIFT); |
1005 | 1030 | ||
1006 | aic31xx->sysclk = freq; | 1031 | aic31xx->sysclk = freq; |
1032 | |||
1007 | return 0; | 1033 | return 0; |
1008 | } | 1034 | } |
1009 | 1035 | ||
@@ -1019,8 +1045,8 @@ static int aic31xx_regulator_event(struct notifier_block *nb, | |||
1019 | * Put codec to reset and as at least one of the | 1045 | * Put codec to reset and as at least one of the |
1020 | * supplies was disabled. | 1046 | * supplies was disabled. |
1021 | */ | 1047 | */ |
1022 | if (gpio_is_valid(aic31xx->pdata.gpio_reset)) | 1048 | if (aic31xx->gpio_reset) |
1023 | gpio_set_value(aic31xx->pdata.gpio_reset, 0); | 1049 | gpiod_set_value(aic31xx->gpio_reset, 1); |
1024 | 1050 | ||
1025 | regcache_mark_dirty(aic31xx->regmap); | 1051 | regcache_mark_dirty(aic31xx->regmap); |
1026 | dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__); | 1052 | dev_dbg(aic31xx->dev, "## %s: DISABLE received\n", __func__); |
@@ -1029,6 +1055,22 @@ static int aic31xx_regulator_event(struct notifier_block *nb, | |||
1029 | return 0; | 1055 | return 0; |
1030 | } | 1056 | } |
1031 | 1057 | ||
1058 | static int aic31xx_reset(struct aic31xx_priv *aic31xx) | ||
1059 | { | ||
1060 | int ret = 0; | ||
1061 | |||
1062 | if (aic31xx->gpio_reset) { | ||
1063 | gpiod_set_value(aic31xx->gpio_reset, 1); | ||
1064 | ndelay(10); /* At least 10ns */ | ||
1065 | gpiod_set_value(aic31xx->gpio_reset, 0); | ||
1066 | } else { | ||
1067 | ret = regmap_write(aic31xx->regmap, AIC31XX_RESET, 1); | ||
1068 | } | ||
1069 | mdelay(1); /* At least 1ms */ | ||
1070 | |||
1071 | return ret; | ||
1072 | } | ||
1073 | |||
1032 | static void aic31xx_clk_on(struct snd_soc_codec *codec) | 1074 | static void aic31xx_clk_on(struct snd_soc_codec *codec) |
1033 | { | 1075 | { |
1034 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 1076 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
@@ -1065,20 +1107,22 @@ static void aic31xx_clk_off(struct snd_soc_codec *codec) | |||
1065 | static int aic31xx_power_on(struct snd_soc_codec *codec) | 1107 | static int aic31xx_power_on(struct snd_soc_codec *codec) |
1066 | { | 1108 | { |
1067 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 1109 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
1068 | int ret = 0; | 1110 | int ret; |
1069 | 1111 | ||
1070 | ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies), | 1112 | ret = regulator_bulk_enable(ARRAY_SIZE(aic31xx->supplies), |
1071 | aic31xx->supplies); | 1113 | aic31xx->supplies); |
1072 | if (ret) | 1114 | if (ret) |
1073 | return ret; | 1115 | return ret; |
1074 | 1116 | ||
1075 | if (gpio_is_valid(aic31xx->pdata.gpio_reset)) { | ||
1076 | gpio_set_value(aic31xx->pdata.gpio_reset, 1); | ||
1077 | udelay(100); | ||
1078 | } | ||
1079 | regcache_cache_only(aic31xx->regmap, false); | 1117 | regcache_cache_only(aic31xx->regmap, false); |
1118 | |||
1119 | /* Reset device registers for a consistent power-on like state */ | ||
1120 | ret = aic31xx_reset(aic31xx); | ||
1121 | if (ret < 0) | ||
1122 | dev_err(aic31xx->dev, "Could not reset device: %d\n", ret); | ||
1123 | |||
1080 | ret = regcache_sync(aic31xx->regmap); | 1124 | ret = regcache_sync(aic31xx->regmap); |
1081 | if (ret != 0) { | 1125 | if (ret) { |
1082 | dev_err(codec->dev, | 1126 | dev_err(codec->dev, |
1083 | "Failed to restore cache: %d\n", ret); | 1127 | "Failed to restore cache: %d\n", ret); |
1084 | regcache_cache_only(aic31xx->regmap, true); | 1128 | regcache_cache_only(aic31xx->regmap, true); |
@@ -1086,19 +1130,17 @@ static int aic31xx_power_on(struct snd_soc_codec *codec) | |||
1086 | aic31xx->supplies); | 1130 | aic31xx->supplies); |
1087 | return ret; | 1131 | return ret; |
1088 | } | 1132 | } |
1133 | |||
1089 | return 0; | 1134 | return 0; |
1090 | } | 1135 | } |
1091 | 1136 | ||
1092 | static int aic31xx_power_off(struct snd_soc_codec *codec) | 1137 | static void aic31xx_power_off(struct snd_soc_codec *codec) |
1093 | { | 1138 | { |
1094 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 1139 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
1095 | int ret = 0; | ||
1096 | 1140 | ||
1097 | regcache_cache_only(aic31xx->regmap, true); | 1141 | regcache_cache_only(aic31xx->regmap, true); |
1098 | ret = regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), | 1142 | regulator_bulk_disable(ARRAY_SIZE(aic31xx->supplies), |
1099 | aic31xx->supplies); | 1143 | aic31xx->supplies); |
1100 | |||
1101 | return ret; | ||
1102 | } | 1144 | } |
1103 | 1145 | ||
1104 | static int aic31xx_set_bias_level(struct snd_soc_codec *codec, | 1146 | static int aic31xx_set_bias_level(struct snd_soc_codec *codec, |
@@ -1137,14 +1179,11 @@ static int aic31xx_set_bias_level(struct snd_soc_codec *codec, | |||
1137 | 1179 | ||
1138 | static int aic31xx_codec_probe(struct snd_soc_codec *codec) | 1180 | static int aic31xx_codec_probe(struct snd_soc_codec *codec) |
1139 | { | 1181 | { |
1140 | int ret = 0; | ||
1141 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); | 1182 | struct aic31xx_priv *aic31xx = snd_soc_codec_get_drvdata(codec); |
1142 | int i; | 1183 | int i, ret; |
1143 | 1184 | ||
1144 | dev_dbg(aic31xx->dev, "## %s\n", __func__); | 1185 | dev_dbg(aic31xx->dev, "## %s\n", __func__); |
1145 | 1186 | ||
1146 | aic31xx = snd_soc_codec_get_drvdata(codec); | ||
1147 | |||
1148 | aic31xx->codec = codec; | 1187 | aic31xx->codec = codec; |
1149 | 1188 | ||
1150 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { | 1189 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) { |
@@ -1169,8 +1208,10 @@ static int aic31xx_codec_probe(struct snd_soc_codec *codec) | |||
1169 | return ret; | 1208 | return ret; |
1170 | 1209 | ||
1171 | ret = aic31xx_add_widgets(codec); | 1210 | ret = aic31xx_add_widgets(codec); |
1211 | if (ret) | ||
1212 | return ret; | ||
1172 | 1213 | ||
1173 | return ret; | 1214 | return 0; |
1174 | } | 1215 | } |
1175 | 1216 | ||
1176 | static int aic31xx_codec_remove(struct snd_soc_codec *codec) | 1217 | static int aic31xx_codec_remove(struct snd_soc_codec *codec) |
@@ -1258,89 +1299,31 @@ static const struct of_device_id tlv320aic31xx_of_match[] = { | |||
1258 | {}, | 1299 | {}, |
1259 | }; | 1300 | }; |
1260 | MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match); | 1301 | MODULE_DEVICE_TABLE(of, tlv320aic31xx_of_match); |
1261 | |||
1262 | static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) | ||
1263 | { | ||
1264 | struct device_node *np = aic31xx->dev->of_node; | ||
1265 | unsigned int value = MICBIAS_2_0V; | ||
1266 | int ret; | ||
1267 | |||
1268 | of_property_read_u32(np, "ai31xx-micbias-vg", &value); | ||
1269 | switch (value) { | ||
1270 | case MICBIAS_2_0V: | ||
1271 | case MICBIAS_2_5V: | ||
1272 | case MICBIAS_AVDDV: | ||
1273 | aic31xx->pdata.micbias_vg = value; | ||
1274 | break; | ||
1275 | default: | ||
1276 | dev_err(aic31xx->dev, | ||
1277 | "Bad ai31xx-micbias-vg value %d DT\n", | ||
1278 | value); | ||
1279 | aic31xx->pdata.micbias_vg = MICBIAS_2_0V; | ||
1280 | } | ||
1281 | |||
1282 | ret = of_get_named_gpio(np, "gpio-reset", 0); | ||
1283 | if (ret > 0) | ||
1284 | aic31xx->pdata.gpio_reset = ret; | ||
1285 | } | ||
1286 | #else /* CONFIG_OF */ | ||
1287 | static void aic31xx_pdata_from_of(struct aic31xx_priv *aic31xx) | ||
1288 | { | ||
1289 | } | ||
1290 | #endif /* CONFIG_OF */ | 1302 | #endif /* CONFIG_OF */ |
1291 | 1303 | ||
1292 | static int aic31xx_device_init(struct aic31xx_priv *aic31xx) | 1304 | #ifdef CONFIG_ACPI |
1293 | { | 1305 | static const struct acpi_device_id aic31xx_acpi_match[] = { |
1294 | int ret, i; | 1306 | { "10TI3100", 0 }, |
1295 | 1307 | { } | |
1296 | dev_set_drvdata(aic31xx->dev, aic31xx); | 1308 | }; |
1297 | 1309 | MODULE_DEVICE_TABLE(acpi, aic31xx_acpi_match); | |
1298 | if (dev_get_platdata(aic31xx->dev)) | 1310 | #endif |
1299 | memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev), | ||
1300 | sizeof(aic31xx->pdata)); | ||
1301 | else if (aic31xx->dev->of_node) | ||
1302 | aic31xx_pdata_from_of(aic31xx); | ||
1303 | |||
1304 | if (aic31xx->pdata.gpio_reset) { | ||
1305 | ret = devm_gpio_request_one(aic31xx->dev, | ||
1306 | aic31xx->pdata.gpio_reset, | ||
1307 | GPIOF_OUT_INIT_HIGH, | ||
1308 | "aic31xx-reset-pin"); | ||
1309 | if (ret < 0) { | ||
1310 | dev_err(aic31xx->dev, "not able to acquire gpio\n"); | ||
1311 | return ret; | ||
1312 | } | ||
1313 | } | ||
1314 | |||
1315 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) | ||
1316 | aic31xx->supplies[i].supply = aic31xx_supply_names[i]; | ||
1317 | |||
1318 | ret = devm_regulator_bulk_get(aic31xx->dev, | ||
1319 | ARRAY_SIZE(aic31xx->supplies), | ||
1320 | aic31xx->supplies); | ||
1321 | if (ret != 0) | ||
1322 | dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); | ||
1323 | |||
1324 | return ret; | ||
1325 | } | ||
1326 | 1311 | ||
1327 | static int aic31xx_i2c_probe(struct i2c_client *i2c, | 1312 | static int aic31xx_i2c_probe(struct i2c_client *i2c, |
1328 | const struct i2c_device_id *id) | 1313 | const struct i2c_device_id *id) |
1329 | { | 1314 | { |
1330 | struct aic31xx_priv *aic31xx; | 1315 | struct aic31xx_priv *aic31xx; |
1331 | int ret; | 1316 | unsigned int micbias_value = MICBIAS_2_0V; |
1332 | const struct regmap_config *regmap_config; | 1317 | int i, ret; |
1333 | 1318 | ||
1334 | dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__, | 1319 | dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__, |
1335 | id->name, (int) id->driver_data); | 1320 | id->name, (int)id->driver_data); |
1336 | |||
1337 | regmap_config = &aic31xx_i2c_regmap; | ||
1338 | 1321 | ||
1339 | aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL); | 1322 | aic31xx = devm_kzalloc(&i2c->dev, sizeof(*aic31xx), GFP_KERNEL); |
1340 | if (aic31xx == NULL) | 1323 | if (!aic31xx) |
1341 | return -ENOMEM; | 1324 | return -ENOMEM; |
1342 | 1325 | ||
1343 | aic31xx->regmap = devm_regmap_init_i2c(i2c, regmap_config); | 1326 | aic31xx->regmap = devm_regmap_init_i2c(i2c, &aic31xx_i2c_regmap); |
1344 | if (IS_ERR(aic31xx->regmap)) { | 1327 | if (IS_ERR(aic31xx->regmap)) { |
1345 | ret = PTR_ERR(aic31xx->regmap); | 1328 | ret = PTR_ERR(aic31xx->regmap); |
1346 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | 1329 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", |
@@ -1349,13 +1332,49 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c, | |||
1349 | } | 1332 | } |
1350 | aic31xx->dev = &i2c->dev; | 1333 | aic31xx->dev = &i2c->dev; |
1351 | 1334 | ||
1352 | aic31xx->pdata.codec_type = id->driver_data; | 1335 | aic31xx->codec_type = id->driver_data; |
1353 | 1336 | ||
1354 | ret = aic31xx_device_init(aic31xx); | 1337 | dev_set_drvdata(aic31xx->dev, aic31xx); |
1355 | if (ret) | 1338 | |
1339 | fwnode_property_read_u32(aic31xx->dev->fwnode, "ai31xx-micbias-vg", | ||
1340 | &micbias_value); | ||
1341 | switch (micbias_value) { | ||
1342 | case MICBIAS_2_0V: | ||
1343 | case MICBIAS_2_5V: | ||
1344 | case MICBIAS_AVDDV: | ||
1345 | aic31xx->micbias_vg = micbias_value; | ||
1346 | break; | ||
1347 | default: | ||
1348 | dev_err(aic31xx->dev, "Bad ai31xx-micbias-vg value %d\n", | ||
1349 | micbias_value); | ||
1350 | aic31xx->micbias_vg = MICBIAS_2_0V; | ||
1351 | } | ||
1352 | |||
1353 | if (dev_get_platdata(aic31xx->dev)) { | ||
1354 | memcpy(&aic31xx->pdata, dev_get_platdata(aic31xx->dev), sizeof(aic31xx->pdata)); | ||
1355 | aic31xx->codec_type = aic31xx->pdata.codec_type; | ||
1356 | aic31xx->micbias_vg = aic31xx->pdata.micbias_vg; | ||
1357 | } | ||
1358 | |||
1359 | aic31xx->gpio_reset = devm_gpiod_get_optional(aic31xx->dev, "reset", | ||
1360 | GPIOD_OUT_LOW); | ||
1361 | if (IS_ERR(aic31xx->gpio_reset)) { | ||
1362 | dev_err(aic31xx->dev, "not able to acquire gpio\n"); | ||
1363 | return PTR_ERR(aic31xx->gpio_reset); | ||
1364 | } | ||
1365 | |||
1366 | for (i = 0; i < ARRAY_SIZE(aic31xx->supplies); i++) | ||
1367 | aic31xx->supplies[i].supply = aic31xx_supply_names[i]; | ||
1368 | |||
1369 | ret = devm_regulator_bulk_get(aic31xx->dev, | ||
1370 | ARRAY_SIZE(aic31xx->supplies), | ||
1371 | aic31xx->supplies); | ||
1372 | if (ret) { | ||
1373 | dev_err(aic31xx->dev, "Failed to request supplies: %d\n", ret); | ||
1356 | return ret; | 1374 | return ret; |
1375 | } | ||
1357 | 1376 | ||
1358 | if (aic31xx->pdata.codec_type & DAC31XX_BIT) | 1377 | if (aic31xx->codec_type & DAC31XX_BIT) |
1359 | return snd_soc_register_codec(&i2c->dev, | 1378 | return snd_soc_register_codec(&i2c->dev, |
1360 | &soc_codec_driver_aic31xx, | 1379 | &soc_codec_driver_aic31xx, |
1361 | dac31xx_dai_driver, | 1380 | dac31xx_dai_driver, |
@@ -1386,14 +1405,6 @@ static const struct i2c_device_id aic31xx_i2c_id[] = { | |||
1386 | }; | 1405 | }; |
1387 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); | 1406 | MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id); |
1388 | 1407 | ||
1389 | #ifdef CONFIG_ACPI | ||
1390 | static const struct acpi_device_id aic31xx_acpi_match[] = { | ||
1391 | { "10TI3100", 0 }, | ||
1392 | { } | ||
1393 | }; | ||
1394 | MODULE_DEVICE_TABLE(acpi, aic31xx_acpi_match); | ||
1395 | #endif | ||
1396 | |||
1397 | static struct i2c_driver aic31xx_i2c_driver = { | 1408 | static struct i2c_driver aic31xx_i2c_driver = { |
1398 | .driver = { | 1409 | .driver = { |
1399 | .name = "tlv320aic31xx-codec", | 1410 | .name = "tlv320aic31xx-codec", |
@@ -1404,9 +1415,8 @@ static struct i2c_driver aic31xx_i2c_driver = { | |||
1404 | .remove = aic31xx_i2c_remove, | 1415 | .remove = aic31xx_i2c_remove, |
1405 | .id_table = aic31xx_i2c_id, | 1416 | .id_table = aic31xx_i2c_id, |
1406 | }; | 1417 | }; |
1407 | |||
1408 | module_i2c_driver(aic31xx_i2c_driver); | 1418 | module_i2c_driver(aic31xx_i2c_driver); |
1409 | 1419 | ||
1410 | MODULE_DESCRIPTION("ASoC TLV320AIC3111 codec driver"); | 1420 | MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>"); |
1411 | MODULE_AUTHOR("Jyri Sarha"); | 1421 | MODULE_DESCRIPTION("ASoC TLV320AIC31xx CODEC Driver"); |
1412 | MODULE_LICENSE("GPL"); | 1422 | MODULE_LICENSE("GPL v2"); |
diff --git a/sound/soc/codecs/tlv320aic31xx.h b/sound/soc/codecs/tlv320aic31xx.h index 1ff3edb7bbb6..15ac7cba86fe 100644 --- a/sound/soc/codecs/tlv320aic31xx.h +++ b/sound/soc/codecs/tlv320aic31xx.h | |||
@@ -1,36 +1,30 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * ALSA SoC TLV320AIC31XX codec driver | 3 | * ALSA SoC TLV320AIC31xx CODEC Driver Definitions |
3 | * | ||
4 | * Copyright (C) 2013 Texas Instruments, Inc. | ||
5 | * | ||
6 | * This package is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR | ||
11 | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED | ||
12 | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | * | 4 | * |
5 | * Copyright (C) 2014-2017 Texas Instruments Incorporated - http://www.ti.com/ | ||
14 | */ | 6 | */ |
7 | |||
15 | #ifndef _TLV320AIC31XX_H | 8 | #ifndef _TLV320AIC31XX_H |
16 | #define _TLV320AIC31XX_H | 9 | #define _TLV320AIC31XX_H |
17 | 10 | ||
18 | #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 | 11 | #define AIC31XX_RATES SNDRV_PCM_RATE_8000_192000 |
19 | 12 | ||
20 | #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ | 13 | #define AIC31XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
21 | | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE \ | 14 | SNDRV_PCM_FMTBIT_S20_3LE | \ |
22 | | SNDRV_PCM_FMTBIT_S32_LE) | 15 | SNDRV_PCM_FMTBIT_S24_3LE | \ |
23 | 16 | SNDRV_PCM_FMTBIT_S24_LE | \ | |
17 | SNDRV_PCM_FMTBIT_S32_LE) | ||
24 | 18 | ||
25 | #define AIC31XX_STEREO_CLASS_D_BIT 0x1 | 19 | #define AIC31XX_STEREO_CLASS_D_BIT BIT(1) |
26 | #define AIC31XX_MINIDSP_BIT 0x2 | 20 | #define AIC31XX_MINIDSP_BIT BIT(2) |
27 | #define DAC31XX_BIT 0x4 | 21 | #define DAC31XX_BIT BIT(3) |
28 | 22 | ||
29 | enum aic31xx_type { | 23 | enum aic31xx_type { |
30 | AIC3100 = 0, | 24 | AIC3100 = 0, |
31 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, | 25 | AIC3110 = AIC31XX_STEREO_CLASS_D_BIT, |
32 | AIC3120 = AIC31XX_MINIDSP_BIT, | 26 | AIC3120 = AIC31XX_MINIDSP_BIT, |
33 | AIC3111 = (AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT), | 27 | AIC3111 = AIC31XX_STEREO_CLASS_D_BIT | AIC31XX_MINIDSP_BIT, |
34 | DAC3100 = DAC31XX_BIT, | 28 | DAC3100 = DAC31XX_BIT, |
35 | DAC3101 = DAC31XX_BIT | AIC31XX_STEREO_CLASS_D_BIT, | 29 | DAC3101 = DAC31XX_BIT | AIC31XX_STEREO_CLASS_D_BIT, |
36 | }; | 30 | }; |
@@ -43,222 +37,167 @@ struct aic31xx_pdata { | |||
43 | 37 | ||
44 | #define AIC31XX_REG(page, reg) ((page * 128) + reg) | 38 | #define AIC31XX_REG(page, reg) ((page * 128) + reg) |
45 | 39 | ||
46 | /* Page Control Register */ | 40 | #define AIC31XX_PAGECTL AIC31XX_REG(0, 0) /* Page Control Register */ |
47 | #define AIC31XX_PAGECTL AIC31XX_REG(0, 0) | ||
48 | 41 | ||
49 | /* Page 0 Registers */ | 42 | /* Page 0 Registers */ |
50 | /* Software reset register */ | 43 | #define AIC31XX_RESET AIC31XX_REG(0, 1) /* Software reset register */ |
51 | #define AIC31XX_RESET AIC31XX_REG(0, 1) | 44 | #define AIC31XX_OT_FLAG AIC31XX_REG(0, 3) /* OT FLAG register */ |
52 | /* OT FLAG register */ | 45 | #define AIC31XX_CLKMUX AIC31XX_REG(0, 4) /* Clock clock Gen muxing, Multiplexers*/ |
53 | #define AIC31XX_OT_FLAG AIC31XX_REG(0, 3) | 46 | #define AIC31XX_PLLPR AIC31XX_REG(0, 5) /* PLL P and R-VAL register */ |
54 | /* Clock clock Gen muxing, Multiplexers*/ | 47 | #define AIC31XX_PLLJ AIC31XX_REG(0, 6) /* PLL J-VAL register */ |
55 | #define AIC31XX_CLKMUX AIC31XX_REG(0, 4) | 48 | #define AIC31XX_PLLDMSB AIC31XX_REG(0, 7) /* PLL D-VAL MSB register */ |
56 | /* PLL P and R-VAL register */ | 49 | #define AIC31XX_PLLDLSB AIC31XX_REG(0, 8) /* PLL D-VAL LSB register */ |
57 | #define AIC31XX_PLLPR AIC31XX_REG(0, 5) | 50 | #define AIC31XX_NDAC AIC31XX_REG(0, 11) /* DAC NDAC_VAL register*/ |
58 | /* PLL J-VAL register */ | 51 | #define AIC31XX_MDAC AIC31XX_REG(0, 12) /* DAC MDAC_VAL register */ |
59 | #define AIC31XX_PLLJ AIC31XX_REG(0, 6) | 52 | #define AIC31XX_DOSRMSB AIC31XX_REG(0, 13) /* DAC OSR setting register 1, MSB value */ |
60 | /* PLL D-VAL MSB register */ | 53 | #define AIC31XX_DOSRLSB AIC31XX_REG(0, 14) /* DAC OSR setting register 2, LSB value */ |
61 | #define AIC31XX_PLLDMSB AIC31XX_REG(0, 7) | ||
62 | /* PLL D-VAL LSB register */ | ||
63 | #define AIC31XX_PLLDLSB AIC31XX_REG(0, 8) | ||
64 | /* DAC NDAC_VAL register*/ | ||
65 | #define AIC31XX_NDAC AIC31XX_REG(0, 11) | ||
66 | /* DAC MDAC_VAL register */ | ||
67 | #define AIC31XX_MDAC AIC31XX_REG(0, 12) | ||
68 | /* DAC OSR setting register 1, MSB value */ | ||
69 | #define AIC31XX_DOSRMSB AIC31XX_REG(0, 13) | ||
70 | /* DAC OSR setting register 2, LSB value */ | ||
71 | #define AIC31XX_DOSRLSB AIC31XX_REG(0, 14) | ||
72 | #define AIC31XX_MINI_DSP_INPOL AIC31XX_REG(0, 16) | 54 | #define AIC31XX_MINI_DSP_INPOL AIC31XX_REG(0, 16) |
73 | /* Clock setting register 8, PLL */ | 55 | #define AIC31XX_NADC AIC31XX_REG(0, 18) /* Clock setting register 8, PLL */ |
74 | #define AIC31XX_NADC AIC31XX_REG(0, 18) | 56 | #define AIC31XX_MADC AIC31XX_REG(0, 19) /* Clock setting register 9, PLL */ |
75 | /* Clock setting register 9, PLL */ | 57 | #define AIC31XX_AOSR AIC31XX_REG(0, 20) /* ADC Oversampling (AOSR) Register */ |
76 | #define AIC31XX_MADC AIC31XX_REG(0, 19) | 58 | #define AIC31XX_CLKOUTMUX AIC31XX_REG(0, 25) /* Clock setting register 9, Multiplexers */ |
77 | /* ADC Oversampling (AOSR) Register */ | 59 | #define AIC31XX_CLKOUTMVAL AIC31XX_REG(0, 26) /* Clock setting register 10, CLOCKOUT M divider value */ |
78 | #define AIC31XX_AOSR AIC31XX_REG(0, 20) | 60 | #define AIC31XX_IFACE1 AIC31XX_REG(0, 27) /* Audio Interface Setting Register 1 */ |
79 | /* Clock setting register 9, Multiplexers */ | 61 | #define AIC31XX_DATA_OFFSET AIC31XX_REG(0, 28) /* Audio Data Slot Offset Programming */ |
80 | #define AIC31XX_CLKOUTMUX AIC31XX_REG(0, 25) | 62 | #define AIC31XX_IFACE2 AIC31XX_REG(0, 29) /* Audio Interface Setting Register 2 */ |
81 | /* Clock setting register 10, CLOCKOUT M divider value */ | 63 | #define AIC31XX_BCLKN AIC31XX_REG(0, 30) /* Clock setting register 11, BCLK N Divider */ |
82 | #define AIC31XX_CLKOUTMVAL AIC31XX_REG(0, 26) | 64 | #define AIC31XX_IFACESEC1 AIC31XX_REG(0, 31) /* Audio Interface Setting Register 3, Secondary Audio Interface */ |
83 | /* Audio Interface Setting Register 1 */ | 65 | #define AIC31XX_IFACESEC2 AIC31XX_REG(0, 32) /* Audio Interface Setting Register 4 */ |
84 | #define AIC31XX_IFACE1 AIC31XX_REG(0, 27) | 66 | #define AIC31XX_IFACESEC3 AIC31XX_REG(0, 33) /* Audio Interface Setting Register 5 */ |
85 | /* Audio Data Slot Offset Programming */ | 67 | #define AIC31XX_I2C AIC31XX_REG(0, 34) /* I2C Bus Condition */ |
86 | #define AIC31XX_DATA_OFFSET AIC31XX_REG(0, 28) | 68 | #define AIC31XX_ADCFLAG AIC31XX_REG(0, 36) /* ADC FLAG */ |
87 | /* Audio Interface Setting Register 2 */ | 69 | #define AIC31XX_DACFLAG1 AIC31XX_REG(0, 37) /* DAC Flag Registers */ |
88 | #define AIC31XX_IFACE2 AIC31XX_REG(0, 29) | ||
89 | /* Clock setting register 11, BCLK N Divider */ | ||
90 | #define AIC31XX_BCLKN AIC31XX_REG(0, 30) | ||
91 | /* Audio Interface Setting Register 3, Secondary Audio Interface */ | ||
92 | #define AIC31XX_IFACESEC1 AIC31XX_REG(0, 31) | ||
93 | /* Audio Interface Setting Register 4 */ | ||
94 | #define AIC31XX_IFACESEC2 AIC31XX_REG(0, 32) | ||
95 | /* Audio Interface Setting Register 5 */ | ||
96 | #define AIC31XX_IFACESEC3 AIC31XX_REG(0, 33) | ||
97 | /* I2C Bus Condition */ | ||
98 | #define AIC31XX_I2C AIC31XX_REG(0, 34) | ||
99 | /* ADC FLAG */ | ||
100 | #define AIC31XX_ADCFLAG AIC31XX_REG(0, 36) | ||
101 | /* DAC Flag Registers */ | ||
102 | #define AIC31XX_DACFLAG1 AIC31XX_REG(0, 37) | ||
103 | #define AIC31XX_DACFLAG2 AIC31XX_REG(0, 38) | 70 | #define AIC31XX_DACFLAG2 AIC31XX_REG(0, 38) |
104 | /* Sticky Interrupt flag (overflow) */ | 71 | #define AIC31XX_OFFLAG AIC31XX_REG(0, 39) /* Sticky Interrupt flag (overflow) */ |
105 | #define AIC31XX_OFFLAG AIC31XX_REG(0, 39) | 72 | #define AIC31XX_INTRDACFLAG AIC31XX_REG(0, 44) /* Sticy DAC Interrupt flags */ |
106 | /* Sticy DAC Interrupt flags */ | 73 | #define AIC31XX_INTRADCFLAG AIC31XX_REG(0, 45) /* Sticy ADC Interrupt flags */ |
107 | #define AIC31XX_INTRDACFLAG AIC31XX_REG(0, 44) | 74 | #define AIC31XX_INTRDACFLAG2 AIC31XX_REG(0, 46) /* DAC Interrupt flags 2 */ |
108 | /* Sticy ADC Interrupt flags */ | 75 | #define AIC31XX_INTRADCFLAG2 AIC31XX_REG(0, 47) /* ADC Interrupt flags 2 */ |
109 | #define AIC31XX_INTRADCFLAG AIC31XX_REG(0, 45) | 76 | #define AIC31XX_INT1CTRL AIC31XX_REG(0, 48) /* INT1 interrupt control */ |
110 | /* DAC Interrupt flags 2 */ | 77 | #define AIC31XX_INT2CTRL AIC31XX_REG(0, 49) /* INT2 interrupt control */ |
111 | #define AIC31XX_INTRDACFLAG2 AIC31XX_REG(0, 46) | 78 | #define AIC31XX_GPIO1 AIC31XX_REG(0, 51) /* GPIO1 control */ |
112 | /* ADC Interrupt flags 2 */ | ||
113 | #define AIC31XX_INTRADCFLAG2 AIC31XX_REG(0, 47) | ||
114 | /* INT1 interrupt control */ | ||
115 | #define AIC31XX_INT1CTRL AIC31XX_REG(0, 48) | ||
116 | /* INT2 interrupt control */ | ||
117 | #define AIC31XX_INT2CTRL AIC31XX_REG(0, 49) | ||
118 | /* GPIO1 control */ | ||
119 | #define AIC31XX_GPIO1 AIC31XX_REG(0, 51) | ||
120 | |||
121 | #define AIC31XX_DACPRB AIC31XX_REG(0, 60) | 79 | #define AIC31XX_DACPRB AIC31XX_REG(0, 60) |
122 | /* ADC Instruction Set Register */ | 80 | #define AIC31XX_ADCPRB AIC31XX_REG(0, 61) /* ADC Instruction Set Register */ |
123 | #define AIC31XX_ADCPRB AIC31XX_REG(0, 61) | 81 | #define AIC31XX_DACSETUP AIC31XX_REG(0, 63) /* DAC channel setup register */ |
124 | /* DAC channel setup register */ | 82 | #define AIC31XX_DACMUTE AIC31XX_REG(0, 64) /* DAC Mute and volume control register */ |
125 | #define AIC31XX_DACSETUP AIC31XX_REG(0, 63) | 83 | #define AIC31XX_LDACVOL AIC31XX_REG(0, 65) /* Left DAC channel digital volume control */ |
126 | /* DAC Mute and volume control register */ | 84 | #define AIC31XX_RDACVOL AIC31XX_REG(0, 66) /* Right DAC channel digital volume control */ |
127 | #define AIC31XX_DACMUTE AIC31XX_REG(0, 64) | 85 | #define AIC31XX_HSDETECT AIC31XX_REG(0, 67) /* Headset detection */ |
128 | /* Left DAC channel digital volume control */ | 86 | #define AIC31XX_ADCSETUP AIC31XX_REG(0, 81) /* ADC Digital Mic */ |
129 | #define AIC31XX_LDACVOL AIC31XX_REG(0, 65) | 87 | #define AIC31XX_ADCFGA AIC31XX_REG(0, 82) /* ADC Digital Volume Control Fine Adjust */ |
130 | /* Right DAC channel digital volume control */ | 88 | #define AIC31XX_ADCVOL AIC31XX_REG(0, 83) /* ADC Digital Volume Control Coarse Adjust */ |
131 | #define AIC31XX_RDACVOL AIC31XX_REG(0, 66) | ||
132 | /* Headset detection */ | ||
133 | #define AIC31XX_HSDETECT AIC31XX_REG(0, 67) | ||
134 | /* ADC Digital Mic */ | ||
135 | #define AIC31XX_ADCSETUP AIC31XX_REG(0, 81) | ||
136 | /* ADC Digital Volume Control Fine Adjust */ | ||
137 | #define AIC31XX_ADCFGA AIC31XX_REG(0, 82) | ||
138 | /* ADC Digital Volume Control Coarse Adjust */ | ||
139 | #define AIC31XX_ADCVOL AIC31XX_REG(0, 83) | ||
140 | |||
141 | 89 | ||
142 | /* Page 1 Registers */ | 90 | /* Page 1 Registers */ |
143 | /* Headphone drivers */ | 91 | #define AIC31XX_HPDRIVER AIC31XX_REG(1, 31) /* Headphone drivers */ |
144 | #define AIC31XX_HPDRIVER AIC31XX_REG(1, 31) | 92 | #define AIC31XX_SPKAMP AIC31XX_REG(1, 32) /* Class-D Speakear Amplifier */ |
145 | /* Class-D Speakear Amplifier */ | 93 | #define AIC31XX_HPPOP AIC31XX_REG(1, 33) /* HP Output Drivers POP Removal Settings */ |
146 | #define AIC31XX_SPKAMP AIC31XX_REG(1, 32) | 94 | #define AIC31XX_SPPGARAMP AIC31XX_REG(1, 34) /* Output Driver PGA Ramp-Down Period Control */ |
147 | /* HP Output Drivers POP Removal Settings */ | 95 | #define AIC31XX_DACMIXERROUTE AIC31XX_REG(1, 35) /* DAC_L and DAC_R Output Mixer Routing */ |
148 | #define AIC31XX_HPPOP AIC31XX_REG(1, 33) | 96 | #define AIC31XX_LANALOGHPL AIC31XX_REG(1, 36) /* Left Analog Vol to HPL */ |
149 | /* Output Driver PGA Ramp-Down Period Control */ | 97 | #define AIC31XX_RANALOGHPR AIC31XX_REG(1, 37) /* Right Analog Vol to HPR */ |
150 | #define AIC31XX_SPPGARAMP AIC31XX_REG(1, 34) | 98 | #define AIC31XX_LANALOGSPL AIC31XX_REG(1, 38) /* Left Analog Vol to SPL */ |
151 | /* DAC_L and DAC_R Output Mixer Routing */ | 99 | #define AIC31XX_RANALOGSPR AIC31XX_REG(1, 39) /* Right Analog Vol to SPR */ |
152 | #define AIC31XX_DACMIXERROUTE AIC31XX_REG(1, 35) | 100 | #define AIC31XX_HPLGAIN AIC31XX_REG(1, 40) /* HPL Driver */ |
153 | /* Left Analog Vol to HPL */ | 101 | #define AIC31XX_HPRGAIN AIC31XX_REG(1, 41) /* HPR Driver */ |
154 | #define AIC31XX_LANALOGHPL AIC31XX_REG(1, 36) | 102 | #define AIC31XX_SPLGAIN AIC31XX_REG(1, 42) /* SPL Driver */ |
155 | /* Right Analog Vol to HPR */ | 103 | #define AIC31XX_SPRGAIN AIC31XX_REG(1, 43) /* SPR Driver */ |
156 | #define AIC31XX_RANALOGHPR AIC31XX_REG(1, 37) | 104 | #define AIC31XX_HPCONTROL AIC31XX_REG(1, 44) /* HP Driver Control */ |
157 | /* Left Analog Vol to SPL */ | 105 | #define AIC31XX_MICBIAS AIC31XX_REG(1, 46) /* MIC Bias Control */ |
158 | #define AIC31XX_LANALOGSPL AIC31XX_REG(1, 38) | 106 | #define AIC31XX_MICPGA AIC31XX_REG(1, 47) /* MIC PGA*/ |
159 | /* Right Analog Vol to SPR */ | 107 | #define AIC31XX_MICPGAPI AIC31XX_REG(1, 48) /* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */ |
160 | #define AIC31XX_RANALOGSPR AIC31XX_REG(1, 39) | 108 | #define AIC31XX_MICPGAMI AIC31XX_REG(1, 49) /* ADC Input Selection for M-Terminal */ |
161 | /* HPL Driver */ | 109 | #define AIC31XX_MICPGACM AIC31XX_REG(1, 50) /* Input CM Settings */ |
162 | #define AIC31XX_HPLGAIN AIC31XX_REG(1, 40) | 110 | |
163 | /* HPR Driver */ | 111 | /* Bits, masks, and shifts */ |
164 | #define AIC31XX_HPRGAIN AIC31XX_REG(1, 41) | ||
165 | /* SPL Driver */ | ||
166 | #define AIC31XX_SPLGAIN AIC31XX_REG(1, 42) | ||
167 | /* SPR Driver */ | ||
168 | #define AIC31XX_SPRGAIN AIC31XX_REG(1, 43) | ||
169 | /* HP Driver Control */ | ||
170 | #define AIC31XX_HPCONTROL AIC31XX_REG(1, 44) | ||
171 | /* MIC Bias Control */ | ||
172 | #define AIC31XX_MICBIAS AIC31XX_REG(1, 46) | ||
173 | /* MIC PGA*/ | ||
174 | #define AIC31XX_MICPGA AIC31XX_REG(1, 47) | ||
175 | /* Delta-Sigma Mono ADC Channel Fine-Gain Input Selection for P-Terminal */ | ||
176 | #define AIC31XX_MICPGAPI AIC31XX_REG(1, 48) | ||
177 | /* ADC Input Selection for M-Terminal */ | ||
178 | #define AIC31XX_MICPGAMI AIC31XX_REG(1, 49) | ||
179 | /* Input CM Settings */ | ||
180 | #define AIC31XX_MICPGACM AIC31XX_REG(1, 50) | ||
181 | |||
182 | /* Bits, masks and shifts */ | ||
183 | 112 | ||
184 | /* AIC31XX_CLKMUX */ | 113 | /* AIC31XX_CLKMUX */ |
185 | #define AIC31XX_PLL_CLKIN_MASK 0x0c | 114 | #define AIC31XX_PLL_CLKIN_MASK GENMASK(3, 2) |
186 | #define AIC31XX_PLL_CLKIN_SHIFT 2 | 115 | #define AIC31XX_PLL_CLKIN_SHIFT (2) |
187 | #define AIC31XX_PLL_CLKIN_MCLK 0 | 116 | #define AIC31XX_PLL_CLKIN_MCLK 0x00 |
188 | #define AIC31XX_CODEC_CLKIN_MASK 0x03 | 117 | #define AIC31XX_PLL_CLKIN_BCKL 0x01 |
189 | #define AIC31XX_CODEC_CLKIN_SHIFT 0 | 118 | #define AIC31XX_PLL_CLKIN_GPIO1 0x02 |
190 | #define AIC31XX_CODEC_CLKIN_PLL 3 | 119 | #define AIC31XX_PLL_CLKIN_DIN 0x03 |
191 | #define AIC31XX_CODEC_CLKIN_BCLK 1 | 120 | #define AIC31XX_CODEC_CLKIN_MASK GENMASK(1, 0) |
192 | 121 | #define AIC31XX_CODEC_CLKIN_SHIFT (0) | |
193 | /* AIC31XX_PLLPR, AIC31XX_NDAC, AIC31XX_MDAC, AIC31XX_NADC, AIC31XX_MADC, | 122 | #define AIC31XX_CODEC_CLKIN_MCLK 0x00 |
194 | AIC31XX_BCLKN */ | 123 | #define AIC31XX_CODEC_CLKIN_BCLK 0x01 |
195 | #define AIC31XX_PLL_MASK 0x7f | 124 | #define AIC31XX_CODEC_CLKIN_GPIO1 0x02 |
196 | #define AIC31XX_PM_MASK 0x80 | 125 | #define AIC31XX_CODEC_CLKIN_PLL 0x03 |
126 | |||
127 | /* AIC31XX_PLLPR */ | ||
128 | /* AIC31XX_NDAC */ | ||
129 | /* AIC31XX_MDAC */ | ||
130 | /* AIC31XX_NADC */ | ||
131 | /* AIC31XX_MADC */ | ||
132 | /* AIC31XX_BCLKN */ | ||
133 | #define AIC31XX_PLL_MASK GENMASK(6, 0) | ||
134 | #define AIC31XX_PM_MASK BIT(7) | ||
197 | 135 | ||
198 | /* AIC31XX_IFACE1 */ | 136 | /* AIC31XX_IFACE1 */ |
199 | #define AIC31XX_WORD_LEN_16BITS 0x00 | 137 | #define AIC31XX_IFACE1_DATATYPE_MASK GENMASK(7, 6) |
200 | #define AIC31XX_WORD_LEN_20BITS 0x01 | ||
201 | #define AIC31XX_WORD_LEN_24BITS 0x02 | ||
202 | #define AIC31XX_WORD_LEN_32BITS 0x03 | ||
203 | #define AIC31XX_IFACE1_DATALEN_MASK 0x30 | ||
204 | #define AIC31XX_IFACE1_DATALEN_SHIFT (4) | ||
205 | #define AIC31XX_IFACE1_DATATYPE_MASK 0xC0 | ||
206 | #define AIC31XX_IFACE1_DATATYPE_SHIFT (6) | 138 | #define AIC31XX_IFACE1_DATATYPE_SHIFT (6) |
207 | #define AIC31XX_I2S_MODE 0x00 | 139 | #define AIC31XX_I2S_MODE 0x00 |
208 | #define AIC31XX_DSP_MODE 0x01 | 140 | #define AIC31XX_DSP_MODE 0x01 |
209 | #define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02 | 141 | #define AIC31XX_RIGHT_JUSTIFIED_MODE 0x02 |
210 | #define AIC31XX_LEFT_JUSTIFIED_MODE 0x03 | 142 | #define AIC31XX_LEFT_JUSTIFIED_MODE 0x03 |
211 | #define AIC31XX_IFACE1_MASTER_MASK 0x0C | 143 | #define AIC31XX_IFACE1_DATALEN_MASK GENMASK(5, 4) |
212 | #define AIC31XX_BCLK_MASTER 0x08 | 144 | #define AIC31XX_IFACE1_DATALEN_SHIFT (4) |
213 | #define AIC31XX_WCLK_MASTER 0x04 | 145 | #define AIC31XX_WORD_LEN_16BITS 0x00 |
146 | #define AIC31XX_WORD_LEN_20BITS 0x01 | ||
147 | #define AIC31XX_WORD_LEN_24BITS 0x02 | ||
148 | #define AIC31XX_WORD_LEN_32BITS 0x03 | ||
149 | #define AIC31XX_IFACE1_MASTER_MASK GENMASK(3, 2) | ||
150 | #define AIC31XX_BCLK_MASTER BIT(2) | ||
151 | #define AIC31XX_WCLK_MASTER BIT(3) | ||
214 | 152 | ||
215 | /* AIC31XX_DATA_OFFSET */ | 153 | /* AIC31XX_DATA_OFFSET */ |
216 | #define AIC31XX_DATA_OFFSET_MASK 0xFF | 154 | #define AIC31XX_DATA_OFFSET_MASK GENMASK(7, 0) |
217 | 155 | ||
218 | /* AIC31XX_IFACE2 */ | 156 | /* AIC31XX_IFACE2 */ |
219 | #define AIC31XX_BCLKINV_MASK 0x08 | 157 | #define AIC31XX_BCLKINV_MASK BIT(3) |
220 | #define AIC31XX_BDIVCLK_MASK 0x03 | 158 | #define AIC31XX_BDIVCLK_MASK GENMASK(1, 0) |
221 | #define AIC31XX_DAC2BCLK 0x00 | 159 | #define AIC31XX_DAC2BCLK 0x00 |
222 | #define AIC31XX_DACMOD2BCLK 0x01 | 160 | #define AIC31XX_DACMOD2BCLK 0x01 |
223 | #define AIC31XX_ADC2BCLK 0x02 | 161 | #define AIC31XX_ADC2BCLK 0x02 |
224 | #define AIC31XX_ADCMOD2BCLK 0x03 | 162 | #define AIC31XX_ADCMOD2BCLK 0x03 |
225 | 163 | ||
226 | /* AIC31XX_ADCFLAG */ | 164 | /* AIC31XX_ADCFLAG */ |
227 | #define AIC31XX_ADCPWRSTATUS_MASK 0x40 | 165 | #define AIC31XX_ADCPWRSTATUS_MASK BIT(6) |
228 | 166 | ||
229 | /* AIC31XX_DACFLAG1 */ | 167 | /* AIC31XX_DACFLAG1 */ |
230 | #define AIC31XX_LDACPWRSTATUS_MASK 0x80 | 168 | #define AIC31XX_LDACPWRSTATUS_MASK BIT(7) |
231 | #define AIC31XX_RDACPWRSTATUS_MASK 0x08 | 169 | #define AIC31XX_HPLDRVPWRSTATUS_MASK BIT(5) |
232 | #define AIC31XX_HPLDRVPWRSTATUS_MASK 0x20 | 170 | #define AIC31XX_SPLDRVPWRSTATUS_MASK BIT(4) |
233 | #define AIC31XX_HPRDRVPWRSTATUS_MASK 0x02 | 171 | #define AIC31XX_RDACPWRSTATUS_MASK BIT(3) |
234 | #define AIC31XX_SPLDRVPWRSTATUS_MASK 0x10 | 172 | #define AIC31XX_HPRDRVPWRSTATUS_MASK BIT(1) |
235 | #define AIC31XX_SPRDRVPWRSTATUS_MASK 0x01 | 173 | #define AIC31XX_SPRDRVPWRSTATUS_MASK BIT(0) |
236 | 174 | ||
237 | /* AIC31XX_INTRDACFLAG */ | 175 | /* AIC31XX_INTRDACFLAG */ |
238 | #define AIC31XX_HPSCDETECT_MASK 0x80 | 176 | #define AIC31XX_HPLSCDETECT BIT(7) |
239 | #define AIC31XX_BUTTONPRESS_MASK 0x20 | 177 | #define AIC31XX_HPRSCDETECT BIT(6) |
240 | #define AIC31XX_HSPLUG_MASK 0x10 | 178 | #define AIC31XX_BUTTONPRESS BIT(5) |
241 | #define AIC31XX_LDRCTHRES_MASK 0x08 | 179 | #define AIC31XX_HSPLUG BIT(4) |
242 | #define AIC31XX_RDRCTHRES_MASK 0x04 | 180 | #define AIC31XX_LDRCTHRES BIT(3) |
243 | #define AIC31XX_DACSINT_MASK 0x02 | 181 | #define AIC31XX_RDRCTHRES BIT(2) |
244 | #define AIC31XX_DACAINT_MASK 0x01 | 182 | #define AIC31XX_DACSINT BIT(1) |
183 | #define AIC31XX_DACAINT BIT(0) | ||
245 | 184 | ||
246 | /* AIC31XX_INT1CTRL */ | 185 | /* AIC31XX_INT1CTRL */ |
247 | #define AIC31XX_HSPLUGDET_MASK 0x80 | 186 | #define AIC31XX_HSPLUGDET BIT(7) |
248 | #define AIC31XX_BUTTONPRESSDET_MASK 0x40 | 187 | #define AIC31XX_BUTTONPRESSDET BIT(6) |
249 | #define AIC31XX_DRCTHRES_MASK 0x20 | 188 | #define AIC31XX_DRCTHRES BIT(5) |
250 | #define AIC31XX_AGCNOISE_MASK 0x10 | 189 | #define AIC31XX_AGCNOISE BIT(4) |
251 | #define AIC31XX_OC_MASK 0x08 | 190 | #define AIC31XX_SC BIT(3) |
252 | #define AIC31XX_ENGINE_MASK 0x04 | 191 | #define AIC31XX_ENGINE BIT(2) |
253 | 192 | ||
254 | /* AIC31XX_DACSETUP */ | 193 | /* AIC31XX_DACSETUP */ |
255 | #define AIC31XX_SOFTSTEP_MASK 0x03 | 194 | #define AIC31XX_SOFTSTEP_MASK GENMASK(1, 0) |
256 | 195 | ||
257 | /* AIC31XX_DACMUTE */ | 196 | /* AIC31XX_DACMUTE */ |
258 | #define AIC31XX_DACMUTE_MASK 0x0C | 197 | #define AIC31XX_DACMUTE_MASK GENMASK(3, 2) |
259 | 198 | ||
260 | /* AIC31XX_MICBIAS */ | 199 | /* AIC31XX_MICBIAS */ |
261 | #define AIC31XX_MICBIAS_MASK 0x03 | 200 | #define AIC31XX_MICBIAS_MASK GENMASK(1, 0) |
262 | #define AIC31XX_MICBIAS_SHIFT 0 | 201 | #define AIC31XX_MICBIAS_SHIFT 0 |
263 | 202 | ||
264 | #endif /* _TLV320AIC31XX_H */ | 203 | #endif /* _TLV320AIC31XX_H */ |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index e694f5f04eb9..fea019343c3b 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
@@ -281,34 +281,34 @@ static const struct snd_kcontrol_new aic32x4_snd_controls[] = { | |||
281 | 281 | ||
282 | static const struct aic32x4_rate_divs aic32x4_divs[] = { | 282 | static const struct aic32x4_rate_divs aic32x4_divs[] = { |
283 | /* 8k rate */ | 283 | /* 8k rate */ |
284 | {AIC32X4_FREQ_12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24}, | 284 | {12000000, 8000, 1, 7, 6800, 768, 5, 3, 128, 5, 18, 24}, |
285 | {AIC32X4_FREQ_24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24}, | 285 | {24000000, 8000, 2, 7, 6800, 768, 15, 1, 64, 45, 4, 24}, |
286 | {AIC32X4_FREQ_25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24}, | 286 | {25000000, 8000, 2, 7, 3728, 768, 15, 1, 64, 45, 4, 24}, |
287 | /* 11.025k rate */ | 287 | /* 11.025k rate */ |
288 | {AIC32X4_FREQ_12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16}, | 288 | {12000000, 11025, 1, 7, 5264, 512, 8, 2, 128, 8, 8, 16}, |
289 | {AIC32X4_FREQ_24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16}, | 289 | {24000000, 11025, 2, 7, 5264, 512, 16, 1, 64, 32, 4, 16}, |
290 | /* 16k rate */ | 290 | /* 16k rate */ |
291 | {AIC32X4_FREQ_12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12}, | 291 | {12000000, 16000, 1, 7, 6800, 384, 5, 3, 128, 5, 9, 12}, |
292 | {AIC32X4_FREQ_24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12}, | 292 | {24000000, 16000, 2, 7, 6800, 384, 15, 1, 64, 18, 5, 12}, |
293 | {AIC32X4_FREQ_25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12}, | 293 | {25000000, 16000, 2, 7, 3728, 384, 15, 1, 64, 18, 5, 12}, |
294 | /* 22.05k rate */ | 294 | /* 22.05k rate */ |
295 | {AIC32X4_FREQ_12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8}, | 295 | {12000000, 22050, 1, 7, 5264, 256, 4, 4, 128, 4, 8, 8}, |
296 | {AIC32X4_FREQ_24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8}, | 296 | {24000000, 22050, 2, 7, 5264, 256, 16, 1, 64, 16, 4, 8}, |
297 | {AIC32X4_FREQ_25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8}, | 297 | {25000000, 22050, 2, 7, 2253, 256, 16, 1, 64, 16, 4, 8}, |
298 | /* 32k rate */ | 298 | /* 32k rate */ |
299 | {AIC32X4_FREQ_12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6}, | 299 | {12000000, 32000, 1, 7, 1680, 192, 2, 7, 64, 2, 21, 6}, |
300 | {AIC32X4_FREQ_24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6}, | 300 | {24000000, 32000, 2, 7, 1680, 192, 7, 2, 64, 7, 6, 6}, |
301 | /* 44.1k rate */ | 301 | /* 44.1k rate */ |
302 | {AIC32X4_FREQ_12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4}, | 302 | {12000000, 44100, 1, 7, 5264, 128, 2, 8, 128, 2, 8, 4}, |
303 | {AIC32X4_FREQ_24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4}, | 303 | {24000000, 44100, 2, 7, 5264, 128, 8, 2, 64, 8, 4, 4}, |
304 | {AIC32X4_FREQ_25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4}, | 304 | {25000000, 44100, 2, 7, 2253, 128, 8, 2, 64, 8, 4, 4}, |
305 | /* 48k rate */ | 305 | /* 48k rate */ |
306 | {AIC32X4_FREQ_12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4}, | 306 | {12000000, 48000, 1, 8, 1920, 128, 2, 8, 128, 2, 8, 4}, |
307 | {AIC32X4_FREQ_24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4}, | 307 | {24000000, 48000, 2, 8, 1920, 128, 8, 2, 64, 8, 4, 4}, |
308 | {AIC32X4_FREQ_25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}, | 308 | {25000000, 48000, 2, 7, 8643, 128, 8, 2, 64, 8, 4, 4}, |
309 | 309 | ||
310 | /* 96k rate */ | 310 | /* 96k rate */ |
311 | {AIC32X4_FREQ_25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1}, | 311 | {25000000, 96000, 2, 7, 8643, 64, 4, 4, 64, 4, 4, 1}, |
312 | }; | 312 | }; |
313 | 313 | ||
314 | static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { | 314 | static const struct snd_kcontrol_new hpl_output_mixer_controls[] = { |
@@ -601,9 +601,9 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
601 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 601 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
602 | 602 | ||
603 | switch (freq) { | 603 | switch (freq) { |
604 | case AIC32X4_FREQ_12000000: | 604 | case 12000000: |
605 | case AIC32X4_FREQ_24000000: | 605 | case 24000000: |
606 | case AIC32X4_FREQ_25000000: | 606 | case 25000000: |
607 | aic32x4->sysclk = freq; | 607 | aic32x4->sysclk = freq; |
608 | return 0; | 608 | return 0; |
609 | } | 609 | } |
@@ -614,16 +614,9 @@ static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
614 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | 614 | static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
615 | { | 615 | { |
616 | struct snd_soc_codec *codec = codec_dai->codec; | 616 | struct snd_soc_codec *codec = codec_dai->codec; |
617 | u8 iface_reg_1; | 617 | u8 iface_reg_1 = 0; |
618 | u8 iface_reg_2; | 618 | u8 iface_reg_2 = 0; |
619 | u8 iface_reg_3; | 619 | u8 iface_reg_3 = 0; |
620 | |||
621 | iface_reg_1 = snd_soc_read(codec, AIC32X4_IFACE1); | ||
622 | iface_reg_1 = iface_reg_1 & ~(3 << 6 | 3 << 2); | ||
623 | iface_reg_2 = snd_soc_read(codec, AIC32X4_IFACE2); | ||
624 | iface_reg_2 = 0; | ||
625 | iface_reg_3 = snd_soc_read(codec, AIC32X4_IFACE3); | ||
626 | iface_reg_3 = iface_reg_3 & ~(1 << 3); | ||
627 | 620 | ||
628 | /* set master/slave audio interface */ | 621 | /* set master/slave audio interface */ |
629 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 622 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
@@ -641,30 +634,37 @@ static int aic32x4_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | |||
641 | case SND_SOC_DAIFMT_I2S: | 634 | case SND_SOC_DAIFMT_I2S: |
642 | break; | 635 | break; |
643 | case SND_SOC_DAIFMT_DSP_A: | 636 | case SND_SOC_DAIFMT_DSP_A: |
644 | iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT); | 637 | iface_reg_1 |= (AIC32X4_DSP_MODE << |
645 | iface_reg_3 |= (1 << 3); /* invert bit clock */ | 638 | AIC32X4_IFACE1_DATATYPE_SHIFT); |
639 | iface_reg_3 |= AIC32X4_BCLKINV_MASK; /* invert bit clock */ | ||
646 | iface_reg_2 = 0x01; /* add offset 1 */ | 640 | iface_reg_2 = 0x01; /* add offset 1 */ |
647 | break; | 641 | break; |
648 | case SND_SOC_DAIFMT_DSP_B: | 642 | case SND_SOC_DAIFMT_DSP_B: |
649 | iface_reg_1 |= (AIC32X4_DSP_MODE << AIC32X4_PLLJ_SHIFT); | 643 | iface_reg_1 |= (AIC32X4_DSP_MODE << |
650 | iface_reg_3 |= (1 << 3); /* invert bit clock */ | 644 | AIC32X4_IFACE1_DATATYPE_SHIFT); |
645 | iface_reg_3 |= AIC32X4_BCLKINV_MASK; /* invert bit clock */ | ||
651 | break; | 646 | break; |
652 | case SND_SOC_DAIFMT_RIGHT_J: | 647 | case SND_SOC_DAIFMT_RIGHT_J: |
653 | iface_reg_1 |= | 648 | iface_reg_1 |= (AIC32X4_RIGHT_JUSTIFIED_MODE << |
654 | (AIC32X4_RIGHT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT); | 649 | AIC32X4_IFACE1_DATATYPE_SHIFT); |
655 | break; | 650 | break; |
656 | case SND_SOC_DAIFMT_LEFT_J: | 651 | case SND_SOC_DAIFMT_LEFT_J: |
657 | iface_reg_1 |= | 652 | iface_reg_1 |= (AIC32X4_LEFT_JUSTIFIED_MODE << |
658 | (AIC32X4_LEFT_JUSTIFIED_MODE << AIC32X4_PLLJ_SHIFT); | 653 | AIC32X4_IFACE1_DATATYPE_SHIFT); |
659 | break; | 654 | break; |
660 | default: | 655 | default: |
661 | printk(KERN_ERR "aic32x4: invalid DAI interface format\n"); | 656 | printk(KERN_ERR "aic32x4: invalid DAI interface format\n"); |
662 | return -EINVAL; | 657 | return -EINVAL; |
663 | } | 658 | } |
664 | 659 | ||
665 | snd_soc_write(codec, AIC32X4_IFACE1, iface_reg_1); | 660 | snd_soc_update_bits(codec, AIC32X4_IFACE1, |
666 | snd_soc_write(codec, AIC32X4_IFACE2, iface_reg_2); | 661 | AIC32X4_IFACE1_DATATYPE_MASK | |
667 | snd_soc_write(codec, AIC32X4_IFACE3, iface_reg_3); | 662 | AIC32X4_IFACE1_MASTER_MASK, iface_reg_1); |
663 | snd_soc_update_bits(codec, AIC32X4_IFACE2, | ||
664 | AIC32X4_DATA_OFFSET_MASK, iface_reg_2); | ||
665 | snd_soc_update_bits(codec, AIC32X4_IFACE3, | ||
666 | AIC32X4_BCLKINV_MASK, iface_reg_3); | ||
667 | |||
668 | return 0; | 668 | return 0; |
669 | } | 669 | } |
670 | 670 | ||
@@ -674,7 +674,8 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, | |||
674 | { | 674 | { |
675 | struct snd_soc_codec *codec = dai->codec; | 675 | struct snd_soc_codec *codec = dai->codec; |
676 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 676 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
677 | u8 data; | 677 | u8 iface1_reg = 0; |
678 | u8 dacsetup_reg = 0; | ||
678 | int i; | 679 | int i; |
679 | 680 | ||
680 | i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params)); | 681 | i = aic32x4_get_divs(aic32x4->sysclk, params_rate(params)); |
@@ -683,82 +684,88 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, | |||
683 | return i; | 684 | return i; |
684 | } | 685 | } |
685 | 686 | ||
686 | /* Use PLL as CODEC_CLKIN and DAC_MOD_CLK as BDIV_CLKIN */ | 687 | /* MCLK as PLL_CLKIN */ |
687 | snd_soc_write(codec, AIC32X4_CLKMUX, AIC32X4_PLLCLKIN); | 688 | snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_PLL_CLKIN_MASK, |
688 | snd_soc_write(codec, AIC32X4_IFACE3, AIC32X4_DACMOD2BCLK); | 689 | AIC32X4_PLL_CLKIN_MCLK << AIC32X4_PLL_CLKIN_SHIFT); |
690 | /* PLL as CODEC_CLKIN */ | ||
691 | snd_soc_update_bits(codec, AIC32X4_CLKMUX, AIC32X4_CODEC_CLKIN_MASK, | ||
692 | AIC32X4_CODEC_CLKIN_PLL << AIC32X4_CODEC_CLKIN_SHIFT); | ||
693 | /* DAC_MOD_CLK as BDIV_CLKIN */ | ||
694 | snd_soc_update_bits(codec, AIC32X4_IFACE3, AIC32X4_BDIVCLK_MASK, | ||
695 | AIC32X4_DACMOD2BCLK << AIC32X4_BDIVCLK_SHIFT); | ||
696 | |||
697 | /* We will fix R value to 1 and will make P & J=K.D as variable */ | ||
698 | snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_R_MASK, 0x01); | ||
689 | 699 | ||
690 | /* We will fix R value to 1 and will make P & J=K.D as varialble */ | 700 | /* PLL P value */ |
691 | data = snd_soc_read(codec, AIC32X4_PLLPR); | 701 | snd_soc_update_bits(codec, AIC32X4_PLLPR, AIC32X4_PLL_P_MASK, |
692 | data &= ~(7 << 4); | 702 | aic32x4_divs[i].p_val << AIC32X4_PLL_P_SHIFT); |
693 | snd_soc_write(codec, AIC32X4_PLLPR, | ||
694 | (data | (aic32x4_divs[i].p_val << 4) | 0x01)); | ||
695 | 703 | ||
704 | /* PLL J value */ | ||
696 | snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j); | 705 | snd_soc_write(codec, AIC32X4_PLLJ, aic32x4_divs[i].pll_j); |
697 | 706 | ||
707 | /* PLL D value */ | ||
698 | snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8)); | 708 | snd_soc_write(codec, AIC32X4_PLLDMSB, (aic32x4_divs[i].pll_d >> 8)); |
699 | snd_soc_write(codec, AIC32X4_PLLDLSB, | 709 | snd_soc_write(codec, AIC32X4_PLLDLSB, (aic32x4_divs[i].pll_d & 0xff)); |
700 | (aic32x4_divs[i].pll_d & 0xff)); | ||
701 | 710 | ||
702 | /* NDAC divider value */ | 711 | /* NDAC divider value */ |
703 | data = snd_soc_read(codec, AIC32X4_NDAC); | 712 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
704 | data &= ~(0x7f); | 713 | AIC32X4_NDAC_MASK, aic32x4_divs[i].ndac); |
705 | snd_soc_write(codec, AIC32X4_NDAC, data | aic32x4_divs[i].ndac); | ||
706 | 714 | ||
707 | /* MDAC divider value */ | 715 | /* MDAC divider value */ |
708 | data = snd_soc_read(codec, AIC32X4_MDAC); | 716 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
709 | data &= ~(0x7f); | 717 | AIC32X4_MDAC_MASK, aic32x4_divs[i].mdac); |
710 | snd_soc_write(codec, AIC32X4_MDAC, data | aic32x4_divs[i].mdac); | ||
711 | 718 | ||
712 | /* DOSR MSB & LSB values */ | 719 | /* DOSR MSB & LSB values */ |
713 | snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); | 720 | snd_soc_write(codec, AIC32X4_DOSRMSB, aic32x4_divs[i].dosr >> 8); |
714 | snd_soc_write(codec, AIC32X4_DOSRLSB, | 721 | snd_soc_write(codec, AIC32X4_DOSRLSB, (aic32x4_divs[i].dosr & 0xff)); |
715 | (aic32x4_divs[i].dosr & 0xff)); | ||
716 | 722 | ||
717 | /* NADC divider value */ | 723 | /* NADC divider value */ |
718 | data = snd_soc_read(codec, AIC32X4_NADC); | 724 | snd_soc_update_bits(codec, AIC32X4_NADC, |
719 | data &= ~(0x7f); | 725 | AIC32X4_NADC_MASK, aic32x4_divs[i].nadc); |
720 | snd_soc_write(codec, AIC32X4_NADC, data | aic32x4_divs[i].nadc); | ||
721 | 726 | ||
722 | /* MADC divider value */ | 727 | /* MADC divider value */ |
723 | data = snd_soc_read(codec, AIC32X4_MADC); | 728 | snd_soc_update_bits(codec, AIC32X4_MADC, |
724 | data &= ~(0x7f); | 729 | AIC32X4_MADC_MASK, aic32x4_divs[i].madc); |
725 | snd_soc_write(codec, AIC32X4_MADC, data | aic32x4_divs[i].madc); | ||
726 | 730 | ||
727 | /* AOSR value */ | 731 | /* AOSR value */ |
728 | snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr); | 732 | snd_soc_write(codec, AIC32X4_AOSR, aic32x4_divs[i].aosr); |
729 | 733 | ||
730 | /* BCLK N divider */ | 734 | /* BCLK N divider */ |
731 | data = snd_soc_read(codec, AIC32X4_BCLKN); | 735 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
732 | data &= ~(0x7f); | 736 | AIC32X4_BCLK_MASK, aic32x4_divs[i].blck_N); |
733 | snd_soc_write(codec, AIC32X4_BCLKN, data | aic32x4_divs[i].blck_N); | ||
734 | 737 | ||
735 | data = snd_soc_read(codec, AIC32X4_IFACE1); | ||
736 | data = data & ~(3 << 4); | ||
737 | switch (params_width(params)) { | 738 | switch (params_width(params)) { |
738 | case 16: | 739 | case 16: |
740 | iface1_reg |= (AIC32X4_WORD_LEN_16BITS << | ||
741 | AIC32X4_IFACE1_DATALEN_SHIFT); | ||
739 | break; | 742 | break; |
740 | case 20: | 743 | case 20: |
741 | data |= (AIC32X4_WORD_LEN_20BITS << AIC32X4_DOSRMSB_SHIFT); | 744 | iface1_reg |= (AIC32X4_WORD_LEN_20BITS << |
745 | AIC32X4_IFACE1_DATALEN_SHIFT); | ||
742 | break; | 746 | break; |
743 | case 24: | 747 | case 24: |
744 | data |= (AIC32X4_WORD_LEN_24BITS << AIC32X4_DOSRMSB_SHIFT); | 748 | iface1_reg |= (AIC32X4_WORD_LEN_24BITS << |
749 | AIC32X4_IFACE1_DATALEN_SHIFT); | ||
745 | break; | 750 | break; |
746 | case 32: | 751 | case 32: |
747 | data |= (AIC32X4_WORD_LEN_32BITS << AIC32X4_DOSRMSB_SHIFT); | 752 | iface1_reg |= (AIC32X4_WORD_LEN_32BITS << |
753 | AIC32X4_IFACE1_DATALEN_SHIFT); | ||
748 | break; | 754 | break; |
749 | } | 755 | } |
750 | snd_soc_write(codec, AIC32X4_IFACE1, data); | 756 | snd_soc_update_bits(codec, AIC32X4_IFACE1, |
757 | AIC32X4_IFACE1_DATALEN_MASK, iface1_reg); | ||
751 | 758 | ||
752 | if (params_channels(params) == 1) { | 759 | if (params_channels(params) == 1) { |
753 | data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN; | 760 | dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2LCHN; |
754 | } else { | 761 | } else { |
755 | if (aic32x4->swapdacs) | 762 | if (aic32x4->swapdacs) |
756 | data = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2RCHN; | 763 | dacsetup_reg = AIC32X4_RDAC2LCHN | AIC32X4_LDAC2RCHN; |
757 | else | 764 | else |
758 | data = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN; | 765 | dacsetup_reg = AIC32X4_LDAC2LCHN | AIC32X4_RDAC2RCHN; |
759 | } | 766 | } |
760 | snd_soc_update_bits(codec, AIC32X4_DACSETUP, AIC32X4_DAC_CHAN_MASK, | 767 | snd_soc_update_bits(codec, AIC32X4_DACSETUP, |
761 | data); | 768 | AIC32X4_DAC_CHAN_MASK, dacsetup_reg); |
762 | 769 | ||
763 | return 0; | 770 | return 0; |
764 | } | 771 | } |
@@ -766,13 +773,10 @@ static int aic32x4_hw_params(struct snd_pcm_substream *substream, | |||
766 | static int aic32x4_mute(struct snd_soc_dai *dai, int mute) | 773 | static int aic32x4_mute(struct snd_soc_dai *dai, int mute) |
767 | { | 774 | { |
768 | struct snd_soc_codec *codec = dai->codec; | 775 | struct snd_soc_codec *codec = dai->codec; |
769 | u8 dac_reg; | ||
770 | 776 | ||
771 | dac_reg = snd_soc_read(codec, AIC32X4_DACMUTE) & ~AIC32X4_MUTEON; | 777 | snd_soc_update_bits(codec, AIC32X4_DACMUTE, |
772 | if (mute) | 778 | AIC32X4_MUTEON, mute ? AIC32X4_MUTEON : 0); |
773 | snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg | AIC32X4_MUTEON); | 779 | |
774 | else | ||
775 | snd_soc_write(codec, AIC32X4_DACMUTE, dac_reg); | ||
776 | return 0; | 780 | return 0; |
777 | } | 781 | } |
778 | 782 | ||
diff --git a/sound/soc/codecs/tlv320aic32x4.h b/sound/soc/codecs/tlv320aic32x4.h index da7cec482bcb..e9df49edbf19 100644 --- a/sound/soc/codecs/tlv320aic32x4.h +++ b/sound/soc/codecs/tlv320aic32x4.h | |||
@@ -19,141 +19,189 @@ int aic32x4_remove(struct device *dev); | |||
19 | 19 | ||
20 | /* tlv320aic32x4 register space (in decimal to match datasheet) */ | 20 | /* tlv320aic32x4 register space (in decimal to match datasheet) */ |
21 | 21 | ||
22 | #define AIC32X4_PAGE1 128 | 22 | #define AIC32X4_REG(page, reg) ((page * 128) + reg) |
23 | 23 | ||
24 | #define AIC32X4_PSEL 0 | 24 | #define AIC32X4_PSEL AIC32X4_REG(0, 0) |
25 | #define AIC32X4_RESET 1 | 25 | |
26 | #define AIC32X4_CLKMUX 4 | 26 | #define AIC32X4_RESET AIC32X4_REG(0, 1) |
27 | #define AIC32X4_PLLPR 5 | 27 | #define AIC32X4_CLKMUX AIC32X4_REG(0, 4) |
28 | #define AIC32X4_PLLJ 6 | 28 | #define AIC32X4_PLLPR AIC32X4_REG(0, 5) |
29 | #define AIC32X4_PLLDMSB 7 | 29 | #define AIC32X4_PLLJ AIC32X4_REG(0, 6) |
30 | #define AIC32X4_PLLDLSB 8 | 30 | #define AIC32X4_PLLDMSB AIC32X4_REG(0, 7) |
31 | #define AIC32X4_NDAC 11 | 31 | #define AIC32X4_PLLDLSB AIC32X4_REG(0, 8) |
32 | #define AIC32X4_MDAC 12 | 32 | #define AIC32X4_NDAC AIC32X4_REG(0, 11) |
33 | #define AIC32X4_DOSRMSB 13 | 33 | #define AIC32X4_MDAC AIC32X4_REG(0, 12) |
34 | #define AIC32X4_DOSRLSB 14 | 34 | #define AIC32X4_DOSRMSB AIC32X4_REG(0, 13) |
35 | #define AIC32X4_NADC 18 | 35 | #define AIC32X4_DOSRLSB AIC32X4_REG(0, 14) |
36 | #define AIC32X4_MADC 19 | 36 | #define AIC32X4_NADC AIC32X4_REG(0, 18) |
37 | #define AIC32X4_AOSR 20 | 37 | #define AIC32X4_MADC AIC32X4_REG(0, 19) |
38 | #define AIC32X4_CLKMUX2 25 | 38 | #define AIC32X4_AOSR AIC32X4_REG(0, 20) |
39 | #define AIC32X4_CLKOUTM 26 | 39 | #define AIC32X4_CLKMUX2 AIC32X4_REG(0, 25) |
40 | #define AIC32X4_IFACE1 27 | 40 | #define AIC32X4_CLKOUTM AIC32X4_REG(0, 26) |
41 | #define AIC32X4_IFACE2 28 | 41 | #define AIC32X4_IFACE1 AIC32X4_REG(0, 27) |
42 | #define AIC32X4_IFACE3 29 | 42 | #define AIC32X4_IFACE2 AIC32X4_REG(0, 28) |
43 | #define AIC32X4_BCLKN 30 | 43 | #define AIC32X4_IFACE3 AIC32X4_REG(0, 29) |
44 | #define AIC32X4_IFACE4 31 | 44 | #define AIC32X4_BCLKN AIC32X4_REG(0, 30) |
45 | #define AIC32X4_IFACE5 32 | 45 | #define AIC32X4_IFACE4 AIC32X4_REG(0, 31) |
46 | #define AIC32X4_IFACE6 33 | 46 | #define AIC32X4_IFACE5 AIC32X4_REG(0, 32) |
47 | #define AIC32X4_GPIOCTL 52 | 47 | #define AIC32X4_IFACE6 AIC32X4_REG(0, 33) |
48 | #define AIC32X4_DOUTCTL 53 | 48 | #define AIC32X4_GPIOCTL AIC32X4_REG(0, 52) |
49 | #define AIC32X4_DINCTL 54 | 49 | #define AIC32X4_DOUTCTL AIC32X4_REG(0, 53) |
50 | #define AIC32X4_MISOCTL 55 | 50 | #define AIC32X4_DINCTL AIC32X4_REG(0, 54) |
51 | #define AIC32X4_SCLKCTL 56 | 51 | #define AIC32X4_MISOCTL AIC32X4_REG(0, 55) |
52 | #define AIC32X4_DACSPB 60 | 52 | #define AIC32X4_SCLKCTL AIC32X4_REG(0, 56) |
53 | #define AIC32X4_ADCSPB 61 | 53 | #define AIC32X4_DACSPB AIC32X4_REG(0, 60) |
54 | #define AIC32X4_DACSETUP 63 | 54 | #define AIC32X4_ADCSPB AIC32X4_REG(0, 61) |
55 | #define AIC32X4_DACMUTE 64 | 55 | #define AIC32X4_DACSETUP AIC32X4_REG(0, 63) |
56 | #define AIC32X4_LDACVOL 65 | 56 | #define AIC32X4_DACMUTE AIC32X4_REG(0, 64) |
57 | #define AIC32X4_RDACVOL 66 | 57 | #define AIC32X4_LDACVOL AIC32X4_REG(0, 65) |
58 | #define AIC32X4_ADCSETUP 81 | 58 | #define AIC32X4_RDACVOL AIC32X4_REG(0, 66) |
59 | #define AIC32X4_ADCFGA 82 | 59 | #define AIC32X4_ADCSETUP AIC32X4_REG(0, 81) |
60 | #define AIC32X4_LADCVOL 83 | 60 | #define AIC32X4_ADCFGA AIC32X4_REG(0, 82) |
61 | #define AIC32X4_RADCVOL 84 | 61 | #define AIC32X4_LADCVOL AIC32X4_REG(0, 83) |
62 | #define AIC32X4_LAGC1 86 | 62 | #define AIC32X4_RADCVOL AIC32X4_REG(0, 84) |
63 | #define AIC32X4_LAGC2 87 | 63 | #define AIC32X4_LAGC1 AIC32X4_REG(0, 86) |
64 | #define AIC32X4_LAGC3 88 | 64 | #define AIC32X4_LAGC2 AIC32X4_REG(0, 87) |
65 | #define AIC32X4_LAGC4 89 | 65 | #define AIC32X4_LAGC3 AIC32X4_REG(0, 88) |
66 | #define AIC32X4_LAGC5 90 | 66 | #define AIC32X4_LAGC4 AIC32X4_REG(0, 89) |
67 | #define AIC32X4_LAGC6 91 | 67 | #define AIC32X4_LAGC5 AIC32X4_REG(0, 90) |
68 | #define AIC32X4_LAGC7 92 | 68 | #define AIC32X4_LAGC6 AIC32X4_REG(0, 91) |
69 | #define AIC32X4_RAGC1 94 | 69 | #define AIC32X4_LAGC7 AIC32X4_REG(0, 92) |
70 | #define AIC32X4_RAGC2 95 | 70 | #define AIC32X4_RAGC1 AIC32X4_REG(0, 94) |
71 | #define AIC32X4_RAGC3 96 | 71 | #define AIC32X4_RAGC2 AIC32X4_REG(0, 95) |
72 | #define AIC32X4_RAGC4 97 | 72 | #define AIC32X4_RAGC3 AIC32X4_REG(0, 96) |
73 | #define AIC32X4_RAGC5 98 | 73 | #define AIC32X4_RAGC4 AIC32X4_REG(0, 97) |
74 | #define AIC32X4_RAGC6 99 | 74 | #define AIC32X4_RAGC5 AIC32X4_REG(0, 98) |
75 | #define AIC32X4_RAGC7 100 | 75 | #define AIC32X4_RAGC6 AIC32X4_REG(0, 99) |
76 | #define AIC32X4_PWRCFG (AIC32X4_PAGE1 + 1) | 76 | #define AIC32X4_RAGC7 AIC32X4_REG(0, 100) |
77 | #define AIC32X4_LDOCTL (AIC32X4_PAGE1 + 2) | 77 | |
78 | #define AIC32X4_OUTPWRCTL (AIC32X4_PAGE1 + 9) | 78 | #define AIC32X4_PWRCFG AIC32X4_REG(1, 1) |
79 | #define AIC32X4_CMMODE (AIC32X4_PAGE1 + 10) | 79 | #define AIC32X4_LDOCTL AIC32X4_REG(1, 2) |
80 | #define AIC32X4_HPLROUTE (AIC32X4_PAGE1 + 12) | 80 | #define AIC32X4_OUTPWRCTL AIC32X4_REG(1, 9) |
81 | #define AIC32X4_HPRROUTE (AIC32X4_PAGE1 + 13) | 81 | #define AIC32X4_CMMODE AIC32X4_REG(1, 10) |
82 | #define AIC32X4_LOLROUTE (AIC32X4_PAGE1 + 14) | 82 | #define AIC32X4_HPLROUTE AIC32X4_REG(1, 12) |
83 | #define AIC32X4_LORROUTE (AIC32X4_PAGE1 + 15) | 83 | #define AIC32X4_HPRROUTE AIC32X4_REG(1, 13) |
84 | #define AIC32X4_HPLGAIN (AIC32X4_PAGE1 + 16) | 84 | #define AIC32X4_LOLROUTE AIC32X4_REG(1, 14) |
85 | #define AIC32X4_HPRGAIN (AIC32X4_PAGE1 + 17) | 85 | #define AIC32X4_LORROUTE AIC32X4_REG(1, 15) |
86 | #define AIC32X4_LOLGAIN (AIC32X4_PAGE1 + 18) | 86 | #define AIC32X4_HPLGAIN AIC32X4_REG(1, 16) |
87 | #define AIC32X4_LORGAIN (AIC32X4_PAGE1 + 19) | 87 | #define AIC32X4_HPRGAIN AIC32X4_REG(1, 17) |
88 | #define AIC32X4_HEADSTART (AIC32X4_PAGE1 + 20) | 88 | #define AIC32X4_LOLGAIN AIC32X4_REG(1, 18) |
89 | #define AIC32X4_MICBIAS (AIC32X4_PAGE1 + 51) | 89 | #define AIC32X4_LORGAIN AIC32X4_REG(1, 19) |
90 | #define AIC32X4_LMICPGAPIN (AIC32X4_PAGE1 + 52) | 90 | #define AIC32X4_HEADSTART AIC32X4_REG(1, 20) |
91 | #define AIC32X4_LMICPGANIN (AIC32X4_PAGE1 + 54) | 91 | #define AIC32X4_MICBIAS AIC32X4_REG(1, 51) |
92 | #define AIC32X4_RMICPGAPIN (AIC32X4_PAGE1 + 55) | 92 | #define AIC32X4_LMICPGAPIN AIC32X4_REG(1, 52) |
93 | #define AIC32X4_RMICPGANIN (AIC32X4_PAGE1 + 57) | 93 | #define AIC32X4_LMICPGANIN AIC32X4_REG(1, 54) |
94 | #define AIC32X4_FLOATINGINPUT (AIC32X4_PAGE1 + 58) | 94 | #define AIC32X4_RMICPGAPIN AIC32X4_REG(1, 55) |
95 | #define AIC32X4_LMICPGAVOL (AIC32X4_PAGE1 + 59) | 95 | #define AIC32X4_RMICPGANIN AIC32X4_REG(1, 57) |
96 | #define AIC32X4_RMICPGAVOL (AIC32X4_PAGE1 + 60) | 96 | #define AIC32X4_FLOATINGINPUT AIC32X4_REG(1, 58) |
97 | 97 | #define AIC32X4_LMICPGAVOL AIC32X4_REG(1, 59) | |
98 | #define AIC32X4_FREQ_12000000 12000000 | 98 | #define AIC32X4_RMICPGAVOL AIC32X4_REG(1, 60) |
99 | #define AIC32X4_FREQ_24000000 24000000 | 99 | |
100 | #define AIC32X4_FREQ_25000000 25000000 | 100 | /* Bits, masks, and shifts */ |
101 | 101 | ||
102 | #define AIC32X4_WORD_LEN_16BITS 0x00 | 102 | /* AIC32X4_CLKMUX */ |
103 | #define AIC32X4_WORD_LEN_20BITS 0x01 | 103 | #define AIC32X4_PLL_CLKIN_MASK GENMASK(3, 2) |
104 | #define AIC32X4_WORD_LEN_24BITS 0x02 | 104 | #define AIC32X4_PLL_CLKIN_SHIFT (2) |
105 | #define AIC32X4_WORD_LEN_32BITS 0x03 | 105 | #define AIC32X4_PLL_CLKIN_MCLK (0x00) |
106 | 106 | #define AIC32X4_PLL_CLKIN_BCKL (0x01) | |
107 | #define AIC32X4_LADC_EN (1 << 7) | 107 | #define AIC32X4_PLL_CLKIN_GPIO1 (0x02) |
108 | #define AIC32X4_RADC_EN (1 << 6) | 108 | #define AIC32X4_PLL_CLKIN_DIN (0x03) |
109 | 109 | #define AIC32X4_CODEC_CLKIN_MASK GENMASK(1, 0) | |
110 | #define AIC32X4_I2S_MODE 0x00 | 110 | #define AIC32X4_CODEC_CLKIN_SHIFT (0) |
111 | #define AIC32X4_DSP_MODE 0x01 | 111 | #define AIC32X4_CODEC_CLKIN_MCLK (0x00) |
112 | #define AIC32X4_RIGHT_JUSTIFIED_MODE 0x02 | 112 | #define AIC32X4_CODEC_CLKIN_BCLK (0x01) |
113 | #define AIC32X4_LEFT_JUSTIFIED_MODE 0x03 | 113 | #define AIC32X4_CODEC_CLKIN_GPIO1 (0x02) |
114 | 114 | #define AIC32X4_CODEC_CLKIN_PLL (0x03) | |
115 | #define AIC32X4_AVDDWEAKDISABLE 0x08 | 115 | |
116 | #define AIC32X4_LDOCTLEN 0x01 | 116 | /* AIC32X4_PLLPR */ |
117 | 117 | #define AIC32X4_PLLEN BIT(7) | |
118 | #define AIC32X4_LDOIN_18_36 0x01 | 118 | #define AIC32X4_PLL_P_MASK GENMASK(6, 4) |
119 | #define AIC32X4_LDOIN2HP 0x02 | 119 | #define AIC32X4_PLL_P_SHIFT (4) |
120 | 120 | #define AIC32X4_PLL_R_MASK GENMASK(3, 0) | |
121 | #define AIC32X4_DACSPBLOCK_MASK 0x1f | 121 | |
122 | #define AIC32X4_ADCSPBLOCK_MASK 0x1f | 122 | /* AIC32X4_NDAC */ |
123 | 123 | #define AIC32X4_NDACEN BIT(7) | |
124 | #define AIC32X4_PLLJ_SHIFT 6 | 124 | #define AIC32X4_NDAC_MASK GENMASK(6, 0) |
125 | #define AIC32X4_DOSRMSB_SHIFT 4 | 125 | |
126 | 126 | /* AIC32X4_MDAC */ | |
127 | #define AIC32X4_PLLCLKIN 0x03 | 127 | #define AIC32X4_MDACEN BIT(7) |
128 | 128 | #define AIC32X4_MDAC_MASK GENMASK(6, 0) | |
129 | #define AIC32X4_MICBIAS_LDOIN 0x08 | 129 | |
130 | /* AIC32X4_NADC */ | ||
131 | #define AIC32X4_NADCEN BIT(7) | ||
132 | #define AIC32X4_NADC_MASK GENMASK(6, 0) | ||
133 | |||
134 | /* AIC32X4_MADC */ | ||
135 | #define AIC32X4_MADCEN BIT(7) | ||
136 | #define AIC32X4_MADC_MASK GENMASK(6, 0) | ||
137 | |||
138 | /* AIC32X4_BCLKN */ | ||
139 | #define AIC32X4_BCLKEN BIT(7) | ||
140 | #define AIC32X4_BCLK_MASK GENMASK(6, 0) | ||
141 | |||
142 | /* AIC32X4_IFACE1 */ | ||
143 | #define AIC32X4_IFACE1_DATATYPE_MASK GENMASK(7, 6) | ||
144 | #define AIC32X4_IFACE1_DATATYPE_SHIFT (6) | ||
145 | #define AIC32X4_I2S_MODE (0x00) | ||
146 | #define AIC32X4_DSP_MODE (0x01) | ||
147 | #define AIC32X4_RIGHT_JUSTIFIED_MODE (0x02) | ||
148 | #define AIC32X4_LEFT_JUSTIFIED_MODE (0x03) | ||
149 | #define AIC32X4_IFACE1_DATALEN_MASK GENMASK(5, 4) | ||
150 | #define AIC32X4_IFACE1_DATALEN_SHIFT (4) | ||
151 | #define AIC32X4_WORD_LEN_16BITS (0x00) | ||
152 | #define AIC32X4_WORD_LEN_20BITS (0x01) | ||
153 | #define AIC32X4_WORD_LEN_24BITS (0x02) | ||
154 | #define AIC32X4_WORD_LEN_32BITS (0x03) | ||
155 | #define AIC32X4_IFACE1_MASTER_MASK GENMASK(3, 2) | ||
156 | #define AIC32X4_BCLKMASTER BIT(2) | ||
157 | #define AIC32X4_WCLKMASTER BIT(3) | ||
158 | |||
159 | /* AIC32X4_IFACE2 */ | ||
160 | #define AIC32X4_DATA_OFFSET_MASK GENMASK(7, 0) | ||
161 | |||
162 | /* AIC32X4_IFACE3 */ | ||
163 | #define AIC32X4_BCLKINV_MASK BIT(3) | ||
164 | #define AIC32X4_BDIVCLK_MASK GENMASK(1, 0) | ||
165 | #define AIC32X4_BDIVCLK_SHIFT (0) | ||
166 | #define AIC32X4_DAC2BCLK (0x00) | ||
167 | #define AIC32X4_DACMOD2BCLK (0x01) | ||
168 | #define AIC32X4_ADC2BCLK (0x02) | ||
169 | #define AIC32X4_ADCMOD2BCLK (0x03) | ||
170 | |||
171 | /* AIC32X4_DACSETUP */ | ||
172 | #define AIC32X4_DAC_CHAN_MASK GENMASK(5, 2) | ||
173 | #define AIC32X4_LDAC2RCHN BIT(5) | ||
174 | #define AIC32X4_LDAC2LCHN BIT(4) | ||
175 | #define AIC32X4_RDAC2LCHN BIT(3) | ||
176 | #define AIC32X4_RDAC2RCHN BIT(2) | ||
177 | |||
178 | /* AIC32X4_DACMUTE */ | ||
179 | #define AIC32X4_MUTEON 0x0C | ||
180 | |||
181 | /* AIC32X4_ADCSETUP */ | ||
182 | #define AIC32X4_LADC_EN BIT(7) | ||
183 | #define AIC32X4_RADC_EN BIT(6) | ||
184 | |||
185 | /* AIC32X4_PWRCFG */ | ||
186 | #define AIC32X4_AVDDWEAKDISABLE BIT(3) | ||
187 | |||
188 | /* AIC32X4_LDOCTL */ | ||
189 | #define AIC32X4_LDOCTLEN BIT(0) | ||
190 | |||
191 | /* AIC32X4_CMMODE */ | ||
192 | #define AIC32X4_LDOIN_18_36 BIT(0) | ||
193 | #define AIC32X4_LDOIN2HP BIT(1) | ||
194 | |||
195 | /* AIC32X4_MICBIAS */ | ||
196 | #define AIC32X4_MICBIAS_LDOIN BIT(3) | ||
130 | #define AIC32X4_MICBIAS_2075V 0x60 | 197 | #define AIC32X4_MICBIAS_2075V 0x60 |
131 | 198 | ||
199 | /* AIC32X4_LMICPGANIN */ | ||
132 | #define AIC32X4_LMICPGANIN_IN2R_10K 0x10 | 200 | #define AIC32X4_LMICPGANIN_IN2R_10K 0x10 |
133 | #define AIC32X4_LMICPGANIN_CM1L_10K 0x40 | 201 | #define AIC32X4_LMICPGANIN_CM1L_10K 0x40 |
202 | |||
203 | /* AIC32X4_RMICPGANIN */ | ||
134 | #define AIC32X4_RMICPGANIN_IN1L_10K 0x10 | 204 | #define AIC32X4_RMICPGANIN_IN1L_10K 0x10 |
135 | #define AIC32X4_RMICPGANIN_CM1R_10K 0x40 | 205 | #define AIC32X4_RMICPGANIN_CM1R_10K 0x40 |
136 | 206 | ||
137 | #define AIC32X4_LMICPGAVOL_NOGAIN 0x80 | ||
138 | #define AIC32X4_RMICPGAVOL_NOGAIN 0x80 | ||
139 | |||
140 | #define AIC32X4_BCLKMASTER 0x08 | ||
141 | #define AIC32X4_WCLKMASTER 0x04 | ||
142 | #define AIC32X4_PLLEN (0x01 << 7) | ||
143 | #define AIC32X4_NDACEN (0x01 << 7) | ||
144 | #define AIC32X4_MDACEN (0x01 << 7) | ||
145 | #define AIC32X4_NADCEN (0x01 << 7) | ||
146 | #define AIC32X4_MADCEN (0x01 << 7) | ||
147 | #define AIC32X4_BCLKEN (0x01 << 7) | ||
148 | #define AIC32X4_DACEN (0x03 << 6) | ||
149 | #define AIC32X4_RDAC2LCHN (0x02 << 2) | ||
150 | #define AIC32X4_LDAC2RCHN (0x02 << 4) | ||
151 | #define AIC32X4_LDAC2LCHN (0x01 << 4) | ||
152 | #define AIC32X4_RDAC2RCHN (0x01 << 2) | ||
153 | #define AIC32X4_DAC_CHAN_MASK 0x3c | ||
154 | |||
155 | #define AIC32X4_SSTEP2WCLK 0x01 | ||
156 | #define AIC32X4_MUTEON 0x0C | ||
157 | #define AIC32X4_DACMOD2BCLK 0x01 | ||
158 | |||
159 | #endif /* _TLV320AIC32X4_H */ | 207 | #endif /* _TLV320AIC32X4_H */ |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 06f92571eba4..b751cad545da 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1804,11 +1804,18 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
1804 | if (!ai3x_setup) | 1804 | if (!ai3x_setup) |
1805 | return -ENOMEM; | 1805 | return -ENOMEM; |
1806 | 1806 | ||
1807 | ret = of_get_named_gpio(np, "gpio-reset", 0); | 1807 | ret = of_get_named_gpio(np, "reset-gpios", 0); |
1808 | if (ret >= 0) | 1808 | if (ret >= 0) { |
1809 | aic3x->gpio_reset = ret; | 1809 | aic3x->gpio_reset = ret; |
1810 | else | 1810 | } else { |
1811 | aic3x->gpio_reset = -1; | 1811 | ret = of_get_named_gpio(np, "gpio-reset", 0); |
1812 | if (ret > 0) { | ||
1813 | dev_warn(&i2c->dev, "Using deprecated property \"gpio-reset\", please update your DT"); | ||
1814 | aic3x->gpio_reset = ret; | ||
1815 | } else { | ||
1816 | aic3x->gpio_reset = -1; | ||
1817 | } | ||
1818 | } | ||
1812 | 1819 | ||
1813 | if (of_property_read_u32_array(np, "ai3x-gpio-func", | 1820 | if (of_property_read_u32_array(np, "ai3x-gpio-func", |
1814 | ai3x_setup->gpio_func, 2) >= 0) { | 1821 | ai3x_setup->gpio_func, 2) >= 0) { |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 5b94a151539c..8c71d2f876ff 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -106,6 +106,7 @@ struct tlv320dac33_priv { | |||
106 | int mode1_latency; /* latency caused by the i2c writes in | 106 | int mode1_latency; /* latency caused by the i2c writes in |
107 | * us */ | 107 | * us */ |
108 | u8 burst_bclkdiv; /* BCLK divider value in burst mode */ | 108 | u8 burst_bclkdiv; /* BCLK divider value in burst mode */ |
109 | u8 *reg_cache; | ||
109 | unsigned int burst_rate; /* Interface speed in Burst modes */ | 110 | unsigned int burst_rate; /* Interface speed in Burst modes */ |
110 | 111 | ||
111 | int keep_bclk; /* Keep the BCLK continuously running | 112 | int keep_bclk; /* Keep the BCLK continuously running |
@@ -121,7 +122,7 @@ struct tlv320dac33_priv { | |||
121 | unsigned int uthr; | 122 | unsigned int uthr; |
122 | 123 | ||
123 | enum dac33_state state; | 124 | enum dac33_state state; |
124 | void *control_data; | 125 | struct i2c_client *i2c; |
125 | }; | 126 | }; |
126 | 127 | ||
127 | static const u8 dac33_reg[DAC33_CACHEREGNUM] = { | 128 | static const u8 dac33_reg[DAC33_CACHEREGNUM] = { |
@@ -173,7 +174,8 @@ static const u8 dac33_reg[DAC33_CACHEREGNUM] = { | |||
173 | static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec, | 174 | static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec, |
174 | unsigned reg) | 175 | unsigned reg) |
175 | { | 176 | { |
176 | u8 *cache = codec->reg_cache; | 177 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
178 | u8 *cache = dac33->reg_cache; | ||
177 | if (reg >= DAC33_CACHEREGNUM) | 179 | if (reg >= DAC33_CACHEREGNUM) |
178 | return 0; | 180 | return 0; |
179 | 181 | ||
@@ -183,7 +185,8 @@ static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec, | |||
183 | static inline void dac33_write_reg_cache(struct snd_soc_codec *codec, | 185 | static inline void dac33_write_reg_cache(struct snd_soc_codec *codec, |
184 | u8 reg, u8 value) | 186 | u8 reg, u8 value) |
185 | { | 187 | { |
186 | u8 *cache = codec->reg_cache; | 188 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
189 | u8 *cache = dac33->reg_cache; | ||
187 | if (reg >= DAC33_CACHEREGNUM) | 190 | if (reg >= DAC33_CACHEREGNUM) |
188 | return; | 191 | return; |
189 | 192 | ||
@@ -200,7 +203,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, | |||
200 | 203 | ||
201 | /* If powered off, return the cached value */ | 204 | /* If powered off, return the cached value */ |
202 | if (dac33->chip_power) { | 205 | if (dac33->chip_power) { |
203 | val = i2c_smbus_read_byte_data(codec->control_data, value[0]); | 206 | val = i2c_smbus_read_byte_data(dac33->i2c, value[0]); |
204 | if (val < 0) { | 207 | if (val < 0) { |
205 | dev_err(codec->dev, "Read failed (%d)\n", val); | 208 | dev_err(codec->dev, "Read failed (%d)\n", val); |
206 | value[0] = dac33_read_reg_cache(codec, reg); | 209 | value[0] = dac33_read_reg_cache(codec, reg); |
@@ -233,7 +236,7 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, | |||
233 | 236 | ||
234 | dac33_write_reg_cache(codec, data[0], data[1]); | 237 | dac33_write_reg_cache(codec, data[0], data[1]); |
235 | if (dac33->chip_power) { | 238 | if (dac33->chip_power) { |
236 | ret = codec->hw_write(codec->control_data, data, 2); | 239 | ret = i2c_master_send(dac33->i2c, data, 2); |
237 | if (ret != 2) | 240 | if (ret != 2) |
238 | dev_err(codec->dev, "Write failed (%d)\n", ret); | 241 | dev_err(codec->dev, "Write failed (%d)\n", ret); |
239 | else | 242 | else |
@@ -244,7 +247,7 @@ static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, | |||
244 | } | 247 | } |
245 | 248 | ||
246 | static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg, | 249 | static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg, |
247 | unsigned int value) | 250 | unsigned int value) |
248 | { | 251 | { |
249 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 252 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
250 | int ret; | 253 | int ret; |
@@ -280,7 +283,7 @@ static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg, | |||
280 | if (dac33->chip_power) { | 283 | if (dac33->chip_power) { |
281 | /* We need to set autoincrement mode for 16 bit writes */ | 284 | /* We need to set autoincrement mode for 16 bit writes */ |
282 | data[0] |= DAC33_I2C_ADDR_AUTOINC; | 285 | data[0] |= DAC33_I2C_ADDR_AUTOINC; |
283 | ret = codec->hw_write(codec->control_data, data, 3); | 286 | ret = i2c_master_send(dac33->i2c, data, 3); |
284 | if (ret != 3) | 287 | if (ret != 3) |
285 | dev_err(codec->dev, "Write failed (%d)\n", ret); | 288 | dev_err(codec->dev, "Write failed (%d)\n", ret); |
286 | else | 289 | else |
@@ -1379,8 +1382,6 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
1379 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 1382 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
1380 | int ret = 0; | 1383 | int ret = 0; |
1381 | 1384 | ||
1382 | codec->control_data = dac33->control_data; | ||
1383 | codec->hw_write = (hw_write_t) i2c_master_send; | ||
1384 | dac33->codec = codec; | 1385 | dac33->codec = codec; |
1385 | 1386 | ||
1386 | /* Read the tlv320dac33 ID registers */ | 1387 | /* Read the tlv320dac33 ID registers */ |
@@ -1438,9 +1439,7 @@ static const struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | |||
1438 | .write = dac33_write_locked, | 1439 | .write = dac33_write_locked, |
1439 | .set_bias_level = dac33_set_bias_level, | 1440 | .set_bias_level = dac33_set_bias_level, |
1440 | .idle_bias_off = true, | 1441 | .idle_bias_off = true, |
1441 | .reg_cache_size = ARRAY_SIZE(dac33_reg), | 1442 | |
1442 | .reg_word_size = sizeof(u8), | ||
1443 | .reg_cache_default = dac33_reg, | ||
1444 | .probe = dac33_soc_probe, | 1443 | .probe = dac33_soc_probe, |
1445 | .remove = dac33_soc_remove, | 1444 | .remove = dac33_soc_remove, |
1446 | 1445 | ||
@@ -1499,7 +1498,14 @@ static int dac33_i2c_probe(struct i2c_client *client, | |||
1499 | if (dac33 == NULL) | 1498 | if (dac33 == NULL) |
1500 | return -ENOMEM; | 1499 | return -ENOMEM; |
1501 | 1500 | ||
1502 | dac33->control_data = client; | 1501 | dac33->reg_cache = devm_kmemdup(&client->dev, |
1502 | dac33_reg, | ||
1503 | ARRAY_SIZE(dac33_reg) * sizeof(u8), | ||
1504 | GFP_KERNEL); | ||
1505 | if (!dac33->reg_cache) | ||
1506 | return -ENOMEM; | ||
1507 | |||
1508 | dac33->i2c = client; | ||
1503 | mutex_init(&dac33->mutex); | 1509 | mutex_init(&dac33->mutex); |
1504 | spin_lock_init(&dac33->lock); | 1510 | spin_lock_init(&dac33->lock); |
1505 | 1511 | ||
diff --git a/sound/soc/codecs/ts3a227e.c b/sound/soc/codecs/ts3a227e.c index 738e04b09116..1271e7e1fc78 100644 --- a/sound/soc/codecs/ts3a227e.c +++ b/sound/soc/codecs/ts3a227e.c | |||
@@ -241,7 +241,7 @@ int ts3a227e_enable_jack_detect(struct snd_soc_component *component, | |||
241 | { | 241 | { |
242 | struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component); | 242 | struct ts3a227e *ts3a227e = snd_soc_component_get_drvdata(component); |
243 | 243 | ||
244 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); | 244 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
245 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); | 245 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
246 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | 246 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
247 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | 247 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); |
diff --git a/sound/soc/codecs/tscs42xx.c b/sound/soc/codecs/tscs42xx.c new file mode 100644 index 000000000000..e7661d0315e6 --- /dev/null +++ b/sound/soc/codecs/tscs42xx.c | |||
@@ -0,0 +1,1456 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // tscs42xx.c -- TSCS42xx ALSA SoC Audio driver | ||
3 | // Copyright 2017 Tempo Semiconductor, Inc. | ||
4 | // Author: Steven Eckhoff <steven.eckhoff.opensource@gmail.com> | ||
5 | |||
6 | #include <linux/i2c.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/mutex.h> | ||
9 | #include <linux/regmap.h> | ||
10 | #include <sound/pcm_params.h> | ||
11 | #include <sound/soc.h> | ||
12 | #include <sound/soc-dapm.h> | ||
13 | #include <sound/tlv.h> | ||
14 | |||
15 | #include "tscs42xx.h" | ||
16 | |||
17 | #define COEFF_SIZE 3 | ||
18 | #define BIQUAD_COEFF_COUNT 5 | ||
19 | #define BIQUAD_SIZE (COEFF_SIZE * BIQUAD_COEFF_COUNT) | ||
20 | |||
21 | #define COEFF_RAM_MAX_ADDR 0xcd | ||
22 | #define COEFF_RAM_COEFF_COUNT (COEFF_RAM_MAX_ADDR + 1) | ||
23 | #define COEFF_RAM_SIZE (COEFF_SIZE * COEFF_RAM_COEFF_COUNT) | ||
24 | |||
25 | struct tscs42xx { | ||
26 | |||
27 | int bclk_ratio; | ||
28 | int samplerate; | ||
29 | unsigned int blrcm; | ||
30 | struct mutex audio_params_lock; | ||
31 | |||
32 | u8 coeff_ram[COEFF_RAM_SIZE]; | ||
33 | bool coeff_ram_synced; | ||
34 | struct mutex coeff_ram_lock; | ||
35 | |||
36 | struct mutex pll_lock; | ||
37 | |||
38 | struct regmap *regmap; | ||
39 | |||
40 | struct device *dev; | ||
41 | }; | ||
42 | |||
43 | struct coeff_ram_ctl { | ||
44 | unsigned int addr; | ||
45 | struct soc_bytes_ext bytes_ext; | ||
46 | }; | ||
47 | |||
48 | static bool tscs42xx_volatile(struct device *dev, unsigned int reg) | ||
49 | { | ||
50 | switch (reg) { | ||
51 | case R_DACCRWRL: | ||
52 | case R_DACCRWRM: | ||
53 | case R_DACCRWRH: | ||
54 | case R_DACCRRDL: | ||
55 | case R_DACCRRDM: | ||
56 | case R_DACCRRDH: | ||
57 | case R_DACCRSTAT: | ||
58 | case R_DACCRADDR: | ||
59 | case R_PLLCTL0: | ||
60 | return true; | ||
61 | default: | ||
62 | return false; | ||
63 | }; | ||
64 | } | ||
65 | |||
66 | static bool tscs42xx_precious(struct device *dev, unsigned int reg) | ||
67 | { | ||
68 | switch (reg) { | ||
69 | case R_DACCRWRL: | ||
70 | case R_DACCRWRM: | ||
71 | case R_DACCRWRH: | ||
72 | case R_DACCRRDL: | ||
73 | case R_DACCRRDM: | ||
74 | case R_DACCRRDH: | ||
75 | return true; | ||
76 | default: | ||
77 | return false; | ||
78 | }; | ||
79 | } | ||
80 | |||
81 | static const struct regmap_config tscs42xx_regmap = { | ||
82 | .reg_bits = 8, | ||
83 | .val_bits = 8, | ||
84 | |||
85 | .volatile_reg = tscs42xx_volatile, | ||
86 | .precious_reg = tscs42xx_precious, | ||
87 | .max_register = R_DACMBCREL3H, | ||
88 | |||
89 | .cache_type = REGCACHE_RBTREE, | ||
90 | .can_multi_write = true, | ||
91 | }; | ||
92 | |||
93 | #define MAX_PLL_LOCK_20MS_WAITS 1 | ||
94 | static bool plls_locked(struct snd_soc_codec *codec) | ||
95 | { | ||
96 | int ret; | ||
97 | int count = MAX_PLL_LOCK_20MS_WAITS; | ||
98 | |||
99 | do { | ||
100 | ret = snd_soc_read(codec, R_PLLCTL0); | ||
101 | if (ret < 0) { | ||
102 | dev_err(codec->dev, | ||
103 | "Failed to read PLL lock status (%d)\n", ret); | ||
104 | return false; | ||
105 | } else if (ret > 0) { | ||
106 | return true; | ||
107 | } | ||
108 | msleep(20); | ||
109 | } while (count--); | ||
110 | |||
111 | return false; | ||
112 | } | ||
113 | |||
114 | static int sample_rate_to_pll_freq_out(int sample_rate) | ||
115 | { | ||
116 | switch (sample_rate) { | ||
117 | case 11025: | ||
118 | case 22050: | ||
119 | case 44100: | ||
120 | case 88200: | ||
121 | return 112896000; | ||
122 | case 8000: | ||
123 | case 16000: | ||
124 | case 32000: | ||
125 | case 48000: | ||
126 | case 96000: | ||
127 | return 122880000; | ||
128 | default: | ||
129 | return -EINVAL; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | #define DACCRSTAT_MAX_TRYS 10 | ||
134 | static int write_coeff_ram(struct snd_soc_codec *codec, u8 *coeff_ram, | ||
135 | unsigned int addr, unsigned int coeff_cnt) | ||
136 | { | ||
137 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
138 | int cnt; | ||
139 | int trys; | ||
140 | int ret; | ||
141 | |||
142 | for (cnt = 0; cnt < coeff_cnt; cnt++, addr++) { | ||
143 | |||
144 | for (trys = 0; trys < DACCRSTAT_MAX_TRYS; trys++) { | ||
145 | ret = snd_soc_read(codec, R_DACCRSTAT); | ||
146 | if (ret < 0) { | ||
147 | dev_err(codec->dev, | ||
148 | "Failed to read stat (%d)\n", ret); | ||
149 | return ret; | ||
150 | } | ||
151 | if (!ret) | ||
152 | break; | ||
153 | } | ||
154 | |||
155 | if (trys == DACCRSTAT_MAX_TRYS) { | ||
156 | ret = -EIO; | ||
157 | dev_err(codec->dev, | ||
158 | "dac coefficient write error (%d)\n", ret); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | ret = regmap_write(tscs42xx->regmap, R_DACCRADDR, addr); | ||
163 | if (ret < 0) { | ||
164 | dev_err(codec->dev, | ||
165 | "Failed to write dac ram address (%d)\n", ret); | ||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | ret = regmap_bulk_write(tscs42xx->regmap, R_DACCRWRL, | ||
170 | &coeff_ram[addr * COEFF_SIZE], | ||
171 | COEFF_SIZE); | ||
172 | if (ret < 0) { | ||
173 | dev_err(codec->dev, | ||
174 | "Failed to write dac ram (%d)\n", ret); | ||
175 | return ret; | ||
176 | } | ||
177 | } | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static int power_up_audio_plls(struct snd_soc_codec *codec) | ||
183 | { | ||
184 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
185 | int freq_out; | ||
186 | int ret; | ||
187 | unsigned int mask; | ||
188 | unsigned int val; | ||
189 | |||
190 | freq_out = sample_rate_to_pll_freq_out(tscs42xx->samplerate); | ||
191 | switch (freq_out) { | ||
192 | case 122880000: /* 48k */ | ||
193 | mask = RM_PLLCTL1C_PDB_PLL1; | ||
194 | val = RV_PLLCTL1C_PDB_PLL1_ENABLE; | ||
195 | break; | ||
196 | case 112896000: /* 44.1k */ | ||
197 | mask = RM_PLLCTL1C_PDB_PLL2; | ||
198 | val = RV_PLLCTL1C_PDB_PLL2_ENABLE; | ||
199 | break; | ||
200 | default: | ||
201 | ret = -EINVAL; | ||
202 | dev_err(codec->dev, "Unrecognized PLL output freq (%d)\n", ret); | ||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | mutex_lock(&tscs42xx->pll_lock); | ||
207 | |||
208 | ret = snd_soc_update_bits(codec, R_PLLCTL1C, mask, val); | ||
209 | if (ret < 0) { | ||
210 | dev_err(codec->dev, "Failed to turn PLL on (%d)\n", ret); | ||
211 | goto exit; | ||
212 | } | ||
213 | |||
214 | if (!plls_locked(codec)) { | ||
215 | dev_err(codec->dev, "Failed to lock plls\n"); | ||
216 | ret = -ENOMSG; | ||
217 | goto exit; | ||
218 | } | ||
219 | |||
220 | ret = 0; | ||
221 | exit: | ||
222 | mutex_unlock(&tscs42xx->pll_lock); | ||
223 | |||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | static int power_down_audio_plls(struct snd_soc_codec *codec) | ||
228 | { | ||
229 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
230 | int ret; | ||
231 | |||
232 | mutex_lock(&tscs42xx->pll_lock); | ||
233 | |||
234 | ret = snd_soc_update_bits(codec, R_PLLCTL1C, | ||
235 | RM_PLLCTL1C_PDB_PLL1, | ||
236 | RV_PLLCTL1C_PDB_PLL1_DISABLE); | ||
237 | if (ret < 0) { | ||
238 | dev_err(codec->dev, "Failed to turn PLL off (%d)\n", ret); | ||
239 | goto exit; | ||
240 | } | ||
241 | ret = snd_soc_update_bits(codec, R_PLLCTL1C, | ||
242 | RM_PLLCTL1C_PDB_PLL2, | ||
243 | RV_PLLCTL1C_PDB_PLL2_DISABLE); | ||
244 | if (ret < 0) { | ||
245 | dev_err(codec->dev, "Failed to turn PLL off (%d)\n", ret); | ||
246 | goto exit; | ||
247 | } | ||
248 | |||
249 | ret = 0; | ||
250 | exit: | ||
251 | mutex_unlock(&tscs42xx->pll_lock); | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | static int coeff_ram_get(struct snd_kcontrol *kcontrol, | ||
257 | struct snd_ctl_elem_value *ucontrol) | ||
258 | { | ||
259 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
260 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
261 | struct coeff_ram_ctl *ctl = | ||
262 | (struct coeff_ram_ctl *)kcontrol->private_value; | ||
263 | struct soc_bytes_ext *params = &ctl->bytes_ext; | ||
264 | |||
265 | mutex_lock(&tscs42xx->coeff_ram_lock); | ||
266 | |||
267 | memcpy(ucontrol->value.bytes.data, | ||
268 | &tscs42xx->coeff_ram[ctl->addr * COEFF_SIZE], params->max); | ||
269 | |||
270 | mutex_unlock(&tscs42xx->coeff_ram_lock); | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | static int coeff_ram_put(struct snd_kcontrol *kcontrol, | ||
276 | struct snd_ctl_elem_value *ucontrol) | ||
277 | { | ||
278 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
279 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
280 | struct coeff_ram_ctl *ctl = | ||
281 | (struct coeff_ram_ctl *)kcontrol->private_value; | ||
282 | struct soc_bytes_ext *params = &ctl->bytes_ext; | ||
283 | unsigned int coeff_cnt = params->max / COEFF_SIZE; | ||
284 | int ret; | ||
285 | |||
286 | mutex_lock(&tscs42xx->coeff_ram_lock); | ||
287 | |||
288 | tscs42xx->coeff_ram_synced = false; | ||
289 | |||
290 | memcpy(&tscs42xx->coeff_ram[ctl->addr * COEFF_SIZE], | ||
291 | ucontrol->value.bytes.data, params->max); | ||
292 | |||
293 | mutex_lock(&tscs42xx->pll_lock); | ||
294 | |||
295 | if (plls_locked(codec)) { | ||
296 | ret = write_coeff_ram(codec, tscs42xx->coeff_ram, | ||
297 | ctl->addr, coeff_cnt); | ||
298 | if (ret < 0) { | ||
299 | dev_err(codec->dev, | ||
300 | "Failed to flush coeff ram cache (%d)\n", ret); | ||
301 | goto exit; | ||
302 | } | ||
303 | tscs42xx->coeff_ram_synced = true; | ||
304 | } | ||
305 | |||
306 | ret = 0; | ||
307 | exit: | ||
308 | mutex_unlock(&tscs42xx->pll_lock); | ||
309 | |||
310 | mutex_unlock(&tscs42xx->coeff_ram_lock); | ||
311 | |||
312 | return ret; | ||
313 | } | ||
314 | |||
315 | /* Input L Capture Route */ | ||
316 | static char const * const input_select_text[] = { | ||
317 | "Line 1", "Line 2", "Line 3", "D2S" | ||
318 | }; | ||
319 | |||
320 | static const struct soc_enum left_input_select_enum = | ||
321 | SOC_ENUM_SINGLE(R_INSELL, FB_INSELL, ARRAY_SIZE(input_select_text), | ||
322 | input_select_text); | ||
323 | |||
324 | static const struct snd_kcontrol_new left_input_select = | ||
325 | SOC_DAPM_ENUM("LEFT_INPUT_SELECT_ENUM", left_input_select_enum); | ||
326 | |||
327 | /* Input R Capture Route */ | ||
328 | static const struct soc_enum right_input_select_enum = | ||
329 | SOC_ENUM_SINGLE(R_INSELR, FB_INSELR, ARRAY_SIZE(input_select_text), | ||
330 | input_select_text); | ||
331 | |||
332 | static const struct snd_kcontrol_new right_input_select = | ||
333 | SOC_DAPM_ENUM("RIGHT_INPUT_SELECT_ENUM", right_input_select_enum); | ||
334 | |||
335 | /* Input Channel Mapping */ | ||
336 | static char const * const ch_map_select_text[] = { | ||
337 | "Normal", "Left to Right", "Right to Left", "Swap" | ||
338 | }; | ||
339 | |||
340 | static const struct soc_enum ch_map_select_enum = | ||
341 | SOC_ENUM_SINGLE(R_AIC2, FB_AIC2_ADCDSEL, ARRAY_SIZE(ch_map_select_text), | ||
342 | ch_map_select_text); | ||
343 | |||
344 | static int dapm_vref_event(struct snd_soc_dapm_widget *w, | ||
345 | struct snd_kcontrol *kcontrol, int event) | ||
346 | { | ||
347 | msleep(20); | ||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | static int dapm_micb_event(struct snd_soc_dapm_widget *w, | ||
352 | struct snd_kcontrol *kcontrol, int event) | ||
353 | { | ||
354 | msleep(20); | ||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static int pll_event(struct snd_soc_dapm_widget *w, | ||
359 | struct snd_kcontrol *kcontrol, int event) | ||
360 | { | ||
361 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
362 | int ret; | ||
363 | |||
364 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
365 | ret = power_up_audio_plls(codec); | ||
366 | else | ||
367 | ret = power_down_audio_plls(codec); | ||
368 | |||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static int dac_event(struct snd_soc_dapm_widget *w, | ||
373 | struct snd_kcontrol *kcontrol, int event) | ||
374 | { | ||
375 | struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); | ||
376 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
377 | int ret; | ||
378 | |||
379 | mutex_lock(&tscs42xx->coeff_ram_lock); | ||
380 | |||
381 | if (tscs42xx->coeff_ram_synced == false) { | ||
382 | ret = write_coeff_ram(codec, tscs42xx->coeff_ram, 0x00, | ||
383 | COEFF_RAM_COEFF_COUNT); | ||
384 | if (ret < 0) | ||
385 | goto exit; | ||
386 | tscs42xx->coeff_ram_synced = true; | ||
387 | } | ||
388 | |||
389 | ret = 0; | ||
390 | exit: | ||
391 | mutex_unlock(&tscs42xx->coeff_ram_lock); | ||
392 | |||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | static const struct snd_soc_dapm_widget tscs42xx_dapm_widgets[] = { | ||
397 | /* Vref */ | ||
398 | SND_SOC_DAPM_SUPPLY_S("Vref", 1, R_PWRM2, FB_PWRM2_VREF, 0, | ||
399 | dapm_vref_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD), | ||
400 | |||
401 | /* PLL */ | ||
402 | SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, pll_event, | ||
403 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
404 | |||
405 | /* Headphone */ | ||
406 | SND_SOC_DAPM_DAC_E("DAC L", "HiFi Playback", R_PWRM2, FB_PWRM2_HPL, 0, | ||
407 | dac_event, SND_SOC_DAPM_POST_PMU), | ||
408 | SND_SOC_DAPM_DAC_E("DAC R", "HiFi Playback", R_PWRM2, FB_PWRM2_HPR, 0, | ||
409 | dac_event, SND_SOC_DAPM_POST_PMU), | ||
410 | SND_SOC_DAPM_OUTPUT("Headphone L"), | ||
411 | SND_SOC_DAPM_OUTPUT("Headphone R"), | ||
412 | |||
413 | /* Speaker */ | ||
414 | SND_SOC_DAPM_DAC_E("ClassD L", "HiFi Playback", | ||
415 | R_PWRM2, FB_PWRM2_SPKL, 0, | ||
416 | dac_event, SND_SOC_DAPM_POST_PMU), | ||
417 | SND_SOC_DAPM_DAC_E("ClassD R", "HiFi Playback", | ||
418 | R_PWRM2, FB_PWRM2_SPKR, 0, | ||
419 | dac_event, SND_SOC_DAPM_POST_PMU), | ||
420 | SND_SOC_DAPM_OUTPUT("Speaker L"), | ||
421 | SND_SOC_DAPM_OUTPUT("Speaker R"), | ||
422 | |||
423 | /* Capture */ | ||
424 | SND_SOC_DAPM_PGA("Analog In PGA L", R_PWRM1, FB_PWRM1_PGAL, 0, NULL, 0), | ||
425 | SND_SOC_DAPM_PGA("Analog In PGA R", R_PWRM1, FB_PWRM1_PGAR, 0, NULL, 0), | ||
426 | SND_SOC_DAPM_PGA("Analog Boost L", R_PWRM1, FB_PWRM1_BSTL, 0, NULL, 0), | ||
427 | SND_SOC_DAPM_PGA("Analog Boost R", R_PWRM1, FB_PWRM1_BSTR, 0, NULL, 0), | ||
428 | SND_SOC_DAPM_PGA("ADC Mute", R_CNVRTR0, FB_CNVRTR0_HPOR, true, NULL, 0), | ||
429 | SND_SOC_DAPM_ADC("ADC L", "HiFi Capture", R_PWRM1, FB_PWRM1_ADCL, 0), | ||
430 | SND_SOC_DAPM_ADC("ADC R", "HiFi Capture", R_PWRM1, FB_PWRM1_ADCR, 0), | ||
431 | |||
432 | /* Capture Input */ | ||
433 | SND_SOC_DAPM_MUX("Input L Capture Route", R_PWRM2, | ||
434 | FB_PWRM2_INSELL, 0, &left_input_select), | ||
435 | SND_SOC_DAPM_MUX("Input R Capture Route", R_PWRM2, | ||
436 | FB_PWRM2_INSELR, 0, &right_input_select), | ||
437 | |||
438 | /* Digital Mic */ | ||
439 | SND_SOC_DAPM_SUPPLY_S("Digital Mic Enable", 2, R_DMICCTL, | ||
440 | FB_DMICCTL_DMICEN, 0, NULL, | ||
441 | SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD), | ||
442 | |||
443 | /* Analog Mic */ | ||
444 | SND_SOC_DAPM_SUPPLY_S("Mic Bias", 2, R_PWRM1, FB_PWRM1_MICB, | ||
445 | 0, dapm_micb_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD), | ||
446 | |||
447 | /* Line In */ | ||
448 | SND_SOC_DAPM_INPUT("Line In 1 L"), | ||
449 | SND_SOC_DAPM_INPUT("Line In 1 R"), | ||
450 | SND_SOC_DAPM_INPUT("Line In 2 L"), | ||
451 | SND_SOC_DAPM_INPUT("Line In 2 R"), | ||
452 | SND_SOC_DAPM_INPUT("Line In 3 L"), | ||
453 | SND_SOC_DAPM_INPUT("Line In 3 R"), | ||
454 | }; | ||
455 | |||
456 | static const struct snd_soc_dapm_route tscs42xx_intercon[] = { | ||
457 | {"DAC L", NULL, "PLL"}, | ||
458 | {"DAC R", NULL, "PLL"}, | ||
459 | {"DAC L", NULL, "Vref"}, | ||
460 | {"DAC R", NULL, "Vref"}, | ||
461 | {"Headphone L", NULL, "DAC L"}, | ||
462 | {"Headphone R", NULL, "DAC R"}, | ||
463 | |||
464 | {"ClassD L", NULL, "PLL"}, | ||
465 | {"ClassD R", NULL, "PLL"}, | ||
466 | {"ClassD L", NULL, "Vref"}, | ||
467 | {"ClassD R", NULL, "Vref"}, | ||
468 | {"Speaker L", NULL, "ClassD L"}, | ||
469 | {"Speaker R", NULL, "ClassD R"}, | ||
470 | |||
471 | {"Input L Capture Route", NULL, "Vref"}, | ||
472 | {"Input R Capture Route", NULL, "Vref"}, | ||
473 | |||
474 | {"Mic Bias", NULL, "Vref"}, | ||
475 | |||
476 | {"Input L Capture Route", "Line 1", "Line In 1 L"}, | ||
477 | {"Input R Capture Route", "Line 1", "Line In 1 R"}, | ||
478 | {"Input L Capture Route", "Line 2", "Line In 2 L"}, | ||
479 | {"Input R Capture Route", "Line 2", "Line In 2 R"}, | ||
480 | {"Input L Capture Route", "Line 3", "Line In 3 L"}, | ||
481 | {"Input R Capture Route", "Line 3", "Line In 3 R"}, | ||
482 | |||
483 | {"Analog In PGA L", NULL, "Input L Capture Route"}, | ||
484 | {"Analog In PGA R", NULL, "Input R Capture Route"}, | ||
485 | {"Analog Boost L", NULL, "Analog In PGA L"}, | ||
486 | {"Analog Boost R", NULL, "Analog In PGA R"}, | ||
487 | {"ADC Mute", NULL, "Analog Boost L"}, | ||
488 | {"ADC Mute", NULL, "Analog Boost R"}, | ||
489 | {"ADC L", NULL, "PLL"}, | ||
490 | {"ADC R", NULL, "PLL"}, | ||
491 | {"ADC L", NULL, "ADC Mute"}, | ||
492 | {"ADC R", NULL, "ADC Mute"}, | ||
493 | }; | ||
494 | |||
495 | /************ | ||
496 | * CONTROLS * | ||
497 | ************/ | ||
498 | |||
499 | static char const * const eq_band_enable_text[] = { | ||
500 | "Prescale only", | ||
501 | "Band1", | ||
502 | "Band1:2", | ||
503 | "Band1:3", | ||
504 | "Band1:4", | ||
505 | "Band1:5", | ||
506 | "Band1:6", | ||
507 | }; | ||
508 | |||
509 | static char const * const level_detection_text[] = { | ||
510 | "Average", | ||
511 | "Peak", | ||
512 | }; | ||
513 | |||
514 | static char const * const level_detection_window_text[] = { | ||
515 | "512 Samples", | ||
516 | "64 Samples", | ||
517 | }; | ||
518 | |||
519 | static char const * const compressor_ratio_text[] = { | ||
520 | "Reserved", "1.5:1", "2:1", "3:1", "4:1", "5:1", "6:1", | ||
521 | "7:1", "8:1", "9:1", "10:1", "11:1", "12:1", "13:1", "14:1", | ||
522 | "15:1", "16:1", "17:1", "18:1", "19:1", "20:1", | ||
523 | }; | ||
524 | |||
525 | static DECLARE_TLV_DB_SCALE(hpvol_scale, -8850, 75, 0); | ||
526 | static DECLARE_TLV_DB_SCALE(spkvol_scale, -7725, 75, 0); | ||
527 | static DECLARE_TLV_DB_SCALE(dacvol_scale, -9563, 38, 0); | ||
528 | static DECLARE_TLV_DB_SCALE(adcvol_scale, -7125, 38, 0); | ||
529 | static DECLARE_TLV_DB_SCALE(invol_scale, -1725, 75, 0); | ||
530 | static DECLARE_TLV_DB_SCALE(mic_boost_scale, 0, 1000, 0); | ||
531 | static DECLARE_TLV_DB_MINMAX(mugain_scale, 0, 4650); | ||
532 | static DECLARE_TLV_DB_MINMAX(compth_scale, -9562, 0); | ||
533 | |||
534 | static const struct soc_enum eq1_band_enable_enum = | ||
535 | SOC_ENUM_SINGLE(R_CONFIG1, FB_CONFIG1_EQ1_BE, | ||
536 | ARRAY_SIZE(eq_band_enable_text), eq_band_enable_text); | ||
537 | |||
538 | static const struct soc_enum eq2_band_enable_enum = | ||
539 | SOC_ENUM_SINGLE(R_CONFIG1, FB_CONFIG1_EQ2_BE, | ||
540 | ARRAY_SIZE(eq_band_enable_text), eq_band_enable_text); | ||
541 | |||
542 | static const struct soc_enum cle_level_detection_enum = | ||
543 | SOC_ENUM_SINGLE(R_CLECTL, FB_CLECTL_LVL_MODE, | ||
544 | ARRAY_SIZE(level_detection_text), | ||
545 | level_detection_text); | ||
546 | |||
547 | static const struct soc_enum cle_level_detection_window_enum = | ||
548 | SOC_ENUM_SINGLE(R_CLECTL, FB_CLECTL_WINDOWSEL, | ||
549 | ARRAY_SIZE(level_detection_window_text), | ||
550 | level_detection_window_text); | ||
551 | |||
552 | static const struct soc_enum mbc_level_detection_enums[] = { | ||
553 | SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_LVLMODE1, | ||
554 | ARRAY_SIZE(level_detection_text), | ||
555 | level_detection_text), | ||
556 | SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_LVLMODE2, | ||
557 | ARRAY_SIZE(level_detection_text), | ||
558 | level_detection_text), | ||
559 | SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_LVLMODE3, | ||
560 | ARRAY_SIZE(level_detection_text), | ||
561 | level_detection_text), | ||
562 | }; | ||
563 | |||
564 | static const struct soc_enum mbc_level_detection_window_enums[] = { | ||
565 | SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_WINSEL1, | ||
566 | ARRAY_SIZE(level_detection_window_text), | ||
567 | level_detection_window_text), | ||
568 | SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_WINSEL2, | ||
569 | ARRAY_SIZE(level_detection_window_text), | ||
570 | level_detection_window_text), | ||
571 | SOC_ENUM_SINGLE(R_DACMBCCTL, FB_DACMBCCTL_WINSEL3, | ||
572 | ARRAY_SIZE(level_detection_window_text), | ||
573 | level_detection_window_text), | ||
574 | }; | ||
575 | |||
576 | static const struct soc_enum compressor_ratio_enum = | ||
577 | SOC_ENUM_SINGLE(R_CMPRAT, FB_CMPRAT, | ||
578 | ARRAY_SIZE(compressor_ratio_text), compressor_ratio_text); | ||
579 | |||
580 | static const struct soc_enum dac_mbc1_compressor_ratio_enum = | ||
581 | SOC_ENUM_SINGLE(R_DACMBCRAT1, FB_DACMBCRAT1_RATIO, | ||
582 | ARRAY_SIZE(compressor_ratio_text), compressor_ratio_text); | ||
583 | |||
584 | static const struct soc_enum dac_mbc2_compressor_ratio_enum = | ||
585 | SOC_ENUM_SINGLE(R_DACMBCRAT2, FB_DACMBCRAT2_RATIO, | ||
586 | ARRAY_SIZE(compressor_ratio_text), compressor_ratio_text); | ||
587 | |||
588 | static const struct soc_enum dac_mbc3_compressor_ratio_enum = | ||
589 | SOC_ENUM_SINGLE(R_DACMBCRAT3, FB_DACMBCRAT3_RATIO, | ||
590 | ARRAY_SIZE(compressor_ratio_text), compressor_ratio_text); | ||
591 | |||
592 | static int bytes_info_ext(struct snd_kcontrol *kcontrol, | ||
593 | struct snd_ctl_elem_info *ucontrol) | ||
594 | { | ||
595 | struct coeff_ram_ctl *ctl = | ||
596 | (struct coeff_ram_ctl *)kcontrol->private_value; | ||
597 | struct soc_bytes_ext *params = &ctl->bytes_ext; | ||
598 | |||
599 | ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
600 | ucontrol->count = params->max; | ||
601 | |||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | #define COEFF_RAM_CTL(xname, xcount, xaddr) \ | ||
606 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
607 | .info = bytes_info_ext, \ | ||
608 | .get = coeff_ram_get, .put = coeff_ram_put, \ | ||
609 | .private_value = (unsigned long)&(struct coeff_ram_ctl) { \ | ||
610 | .addr = xaddr, \ | ||
611 | .bytes_ext = {.max = xcount, }, \ | ||
612 | } \ | ||
613 | } | ||
614 | |||
615 | static const struct snd_kcontrol_new tscs42xx_snd_controls[] = { | ||
616 | /* Volumes */ | ||
617 | SOC_DOUBLE_R_TLV("Headphone Playback Volume", R_HPVOLL, R_HPVOLR, | ||
618 | FB_HPVOLL, 0x7F, 0, hpvol_scale), | ||
619 | SOC_DOUBLE_R_TLV("Speaker Playback Volume", R_SPKVOLL, R_SPKVOLR, | ||
620 | FB_SPKVOLL, 0x7F, 0, spkvol_scale), | ||
621 | SOC_DOUBLE_R_TLV("Master Playback Volume", R_DACVOLL, R_DACVOLR, | ||
622 | FB_DACVOLL, 0xFF, 0, dacvol_scale), | ||
623 | SOC_DOUBLE_R_TLV("PCM Capture Volume", R_ADCVOLL, R_ADCVOLR, | ||
624 | FB_ADCVOLL, 0xFF, 0, adcvol_scale), | ||
625 | SOC_DOUBLE_R_TLV("Master Capture Volume", R_INVOLL, R_INVOLR, | ||
626 | FB_INVOLL, 0x3F, 0, invol_scale), | ||
627 | |||
628 | /* INSEL */ | ||
629 | SOC_DOUBLE_R_TLV("Mic Boost Capture Volume", R_INSELL, R_INSELR, | ||
630 | FB_INSELL_MICBSTL, FV_INSELL_MICBSTL_30DB, | ||
631 | 0, mic_boost_scale), | ||
632 | |||
633 | /* Input Channel Map */ | ||
634 | SOC_ENUM("Input Channel Map", ch_map_select_enum), | ||
635 | |||
636 | /* Coefficient Ram */ | ||
637 | COEFF_RAM_CTL("Cascade1L BiQuad1", BIQUAD_SIZE, 0x00), | ||
638 | COEFF_RAM_CTL("Cascade1L BiQuad2", BIQUAD_SIZE, 0x05), | ||
639 | COEFF_RAM_CTL("Cascade1L BiQuad3", BIQUAD_SIZE, 0x0a), | ||
640 | COEFF_RAM_CTL("Cascade1L BiQuad4", BIQUAD_SIZE, 0x0f), | ||
641 | COEFF_RAM_CTL("Cascade1L BiQuad5", BIQUAD_SIZE, 0x14), | ||
642 | COEFF_RAM_CTL("Cascade1L BiQuad6", BIQUAD_SIZE, 0x19), | ||
643 | |||
644 | COEFF_RAM_CTL("Cascade1R BiQuad1", BIQUAD_SIZE, 0x20), | ||
645 | COEFF_RAM_CTL("Cascade1R BiQuad2", BIQUAD_SIZE, 0x25), | ||
646 | COEFF_RAM_CTL("Cascade1R BiQuad3", BIQUAD_SIZE, 0x2a), | ||
647 | COEFF_RAM_CTL("Cascade1R BiQuad4", BIQUAD_SIZE, 0x2f), | ||
648 | COEFF_RAM_CTL("Cascade1R BiQuad5", BIQUAD_SIZE, 0x34), | ||
649 | COEFF_RAM_CTL("Cascade1R BiQuad6", BIQUAD_SIZE, 0x39), | ||
650 | |||
651 | COEFF_RAM_CTL("Cascade1L Prescale", COEFF_SIZE, 0x1f), | ||
652 | COEFF_RAM_CTL("Cascade1R Prescale", COEFF_SIZE, 0x3f), | ||
653 | |||
654 | COEFF_RAM_CTL("Cascade2L BiQuad1", BIQUAD_SIZE, 0x40), | ||
655 | COEFF_RAM_CTL("Cascade2L BiQuad2", BIQUAD_SIZE, 0x45), | ||
656 | COEFF_RAM_CTL("Cascade2L BiQuad3", BIQUAD_SIZE, 0x4a), | ||
657 | COEFF_RAM_CTL("Cascade2L BiQuad4", BIQUAD_SIZE, 0x4f), | ||
658 | COEFF_RAM_CTL("Cascade2L BiQuad5", BIQUAD_SIZE, 0x54), | ||
659 | COEFF_RAM_CTL("Cascade2L BiQuad6", BIQUAD_SIZE, 0x59), | ||
660 | |||
661 | COEFF_RAM_CTL("Cascade2R BiQuad1", BIQUAD_SIZE, 0x60), | ||
662 | COEFF_RAM_CTL("Cascade2R BiQuad2", BIQUAD_SIZE, 0x65), | ||
663 | COEFF_RAM_CTL("Cascade2R BiQuad3", BIQUAD_SIZE, 0x6a), | ||
664 | COEFF_RAM_CTL("Cascade2R BiQuad4", BIQUAD_SIZE, 0x6f), | ||
665 | COEFF_RAM_CTL("Cascade2R BiQuad5", BIQUAD_SIZE, 0x74), | ||
666 | COEFF_RAM_CTL("Cascade2R BiQuad6", BIQUAD_SIZE, 0x79), | ||
667 | |||
668 | COEFF_RAM_CTL("Cascade2L Prescale", COEFF_SIZE, 0x5f), | ||
669 | COEFF_RAM_CTL("Cascade2R Prescale", COEFF_SIZE, 0x7f), | ||
670 | |||
671 | COEFF_RAM_CTL("Bass Extraction BiQuad1", BIQUAD_SIZE, 0x80), | ||
672 | COEFF_RAM_CTL("Bass Extraction BiQuad2", BIQUAD_SIZE, 0x85), | ||
673 | |||
674 | COEFF_RAM_CTL("Bass Non Linear Function 1", COEFF_SIZE, 0x8a), | ||
675 | COEFF_RAM_CTL("Bass Non Linear Function 2", COEFF_SIZE, 0x8b), | ||
676 | |||
677 | COEFF_RAM_CTL("Bass Limiter BiQuad", BIQUAD_SIZE, 0x8c), | ||
678 | |||
679 | COEFF_RAM_CTL("Bass Cut Off BiQuad", BIQUAD_SIZE, 0x91), | ||
680 | |||
681 | COEFF_RAM_CTL("Bass Mix", COEFF_SIZE, 0x96), | ||
682 | |||
683 | COEFF_RAM_CTL("Treb Extraction BiQuad1", BIQUAD_SIZE, 0x97), | ||
684 | COEFF_RAM_CTL("Treb Extraction BiQuad2", BIQUAD_SIZE, 0x9c), | ||
685 | |||
686 | COEFF_RAM_CTL("Treb Non Linear Function 1", COEFF_SIZE, 0xa1), | ||
687 | COEFF_RAM_CTL("Treb Non Linear Function 2", COEFF_SIZE, 0xa2), | ||
688 | |||
689 | COEFF_RAM_CTL("Treb Limiter BiQuad", BIQUAD_SIZE, 0xa3), | ||
690 | |||
691 | COEFF_RAM_CTL("Treb Cut Off BiQuad", BIQUAD_SIZE, 0xa8), | ||
692 | |||
693 | COEFF_RAM_CTL("Treb Mix", COEFF_SIZE, 0xad), | ||
694 | |||
695 | COEFF_RAM_CTL("3D", COEFF_SIZE, 0xae), | ||
696 | |||
697 | COEFF_RAM_CTL("3D Mix", COEFF_SIZE, 0xaf), | ||
698 | |||
699 | COEFF_RAM_CTL("MBC1 BiQuad1", BIQUAD_SIZE, 0xb0), | ||
700 | COEFF_RAM_CTL("MBC1 BiQuad2", BIQUAD_SIZE, 0xb5), | ||
701 | |||
702 | COEFF_RAM_CTL("MBC2 BiQuad1", BIQUAD_SIZE, 0xba), | ||
703 | COEFF_RAM_CTL("MBC2 BiQuad2", BIQUAD_SIZE, 0xbf), | ||
704 | |||
705 | COEFF_RAM_CTL("MBC3 BiQuad1", BIQUAD_SIZE, 0xc4), | ||
706 | COEFF_RAM_CTL("MBC3 BiQuad2", BIQUAD_SIZE, 0xc9), | ||
707 | |||
708 | /* EQ */ | ||
709 | SOC_SINGLE("EQ1 Switch", R_CONFIG1, FB_CONFIG1_EQ1_EN, 1, 0), | ||
710 | SOC_SINGLE("EQ2 Switch", R_CONFIG1, FB_CONFIG1_EQ2_EN, 1, 0), | ||
711 | SOC_ENUM("EQ1 Band Enable", eq1_band_enable_enum), | ||
712 | SOC_ENUM("EQ2 Band Enable", eq2_band_enable_enum), | ||
713 | |||
714 | /* CLE */ | ||
715 | SOC_ENUM("CLE Level Detect", | ||
716 | cle_level_detection_enum), | ||
717 | SOC_ENUM("CLE Level Detect Win", | ||
718 | cle_level_detection_window_enum), | ||
719 | SOC_SINGLE("Expander Switch", | ||
720 | R_CLECTL, FB_CLECTL_EXP_EN, 1, 0), | ||
721 | SOC_SINGLE("Limiter Switch", | ||
722 | R_CLECTL, FB_CLECTL_LIMIT_EN, 1, 0), | ||
723 | SOC_SINGLE("Comp Switch", | ||
724 | R_CLECTL, FB_CLECTL_COMP_EN, 1, 0), | ||
725 | SOC_SINGLE_TLV("CLE Make-Up Gain Playback Volume", | ||
726 | R_MUGAIN, FB_MUGAIN_CLEMUG, 0x1f, 0, mugain_scale), | ||
727 | SOC_SINGLE_TLV("Comp Thresh Playback Volume", | ||
728 | R_COMPTH, FB_COMPTH, 0xff, 0, compth_scale), | ||
729 | SOC_ENUM("Comp Ratio", compressor_ratio_enum), | ||
730 | SND_SOC_BYTES("Comp Atk Time", R_CATKTCL, 2), | ||
731 | |||
732 | /* Effects */ | ||
733 | SOC_SINGLE("3D Switch", R_FXCTL, FB_FXCTL_3DEN, 1, 0), | ||
734 | SOC_SINGLE("Treble Switch", R_FXCTL, FB_FXCTL_TEEN, 1, 0), | ||
735 | SOC_SINGLE("Treble Bypass Switch", R_FXCTL, FB_FXCTL_TNLFBYPASS, 1, 0), | ||
736 | SOC_SINGLE("Bass Switch", R_FXCTL, FB_FXCTL_BEEN, 1, 0), | ||
737 | SOC_SINGLE("Bass Bypass Switch", R_FXCTL, FB_FXCTL_BNLFBYPASS, 1, 0), | ||
738 | |||
739 | /* MBC */ | ||
740 | SOC_SINGLE("MBC Band1 Switch", R_DACMBCEN, FB_DACMBCEN_MBCEN1, 1, 0), | ||
741 | SOC_SINGLE("MBC Band2 Switch", R_DACMBCEN, FB_DACMBCEN_MBCEN2, 1, 0), | ||
742 | SOC_SINGLE("MBC Band3 Switch", R_DACMBCEN, FB_DACMBCEN_MBCEN3, 1, 0), | ||
743 | SOC_ENUM("MBC Band1 Level Detect", | ||
744 | mbc_level_detection_enums[0]), | ||
745 | SOC_ENUM("MBC Band2 Level Detect", | ||
746 | mbc_level_detection_enums[1]), | ||
747 | SOC_ENUM("MBC Band3 Level Detect", | ||
748 | mbc_level_detection_enums[2]), | ||
749 | SOC_ENUM("MBC Band1 Level Detect Win", | ||
750 | mbc_level_detection_window_enums[0]), | ||
751 | SOC_ENUM("MBC Band2 Level Detect Win", | ||
752 | mbc_level_detection_window_enums[1]), | ||
753 | SOC_ENUM("MBC Band3 Level Detect Win", | ||
754 | mbc_level_detection_window_enums[2]), | ||
755 | |||
756 | SOC_SINGLE("MBC1 Phase Invert Switch", | ||
757 | R_DACMBCMUG1, FB_DACMBCMUG1_PHASE, 1, 0), | ||
758 | SOC_SINGLE_TLV("DAC MBC1 Make-Up Gain Playback Volume", | ||
759 | R_DACMBCMUG1, FB_DACMBCMUG1_MUGAIN, 0x1f, 0, mugain_scale), | ||
760 | SOC_SINGLE_TLV("DAC MBC1 Comp Thresh Playback Volume", | ||
761 | R_DACMBCTHR1, FB_DACMBCTHR1_THRESH, 0xff, 0, compth_scale), | ||
762 | SOC_ENUM("DAC MBC1 Comp Ratio", | ||
763 | dac_mbc1_compressor_ratio_enum), | ||
764 | SND_SOC_BYTES("DAC MBC1 Comp Atk Time", R_DACMBCATK1L, 2), | ||
765 | SND_SOC_BYTES("DAC MBC1 Comp Rel Time Const", | ||
766 | R_DACMBCREL1L, 2), | ||
767 | |||
768 | SOC_SINGLE("MBC2 Phase Invert Switch", | ||
769 | R_DACMBCMUG2, FB_DACMBCMUG2_PHASE, 1, 0), | ||
770 | SOC_SINGLE_TLV("DAC MBC2 Make-Up Gain Playback Volume", | ||
771 | R_DACMBCMUG2, FB_DACMBCMUG2_MUGAIN, 0x1f, 0, mugain_scale), | ||
772 | SOC_SINGLE_TLV("DAC MBC2 Comp Thresh Playback Volume", | ||
773 | R_DACMBCTHR2, FB_DACMBCTHR2_THRESH, 0xff, 0, compth_scale), | ||
774 | SOC_ENUM("DAC MBC2 Comp Ratio", | ||
775 | dac_mbc2_compressor_ratio_enum), | ||
776 | SND_SOC_BYTES("DAC MBC2 Comp Atk Time", R_DACMBCATK2L, 2), | ||
777 | SND_SOC_BYTES("DAC MBC2 Comp Rel Time Const", | ||
778 | R_DACMBCREL2L, 2), | ||
779 | |||
780 | SOC_SINGLE("MBC3 Phase Invert Switch", | ||
781 | R_DACMBCMUG3, FB_DACMBCMUG3_PHASE, 1, 0), | ||
782 | SOC_SINGLE_TLV("DAC MBC3 Make-Up Gain Playback Volume", | ||
783 | R_DACMBCMUG3, FB_DACMBCMUG3_MUGAIN, 0x1f, 0, mugain_scale), | ||
784 | SOC_SINGLE_TLV("DAC MBC3 Comp Thresh Playback Volume", | ||
785 | R_DACMBCTHR3, FB_DACMBCTHR3_THRESH, 0xff, 0, compth_scale), | ||
786 | SOC_ENUM("DAC MBC3 Comp Ratio", | ||
787 | dac_mbc3_compressor_ratio_enum), | ||
788 | SND_SOC_BYTES("DAC MBC3 Comp Atk Time", R_DACMBCATK3L, 2), | ||
789 | SND_SOC_BYTES("DAC MBC3 Comp Rel Time Const", | ||
790 | R_DACMBCREL3L, 2), | ||
791 | }; | ||
792 | |||
793 | static int setup_sample_format(struct snd_soc_codec *codec, | ||
794 | snd_pcm_format_t format) | ||
795 | { | ||
796 | unsigned int width; | ||
797 | int ret; | ||
798 | |||
799 | switch (format) { | ||
800 | case SNDRV_PCM_FORMAT_S16_LE: | ||
801 | width = RV_AIC1_WL_16; | ||
802 | break; | ||
803 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
804 | width = RV_AIC1_WL_20; | ||
805 | break; | ||
806 | case SNDRV_PCM_FORMAT_S24_LE: | ||
807 | width = RV_AIC1_WL_24; | ||
808 | break; | ||
809 | case SNDRV_PCM_FORMAT_S32_LE: | ||
810 | width = RV_AIC1_WL_32; | ||
811 | break; | ||
812 | default: | ||
813 | ret = -EINVAL; | ||
814 | dev_err(codec->dev, "Unsupported format width (%d)\n", ret); | ||
815 | return ret; | ||
816 | } | ||
817 | ret = snd_soc_update_bits(codec, R_AIC1, RM_AIC1_WL, width); | ||
818 | if (ret < 0) { | ||
819 | dev_err(codec->dev, "Failed to set sample width (%d)\n", ret); | ||
820 | return ret; | ||
821 | } | ||
822 | |||
823 | return 0; | ||
824 | } | ||
825 | |||
826 | static int setup_sample_rate(struct snd_soc_codec *codec, unsigned int rate) | ||
827 | { | ||
828 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
829 | unsigned int br, bm; | ||
830 | int ret; | ||
831 | |||
832 | switch (rate) { | ||
833 | case 8000: | ||
834 | br = RV_DACSR_DBR_32; | ||
835 | bm = RV_DACSR_DBM_PT25; | ||
836 | break; | ||
837 | case 16000: | ||
838 | br = RV_DACSR_DBR_32; | ||
839 | bm = RV_DACSR_DBM_PT5; | ||
840 | break; | ||
841 | case 24000: | ||
842 | br = RV_DACSR_DBR_48; | ||
843 | bm = RV_DACSR_DBM_PT5; | ||
844 | break; | ||
845 | case 32000: | ||
846 | br = RV_DACSR_DBR_32; | ||
847 | bm = RV_DACSR_DBM_1; | ||
848 | break; | ||
849 | case 48000: | ||
850 | br = RV_DACSR_DBR_48; | ||
851 | bm = RV_DACSR_DBM_1; | ||
852 | break; | ||
853 | case 96000: | ||
854 | br = RV_DACSR_DBR_48; | ||
855 | bm = RV_DACSR_DBM_2; | ||
856 | break; | ||
857 | case 11025: | ||
858 | br = RV_DACSR_DBR_44_1; | ||
859 | bm = RV_DACSR_DBM_PT25; | ||
860 | break; | ||
861 | case 22050: | ||
862 | br = RV_DACSR_DBR_44_1; | ||
863 | bm = RV_DACSR_DBM_PT5; | ||
864 | break; | ||
865 | case 44100: | ||
866 | br = RV_DACSR_DBR_44_1; | ||
867 | bm = RV_DACSR_DBM_1; | ||
868 | break; | ||
869 | case 88200: | ||
870 | br = RV_DACSR_DBR_44_1; | ||
871 | bm = RV_DACSR_DBM_2; | ||
872 | break; | ||
873 | default: | ||
874 | dev_err(codec->dev, "Unsupported sample rate %d\n", rate); | ||
875 | return -EINVAL; | ||
876 | } | ||
877 | |||
878 | /* DAC and ADC share bit and frame clock */ | ||
879 | ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBR, br); | ||
880 | if (ret < 0) { | ||
881 | dev_err(codec->dev, "Failed to update register (%d)\n", ret); | ||
882 | return ret; | ||
883 | } | ||
884 | ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBM, bm); | ||
885 | if (ret < 0) { | ||
886 | dev_err(codec->dev, "Failed to update register (%d)\n", ret); | ||
887 | return ret; | ||
888 | } | ||
889 | ret = snd_soc_update_bits(codec, R_ADCSR, RM_DACSR_DBR, br); | ||
890 | if (ret < 0) { | ||
891 | dev_err(codec->dev, "Failed to update register (%d)\n", ret); | ||
892 | return ret; | ||
893 | } | ||
894 | ret = snd_soc_update_bits(codec, R_ADCSR, RM_DACSR_DBM, bm); | ||
895 | if (ret < 0) { | ||
896 | dev_err(codec->dev, "Failed to update register (%d)\n", ret); | ||
897 | return ret; | ||
898 | } | ||
899 | |||
900 | mutex_lock(&tscs42xx->audio_params_lock); | ||
901 | |||
902 | tscs42xx->samplerate = rate; | ||
903 | |||
904 | mutex_unlock(&tscs42xx->audio_params_lock); | ||
905 | |||
906 | return 0; | ||
907 | } | ||
908 | |||
909 | struct reg_setting { | ||
910 | unsigned int addr; | ||
911 | unsigned int val; | ||
912 | unsigned int mask; | ||
913 | }; | ||
914 | |||
915 | #define PLL_REG_SETTINGS_COUNT 13 | ||
916 | struct pll_ctl { | ||
917 | int input_freq; | ||
918 | struct reg_setting settings[PLL_REG_SETTINGS_COUNT]; | ||
919 | }; | ||
920 | |||
921 | #define PLL_CTL(f, rt, rd, r1b_l, r9, ra, rb, \ | ||
922 | rc, r12, r1b_h, re, rf, r10, r11) \ | ||
923 | { \ | ||
924 | .input_freq = f, \ | ||
925 | .settings = { \ | ||
926 | {R_TIMEBASE, rt, 0xFF}, \ | ||
927 | {R_PLLCTLD, rd, 0xFF}, \ | ||
928 | {R_PLLCTL1B, r1b_l, 0x0F}, \ | ||
929 | {R_PLLCTL9, r9, 0xFF}, \ | ||
930 | {R_PLLCTLA, ra, 0xFF}, \ | ||
931 | {R_PLLCTLB, rb, 0xFF}, \ | ||
932 | {R_PLLCTLC, rc, 0xFF}, \ | ||
933 | {R_PLLCTL12, r12, 0xFF}, \ | ||
934 | {R_PLLCTL1B, r1b_h, 0xF0}, \ | ||
935 | {R_PLLCTLE, re, 0xFF}, \ | ||
936 | {R_PLLCTLF, rf, 0xFF}, \ | ||
937 | {R_PLLCTL10, r10, 0xFF}, \ | ||
938 | {R_PLLCTL11, r11, 0xFF}, \ | ||
939 | }, \ | ||
940 | } | ||
941 | |||
942 | static const struct pll_ctl pll_ctls[] = { | ||
943 | PLL_CTL(1411200, 0x05, | ||
944 | 0x39, 0x04, 0x07, 0x02, 0xC3, 0x04, | ||
945 | 0x1B, 0x10, 0x03, 0x03, 0xD0, 0x02), | ||
946 | PLL_CTL(1536000, 0x05, | ||
947 | 0x1A, 0x04, 0x02, 0x03, 0xE0, 0x01, | ||
948 | 0x1A, 0x10, 0x02, 0x03, 0xB9, 0x01), | ||
949 | PLL_CTL(2822400, 0x0A, | ||
950 | 0x23, 0x04, 0x07, 0x04, 0xC3, 0x04, | ||
951 | 0x22, 0x10, 0x05, 0x03, 0x58, 0x02), | ||
952 | PLL_CTL(3072000, 0x0B, | ||
953 | 0x22, 0x04, 0x07, 0x03, 0x48, 0x03, | ||
954 | 0x1A, 0x10, 0x04, 0x03, 0xB9, 0x01), | ||
955 | PLL_CTL(5644800, 0x15, | ||
956 | 0x23, 0x04, 0x0E, 0x04, 0xC3, 0x04, | ||
957 | 0x1A, 0x10, 0x08, 0x03, 0xE0, 0x01), | ||
958 | PLL_CTL(6144000, 0x17, | ||
959 | 0x1A, 0x04, 0x08, 0x03, 0xE0, 0x01, | ||
960 | 0x1A, 0x10, 0x08, 0x03, 0xB9, 0x01), | ||
961 | PLL_CTL(12000000, 0x2E, | ||
962 | 0x1B, 0x04, 0x19, 0x03, 0x00, 0x03, | ||
963 | 0x2A, 0x10, 0x19, 0x05, 0x98, 0x04), | ||
964 | PLL_CTL(19200000, 0x4A, | ||
965 | 0x13, 0x04, 0x14, 0x03, 0x80, 0x01, | ||
966 | 0x1A, 0x10, 0x19, 0x03, 0xB9, 0x01), | ||
967 | PLL_CTL(22000000, 0x55, | ||
968 | 0x2A, 0x04, 0x37, 0x05, 0x00, 0x06, | ||
969 | 0x22, 0x10, 0x26, 0x03, 0x49, 0x02), | ||
970 | PLL_CTL(22579200, 0x57, | ||
971 | 0x22, 0x04, 0x31, 0x03, 0x20, 0x03, | ||
972 | 0x1A, 0x10, 0x1D, 0x03, 0xB3, 0x01), | ||
973 | PLL_CTL(24000000, 0x5D, | ||
974 | 0x13, 0x04, 0x19, 0x03, 0x80, 0x01, | ||
975 | 0x1B, 0x10, 0x19, 0x05, 0x4C, 0x02), | ||
976 | PLL_CTL(24576000, 0x5F, | ||
977 | 0x13, 0x04, 0x1D, 0x03, 0xB3, 0x01, | ||
978 | 0x22, 0x10, 0x40, 0x03, 0x72, 0x03), | ||
979 | PLL_CTL(27000000, 0x68, | ||
980 | 0x22, 0x04, 0x4B, 0x03, 0x00, 0x04, | ||
981 | 0x2A, 0x10, 0x7D, 0x03, 0x20, 0x06), | ||
982 | PLL_CTL(36000000, 0x8C, | ||
983 | 0x1B, 0x04, 0x4B, 0x03, 0x00, 0x03, | ||
984 | 0x2A, 0x10, 0x7D, 0x03, 0x98, 0x04), | ||
985 | PLL_CTL(25000000, 0x61, | ||
986 | 0x1B, 0x04, 0x37, 0x03, 0x2B, 0x03, | ||
987 | 0x1A, 0x10, 0x2A, 0x03, 0x39, 0x02), | ||
988 | PLL_CTL(26000000, 0x65, | ||
989 | 0x23, 0x04, 0x41, 0x05, 0x00, 0x06, | ||
990 | 0x1A, 0x10, 0x26, 0x03, 0xEF, 0x01), | ||
991 | PLL_CTL(12288000, 0x2F, | ||
992 | 0x1A, 0x04, 0x12, 0x03, 0x1C, 0x02, | ||
993 | 0x22, 0x10, 0x20, 0x03, 0x72, 0x03), | ||
994 | PLL_CTL(40000000, 0x9B, | ||
995 | 0x22, 0x08, 0x7D, 0x03, 0x80, 0x04, | ||
996 | 0x23, 0x10, 0x7D, 0x05, 0xE4, 0x06), | ||
997 | PLL_CTL(512000, 0x01, | ||
998 | 0x22, 0x04, 0x01, 0x03, 0xD0, 0x02, | ||
999 | 0x1B, 0x10, 0x01, 0x04, 0x72, 0x03), | ||
1000 | PLL_CTL(705600, 0x02, | ||
1001 | 0x22, 0x04, 0x02, 0x03, 0x15, 0x04, | ||
1002 | 0x22, 0x10, 0x01, 0x04, 0x80, 0x02), | ||
1003 | PLL_CTL(1024000, 0x03, | ||
1004 | 0x22, 0x04, 0x02, 0x03, 0xD0, 0x02, | ||
1005 | 0x1B, 0x10, 0x02, 0x04, 0x72, 0x03), | ||
1006 | PLL_CTL(2048000, 0x07, | ||
1007 | 0x22, 0x04, 0x04, 0x03, 0xD0, 0x02, | ||
1008 | 0x1B, 0x10, 0x04, 0x04, 0x72, 0x03), | ||
1009 | PLL_CTL(2400000, 0x08, | ||
1010 | 0x22, 0x04, 0x05, 0x03, 0x00, 0x03, | ||
1011 | 0x23, 0x10, 0x05, 0x05, 0x98, 0x04), | ||
1012 | }; | ||
1013 | |||
1014 | static const struct pll_ctl *get_pll_ctl(int input_freq) | ||
1015 | { | ||
1016 | int i; | ||
1017 | const struct pll_ctl *pll_ctl = NULL; | ||
1018 | |||
1019 | for (i = 0; i < ARRAY_SIZE(pll_ctls); ++i) | ||
1020 | if (input_freq == pll_ctls[i].input_freq) { | ||
1021 | pll_ctl = &pll_ctls[i]; | ||
1022 | break; | ||
1023 | } | ||
1024 | |||
1025 | return pll_ctl; | ||
1026 | } | ||
1027 | |||
1028 | static int set_pll_ctl_from_input_freq(struct snd_soc_codec *codec, | ||
1029 | const int input_freq) | ||
1030 | { | ||
1031 | int ret; | ||
1032 | int i; | ||
1033 | const struct pll_ctl *pll_ctl; | ||
1034 | |||
1035 | pll_ctl = get_pll_ctl(input_freq); | ||
1036 | if (!pll_ctl) { | ||
1037 | ret = -EINVAL; | ||
1038 | dev_err(codec->dev, "No PLL input entry for %d (%d)\n", | ||
1039 | input_freq, ret); | ||
1040 | return ret; | ||
1041 | } | ||
1042 | |||
1043 | for (i = 0; i < PLL_REG_SETTINGS_COUNT; ++i) { | ||
1044 | ret = snd_soc_update_bits(codec, | ||
1045 | pll_ctl->settings[i].addr, | ||
1046 | pll_ctl->settings[i].mask, | ||
1047 | pll_ctl->settings[i].val); | ||
1048 | if (ret < 0) { | ||
1049 | dev_err(codec->dev, "Failed to set pll ctl (%d)\n", | ||
1050 | ret); | ||
1051 | return ret; | ||
1052 | } | ||
1053 | } | ||
1054 | |||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | static int tscs42xx_hw_params(struct snd_pcm_substream *substream, | ||
1059 | struct snd_pcm_hw_params *params, | ||
1060 | struct snd_soc_dai *codec_dai) | ||
1061 | { | ||
1062 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1063 | int ret; | ||
1064 | |||
1065 | ret = setup_sample_format(codec, params_format(params)); | ||
1066 | if (ret < 0) { | ||
1067 | dev_err(codec->dev, "Failed to setup sample format (%d)\n", | ||
1068 | ret); | ||
1069 | return ret; | ||
1070 | } | ||
1071 | |||
1072 | ret = setup_sample_rate(codec, params_rate(params)); | ||
1073 | if (ret < 0) { | ||
1074 | dev_err(codec->dev, "Failed to setup sample rate (%d)\n", ret); | ||
1075 | return ret; | ||
1076 | } | ||
1077 | |||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | static inline int dac_mute(struct snd_soc_codec *codec) | ||
1082 | { | ||
1083 | int ret; | ||
1084 | |||
1085 | ret = snd_soc_update_bits(codec, R_CNVRTR1, RM_CNVRTR1_DACMU, | ||
1086 | RV_CNVRTR1_DACMU_ENABLE); | ||
1087 | if (ret < 0) { | ||
1088 | dev_err(codec->dev, "Failed to mute DAC (%d)\n", | ||
1089 | ret); | ||
1090 | return ret; | ||
1091 | } | ||
1092 | |||
1093 | return 0; | ||
1094 | } | ||
1095 | |||
1096 | static inline int dac_unmute(struct snd_soc_codec *codec) | ||
1097 | { | ||
1098 | int ret; | ||
1099 | |||
1100 | ret = snd_soc_update_bits(codec, R_CNVRTR1, RM_CNVRTR1_DACMU, | ||
1101 | RV_CNVRTR1_DACMU_DISABLE); | ||
1102 | if (ret < 0) { | ||
1103 | dev_err(codec->dev, "Failed to unmute DAC (%d)\n", | ||
1104 | ret); | ||
1105 | return ret; | ||
1106 | } | ||
1107 | |||
1108 | return 0; | ||
1109 | } | ||
1110 | |||
1111 | static inline int adc_mute(struct snd_soc_codec *codec) | ||
1112 | { | ||
1113 | int ret; | ||
1114 | |||
1115 | ret = snd_soc_update_bits(codec, R_CNVRTR0, RM_CNVRTR0_ADCMU, | ||
1116 | RV_CNVRTR0_ADCMU_ENABLE); | ||
1117 | if (ret < 0) { | ||
1118 | dev_err(codec->dev, "Failed to mute ADC (%d)\n", | ||
1119 | ret); | ||
1120 | return ret; | ||
1121 | } | ||
1122 | |||
1123 | return 0; | ||
1124 | } | ||
1125 | |||
1126 | static inline int adc_unmute(struct snd_soc_codec *codec) | ||
1127 | { | ||
1128 | int ret; | ||
1129 | |||
1130 | ret = snd_soc_update_bits(codec, R_CNVRTR0, RM_CNVRTR0_ADCMU, | ||
1131 | RV_CNVRTR0_ADCMU_DISABLE); | ||
1132 | if (ret < 0) { | ||
1133 | dev_err(codec->dev, "Failed to unmute ADC (%d)\n", | ||
1134 | ret); | ||
1135 | return ret; | ||
1136 | } | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | |||
1141 | static int tscs42xx_mute_stream(struct snd_soc_dai *dai, int mute, int stream) | ||
1142 | { | ||
1143 | struct snd_soc_codec *codec = dai->codec; | ||
1144 | int ret; | ||
1145 | |||
1146 | if (mute) | ||
1147 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1148 | ret = dac_mute(codec); | ||
1149 | else | ||
1150 | ret = adc_mute(codec); | ||
1151 | else | ||
1152 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1153 | ret = dac_unmute(codec); | ||
1154 | else | ||
1155 | ret = adc_unmute(codec); | ||
1156 | |||
1157 | return ret; | ||
1158 | } | ||
1159 | |||
1160 | static int tscs42xx_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
1161 | unsigned int fmt) | ||
1162 | { | ||
1163 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1164 | int ret; | ||
1165 | |||
1166 | /* Slave mode not supported since it needs always-on frame clock */ | ||
1167 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1168 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1169 | ret = snd_soc_update_bits(codec, R_AIC1, RM_AIC1_MS, | ||
1170 | RV_AIC1_MS_MASTER); | ||
1171 | if (ret < 0) { | ||
1172 | dev_err(codec->dev, | ||
1173 | "Failed to set codec DAI master (%d)\n", ret); | ||
1174 | return ret; | ||
1175 | } | ||
1176 | break; | ||
1177 | default: | ||
1178 | ret = -EINVAL; | ||
1179 | dev_err(codec->dev, "Unsupported format (%d)\n", ret); | ||
1180 | return ret; | ||
1181 | } | ||
1182 | |||
1183 | return 0; | ||
1184 | } | ||
1185 | |||
1186 | static int tscs42xx_set_dai_bclk_ratio(struct snd_soc_dai *codec_dai, | ||
1187 | unsigned int ratio) | ||
1188 | { | ||
1189 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1190 | struct tscs42xx *tscs42xx = snd_soc_codec_get_drvdata(codec); | ||
1191 | unsigned int value; | ||
1192 | int ret = 0; | ||
1193 | |||
1194 | switch (ratio) { | ||
1195 | case 32: | ||
1196 | value = RV_DACSR_DBCM_32; | ||
1197 | break; | ||
1198 | case 40: | ||
1199 | value = RV_DACSR_DBCM_40; | ||
1200 | break; | ||
1201 | case 64: | ||
1202 | value = RV_DACSR_DBCM_64; | ||
1203 | break; | ||
1204 | default: | ||
1205 | dev_err(codec->dev, "Unsupported bclk ratio (%d)\n", ret); | ||
1206 | return -EINVAL; | ||
1207 | } | ||
1208 | |||
1209 | ret = snd_soc_update_bits(codec, R_DACSR, RM_DACSR_DBCM, value); | ||
1210 | if (ret < 0) { | ||
1211 | dev_err(codec->dev, "Failed to set DAC BCLK ratio (%d)\n", ret); | ||
1212 | return ret; | ||
1213 | } | ||
1214 | ret = snd_soc_update_bits(codec, R_ADCSR, RM_ADCSR_ABCM, value); | ||
1215 | if (ret < 0) { | ||
1216 | dev_err(codec->dev, "Failed to set ADC BCLK ratio (%d)\n", ret); | ||
1217 | return ret; | ||
1218 | } | ||
1219 | |||
1220 | mutex_lock(&tscs42xx->audio_params_lock); | ||
1221 | |||
1222 | tscs42xx->bclk_ratio = ratio; | ||
1223 | |||
1224 | mutex_unlock(&tscs42xx->audio_params_lock); | ||
1225 | |||
1226 | return 0; | ||
1227 | } | ||
1228 | |||
1229 | static int tscs42xx_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
1230 | int clk_id, unsigned int freq, int dir) | ||
1231 | { | ||
1232 | struct snd_soc_codec *codec = codec_dai->codec; | ||
1233 | int ret; | ||
1234 | |||
1235 | switch (clk_id) { | ||
1236 | case TSCS42XX_PLL_SRC_XTAL: | ||
1237 | case TSCS42XX_PLL_SRC_MCLK1: | ||
1238 | ret = snd_soc_write(codec, R_PLLREFSEL, | ||
1239 | RV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 | | ||
1240 | RV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1); | ||
1241 | if (ret < 0) { | ||
1242 | dev_err(codec->dev, | ||
1243 | "Failed to set pll reference input (%d)\n", | ||
1244 | ret); | ||
1245 | return ret; | ||
1246 | } | ||
1247 | break; | ||
1248 | case TSCS42XX_PLL_SRC_MCLK2: | ||
1249 | ret = snd_soc_write(codec, R_PLLREFSEL, | ||
1250 | RV_PLLREFSEL_PLL1_REF_SEL_MCLK2 | | ||
1251 | RV_PLLREFSEL_PLL2_REF_SEL_MCLK2); | ||
1252 | if (ret < 0) { | ||
1253 | dev_err(codec->dev, | ||
1254 | "Failed to set PLL reference (%d)\n", ret); | ||
1255 | return ret; | ||
1256 | } | ||
1257 | break; | ||
1258 | default: | ||
1259 | dev_err(codec->dev, "pll src is unsupported\n"); | ||
1260 | return -EINVAL; | ||
1261 | } | ||
1262 | |||
1263 | ret = set_pll_ctl_from_input_freq(codec, freq); | ||
1264 | if (ret < 0) { | ||
1265 | dev_err(codec->dev, | ||
1266 | "Failed to setup PLL input freq (%d)\n", ret); | ||
1267 | return ret; | ||
1268 | } | ||
1269 | |||
1270 | return 0; | ||
1271 | } | ||
1272 | |||
1273 | static const struct snd_soc_dai_ops tscs42xx_dai_ops = { | ||
1274 | .hw_params = tscs42xx_hw_params, | ||
1275 | .mute_stream = tscs42xx_mute_stream, | ||
1276 | .set_fmt = tscs42xx_set_dai_fmt, | ||
1277 | .set_bclk_ratio = tscs42xx_set_dai_bclk_ratio, | ||
1278 | .set_sysclk = tscs42xx_set_dai_sysclk, | ||
1279 | }; | ||
1280 | |||
1281 | static int part_is_valid(struct tscs42xx *tscs42xx) | ||
1282 | { | ||
1283 | int val; | ||
1284 | int ret; | ||
1285 | unsigned int reg; | ||
1286 | |||
1287 | ret = regmap_read(tscs42xx->regmap, R_DEVIDH, ®); | ||
1288 | if (ret < 0) | ||
1289 | return ret; | ||
1290 | |||
1291 | val = reg << 8; | ||
1292 | ret = regmap_read(tscs42xx->regmap, R_DEVIDL, ®); | ||
1293 | if (ret < 0) | ||
1294 | return ret; | ||
1295 | |||
1296 | val |= reg; | ||
1297 | |||
1298 | switch (val) { | ||
1299 | case 0x4A74: | ||
1300 | case 0x4A73: | ||
1301 | return true; | ||
1302 | default: | ||
1303 | return false; | ||
1304 | }; | ||
1305 | } | ||
1306 | |||
1307 | static struct snd_soc_codec_driver soc_codec_dev_tscs42xx = { | ||
1308 | .component_driver = { | ||
1309 | .dapm_widgets = tscs42xx_dapm_widgets, | ||
1310 | .num_dapm_widgets = ARRAY_SIZE(tscs42xx_dapm_widgets), | ||
1311 | .dapm_routes = tscs42xx_intercon, | ||
1312 | .num_dapm_routes = ARRAY_SIZE(tscs42xx_intercon), | ||
1313 | .controls = tscs42xx_snd_controls, | ||
1314 | .num_controls = ARRAY_SIZE(tscs42xx_snd_controls), | ||
1315 | }, | ||
1316 | }; | ||
1317 | |||
1318 | static inline void init_coeff_ram_cache(struct tscs42xx *tscs42xx) | ||
1319 | { | ||
1320 | const u8 norm_addrs[] = { 0x00, 0x05, 0x0a, 0x0f, 0x14, 0x19, 0x1f, | ||
1321 | 0x20, 0x25, 0x2a, 0x2f, 0x34, 0x39, 0x3f, 0x40, 0x45, 0x4a, | ||
1322 | 0x4f, 0x54, 0x59, 0x5f, 0x60, 0x65, 0x6a, 0x6f, 0x74, 0x79, | ||
1323 | 0x7f, 0x80, 0x85, 0x8c, 0x91, 0x96, 0x97, 0x9c, 0xa3, 0xa8, | ||
1324 | 0xad, 0xaf, 0xb0, 0xb5, 0xba, 0xbf, 0xc4, 0xc9, }; | ||
1325 | u8 *coeff_ram = tscs42xx->coeff_ram; | ||
1326 | int i; | ||
1327 | |||
1328 | for (i = 0; i < ARRAY_SIZE(norm_addrs); i++) | ||
1329 | coeff_ram[((norm_addrs[i] + 1) * COEFF_SIZE) - 1] = 0x40; | ||
1330 | } | ||
1331 | |||
1332 | #define TSCS42XX_RATES SNDRV_PCM_RATE_8000_96000 | ||
1333 | |||
1334 | #define TSCS42XX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ | ||
1335 | | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
1336 | |||
1337 | static struct snd_soc_dai_driver tscs42xx_dai = { | ||
1338 | .name = "tscs42xx-HiFi", | ||
1339 | .playback = { | ||
1340 | .stream_name = "HiFi Playback", | ||
1341 | .channels_min = 2, | ||
1342 | .channels_max = 2, | ||
1343 | .rates = TSCS42XX_RATES, | ||
1344 | .formats = TSCS42XX_FORMATS,}, | ||
1345 | .capture = { | ||
1346 | .stream_name = "HiFi Capture", | ||
1347 | .channels_min = 2, | ||
1348 | .channels_max = 2, | ||
1349 | .rates = TSCS42XX_RATES, | ||
1350 | .formats = TSCS42XX_FORMATS,}, | ||
1351 | .ops = &tscs42xx_dai_ops, | ||
1352 | .symmetric_rates = 1, | ||
1353 | .symmetric_channels = 1, | ||
1354 | .symmetric_samplebits = 1, | ||
1355 | }; | ||
1356 | |||
1357 | static const struct reg_sequence tscs42xx_patch[] = { | ||
1358 | { R_AIC2, RV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED }, | ||
1359 | }; | ||
1360 | |||
1361 | static int tscs42xx_i2c_probe(struct i2c_client *i2c, | ||
1362 | const struct i2c_device_id *id) | ||
1363 | { | ||
1364 | struct tscs42xx *tscs42xx; | ||
1365 | int ret = 0; | ||
1366 | |||
1367 | tscs42xx = devm_kzalloc(&i2c->dev, sizeof(*tscs42xx), GFP_KERNEL); | ||
1368 | if (!tscs42xx) { | ||
1369 | ret = -ENOMEM; | ||
1370 | dev_err(&i2c->dev, | ||
1371 | "Failed to allocate memory for data (%d)\n", ret); | ||
1372 | return ret; | ||
1373 | } | ||
1374 | i2c_set_clientdata(i2c, tscs42xx); | ||
1375 | tscs42xx->dev = &i2c->dev; | ||
1376 | |||
1377 | tscs42xx->regmap = devm_regmap_init_i2c(i2c, &tscs42xx_regmap); | ||
1378 | if (IS_ERR(tscs42xx->regmap)) { | ||
1379 | ret = PTR_ERR(tscs42xx->regmap); | ||
1380 | dev_err(tscs42xx->dev, "Failed to allocate regmap (%d)\n", ret); | ||
1381 | return ret; | ||
1382 | } | ||
1383 | |||
1384 | init_coeff_ram_cache(tscs42xx); | ||
1385 | |||
1386 | ret = part_is_valid(tscs42xx); | ||
1387 | if (ret <= 0) { | ||
1388 | dev_err(tscs42xx->dev, "No valid part (%d)\n", ret); | ||
1389 | ret = -ENODEV; | ||
1390 | return ret; | ||
1391 | } | ||
1392 | |||
1393 | ret = regmap_write(tscs42xx->regmap, R_RESET, RV_RESET_ENABLE); | ||
1394 | if (ret < 0) { | ||
1395 | dev_err(tscs42xx->dev, "Failed to reset device (%d)\n", ret); | ||
1396 | return ret; | ||
1397 | } | ||
1398 | |||
1399 | ret = regmap_register_patch(tscs42xx->regmap, tscs42xx_patch, | ||
1400 | ARRAY_SIZE(tscs42xx_patch)); | ||
1401 | if (ret < 0) { | ||
1402 | dev_err(tscs42xx->dev, "Failed to apply patch (%d)\n", ret); | ||
1403 | return ret; | ||
1404 | } | ||
1405 | |||
1406 | mutex_init(&tscs42xx->audio_params_lock); | ||
1407 | mutex_init(&tscs42xx->coeff_ram_lock); | ||
1408 | mutex_init(&tscs42xx->pll_lock); | ||
1409 | |||
1410 | ret = snd_soc_register_codec(tscs42xx->dev, &soc_codec_dev_tscs42xx, | ||
1411 | &tscs42xx_dai, 1); | ||
1412 | if (ret) { | ||
1413 | dev_err(tscs42xx->dev, "Failed to register codec (%d)\n", ret); | ||
1414 | return ret; | ||
1415 | } | ||
1416 | |||
1417 | return 0; | ||
1418 | } | ||
1419 | |||
1420 | static int tscs42xx_i2c_remove(struct i2c_client *client) | ||
1421 | { | ||
1422 | snd_soc_unregister_codec(&client->dev); | ||
1423 | |||
1424 | return 0; | ||
1425 | } | ||
1426 | |||
1427 | static const struct i2c_device_id tscs42xx_i2c_id[] = { | ||
1428 | { "tscs42A1", 0 }, | ||
1429 | { "tscs42A2", 0 }, | ||
1430 | { } | ||
1431 | }; | ||
1432 | MODULE_DEVICE_TABLE(i2c, tscs42xx_i2c_id); | ||
1433 | |||
1434 | static const struct of_device_id tscs42xx_of_match[] = { | ||
1435 | { .compatible = "tempo,tscs42A1", }, | ||
1436 | { .compatible = "tempo,tscs42A2", }, | ||
1437 | { } | ||
1438 | }; | ||
1439 | MODULE_DEVICE_TABLE(of, tscs42xx_of_match); | ||
1440 | |||
1441 | static struct i2c_driver tscs42xx_i2c_driver = { | ||
1442 | .driver = { | ||
1443 | .name = "tscs42xx", | ||
1444 | .owner = THIS_MODULE, | ||
1445 | .of_match_table = tscs42xx_of_match, | ||
1446 | }, | ||
1447 | .probe = tscs42xx_i2c_probe, | ||
1448 | .remove = tscs42xx_i2c_remove, | ||
1449 | .id_table = tscs42xx_i2c_id, | ||
1450 | }; | ||
1451 | |||
1452 | module_i2c_driver(tscs42xx_i2c_driver); | ||
1453 | |||
1454 | MODULE_AUTHOR("Tempo Semiconductor <steven.eckhoff.opensource@gmail.com"); | ||
1455 | MODULE_DESCRIPTION("ASoC TSCS42xx driver"); | ||
1456 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/tscs42xx.h b/sound/soc/codecs/tscs42xx.h new file mode 100644 index 000000000000..d4a30bcbf64b --- /dev/null +++ b/sound/soc/codecs/tscs42xx.h | |||
@@ -0,0 +1,2693 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // tscs42xx.h -- TSCS42xx ALSA SoC Audio driver | ||
3 | // Copyright 2017 Tempo Semiconductor, Inc. | ||
4 | // Author: Steven Eckhoff <steven.eckhoff.opensource@gmail.com> | ||
5 | |||
6 | #ifndef __WOOKIE_H__ | ||
7 | #define __WOOKIE_H__ | ||
8 | |||
9 | enum { | ||
10 | TSCS42XX_PLL_SRC_NONE, | ||
11 | TSCS42XX_PLL_SRC_XTAL, | ||
12 | TSCS42XX_PLL_SRC_MCLK1, | ||
13 | TSCS42XX_PLL_SRC_MCLK2, | ||
14 | }; | ||
15 | |||
16 | #define R_HPVOLL 0x0 | ||
17 | #define R_HPVOLR 0x1 | ||
18 | #define R_SPKVOLL 0x2 | ||
19 | #define R_SPKVOLR 0x3 | ||
20 | #define R_DACVOLL 0x4 | ||
21 | #define R_DACVOLR 0x5 | ||
22 | #define R_ADCVOLL 0x6 | ||
23 | #define R_ADCVOLR 0x7 | ||
24 | #define R_INVOLL 0x8 | ||
25 | #define R_INVOLR 0x9 | ||
26 | #define R_INMODE 0x0B | ||
27 | #define R_INSELL 0x0C | ||
28 | #define R_INSELR 0x0D | ||
29 | #define R_AIC1 0x13 | ||
30 | #define R_AIC2 0x14 | ||
31 | #define R_CNVRTR0 0x16 | ||
32 | #define R_ADCSR 0x17 | ||
33 | #define R_CNVRTR1 0x18 | ||
34 | #define R_DACSR 0x19 | ||
35 | #define R_PWRM1 0x1A | ||
36 | #define R_PWRM2 0x1B | ||
37 | #define R_CONFIG0 0x1F | ||
38 | #define R_CONFIG1 0x20 | ||
39 | #define R_DMICCTL 0x24 | ||
40 | #define R_CLECTL 0x25 | ||
41 | #define R_MUGAIN 0x26 | ||
42 | #define R_COMPTH 0x27 | ||
43 | #define R_CMPRAT 0x28 | ||
44 | #define R_CATKTCL 0x29 | ||
45 | #define R_CATKTCH 0x2A | ||
46 | #define R_CRELTCL 0x2B | ||
47 | #define R_CRELTCH 0x2C | ||
48 | #define R_LIMTH 0x2D | ||
49 | #define R_LIMTGT 0x2E | ||
50 | #define R_LATKTCL 0x2F | ||
51 | #define R_LATKTCH 0x30 | ||
52 | #define R_LRELTCL 0x31 | ||
53 | #define R_LRELTCH 0x32 | ||
54 | #define R_EXPTH 0x33 | ||
55 | #define R_EXPRAT 0x34 | ||
56 | #define R_XATKTCL 0x35 | ||
57 | #define R_XATKTCH 0x36 | ||
58 | #define R_XRELTCL 0x37 | ||
59 | #define R_XRELTCH 0x38 | ||
60 | #define R_FXCTL 0x39 | ||
61 | #define R_DACCRWRL 0x3A | ||
62 | #define R_DACCRWRM 0x3B | ||
63 | #define R_DACCRWRH 0x3C | ||
64 | #define R_DACCRRDL 0x3D | ||
65 | #define R_DACCRRDM 0x3E | ||
66 | #define R_DACCRRDH 0x3F | ||
67 | #define R_DACCRADDR 0x40 | ||
68 | #define R_DCOFSEL 0x41 | ||
69 | #define R_PLLCTL9 0x4E | ||
70 | #define R_PLLCTLA 0x4F | ||
71 | #define R_PLLCTLB 0x50 | ||
72 | #define R_PLLCTLC 0x51 | ||
73 | #define R_PLLCTLD 0x52 | ||
74 | #define R_PLLCTLE 0x53 | ||
75 | #define R_PLLCTLF 0x54 | ||
76 | #define R_PLLCTL10 0x55 | ||
77 | #define R_PLLCTL11 0x56 | ||
78 | #define R_PLLCTL12 0x57 | ||
79 | #define R_PLLCTL1B 0x60 | ||
80 | #define R_PLLCTL1C 0x61 | ||
81 | #define R_TIMEBASE 0x77 | ||
82 | #define R_DEVIDL 0x7D | ||
83 | #define R_DEVIDH 0x7E | ||
84 | #define R_RESET 0x80 | ||
85 | #define R_DACCRSTAT 0x8A | ||
86 | #define R_PLLCTL0 0x8E | ||
87 | #define R_PLLREFSEL 0x8F | ||
88 | #define R_DACMBCEN 0xC7 | ||
89 | #define R_DACMBCCTL 0xC8 | ||
90 | #define R_DACMBCMUG1 0xC9 | ||
91 | #define R_DACMBCTHR1 0xCA | ||
92 | #define R_DACMBCRAT1 0xCB | ||
93 | #define R_DACMBCATK1L 0xCC | ||
94 | #define R_DACMBCATK1H 0xCD | ||
95 | #define R_DACMBCREL1L 0xCE | ||
96 | #define R_DACMBCREL1H 0xCF | ||
97 | #define R_DACMBCMUG2 0xD0 | ||
98 | #define R_DACMBCTHR2 0xD1 | ||
99 | #define R_DACMBCRAT2 0xD2 | ||
100 | #define R_DACMBCATK2L 0xD3 | ||
101 | #define R_DACMBCATK2H 0xD4 | ||
102 | #define R_DACMBCREL2L 0xD5 | ||
103 | #define R_DACMBCREL2H 0xD6 | ||
104 | #define R_DACMBCMUG3 0xD7 | ||
105 | #define R_DACMBCTHR3 0xD8 | ||
106 | #define R_DACMBCRAT3 0xD9 | ||
107 | #define R_DACMBCATK3L 0xDA | ||
108 | #define R_DACMBCATK3H 0xDB | ||
109 | #define R_DACMBCREL3L 0xDC | ||
110 | #define R_DACMBCREL3H 0xDD | ||
111 | |||
112 | /* Helpers */ | ||
113 | #define RM(m, b) ((m)<<(b)) | ||
114 | #define RV(v, b) ((v)<<(b)) | ||
115 | |||
116 | /**************************** | ||
117 | * R_HPVOLL (0x0) * | ||
118 | ****************************/ | ||
119 | |||
120 | /* Field Offsets */ | ||
121 | #define FB_HPVOLL 0 | ||
122 | |||
123 | /* Field Masks */ | ||
124 | #define FM_HPVOLL 0X7F | ||
125 | |||
126 | /* Field Values */ | ||
127 | #define FV_HPVOLL_P6DB 0x7F | ||
128 | #define FV_HPVOLL_N88PT5DB 0x1 | ||
129 | #define FV_HPVOLL_MUTE 0x0 | ||
130 | |||
131 | /* Register Masks */ | ||
132 | #define RM_HPVOLL RM(FM_HPVOLL, FB_HPVOLL) | ||
133 | |||
134 | /* Register Values */ | ||
135 | #define RV_HPVOLL_P6DB RV(FV_HPVOLL_P6DB, FB_HPVOLL) | ||
136 | #define RV_HPVOLL_N88PT5DB RV(FV_HPVOLL_N88PT5DB, FB_HPVOLL) | ||
137 | #define RV_HPVOLL_MUTE RV(FV_HPVOLL_MUTE, FB_HPVOLL) | ||
138 | |||
139 | /**************************** | ||
140 | * R_HPVOLR (0x1) * | ||
141 | ****************************/ | ||
142 | |||
143 | /* Field Offsets */ | ||
144 | #define FB_HPVOLR 0 | ||
145 | |||
146 | /* Field Masks */ | ||
147 | #define FM_HPVOLR 0X7F | ||
148 | |||
149 | /* Field Values */ | ||
150 | #define FV_HPVOLR_P6DB 0x7F | ||
151 | #define FV_HPVOLR_N88PT5DB 0x1 | ||
152 | #define FV_HPVOLR_MUTE 0x0 | ||
153 | |||
154 | /* Register Masks */ | ||
155 | #define RM_HPVOLR RM(FM_HPVOLR, FB_HPVOLR) | ||
156 | |||
157 | /* Register Values */ | ||
158 | #define RV_HPVOLR_P6DB RV(FV_HPVOLR_P6DB, FB_HPVOLR) | ||
159 | #define RV_HPVOLR_N88PT5DB RV(FV_HPVOLR_N88PT5DB, FB_HPVOLR) | ||
160 | #define RV_HPVOLR_MUTE RV(FV_HPVOLR_MUTE, FB_HPVOLR) | ||
161 | |||
162 | /***************************** | ||
163 | * R_SPKVOLL (0x2) * | ||
164 | *****************************/ | ||
165 | |||
166 | /* Field Offsets */ | ||
167 | #define FB_SPKVOLL 0 | ||
168 | |||
169 | /* Field Masks */ | ||
170 | #define FM_SPKVOLL 0X7F | ||
171 | |||
172 | /* Field Values */ | ||
173 | #define FV_SPKVOLL_P12DB 0x7F | ||
174 | #define FV_SPKVOLL_N77PT25DB 0x8 | ||
175 | #define FV_SPKVOLL_MUTE 0x0 | ||
176 | |||
177 | /* Register Masks */ | ||
178 | #define RM_SPKVOLL RM(FM_SPKVOLL, FB_SPKVOLL) | ||
179 | |||
180 | /* Register Values */ | ||
181 | #define RV_SPKVOLL_P12DB RV(FV_SPKVOLL_P12DB, FB_SPKVOLL) | ||
182 | #define RV_SPKVOLL_N77PT25DB \ | ||
183 | RV(FV_SPKVOLL_N77PT25DB, FB_SPKVOLL) | ||
184 | |||
185 | #define RV_SPKVOLL_MUTE RV(FV_SPKVOLL_MUTE, FB_SPKVOLL) | ||
186 | |||
187 | /***************************** | ||
188 | * R_SPKVOLR (0x3) * | ||
189 | *****************************/ | ||
190 | |||
191 | /* Field Offsets */ | ||
192 | #define FB_SPKVOLR 0 | ||
193 | |||
194 | /* Field Masks */ | ||
195 | #define FM_SPKVOLR 0X7F | ||
196 | |||
197 | /* Field Values */ | ||
198 | #define FV_SPKVOLR_P12DB 0x7F | ||
199 | #define FV_SPKVOLR_N77PT25DB 0x8 | ||
200 | #define FV_SPKVOLR_MUTE 0x0 | ||
201 | |||
202 | /* Register Masks */ | ||
203 | #define RM_SPKVOLR RM(FM_SPKVOLR, FB_SPKVOLR) | ||
204 | |||
205 | /* Register Values */ | ||
206 | #define RV_SPKVOLR_P12DB RV(FV_SPKVOLR_P12DB, FB_SPKVOLR) | ||
207 | #define RV_SPKVOLR_N77PT25DB \ | ||
208 | RV(FV_SPKVOLR_N77PT25DB, FB_SPKVOLR) | ||
209 | |||
210 | #define RV_SPKVOLR_MUTE RV(FV_SPKVOLR_MUTE, FB_SPKVOLR) | ||
211 | |||
212 | /***************************** | ||
213 | * R_DACVOLL (0x4) * | ||
214 | *****************************/ | ||
215 | |||
216 | /* Field Offsets */ | ||
217 | #define FB_DACVOLL 0 | ||
218 | |||
219 | /* Field Masks */ | ||
220 | #define FM_DACVOLL 0XFF | ||
221 | |||
222 | /* Field Values */ | ||
223 | #define FV_DACVOLL_0DB 0xFF | ||
224 | #define FV_DACVOLL_N95PT625DB 0x1 | ||
225 | #define FV_DACVOLL_MUTE 0x0 | ||
226 | |||
227 | /* Register Masks */ | ||
228 | #define RM_DACVOLL RM(FM_DACVOLL, FB_DACVOLL) | ||
229 | |||
230 | /* Register Values */ | ||
231 | #define RV_DACVOLL_0DB RV(FV_DACVOLL_0DB, FB_DACVOLL) | ||
232 | #define RV_DACVOLL_N95PT625DB \ | ||
233 | RV(FV_DACVOLL_N95PT625DB, FB_DACVOLL) | ||
234 | |||
235 | #define RV_DACVOLL_MUTE RV(FV_DACVOLL_MUTE, FB_DACVOLL) | ||
236 | |||
237 | /***************************** | ||
238 | * R_DACVOLR (0x5) * | ||
239 | *****************************/ | ||
240 | |||
241 | /* Field Offsets */ | ||
242 | #define FB_DACVOLR 0 | ||
243 | |||
244 | /* Field Masks */ | ||
245 | #define FM_DACVOLR 0XFF | ||
246 | |||
247 | /* Field Values */ | ||
248 | #define FV_DACVOLR_0DB 0xFF | ||
249 | #define FV_DACVOLR_N95PT625DB 0x1 | ||
250 | #define FV_DACVOLR_MUTE 0x0 | ||
251 | |||
252 | /* Register Masks */ | ||
253 | #define RM_DACVOLR RM(FM_DACVOLR, FB_DACVOLR) | ||
254 | |||
255 | /* Register Values */ | ||
256 | #define RV_DACVOLR_0DB RV(FV_DACVOLR_0DB, FB_DACVOLR) | ||
257 | #define RV_DACVOLR_N95PT625DB \ | ||
258 | RV(FV_DACVOLR_N95PT625DB, FB_DACVOLR) | ||
259 | |||
260 | #define RV_DACVOLR_MUTE RV(FV_DACVOLR_MUTE, FB_DACVOLR) | ||
261 | |||
262 | /***************************** | ||
263 | * R_ADCVOLL (0x6) * | ||
264 | *****************************/ | ||
265 | |||
266 | /* Field Offsets */ | ||
267 | #define FB_ADCVOLL 0 | ||
268 | |||
269 | /* Field Masks */ | ||
270 | #define FM_ADCVOLL 0XFF | ||
271 | |||
272 | /* Field Values */ | ||
273 | #define FV_ADCVOLL_P24DB 0xFF | ||
274 | #define FV_ADCVOLL_N71PT25DB 0x1 | ||
275 | #define FV_ADCVOLL_MUTE 0x0 | ||
276 | |||
277 | /* Register Masks */ | ||
278 | #define RM_ADCVOLL RM(FM_ADCVOLL, FB_ADCVOLL) | ||
279 | |||
280 | /* Register Values */ | ||
281 | #define RV_ADCVOLL_P24DB RV(FV_ADCVOLL_P24DB, FB_ADCVOLL) | ||
282 | #define RV_ADCVOLL_N71PT25DB \ | ||
283 | RV(FV_ADCVOLL_N71PT25DB, FB_ADCVOLL) | ||
284 | |||
285 | #define RV_ADCVOLL_MUTE RV(FV_ADCVOLL_MUTE, FB_ADCVOLL) | ||
286 | |||
287 | /***************************** | ||
288 | * R_ADCVOLR (0x7) * | ||
289 | *****************************/ | ||
290 | |||
291 | /* Field Offsets */ | ||
292 | #define FB_ADCVOLR 0 | ||
293 | |||
294 | /* Field Masks */ | ||
295 | #define FM_ADCVOLR 0XFF | ||
296 | |||
297 | /* Field Values */ | ||
298 | #define FV_ADCVOLR_P24DB 0xFF | ||
299 | #define FV_ADCVOLR_N71PT25DB 0x1 | ||
300 | #define FV_ADCVOLR_MUTE 0x0 | ||
301 | |||
302 | /* Register Masks */ | ||
303 | #define RM_ADCVOLR RM(FM_ADCVOLR, FB_ADCVOLR) | ||
304 | |||
305 | /* Register Values */ | ||
306 | #define RV_ADCVOLR_P24DB RV(FV_ADCVOLR_P24DB, FB_ADCVOLR) | ||
307 | #define RV_ADCVOLR_N71PT25DB \ | ||
308 | RV(FV_ADCVOLR_N71PT25DB, FB_ADCVOLR) | ||
309 | |||
310 | #define RV_ADCVOLR_MUTE RV(FV_ADCVOLR_MUTE, FB_ADCVOLR) | ||
311 | |||
312 | /**************************** | ||
313 | * R_INVOLL (0x8) * | ||
314 | ****************************/ | ||
315 | |||
316 | /* Field Offsets */ | ||
317 | #define FB_INVOLL_INMUTEL 7 | ||
318 | #define FB_INVOLL_IZCL 6 | ||
319 | #define FB_INVOLL 0 | ||
320 | |||
321 | /* Field Masks */ | ||
322 | #define FM_INVOLL_INMUTEL 0X1 | ||
323 | #define FM_INVOLL_IZCL 0X1 | ||
324 | #define FM_INVOLL 0X3F | ||
325 | |||
326 | /* Field Values */ | ||
327 | #define FV_INVOLL_INMUTEL_ENABLE 0x1 | ||
328 | #define FV_INVOLL_INMUTEL_DISABLE 0x0 | ||
329 | #define FV_INVOLL_IZCL_ENABLE 0x1 | ||
330 | #define FV_INVOLL_IZCL_DISABLE 0x0 | ||
331 | #define FV_INVOLL_P30DB 0x3F | ||
332 | #define FV_INVOLL_N17PT25DB 0x0 | ||
333 | |||
334 | /* Register Masks */ | ||
335 | #define RM_INVOLL_INMUTEL \ | ||
336 | RM(FM_INVOLL_INMUTEL, FB_INVOLL_INMUTEL) | ||
337 | |||
338 | #define RM_INVOLL_IZCL RM(FM_INVOLL_IZCL, FB_INVOLL_IZCL) | ||
339 | #define RM_INVOLL RM(FM_INVOLL, FB_INVOLL) | ||
340 | |||
341 | /* Register Values */ | ||
342 | #define RV_INVOLL_INMUTEL_ENABLE \ | ||
343 | RV(FV_INVOLL_INMUTEL_ENABLE, FB_INVOLL_INMUTEL) | ||
344 | |||
345 | #define RV_INVOLL_INMUTEL_DISABLE \ | ||
346 | RV(FV_INVOLL_INMUTEL_DISABLE, FB_INVOLL_INMUTEL) | ||
347 | |||
348 | #define RV_INVOLL_IZCL_ENABLE \ | ||
349 | RV(FV_INVOLL_IZCL_ENABLE, FB_INVOLL_IZCL) | ||
350 | |||
351 | #define RV_INVOLL_IZCL_DISABLE \ | ||
352 | RV(FV_INVOLL_IZCL_DISABLE, FB_INVOLL_IZCL) | ||
353 | |||
354 | #define RV_INVOLL_P30DB RV(FV_INVOLL_P30DB, FB_INVOLL) | ||
355 | #define RV_INVOLL_N17PT25DB RV(FV_INVOLL_N17PT25DB, FB_INVOLL) | ||
356 | |||
357 | /**************************** | ||
358 | * R_INVOLR (0x9) * | ||
359 | ****************************/ | ||
360 | |||
361 | /* Field Offsets */ | ||
362 | #define FB_INVOLR_INMUTER 7 | ||
363 | #define FB_INVOLR_IZCR 6 | ||
364 | #define FB_INVOLR 0 | ||
365 | |||
366 | /* Field Masks */ | ||
367 | #define FM_INVOLR_INMUTER 0X1 | ||
368 | #define FM_INVOLR_IZCR 0X1 | ||
369 | #define FM_INVOLR 0X3F | ||
370 | |||
371 | /* Field Values */ | ||
372 | #define FV_INVOLR_INMUTER_ENABLE 0x1 | ||
373 | #define FV_INVOLR_INMUTER_DISABLE 0x0 | ||
374 | #define FV_INVOLR_IZCR_ENABLE 0x1 | ||
375 | #define FV_INVOLR_IZCR_DISABLE 0x0 | ||
376 | #define FV_INVOLR_P30DB 0x3F | ||
377 | #define FV_INVOLR_N17PT25DB 0x0 | ||
378 | |||
379 | /* Register Masks */ | ||
380 | #define RM_INVOLR_INMUTER \ | ||
381 | RM(FM_INVOLR_INMUTER, FB_INVOLR_INMUTER) | ||
382 | |||
383 | #define RM_INVOLR_IZCR RM(FM_INVOLR_IZCR, FB_INVOLR_IZCR) | ||
384 | #define RM_INVOLR RM(FM_INVOLR, FB_INVOLR) | ||
385 | |||
386 | /* Register Values */ | ||
387 | #define RV_INVOLR_INMUTER_ENABLE \ | ||
388 | RV(FV_INVOLR_INMUTER_ENABLE, FB_INVOLR_INMUTER) | ||
389 | |||
390 | #define RV_INVOLR_INMUTER_DISABLE \ | ||
391 | RV(FV_INVOLR_INMUTER_DISABLE, FB_INVOLR_INMUTER) | ||
392 | |||
393 | #define RV_INVOLR_IZCR_ENABLE \ | ||
394 | RV(FV_INVOLR_IZCR_ENABLE, FB_INVOLR_IZCR) | ||
395 | |||
396 | #define RV_INVOLR_IZCR_DISABLE \ | ||
397 | RV(FV_INVOLR_IZCR_DISABLE, FB_INVOLR_IZCR) | ||
398 | |||
399 | #define RV_INVOLR_P30DB RV(FV_INVOLR_P30DB, FB_INVOLR) | ||
400 | #define RV_INVOLR_N17PT25DB RV(FV_INVOLR_N17PT25DB, FB_INVOLR) | ||
401 | |||
402 | /***************************** | ||
403 | * R_INMODE (0x0B) * | ||
404 | *****************************/ | ||
405 | |||
406 | /* Field Offsets */ | ||
407 | #define FB_INMODE_DS 0 | ||
408 | |||
409 | /* Field Masks */ | ||
410 | #define FM_INMODE_DS 0X1 | ||
411 | |||
412 | /* Field Values */ | ||
413 | #define FV_INMODE_DS_LRIN1 0x0 | ||
414 | #define FV_INMODE_DS_LRIN2 0x1 | ||
415 | |||
416 | /* Register Masks */ | ||
417 | #define RM_INMODE_DS RM(FM_INMODE_DS, FB_INMODE_DS) | ||
418 | |||
419 | /* Register Values */ | ||
420 | #define RV_INMODE_DS_LRIN1 \ | ||
421 | RV(FV_INMODE_DS_LRIN1, FB_INMODE_DS) | ||
422 | |||
423 | #define RV_INMODE_DS_LRIN2 \ | ||
424 | RV(FV_INMODE_DS_LRIN2, FB_INMODE_DS) | ||
425 | |||
426 | |||
427 | /***************************** | ||
428 | * R_INSELL (0x0C) * | ||
429 | *****************************/ | ||
430 | |||
431 | /* Field Offsets */ | ||
432 | #define FB_INSELL 6 | ||
433 | #define FB_INSELL_MICBSTL 4 | ||
434 | |||
435 | /* Field Masks */ | ||
436 | #define FM_INSELL 0X3 | ||
437 | #define FM_INSELL_MICBSTL 0X3 | ||
438 | |||
439 | /* Field Values */ | ||
440 | #define FV_INSELL_IN1 0x0 | ||
441 | #define FV_INSELL_IN2 0x1 | ||
442 | #define FV_INSELL_IN3 0x2 | ||
443 | #define FV_INSELL_D2S 0x3 | ||
444 | #define FV_INSELL_MICBSTL_OFF 0x0 | ||
445 | #define FV_INSELL_MICBSTL_10DB 0x1 | ||
446 | #define FV_INSELL_MICBSTL_20DB 0x2 | ||
447 | #define FV_INSELL_MICBSTL_30DB 0x3 | ||
448 | |||
449 | /* Register Masks */ | ||
450 | #define RM_INSELL RM(FM_INSELL, FB_INSELL) | ||
451 | #define RM_INSELL_MICBSTL \ | ||
452 | RM(FM_INSELL_MICBSTL, FB_INSELL_MICBSTL) | ||
453 | |||
454 | |||
455 | /* Register Values */ | ||
456 | #define RV_INSELL_IN1 RV(FV_INSELL_IN1, FB_INSELL) | ||
457 | #define RV_INSELL_IN2 RV(FV_INSELL_IN2, FB_INSELL) | ||
458 | #define RV_INSELL_IN3 RV(FV_INSELL_IN3, FB_INSELL) | ||
459 | #define RV_INSELL_D2S RV(FV_INSELL_D2S, FB_INSELL) | ||
460 | #define RV_INSELL_MICBSTL_OFF \ | ||
461 | RV(FV_INSELL_MICBSTL_OFF, FB_INSELL_MICBSTL) | ||
462 | |||
463 | #define RV_INSELL_MICBSTL_10DB \ | ||
464 | RV(FV_INSELL_MICBSTL_10DB, FB_INSELL_MICBSTL) | ||
465 | |||
466 | #define RV_INSELL_MICBSTL_20DB \ | ||
467 | RV(FV_INSELL_MICBSTL_20DB, FB_INSELL_MICBSTL) | ||
468 | |||
469 | #define RV_INSELL_MICBSTL_30DB \ | ||
470 | RV(FV_INSELL_MICBSTL_30DB, FB_INSELL_MICBSTL) | ||
471 | |||
472 | |||
473 | /***************************** | ||
474 | * R_INSELR (0x0D) * | ||
475 | *****************************/ | ||
476 | |||
477 | /* Field Offsets */ | ||
478 | #define FB_INSELR 6 | ||
479 | #define FB_INSELR_MICBSTR 4 | ||
480 | |||
481 | /* Field Masks */ | ||
482 | #define FM_INSELR 0X3 | ||
483 | #define FM_INSELR_MICBSTR 0X3 | ||
484 | |||
485 | /* Field Values */ | ||
486 | #define FV_INSELR_IN1 0x0 | ||
487 | #define FV_INSELR_IN2 0x1 | ||
488 | #define FV_INSELR_IN3 0x2 | ||
489 | #define FV_INSELR_D2S 0x3 | ||
490 | #define FV_INSELR_MICBSTR_OFF 0x0 | ||
491 | #define FV_INSELR_MICBSTR_10DB 0x1 | ||
492 | #define FV_INSELR_MICBSTR_20DB 0x2 | ||
493 | #define FV_INSELR_MICBSTR_30DB 0x3 | ||
494 | |||
495 | /* Register Masks */ | ||
496 | #define RM_INSELR RM(FM_INSELR, FB_INSELR) | ||
497 | #define RM_INSELR_MICBSTR \ | ||
498 | RM(FM_INSELR_MICBSTR, FB_INSELR_MICBSTR) | ||
499 | |||
500 | |||
501 | /* Register Values */ | ||
502 | #define RV_INSELR_IN1 RV(FV_INSELR_IN1, FB_INSELR) | ||
503 | #define RV_INSELR_IN2 RV(FV_INSELR_IN2, FB_INSELR) | ||
504 | #define RV_INSELR_IN3 RV(FV_INSELR_IN3, FB_INSELR) | ||
505 | #define RV_INSELR_D2S RV(FV_INSELR_D2S, FB_INSELR) | ||
506 | #define RV_INSELR_MICBSTR_OFF \ | ||
507 | RV(FV_INSELR_MICBSTR_OFF, FB_INSELR_MICBSTR) | ||
508 | |||
509 | #define RV_INSELR_MICBSTR_10DB \ | ||
510 | RV(FV_INSELR_MICBSTR_10DB, FB_INSELR_MICBSTR) | ||
511 | |||
512 | #define RV_INSELR_MICBSTR_20DB \ | ||
513 | RV(FV_INSELR_MICBSTR_20DB, FB_INSELR_MICBSTR) | ||
514 | |||
515 | #define RV_INSELR_MICBSTR_30DB \ | ||
516 | RV(FV_INSELR_MICBSTR_30DB, FB_INSELR_MICBSTR) | ||
517 | |||
518 | |||
519 | /*************************** | ||
520 | * R_AIC1 (0x13) * | ||
521 | ***************************/ | ||
522 | |||
523 | /* Field Offsets */ | ||
524 | #define FB_AIC1_BCLKINV 6 | ||
525 | #define FB_AIC1_MS 5 | ||
526 | #define FB_AIC1_LRP 4 | ||
527 | #define FB_AIC1_WL 2 | ||
528 | #define FB_AIC1_FORMAT 0 | ||
529 | |||
530 | /* Field Masks */ | ||
531 | #define FM_AIC1_BCLKINV 0X1 | ||
532 | #define FM_AIC1_MS 0X1 | ||
533 | #define FM_AIC1_LRP 0X1 | ||
534 | #define FM_AIC1_WL 0X3 | ||
535 | #define FM_AIC1_FORMAT 0X3 | ||
536 | |||
537 | /* Field Values */ | ||
538 | #define FV_AIC1_BCLKINV_ENABLE 0x1 | ||
539 | #define FV_AIC1_BCLKINV_DISABLE 0x0 | ||
540 | #define FV_AIC1_MS_MASTER 0x1 | ||
541 | #define FV_AIC1_MS_SLAVE 0x0 | ||
542 | #define FV_AIC1_LRP_INVERT 0x1 | ||
543 | #define FV_AIC1_LRP_NORMAL 0x0 | ||
544 | #define FV_AIC1_WL_16 0x0 | ||
545 | #define FV_AIC1_WL_20 0x1 | ||
546 | #define FV_AIC1_WL_24 0x2 | ||
547 | #define FV_AIC1_WL_32 0x3 | ||
548 | #define FV_AIC1_FORMAT_RIGHT 0x0 | ||
549 | #define FV_AIC1_FORMAT_LEFT 0x1 | ||
550 | #define FV_AIC1_FORMAT_I2S 0x2 | ||
551 | |||
552 | /* Register Masks */ | ||
553 | #define RM_AIC1_BCLKINV \ | ||
554 | RM(FM_AIC1_BCLKINV, FB_AIC1_BCLKINV) | ||
555 | |||
556 | #define RM_AIC1_MS RM(FM_AIC1_MS, FB_AIC1_MS) | ||
557 | #define RM_AIC1_LRP RM(FM_AIC1_LRP, FB_AIC1_LRP) | ||
558 | #define RM_AIC1_WL RM(FM_AIC1_WL, FB_AIC1_WL) | ||
559 | #define RM_AIC1_FORMAT RM(FM_AIC1_FORMAT, FB_AIC1_FORMAT) | ||
560 | |||
561 | /* Register Values */ | ||
562 | #define RV_AIC1_BCLKINV_ENABLE \ | ||
563 | RV(FV_AIC1_BCLKINV_ENABLE, FB_AIC1_BCLKINV) | ||
564 | |||
565 | #define RV_AIC1_BCLKINV_DISABLE \ | ||
566 | RV(FV_AIC1_BCLKINV_DISABLE, FB_AIC1_BCLKINV) | ||
567 | |||
568 | #define RV_AIC1_MS_MASTER RV(FV_AIC1_MS_MASTER, FB_AIC1_MS) | ||
569 | #define RV_AIC1_MS_SLAVE RV(FV_AIC1_MS_SLAVE, FB_AIC1_MS) | ||
570 | #define RV_AIC1_LRP_INVERT \ | ||
571 | RV(FV_AIC1_LRP_INVERT, FB_AIC1_LRP) | ||
572 | |||
573 | #define RV_AIC1_LRP_NORMAL \ | ||
574 | RV(FV_AIC1_LRP_NORMAL, FB_AIC1_LRP) | ||
575 | |||
576 | #define RV_AIC1_WL_16 RV(FV_AIC1_WL_16, FB_AIC1_WL) | ||
577 | #define RV_AIC1_WL_20 RV(FV_AIC1_WL_20, FB_AIC1_WL) | ||
578 | #define RV_AIC1_WL_24 RV(FV_AIC1_WL_24, FB_AIC1_WL) | ||
579 | #define RV_AIC1_WL_32 RV(FV_AIC1_WL_32, FB_AIC1_WL) | ||
580 | #define RV_AIC1_FORMAT_RIGHT \ | ||
581 | RV(FV_AIC1_FORMAT_RIGHT, FB_AIC1_FORMAT) | ||
582 | |||
583 | #define RV_AIC1_FORMAT_LEFT \ | ||
584 | RV(FV_AIC1_FORMAT_LEFT, FB_AIC1_FORMAT) | ||
585 | |||
586 | #define RV_AIC1_FORMAT_I2S \ | ||
587 | RV(FV_AIC1_FORMAT_I2S, FB_AIC1_FORMAT) | ||
588 | |||
589 | |||
590 | /*************************** | ||
591 | * R_AIC2 (0x14) * | ||
592 | ***************************/ | ||
593 | |||
594 | /* Field Offsets */ | ||
595 | #define FB_AIC2_DACDSEL 6 | ||
596 | #define FB_AIC2_ADCDSEL 4 | ||
597 | #define FB_AIC2_TRI 3 | ||
598 | #define FB_AIC2_BLRCM 0 | ||
599 | |||
600 | /* Field Masks */ | ||
601 | #define FM_AIC2_DACDSEL 0X3 | ||
602 | #define FM_AIC2_ADCDSEL 0X3 | ||
603 | #define FM_AIC2_TRI 0X1 | ||
604 | #define FM_AIC2_BLRCM 0X7 | ||
605 | |||
606 | /* Field Values */ | ||
607 | #define FV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED 0x3 | ||
608 | |||
609 | /* Register Masks */ | ||
610 | #define RM_AIC2_DACDSEL \ | ||
611 | RM(FM_AIC2_DACDSEL, FB_AIC2_DACDSEL) | ||
612 | |||
613 | #define RM_AIC2_ADCDSEL \ | ||
614 | RM(FM_AIC2_ADCDSEL, FB_AIC2_ADCDSEL) | ||
615 | |||
616 | #define RM_AIC2_TRI RM(FM_AIC2_TRI, FB_AIC2_TRI) | ||
617 | #define RM_AIC2_BLRCM RM(FM_AIC2_BLRCM, FB_AIC2_BLRCM) | ||
618 | |||
619 | /* Register Values */ | ||
620 | #define RV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED \ | ||
621 | RV(FV_AIC2_BLRCM_DAC_BCLK_LRCLK_SHARED, FB_AIC2_BLRCM) | ||
622 | |||
623 | |||
624 | /****************************** | ||
625 | * R_CNVRTR0 (0x16) * | ||
626 | ******************************/ | ||
627 | |||
628 | /* Field Offsets */ | ||
629 | #define FB_CNVRTR0_ADCPOLR 7 | ||
630 | #define FB_CNVRTR0_ADCPOLL 6 | ||
631 | #define FB_CNVRTR0_AMONOMIX 4 | ||
632 | #define FB_CNVRTR0_ADCMU 3 | ||
633 | #define FB_CNVRTR0_HPOR 2 | ||
634 | #define FB_CNVRTR0_ADCHPDR 1 | ||
635 | #define FB_CNVRTR0_ADCHPDL 0 | ||
636 | |||
637 | /* Field Masks */ | ||
638 | #define FM_CNVRTR0_ADCPOLR 0X1 | ||
639 | #define FM_CNVRTR0_ADCPOLL 0X1 | ||
640 | #define FM_CNVRTR0_AMONOMIX 0X3 | ||
641 | #define FM_CNVRTR0_ADCMU 0X1 | ||
642 | #define FM_CNVRTR0_HPOR 0X1 | ||
643 | #define FM_CNVRTR0_ADCHPDR 0X1 | ||
644 | #define FM_CNVRTR0_ADCHPDL 0X1 | ||
645 | |||
646 | /* Field Values */ | ||
647 | #define FV_CNVRTR0_ADCPOLR_INVERT 0x1 | ||
648 | #define FV_CNVRTR0_ADCPOLR_NORMAL 0x0 | ||
649 | #define FV_CNVRTR0_ADCPOLL_INVERT 0x1 | ||
650 | #define FV_CNVRTR0_ADCPOLL_NORMAL 0x0 | ||
651 | #define FV_CNVRTR0_ADCMU_ENABLE 0x1 | ||
652 | #define FV_CNVRTR0_ADCMU_DISABLE 0x0 | ||
653 | #define FV_CNVRTR0_ADCHPDR_ENABLE 0x1 | ||
654 | #define FV_CNVRTR0_ADCHPDR_DISABLE 0x0 | ||
655 | #define FV_CNVRTR0_ADCHPDL_ENABLE 0x1 | ||
656 | #define FV_CNVRTR0_ADCHPDL_DISABLE 0x0 | ||
657 | |||
658 | /* Register Masks */ | ||
659 | #define RM_CNVRTR0_ADCPOLR \ | ||
660 | RM(FM_CNVRTR0_ADCPOLR, FB_CNVRTR0_ADCPOLR) | ||
661 | |||
662 | #define RM_CNVRTR0_ADCPOLL \ | ||
663 | RM(FM_CNVRTR0_ADCPOLL, FB_CNVRTR0_ADCPOLL) | ||
664 | |||
665 | #define RM_CNVRTR0_AMONOMIX \ | ||
666 | RM(FM_CNVRTR0_AMONOMIX, FB_CNVRTR0_AMONOMIX) | ||
667 | |||
668 | #define RM_CNVRTR0_ADCMU \ | ||
669 | RM(FM_CNVRTR0_ADCMU, FB_CNVRTR0_ADCMU) | ||
670 | |||
671 | #define RM_CNVRTR0_HPOR \ | ||
672 | RM(FM_CNVRTR0_HPOR, FB_CNVRTR0_HPOR) | ||
673 | |||
674 | #define RM_CNVRTR0_ADCHPDR \ | ||
675 | RM(FM_CNVRTR0_ADCHPDR, FB_CNVRTR0_ADCHPDR) | ||
676 | |||
677 | #define RM_CNVRTR0_ADCHPDL \ | ||
678 | RM(FM_CNVRTR0_ADCHPDL, FB_CNVRTR0_ADCHPDL) | ||
679 | |||
680 | |||
681 | /* Register Values */ | ||
682 | #define RV_CNVRTR0_ADCPOLR_INVERT \ | ||
683 | RV(FV_CNVRTR0_ADCPOLR_INVERT, FB_CNVRTR0_ADCPOLR) | ||
684 | |||
685 | #define RV_CNVRTR0_ADCPOLR_NORMAL \ | ||
686 | RV(FV_CNVRTR0_ADCPOLR_NORMAL, FB_CNVRTR0_ADCPOLR) | ||
687 | |||
688 | #define RV_CNVRTR0_ADCPOLL_INVERT \ | ||
689 | RV(FV_CNVRTR0_ADCPOLL_INVERT, FB_CNVRTR0_ADCPOLL) | ||
690 | |||
691 | #define RV_CNVRTR0_ADCPOLL_NORMAL \ | ||
692 | RV(FV_CNVRTR0_ADCPOLL_NORMAL, FB_CNVRTR0_ADCPOLL) | ||
693 | |||
694 | #define RV_CNVRTR0_ADCMU_ENABLE \ | ||
695 | RV(FV_CNVRTR0_ADCMU_ENABLE, FB_CNVRTR0_ADCMU) | ||
696 | |||
697 | #define RV_CNVRTR0_ADCMU_DISABLE \ | ||
698 | RV(FV_CNVRTR0_ADCMU_DISABLE, FB_CNVRTR0_ADCMU) | ||
699 | |||
700 | #define RV_CNVRTR0_ADCHPDR_ENABLE \ | ||
701 | RV(FV_CNVRTR0_ADCHPDR_ENABLE, FB_CNVRTR0_ADCHPDR) | ||
702 | |||
703 | #define RV_CNVRTR0_ADCHPDR_DISABLE \ | ||
704 | RV(FV_CNVRTR0_ADCHPDR_DISABLE, FB_CNVRTR0_ADCHPDR) | ||
705 | |||
706 | #define RV_CNVRTR0_ADCHPDL_ENABLE \ | ||
707 | RV(FV_CNVRTR0_ADCHPDL_ENABLE, FB_CNVRTR0_ADCHPDL) | ||
708 | |||
709 | #define RV_CNVRTR0_ADCHPDL_DISABLE \ | ||
710 | RV(FV_CNVRTR0_ADCHPDL_DISABLE, FB_CNVRTR0_ADCHPDL) | ||
711 | |||
712 | |||
713 | /**************************** | ||
714 | * R_ADCSR (0x17) * | ||
715 | ****************************/ | ||
716 | |||
717 | /* Field Offsets */ | ||
718 | #define FB_ADCSR_ABCM 6 | ||
719 | #define FB_ADCSR_ABR 3 | ||
720 | #define FB_ADCSR_ABM 0 | ||
721 | |||
722 | /* Field Masks */ | ||
723 | #define FM_ADCSR_ABCM 0X3 | ||
724 | #define FM_ADCSR_ABR 0X3 | ||
725 | #define FM_ADCSR_ABM 0X7 | ||
726 | |||
727 | /* Field Values */ | ||
728 | #define FV_ADCSR_ABCM_AUTO 0x0 | ||
729 | #define FV_ADCSR_ABCM_32 0x1 | ||
730 | #define FV_ADCSR_ABCM_40 0x2 | ||
731 | #define FV_ADCSR_ABCM_64 0x3 | ||
732 | #define FV_ADCSR_ABR_32 0x0 | ||
733 | #define FV_ADCSR_ABR_44_1 0x1 | ||
734 | #define FV_ADCSR_ABR_48 0x2 | ||
735 | #define FV_ADCSR_ABM_PT25 0x0 | ||
736 | #define FV_ADCSR_ABM_PT5 0x1 | ||
737 | #define FV_ADCSR_ABM_1 0x2 | ||
738 | #define FV_ADCSR_ABM_2 0x3 | ||
739 | |||
740 | /* Register Masks */ | ||
741 | #define RM_ADCSR_ABCM RM(FM_ADCSR_ABCM, FB_ADCSR_ABCM) | ||
742 | #define RM_ADCSR_ABR RM(FM_ADCSR_ABR, FB_ADCSR_ABR) | ||
743 | #define RM_ADCSR_ABM RM(FM_ADCSR_ABM, FB_ADCSR_ABM) | ||
744 | |||
745 | /* Register Values */ | ||
746 | #define RV_ADCSR_ABCM_AUTO \ | ||
747 | RV(FV_ADCSR_ABCM_AUTO, FB_ADCSR_ABCM) | ||
748 | |||
749 | #define RV_ADCSR_ABCM_32 \ | ||
750 | RV(FV_ADCSR_ABCM_32, FB_ADCSR_ABCM) | ||
751 | |||
752 | #define RV_ADCSR_ABCM_40 \ | ||
753 | RV(FV_ADCSR_ABCM_40, FB_ADCSR_ABCM) | ||
754 | |||
755 | #define RV_ADCSR_ABCM_64 \ | ||
756 | RV(FV_ADCSR_ABCM_64, FB_ADCSR_ABCM) | ||
757 | |||
758 | #define RV_ADCSR_ABR_32 RV(FV_ADCSR_ABR_32, FB_ADCSR_ABR) | ||
759 | #define RV_ADCSR_ABR_44_1 \ | ||
760 | RV(FV_ADCSR_ABR_44_1, FB_ADCSR_ABR) | ||
761 | |||
762 | #define RV_ADCSR_ABR_48 RV(FV_ADCSR_ABR_48, FB_ADCSR_ABR) | ||
763 | #define RV_ADCSR_ABR_ RV(FV_ADCSR_ABR_, FB_ADCSR_ABR) | ||
764 | #define RV_ADCSR_ABM_PT25 \ | ||
765 | RV(FV_ADCSR_ABM_PT25, FB_ADCSR_ABM) | ||
766 | |||
767 | #define RV_ADCSR_ABM_PT5 RV(FV_ADCSR_ABM_PT5, FB_ADCSR_ABM) | ||
768 | #define RV_ADCSR_ABM_1 RV(FV_ADCSR_ABM_1, FB_ADCSR_ABM) | ||
769 | #define RV_ADCSR_ABM_2 RV(FV_ADCSR_ABM_2, FB_ADCSR_ABM) | ||
770 | |||
771 | /****************************** | ||
772 | * R_CNVRTR1 (0x18) * | ||
773 | ******************************/ | ||
774 | |||
775 | /* Field Offsets */ | ||
776 | #define FB_CNVRTR1_DACPOLR 7 | ||
777 | #define FB_CNVRTR1_DACPOLL 6 | ||
778 | #define FB_CNVRTR1_DMONOMIX 4 | ||
779 | #define FB_CNVRTR1_DACMU 3 | ||
780 | #define FB_CNVRTR1_DEEMPH 2 | ||
781 | #define FB_CNVRTR1_DACDITH 0 | ||
782 | |||
783 | /* Field Masks */ | ||
784 | #define FM_CNVRTR1_DACPOLR 0X1 | ||
785 | #define FM_CNVRTR1_DACPOLL 0X1 | ||
786 | #define FM_CNVRTR1_DMONOMIX 0X3 | ||
787 | #define FM_CNVRTR1_DACMU 0X1 | ||
788 | #define FM_CNVRTR1_DEEMPH 0X1 | ||
789 | #define FM_CNVRTR1_DACDITH 0X3 | ||
790 | |||
791 | /* Field Values */ | ||
792 | #define FV_CNVRTR1_DACPOLR_INVERT 0x1 | ||
793 | #define FV_CNVRTR1_DACPOLR_NORMAL 0x0 | ||
794 | #define FV_CNVRTR1_DACPOLL_INVERT 0x1 | ||
795 | #define FV_CNVRTR1_DACPOLL_NORMAL 0x0 | ||
796 | #define FV_CNVRTR1_DMONOMIX_ENABLE 0x1 | ||
797 | #define FV_CNVRTR1_DMONOMIX_DISABLE 0x0 | ||
798 | #define FV_CNVRTR1_DACMU_ENABLE 0x1 | ||
799 | #define FV_CNVRTR1_DACMU_DISABLE 0x0 | ||
800 | |||
801 | /* Register Masks */ | ||
802 | #define RM_CNVRTR1_DACPOLR \ | ||
803 | RM(FM_CNVRTR1_DACPOLR, FB_CNVRTR1_DACPOLR) | ||
804 | |||
805 | #define RM_CNVRTR1_DACPOLL \ | ||
806 | RM(FM_CNVRTR1_DACPOLL, FB_CNVRTR1_DACPOLL) | ||
807 | |||
808 | #define RM_CNVRTR1_DMONOMIX \ | ||
809 | RM(FM_CNVRTR1_DMONOMIX, FB_CNVRTR1_DMONOMIX) | ||
810 | |||
811 | #define RM_CNVRTR1_DACMU \ | ||
812 | RM(FM_CNVRTR1_DACMU, FB_CNVRTR1_DACMU) | ||
813 | |||
814 | #define RM_CNVRTR1_DEEMPH \ | ||
815 | RM(FM_CNVRTR1_DEEMPH, FB_CNVRTR1_DEEMPH) | ||
816 | |||
817 | #define RM_CNVRTR1_DACDITH \ | ||
818 | RM(FM_CNVRTR1_DACDITH, FB_CNVRTR1_DACDITH) | ||
819 | |||
820 | |||
821 | /* Register Values */ | ||
822 | #define RV_CNVRTR1_DACPOLR_INVERT \ | ||
823 | RV(FV_CNVRTR1_DACPOLR_INVERT, FB_CNVRTR1_DACPOLR) | ||
824 | |||
825 | #define RV_CNVRTR1_DACPOLR_NORMAL \ | ||
826 | RV(FV_CNVRTR1_DACPOLR_NORMAL, FB_CNVRTR1_DACPOLR) | ||
827 | |||
828 | #define RV_CNVRTR1_DACPOLL_INVERT \ | ||
829 | RV(FV_CNVRTR1_DACPOLL_INVERT, FB_CNVRTR1_DACPOLL) | ||
830 | |||
831 | #define RV_CNVRTR1_DACPOLL_NORMAL \ | ||
832 | RV(FV_CNVRTR1_DACPOLL_NORMAL, FB_CNVRTR1_DACPOLL) | ||
833 | |||
834 | #define RV_CNVRTR1_DMONOMIX_ENABLE \ | ||
835 | RV(FV_CNVRTR1_DMONOMIX_ENABLE, FB_CNVRTR1_DMONOMIX) | ||
836 | |||
837 | #define RV_CNVRTR1_DMONOMIX_DISABLE \ | ||
838 | RV(FV_CNVRTR1_DMONOMIX_DISABLE, FB_CNVRTR1_DMONOMIX) | ||
839 | |||
840 | #define RV_CNVRTR1_DACMU_ENABLE \ | ||
841 | RV(FV_CNVRTR1_DACMU_ENABLE, FB_CNVRTR1_DACMU) | ||
842 | |||
843 | #define RV_CNVRTR1_DACMU_DISABLE \ | ||
844 | RV(FV_CNVRTR1_DACMU_DISABLE, FB_CNVRTR1_DACMU) | ||
845 | |||
846 | |||
847 | /**************************** | ||
848 | * R_DACSR (0x19) * | ||
849 | ****************************/ | ||
850 | |||
851 | /* Field Offsets */ | ||
852 | #define FB_DACSR_DBCM 6 | ||
853 | #define FB_DACSR_DBR 3 | ||
854 | #define FB_DACSR_DBM 0 | ||
855 | |||
856 | /* Field Masks */ | ||
857 | #define FM_DACSR_DBCM 0X3 | ||
858 | #define FM_DACSR_DBR 0X3 | ||
859 | #define FM_DACSR_DBM 0X7 | ||
860 | |||
861 | /* Field Values */ | ||
862 | #define FV_DACSR_DBCM_AUTO 0x0 | ||
863 | #define FV_DACSR_DBCM_32 0x1 | ||
864 | #define FV_DACSR_DBCM_40 0x2 | ||
865 | #define FV_DACSR_DBCM_64 0x3 | ||
866 | #define FV_DACSR_DBR_32 0x0 | ||
867 | #define FV_DACSR_DBR_44_1 0x1 | ||
868 | #define FV_DACSR_DBR_48 0x2 | ||
869 | #define FV_DACSR_DBM_PT25 0x0 | ||
870 | #define FV_DACSR_DBM_PT5 0x1 | ||
871 | #define FV_DACSR_DBM_1 0x2 | ||
872 | #define FV_DACSR_DBM_2 0x3 | ||
873 | |||
874 | /* Register Masks */ | ||
875 | #define RM_DACSR_DBCM RM(FM_DACSR_DBCM, FB_DACSR_DBCM) | ||
876 | #define RM_DACSR_DBR RM(FM_DACSR_DBR, FB_DACSR_DBR) | ||
877 | #define RM_DACSR_DBM RM(FM_DACSR_DBM, FB_DACSR_DBM) | ||
878 | |||
879 | /* Register Values */ | ||
880 | #define RV_DACSR_DBCM_AUTO \ | ||
881 | RV(FV_DACSR_DBCM_AUTO, FB_DACSR_DBCM) | ||
882 | |||
883 | #define RV_DACSR_DBCM_32 \ | ||
884 | RV(FV_DACSR_DBCM_32, FB_DACSR_DBCM) | ||
885 | |||
886 | #define RV_DACSR_DBCM_40 \ | ||
887 | RV(FV_DACSR_DBCM_40, FB_DACSR_DBCM) | ||
888 | |||
889 | #define RV_DACSR_DBCM_64 \ | ||
890 | RV(FV_DACSR_DBCM_64, FB_DACSR_DBCM) | ||
891 | |||
892 | #define RV_DACSR_DBR_32 RV(FV_DACSR_DBR_32, FB_DACSR_DBR) | ||
893 | #define RV_DACSR_DBR_44_1 \ | ||
894 | RV(FV_DACSR_DBR_44_1, FB_DACSR_DBR) | ||
895 | |||
896 | #define RV_DACSR_DBR_48 RV(FV_DACSR_DBR_48, FB_DACSR_DBR) | ||
897 | #define RV_DACSR_DBM_PT25 \ | ||
898 | RV(FV_DACSR_DBM_PT25, FB_DACSR_DBM) | ||
899 | |||
900 | #define RV_DACSR_DBM_PT5 RV(FV_DACSR_DBM_PT5, FB_DACSR_DBM) | ||
901 | #define RV_DACSR_DBM_1 RV(FV_DACSR_DBM_1, FB_DACSR_DBM) | ||
902 | #define RV_DACSR_DBM_2 RV(FV_DACSR_DBM_2, FB_DACSR_DBM) | ||
903 | |||
904 | /**************************** | ||
905 | * R_PWRM1 (0x1A) * | ||
906 | ****************************/ | ||
907 | |||
908 | /* Field Offsets */ | ||
909 | #define FB_PWRM1_BSTL 7 | ||
910 | #define FB_PWRM1_BSTR 6 | ||
911 | #define FB_PWRM1_PGAL 5 | ||
912 | #define FB_PWRM1_PGAR 4 | ||
913 | #define FB_PWRM1_ADCL 3 | ||
914 | #define FB_PWRM1_ADCR 2 | ||
915 | #define FB_PWRM1_MICB 1 | ||
916 | #define FB_PWRM1_DIGENB 0 | ||
917 | |||
918 | /* Field Masks */ | ||
919 | #define FM_PWRM1_BSTL 0X1 | ||
920 | #define FM_PWRM1_BSTR 0X1 | ||
921 | #define FM_PWRM1_PGAL 0X1 | ||
922 | #define FM_PWRM1_PGAR 0X1 | ||
923 | #define FM_PWRM1_ADCL 0X1 | ||
924 | #define FM_PWRM1_ADCR 0X1 | ||
925 | #define FM_PWRM1_MICB 0X1 | ||
926 | #define FM_PWRM1_DIGENB 0X1 | ||
927 | |||
928 | /* Field Values */ | ||
929 | #define FV_PWRM1_BSTL_ENABLE 0x1 | ||
930 | #define FV_PWRM1_BSTL_DISABLE 0x0 | ||
931 | #define FV_PWRM1_BSTR_ENABLE 0x1 | ||
932 | #define FV_PWRM1_BSTR_DISABLE 0x0 | ||
933 | #define FV_PWRM1_PGAL_ENABLE 0x1 | ||
934 | #define FV_PWRM1_PGAL_DISABLE 0x0 | ||
935 | #define FV_PWRM1_PGAR_ENABLE 0x1 | ||
936 | #define FV_PWRM1_PGAR_DISABLE 0x0 | ||
937 | #define FV_PWRM1_ADCL_ENABLE 0x1 | ||
938 | #define FV_PWRM1_ADCL_DISABLE 0x0 | ||
939 | #define FV_PWRM1_ADCR_ENABLE 0x1 | ||
940 | #define FV_PWRM1_ADCR_DISABLE 0x0 | ||
941 | #define FV_PWRM1_MICB_ENABLE 0x1 | ||
942 | #define FV_PWRM1_MICB_DISABLE 0x0 | ||
943 | #define FV_PWRM1_DIGENB_DISABLE 0x1 | ||
944 | #define FV_PWRM1_DIGENB_ENABLE 0x0 | ||
945 | |||
946 | /* Register Masks */ | ||
947 | #define RM_PWRM1_BSTL RM(FM_PWRM1_BSTL, FB_PWRM1_BSTL) | ||
948 | #define RM_PWRM1_BSTR RM(FM_PWRM1_BSTR, FB_PWRM1_BSTR) | ||
949 | #define RM_PWRM1_PGAL RM(FM_PWRM1_PGAL, FB_PWRM1_PGAL) | ||
950 | #define RM_PWRM1_PGAR RM(FM_PWRM1_PGAR, FB_PWRM1_PGAR) | ||
951 | #define RM_PWRM1_ADCL RM(FM_PWRM1_ADCL, FB_PWRM1_ADCL) | ||
952 | #define RM_PWRM1_ADCR RM(FM_PWRM1_ADCR, FB_PWRM1_ADCR) | ||
953 | #define RM_PWRM1_MICB RM(FM_PWRM1_MICB, FB_PWRM1_MICB) | ||
954 | #define RM_PWRM1_DIGENB \ | ||
955 | RM(FM_PWRM1_DIGENB, FB_PWRM1_DIGENB) | ||
956 | |||
957 | |||
958 | /* Register Values */ | ||
959 | #define RV_PWRM1_BSTL_ENABLE \ | ||
960 | RV(FV_PWRM1_BSTL_ENABLE, FB_PWRM1_BSTL) | ||
961 | |||
962 | #define RV_PWRM1_BSTL_DISABLE \ | ||
963 | RV(FV_PWRM1_BSTL_DISABLE, FB_PWRM1_BSTL) | ||
964 | |||
965 | #define RV_PWRM1_BSTR_ENABLE \ | ||
966 | RV(FV_PWRM1_BSTR_ENABLE, FB_PWRM1_BSTR) | ||
967 | |||
968 | #define RV_PWRM1_BSTR_DISABLE \ | ||
969 | RV(FV_PWRM1_BSTR_DISABLE, FB_PWRM1_BSTR) | ||
970 | |||
971 | #define RV_PWRM1_PGAL_ENABLE \ | ||
972 | RV(FV_PWRM1_PGAL_ENABLE, FB_PWRM1_PGAL) | ||
973 | |||
974 | #define RV_PWRM1_PGAL_DISABLE \ | ||
975 | RV(FV_PWRM1_PGAL_DISABLE, FB_PWRM1_PGAL) | ||
976 | |||
977 | #define RV_PWRM1_PGAR_ENABLE \ | ||
978 | RV(FV_PWRM1_PGAR_ENABLE, FB_PWRM1_PGAR) | ||
979 | |||
980 | #define RV_PWRM1_PGAR_DISABLE \ | ||
981 | RV(FV_PWRM1_PGAR_DISABLE, FB_PWRM1_PGAR) | ||
982 | |||
983 | #define RV_PWRM1_ADCL_ENABLE \ | ||
984 | RV(FV_PWRM1_ADCL_ENABLE, FB_PWRM1_ADCL) | ||
985 | |||
986 | #define RV_PWRM1_ADCL_DISABLE \ | ||
987 | RV(FV_PWRM1_ADCL_DISABLE, FB_PWRM1_ADCL) | ||
988 | |||
989 | #define RV_PWRM1_ADCR_ENABLE \ | ||
990 | RV(FV_PWRM1_ADCR_ENABLE, FB_PWRM1_ADCR) | ||
991 | |||
992 | #define RV_PWRM1_ADCR_DISABLE \ | ||
993 | RV(FV_PWRM1_ADCR_DISABLE, FB_PWRM1_ADCR) | ||
994 | |||
995 | #define RV_PWRM1_MICB_ENABLE \ | ||
996 | RV(FV_PWRM1_MICB_ENABLE, FB_PWRM1_MICB) | ||
997 | |||
998 | #define RV_PWRM1_MICB_DISABLE \ | ||
999 | RV(FV_PWRM1_MICB_DISABLE, FB_PWRM1_MICB) | ||
1000 | |||
1001 | #define RV_PWRM1_DIGENB_DISABLE \ | ||
1002 | RV(FV_PWRM1_DIGENB_DISABLE, FB_PWRM1_DIGENB) | ||
1003 | |||
1004 | #define RV_PWRM1_DIGENB_ENABLE \ | ||
1005 | RV(FV_PWRM1_DIGENB_ENABLE, FB_PWRM1_DIGENB) | ||
1006 | |||
1007 | |||
1008 | /**************************** | ||
1009 | * R_PWRM2 (0x1B) * | ||
1010 | ****************************/ | ||
1011 | |||
1012 | /* Field Offsets */ | ||
1013 | #define FB_PWRM2_D2S 7 | ||
1014 | #define FB_PWRM2_HPL 6 | ||
1015 | #define FB_PWRM2_HPR 5 | ||
1016 | #define FB_PWRM2_SPKL 4 | ||
1017 | #define FB_PWRM2_SPKR 3 | ||
1018 | #define FB_PWRM2_INSELL 2 | ||
1019 | #define FB_PWRM2_INSELR 1 | ||
1020 | #define FB_PWRM2_VREF 0 | ||
1021 | |||
1022 | /* Field Masks */ | ||
1023 | #define FM_PWRM2_D2S 0X1 | ||
1024 | #define FM_PWRM2_HPL 0X1 | ||
1025 | #define FM_PWRM2_HPR 0X1 | ||
1026 | #define FM_PWRM2_SPKL 0X1 | ||
1027 | #define FM_PWRM2_SPKR 0X1 | ||
1028 | #define FM_PWRM2_INSELL 0X1 | ||
1029 | #define FM_PWRM2_INSELR 0X1 | ||
1030 | #define FM_PWRM2_VREF 0X1 | ||
1031 | |||
1032 | /* Field Values */ | ||
1033 | #define FV_PWRM2_D2S_ENABLE 0x1 | ||
1034 | #define FV_PWRM2_D2S_DISABLE 0x0 | ||
1035 | #define FV_PWRM2_HPL_ENABLE 0x1 | ||
1036 | #define FV_PWRM2_HPL_DISABLE 0x0 | ||
1037 | #define FV_PWRM2_HPR_ENABLE 0x1 | ||
1038 | #define FV_PWRM2_HPR_DISABLE 0x0 | ||
1039 | #define FV_PWRM2_SPKL_ENABLE 0x1 | ||
1040 | #define FV_PWRM2_SPKL_DISABLE 0x0 | ||
1041 | #define FV_PWRM2_SPKR_ENABLE 0x1 | ||
1042 | #define FV_PWRM2_SPKR_DISABLE 0x0 | ||
1043 | #define FV_PWRM2_INSELL_ENABLE 0x1 | ||
1044 | #define FV_PWRM2_INSELL_DISABLE 0x0 | ||
1045 | #define FV_PWRM2_INSELR_ENABLE 0x1 | ||
1046 | #define FV_PWRM2_INSELR_DISABLE 0x0 | ||
1047 | #define FV_PWRM2_VREF_ENABLE 0x1 | ||
1048 | #define FV_PWRM2_VREF_DISABLE 0x0 | ||
1049 | |||
1050 | /* Register Masks */ | ||
1051 | #define RM_PWRM2_D2S RM(FM_PWRM2_D2S, FB_PWRM2_D2S) | ||
1052 | #define RM_PWRM2_HPL RM(FM_PWRM2_HPL, FB_PWRM2_HPL) | ||
1053 | #define RM_PWRM2_HPR RM(FM_PWRM2_HPR, FB_PWRM2_HPR) | ||
1054 | #define RM_PWRM2_SPKL RM(FM_PWRM2_SPKL, FB_PWRM2_SPKL) | ||
1055 | #define RM_PWRM2_SPKR RM(FM_PWRM2_SPKR, FB_PWRM2_SPKR) | ||
1056 | #define RM_PWRM2_INSELL \ | ||
1057 | RM(FM_PWRM2_INSELL, FB_PWRM2_INSELL) | ||
1058 | |||
1059 | #define RM_PWRM2_INSELR \ | ||
1060 | RM(FM_PWRM2_INSELR, FB_PWRM2_INSELR) | ||
1061 | |||
1062 | #define RM_PWRM2_VREF RM(FM_PWRM2_VREF, FB_PWRM2_VREF) | ||
1063 | |||
1064 | /* Register Values */ | ||
1065 | #define RV_PWRM2_D2S_ENABLE \ | ||
1066 | RV(FV_PWRM2_D2S_ENABLE, FB_PWRM2_D2S) | ||
1067 | |||
1068 | #define RV_PWRM2_D2S_DISABLE \ | ||
1069 | RV(FV_PWRM2_D2S_DISABLE, FB_PWRM2_D2S) | ||
1070 | |||
1071 | #define RV_PWRM2_HPL_ENABLE \ | ||
1072 | RV(FV_PWRM2_HPL_ENABLE, FB_PWRM2_HPL) | ||
1073 | |||
1074 | #define RV_PWRM2_HPL_DISABLE \ | ||
1075 | RV(FV_PWRM2_HPL_DISABLE, FB_PWRM2_HPL) | ||
1076 | |||
1077 | #define RV_PWRM2_HPR_ENABLE \ | ||
1078 | RV(FV_PWRM2_HPR_ENABLE, FB_PWRM2_HPR) | ||
1079 | |||
1080 | #define RV_PWRM2_HPR_DISABLE \ | ||
1081 | RV(FV_PWRM2_HPR_DISABLE, FB_PWRM2_HPR) | ||
1082 | |||
1083 | #define RV_PWRM2_SPKL_ENABLE \ | ||
1084 | RV(FV_PWRM2_SPKL_ENABLE, FB_PWRM2_SPKL) | ||
1085 | |||
1086 | #define RV_PWRM2_SPKL_DISABLE \ | ||
1087 | RV(FV_PWRM2_SPKL_DISABLE, FB_PWRM2_SPKL) | ||
1088 | |||
1089 | #define RV_PWRM2_SPKR_ENABLE \ | ||
1090 | RV(FV_PWRM2_SPKR_ENABLE, FB_PWRM2_SPKR) | ||
1091 | |||
1092 | #define RV_PWRM2_SPKR_DISABLE \ | ||
1093 | RV(FV_PWRM2_SPKR_DISABLE, FB_PWRM2_SPKR) | ||
1094 | |||
1095 | #define RV_PWRM2_INSELL_ENABLE \ | ||
1096 | RV(FV_PWRM2_INSELL_ENABLE, FB_PWRM2_INSELL) | ||
1097 | |||
1098 | #define RV_PWRM2_INSELL_DISABLE \ | ||
1099 | RV(FV_PWRM2_INSELL_DISABLE, FB_PWRM2_INSELL) | ||
1100 | |||
1101 | #define RV_PWRM2_INSELR_ENABLE \ | ||
1102 | RV(FV_PWRM2_INSELR_ENABLE, FB_PWRM2_INSELR) | ||
1103 | |||
1104 | #define RV_PWRM2_INSELR_DISABLE \ | ||
1105 | RV(FV_PWRM2_INSELR_DISABLE, FB_PWRM2_INSELR) | ||
1106 | |||
1107 | #define RV_PWRM2_VREF_ENABLE \ | ||
1108 | RV(FV_PWRM2_VREF_ENABLE, FB_PWRM2_VREF) | ||
1109 | |||
1110 | #define RV_PWRM2_VREF_DISABLE \ | ||
1111 | RV(FV_PWRM2_VREF_DISABLE, FB_PWRM2_VREF) | ||
1112 | |||
1113 | |||
1114 | /****************************** | ||
1115 | * R_CONFIG0 (0x1F) * | ||
1116 | ******************************/ | ||
1117 | |||
1118 | /* Field Offsets */ | ||
1119 | #define FB_CONFIG0_ASDM 6 | ||
1120 | #define FB_CONFIG0_DSDM 4 | ||
1121 | #define FB_CONFIG0_DC_BYPASS 1 | ||
1122 | #define FB_CONFIG0_SD_FORCE_ON 0 | ||
1123 | |||
1124 | /* Field Masks */ | ||
1125 | #define FM_CONFIG0_ASDM 0X3 | ||
1126 | #define FM_CONFIG0_DSDM 0X3 | ||
1127 | #define FM_CONFIG0_DC_BYPASS 0X1 | ||
1128 | #define FM_CONFIG0_SD_FORCE_ON 0X1 | ||
1129 | |||
1130 | /* Field Values */ | ||
1131 | #define FV_CONFIG0_ASDM_HALF 0x1 | ||
1132 | #define FV_CONFIG0_ASDM_FULL 0x2 | ||
1133 | #define FV_CONFIG0_ASDM_AUTO 0x3 | ||
1134 | #define FV_CONFIG0_DSDM_HALF 0x1 | ||
1135 | #define FV_CONFIG0_DSDM_FULL 0x2 | ||
1136 | #define FV_CONFIG0_DSDM_AUTO 0x3 | ||
1137 | #define FV_CONFIG0_DC_BYPASS_ENABLE 0x1 | ||
1138 | #define FV_CONFIG0_DC_BYPASS_DISABLE 0x0 | ||
1139 | #define FV_CONFIG0_SD_FORCE_ON_ENABLE 0x1 | ||
1140 | #define FV_CONFIG0_SD_FORCE_ON_DISABLE 0x0 | ||
1141 | |||
1142 | /* Register Masks */ | ||
1143 | #define RM_CONFIG0_ASDM \ | ||
1144 | RM(FM_CONFIG0_ASDM, FB_CONFIG0_ASDM) | ||
1145 | |||
1146 | #define RM_CONFIG0_DSDM \ | ||
1147 | RM(FM_CONFIG0_DSDM, FB_CONFIG0_DSDM) | ||
1148 | |||
1149 | #define RM_CONFIG0_DC_BYPASS \ | ||
1150 | RM(FM_CONFIG0_DC_BYPASS, FB_CONFIG0_DC_BYPASS) | ||
1151 | |||
1152 | #define RM_CONFIG0_SD_FORCE_ON \ | ||
1153 | RM(FM_CONFIG0_SD_FORCE_ON, FB_CONFIG0_SD_FORCE_ON) | ||
1154 | |||
1155 | |||
1156 | /* Register Values */ | ||
1157 | #define RV_CONFIG0_ASDM_HALF \ | ||
1158 | RV(FV_CONFIG0_ASDM_HALF, FB_CONFIG0_ASDM) | ||
1159 | |||
1160 | #define RV_CONFIG0_ASDM_FULL \ | ||
1161 | RV(FV_CONFIG0_ASDM_FULL, FB_CONFIG0_ASDM) | ||
1162 | |||
1163 | #define RV_CONFIG0_ASDM_AUTO \ | ||
1164 | RV(FV_CONFIG0_ASDM_AUTO, FB_CONFIG0_ASDM) | ||
1165 | |||
1166 | #define RV_CONFIG0_DSDM_HALF \ | ||
1167 | RV(FV_CONFIG0_DSDM_HALF, FB_CONFIG0_DSDM) | ||
1168 | |||
1169 | #define RV_CONFIG0_DSDM_FULL \ | ||
1170 | RV(FV_CONFIG0_DSDM_FULL, FB_CONFIG0_DSDM) | ||
1171 | |||
1172 | #define RV_CONFIG0_DSDM_AUTO \ | ||
1173 | RV(FV_CONFIG0_DSDM_AUTO, FB_CONFIG0_DSDM) | ||
1174 | |||
1175 | #define RV_CONFIG0_DC_BYPASS_ENABLE \ | ||
1176 | RV(FV_CONFIG0_DC_BYPASS_ENABLE, FB_CONFIG0_DC_BYPASS) | ||
1177 | |||
1178 | #define RV_CONFIG0_DC_BYPASS_DISABLE \ | ||
1179 | RV(FV_CONFIG0_DC_BYPASS_DISABLE, FB_CONFIG0_DC_BYPASS) | ||
1180 | |||
1181 | #define RV_CONFIG0_SD_FORCE_ON_ENABLE \ | ||
1182 | RV(FV_CONFIG0_SD_FORCE_ON_ENABLE, FB_CONFIG0_SD_FORCE_ON) | ||
1183 | |||
1184 | #define RV_CONFIG0_SD_FORCE_ON_DISABLE \ | ||
1185 | RV(FV_CONFIG0_SD_FORCE_ON_DISABLE, FB_CONFIG0_SD_FORCE_ON) | ||
1186 | |||
1187 | |||
1188 | /****************************** | ||
1189 | * R_CONFIG1 (0x20) * | ||
1190 | ******************************/ | ||
1191 | |||
1192 | /* Field Offsets */ | ||
1193 | #define FB_CONFIG1_EQ2_EN 7 | ||
1194 | #define FB_CONFIG1_EQ2_BE 4 | ||
1195 | #define FB_CONFIG1_EQ1_EN 3 | ||
1196 | #define FB_CONFIG1_EQ1_BE 0 | ||
1197 | |||
1198 | /* Field Masks */ | ||
1199 | #define FM_CONFIG1_EQ2_EN 0X1 | ||
1200 | #define FM_CONFIG1_EQ2_BE 0X7 | ||
1201 | #define FM_CONFIG1_EQ1_EN 0X1 | ||
1202 | #define FM_CONFIG1_EQ1_BE 0X7 | ||
1203 | |||
1204 | /* Field Values */ | ||
1205 | #define FV_CONFIG1_EQ2_EN_ENABLE 0x1 | ||
1206 | #define FV_CONFIG1_EQ2_EN_DISABLE 0x0 | ||
1207 | #define FV_CONFIG1_EQ2_BE_PRE 0x0 | ||
1208 | #define FV_CONFIG1_EQ2_BE_PRE_EQ_0 0x1 | ||
1209 | #define FV_CONFIG1_EQ2_BE_PRE_EQ0_1 0x2 | ||
1210 | #define FV_CONFIG1_EQ2_BE_PRE_EQ0_2 0x3 | ||
1211 | #define FV_CONFIG1_EQ2_BE_PRE_EQ0_3 0x4 | ||
1212 | #define FV_CONFIG1_EQ2_BE_PRE_EQ0_4 0x5 | ||
1213 | #define FV_CONFIG1_EQ2_BE_PRE_EQ0_5 0x6 | ||
1214 | #define FV_CONFIG1_EQ1_EN_ENABLE 0x1 | ||
1215 | #define FV_CONFIG1_EQ1_EN_DISABLE 0x0 | ||
1216 | #define FV_CONFIG1_EQ1_BE_PRE 0x0 | ||
1217 | #define FV_CONFIG1_EQ1_BE_PRE_EQ_0 0x1 | ||
1218 | #define FV_CONFIG1_EQ1_BE_PRE_EQ0_1 0x2 | ||
1219 | #define FV_CONFIG1_EQ1_BE_PRE_EQ0_2 0x3 | ||
1220 | #define FV_CONFIG1_EQ1_BE_PRE_EQ0_3 0x4 | ||
1221 | #define FV_CONFIG1_EQ1_BE_PRE_EQ0_4 0x5 | ||
1222 | #define FV_CONFIG1_EQ1_BE_PRE_EQ0_5 0x6 | ||
1223 | |||
1224 | /* Register Masks */ | ||
1225 | #define RM_CONFIG1_EQ2_EN \ | ||
1226 | RM(FM_CONFIG1_EQ2_EN, FB_CONFIG1_EQ2_EN) | ||
1227 | |||
1228 | #define RM_CONFIG1_EQ2_BE \ | ||
1229 | RM(FM_CONFIG1_EQ2_BE, FB_CONFIG1_EQ2_BE) | ||
1230 | |||
1231 | #define RM_CONFIG1_EQ1_EN \ | ||
1232 | RM(FM_CONFIG1_EQ1_EN, FB_CONFIG1_EQ1_EN) | ||
1233 | |||
1234 | #define RM_CONFIG1_EQ1_BE \ | ||
1235 | RM(FM_CONFIG1_EQ1_BE, FB_CONFIG1_EQ1_BE) | ||
1236 | |||
1237 | |||
1238 | /* Register Values */ | ||
1239 | #define RV_CONFIG1_EQ2_EN_ENABLE \ | ||
1240 | RV(FV_CONFIG1_EQ2_EN_ENABLE, FB_CONFIG1_EQ2_EN) | ||
1241 | |||
1242 | #define RV_CONFIG1_EQ2_EN_DISABLE \ | ||
1243 | RV(FV_CONFIG1_EQ2_EN_DISABLE, FB_CONFIG1_EQ2_EN) | ||
1244 | |||
1245 | #define RV_CONFIG1_EQ2_BE_PRE \ | ||
1246 | RV(FV_CONFIG1_EQ2_BE_PRE, FB_CONFIG1_EQ2_BE) | ||
1247 | |||
1248 | #define RV_CONFIG1_EQ2_BE_PRE_EQ_0 \ | ||
1249 | RV(FV_CONFIG1_EQ2_BE_PRE_EQ_0, FB_CONFIG1_EQ2_BE) | ||
1250 | |||
1251 | #define RV_CONFIG1_EQ2_BE_PRE_EQ0_1 \ | ||
1252 | RV(FV_CONFIG1_EQ2_BE_PRE_EQ0_1, FB_CONFIG1_EQ2_BE) | ||
1253 | |||
1254 | #define RV_CONFIG1_EQ2_BE_PRE_EQ0_2 \ | ||
1255 | RV(FV_CONFIG1_EQ2_BE_PRE_EQ0_2, FB_CONFIG1_EQ2_BE) | ||
1256 | |||
1257 | #define RV_CONFIG1_EQ2_BE_PRE_EQ0_3 \ | ||
1258 | RV(FV_CONFIG1_EQ2_BE_PRE_EQ0_3, FB_CONFIG1_EQ2_BE) | ||
1259 | |||
1260 | #define RV_CONFIG1_EQ2_BE_PRE_EQ0_4 \ | ||
1261 | RV(FV_CONFIG1_EQ2_BE_PRE_EQ0_4, FB_CONFIG1_EQ2_BE) | ||
1262 | |||
1263 | #define RV_CONFIG1_EQ2_BE_PRE_EQ0_5 \ | ||
1264 | RV(FV_CONFIG1_EQ2_BE_PRE_EQ0_5, FB_CONFIG1_EQ2_BE) | ||
1265 | |||
1266 | #define RV_CONFIG1_EQ1_EN_ENABLE \ | ||
1267 | RV(FV_CONFIG1_EQ1_EN_ENABLE, FB_CONFIG1_EQ1_EN) | ||
1268 | |||
1269 | #define RV_CONFIG1_EQ1_EN_DISABLE \ | ||
1270 | RV(FV_CONFIG1_EQ1_EN_DISABLE, FB_CONFIG1_EQ1_EN) | ||
1271 | |||
1272 | #define RV_CONFIG1_EQ1_BE_PRE \ | ||
1273 | RV(FV_CONFIG1_EQ1_BE_PRE, FB_CONFIG1_EQ1_BE) | ||
1274 | |||
1275 | #define RV_CONFIG1_EQ1_BE_PRE_EQ_0 \ | ||
1276 | RV(FV_CONFIG1_EQ1_BE_PRE_EQ_0, FB_CONFIG1_EQ1_BE) | ||
1277 | |||
1278 | #define RV_CONFIG1_EQ1_BE_PRE_EQ0_1 \ | ||
1279 | RV(FV_CONFIG1_EQ1_BE_PRE_EQ0_1, FB_CONFIG1_EQ1_BE) | ||
1280 | |||
1281 | #define RV_CONFIG1_EQ1_BE_PRE_EQ0_2 \ | ||
1282 | RV(FV_CONFIG1_EQ1_BE_PRE_EQ0_2, FB_CONFIG1_EQ1_BE) | ||
1283 | |||
1284 | #define RV_CONFIG1_EQ1_BE_PRE_EQ0_3 \ | ||
1285 | RV(FV_CONFIG1_EQ1_BE_PRE_EQ0_3, FB_CONFIG1_EQ1_BE) | ||
1286 | |||
1287 | #define RV_CONFIG1_EQ1_BE_PRE_EQ0_4 \ | ||
1288 | RV(FV_CONFIG1_EQ1_BE_PRE_EQ0_4, FB_CONFIG1_EQ1_BE) | ||
1289 | |||
1290 | #define RV_CONFIG1_EQ1_BE_PRE_EQ0_5 \ | ||
1291 | RV(FV_CONFIG1_EQ1_BE_PRE_EQ0_5, FB_CONFIG1_EQ1_BE) | ||
1292 | |||
1293 | |||
1294 | /****************************** | ||
1295 | * R_DMICCTL (0x24) * | ||
1296 | ******************************/ | ||
1297 | |||
1298 | /* Field Offsets */ | ||
1299 | #define FB_DMICCTL_DMICEN 7 | ||
1300 | #define FB_DMICCTL_DMONO 4 | ||
1301 | #define FB_DMICCTL_DMPHADJ 2 | ||
1302 | #define FB_DMICCTL_DMRATE 0 | ||
1303 | |||
1304 | /* Field Masks */ | ||
1305 | #define FM_DMICCTL_DMICEN 0X1 | ||
1306 | #define FM_DMICCTL_DMONO 0X1 | ||
1307 | #define FM_DMICCTL_DMPHADJ 0X3 | ||
1308 | #define FM_DMICCTL_DMRATE 0X3 | ||
1309 | |||
1310 | /* Field Values */ | ||
1311 | #define FV_DMICCTL_DMICEN_ENABLE 0x1 | ||
1312 | #define FV_DMICCTL_DMICEN_DISABLE 0x0 | ||
1313 | #define FV_DMICCTL_DMONO_STEREO 0x0 | ||
1314 | #define FV_DMICCTL_DMONO_MONO 0x1 | ||
1315 | |||
1316 | /* Register Masks */ | ||
1317 | #define RM_DMICCTL_DMICEN \ | ||
1318 | RM(FM_DMICCTL_DMICEN, FB_DMICCTL_DMICEN) | ||
1319 | |||
1320 | #define RM_DMICCTL_DMONO \ | ||
1321 | RM(FM_DMICCTL_DMONO, FB_DMICCTL_DMONO) | ||
1322 | |||
1323 | #define RM_DMICCTL_DMPHADJ \ | ||
1324 | RM(FM_DMICCTL_DMPHADJ, FB_DMICCTL_DMPHADJ) | ||
1325 | |||
1326 | #define RM_DMICCTL_DMRATE \ | ||
1327 | RM(FM_DMICCTL_DMRATE, FB_DMICCTL_DMRATE) | ||
1328 | |||
1329 | |||
1330 | /* Register Values */ | ||
1331 | #define RV_DMICCTL_DMICEN_ENABLE \ | ||
1332 | RV(FV_DMICCTL_DMICEN_ENABLE, FB_DMICCTL_DMICEN) | ||
1333 | |||
1334 | #define RV_DMICCTL_DMICEN_DISABLE \ | ||
1335 | RV(FV_DMICCTL_DMICEN_DISABLE, FB_DMICCTL_DMICEN) | ||
1336 | |||
1337 | #define RV_DMICCTL_DMONO_STEREO \ | ||
1338 | RV(FV_DMICCTL_DMONO_STEREO, FB_DMICCTL_DMONO) | ||
1339 | |||
1340 | #define RV_DMICCTL_DMONO_MONO \ | ||
1341 | RV(FV_DMICCTL_DMONO_MONO, FB_DMICCTL_DMONO) | ||
1342 | |||
1343 | |||
1344 | /***************************** | ||
1345 | * R_CLECTL (0x25) * | ||
1346 | *****************************/ | ||
1347 | |||
1348 | /* Field Offsets */ | ||
1349 | #define FB_CLECTL_LVL_MODE 4 | ||
1350 | #define FB_CLECTL_WINDOWSEL 3 | ||
1351 | #define FB_CLECTL_EXP_EN 2 | ||
1352 | #define FB_CLECTL_LIMIT_EN 1 | ||
1353 | #define FB_CLECTL_COMP_EN 0 | ||
1354 | |||
1355 | /* Field Masks */ | ||
1356 | #define FM_CLECTL_LVL_MODE 0X1 | ||
1357 | #define FM_CLECTL_WINDOWSEL 0X1 | ||
1358 | #define FM_CLECTL_EXP_EN 0X1 | ||
1359 | #define FM_CLECTL_LIMIT_EN 0X1 | ||
1360 | #define FM_CLECTL_COMP_EN 0X1 | ||
1361 | |||
1362 | /* Field Values */ | ||
1363 | #define FV_CLECTL_LVL_MODE_AVG 0x0 | ||
1364 | #define FV_CLECTL_LVL_MODE_PEAK 0x1 | ||
1365 | #define FV_CLECTL_WINDOWSEL_512 0x0 | ||
1366 | #define FV_CLECTL_WINDOWSEL_64 0x1 | ||
1367 | #define FV_CLECTL_EXP_EN_ENABLE 0x1 | ||
1368 | #define FV_CLECTL_EXP_EN_DISABLE 0x0 | ||
1369 | #define FV_CLECTL_LIMIT_EN_ENABLE 0x1 | ||
1370 | #define FV_CLECTL_LIMIT_EN_DISABLE 0x0 | ||
1371 | #define FV_CLECTL_COMP_EN_ENABLE 0x1 | ||
1372 | #define FV_CLECTL_COMP_EN_DISABLE 0x0 | ||
1373 | |||
1374 | /* Register Masks */ | ||
1375 | #define RM_CLECTL_LVL_MODE \ | ||
1376 | RM(FM_CLECTL_LVL_MODE, FB_CLECTL_LVL_MODE) | ||
1377 | |||
1378 | #define RM_CLECTL_WINDOWSEL \ | ||
1379 | RM(FM_CLECTL_WINDOWSEL, FB_CLECTL_WINDOWSEL) | ||
1380 | |||
1381 | #define RM_CLECTL_EXP_EN \ | ||
1382 | RM(FM_CLECTL_EXP_EN, FB_CLECTL_EXP_EN) | ||
1383 | |||
1384 | #define RM_CLECTL_LIMIT_EN \ | ||
1385 | RM(FM_CLECTL_LIMIT_EN, FB_CLECTL_LIMIT_EN) | ||
1386 | |||
1387 | #define RM_CLECTL_COMP_EN \ | ||
1388 | RM(FM_CLECTL_COMP_EN, FB_CLECTL_COMP_EN) | ||
1389 | |||
1390 | |||
1391 | /* Register Values */ | ||
1392 | #define RV_CLECTL_LVL_MODE_AVG \ | ||
1393 | RV(FV_CLECTL_LVL_MODE_AVG, FB_CLECTL_LVL_MODE) | ||
1394 | |||
1395 | #define RV_CLECTL_LVL_MODE_PEAK \ | ||
1396 | RV(FV_CLECTL_LVL_MODE_PEAK, FB_CLECTL_LVL_MODE) | ||
1397 | |||
1398 | #define RV_CLECTL_WINDOWSEL_512 \ | ||
1399 | RV(FV_CLECTL_WINDOWSEL_512, FB_CLECTL_WINDOWSEL) | ||
1400 | |||
1401 | #define RV_CLECTL_WINDOWSEL_64 \ | ||
1402 | RV(FV_CLECTL_WINDOWSEL_64, FB_CLECTL_WINDOWSEL) | ||
1403 | |||
1404 | #define RV_CLECTL_EXP_EN_ENABLE \ | ||
1405 | RV(FV_CLECTL_EXP_EN_ENABLE, FB_CLECTL_EXP_EN) | ||
1406 | |||
1407 | #define RV_CLECTL_EXP_EN_DISABLE \ | ||
1408 | RV(FV_CLECTL_EXP_EN_DISABLE, FB_CLECTL_EXP_EN) | ||
1409 | |||
1410 | #define RV_CLECTL_LIMIT_EN_ENABLE \ | ||
1411 | RV(FV_CLECTL_LIMIT_EN_ENABLE, FB_CLECTL_LIMIT_EN) | ||
1412 | |||
1413 | #define RV_CLECTL_LIMIT_EN_DISABLE \ | ||
1414 | RV(FV_CLECTL_LIMIT_EN_DISABLE, FB_CLECTL_LIMIT_EN) | ||
1415 | |||
1416 | #define RV_CLECTL_COMP_EN_ENABLE \ | ||
1417 | RV(FV_CLECTL_COMP_EN_ENABLE, FB_CLECTL_COMP_EN) | ||
1418 | |||
1419 | #define RV_CLECTL_COMP_EN_DISABLE \ | ||
1420 | RV(FV_CLECTL_COMP_EN_DISABLE, FB_CLECTL_COMP_EN) | ||
1421 | |||
1422 | |||
1423 | /***************************** | ||
1424 | * R_MUGAIN (0x26) * | ||
1425 | *****************************/ | ||
1426 | |||
1427 | /* Field Offsets */ | ||
1428 | #define FB_MUGAIN_CLEMUG 0 | ||
1429 | |||
1430 | /* Field Masks */ | ||
1431 | #define FM_MUGAIN_CLEMUG 0X1F | ||
1432 | |||
1433 | /* Field Values */ | ||
1434 | #define FV_MUGAIN_CLEMUG_46PT5DB 0x1F | ||
1435 | #define FV_MUGAIN_CLEMUG_0DB 0x0 | ||
1436 | |||
1437 | /* Register Masks */ | ||
1438 | #define RM_MUGAIN_CLEMUG \ | ||
1439 | RM(FM_MUGAIN_CLEMUG, FB_MUGAIN_CLEMUG) | ||
1440 | |||
1441 | |||
1442 | /* Register Values */ | ||
1443 | #define RV_MUGAIN_CLEMUG_46PT5DB \ | ||
1444 | RV(FV_MUGAIN_CLEMUG_46PT5DB, FB_MUGAIN_CLEMUG) | ||
1445 | |||
1446 | #define RV_MUGAIN_CLEMUG_0DB \ | ||
1447 | RV(FV_MUGAIN_CLEMUG_0DB, FB_MUGAIN_CLEMUG) | ||
1448 | |||
1449 | |||
1450 | /***************************** | ||
1451 | * R_COMPTH (0x27) * | ||
1452 | *****************************/ | ||
1453 | |||
1454 | /* Field Offsets */ | ||
1455 | #define FB_COMPTH 0 | ||
1456 | |||
1457 | /* Field Masks */ | ||
1458 | #define FM_COMPTH 0XFF | ||
1459 | |||
1460 | /* Field Values */ | ||
1461 | #define FV_COMPTH_0DB 0xFF | ||
1462 | #define FV_COMPTH_N95PT625DB 0x0 | ||
1463 | |||
1464 | /* Register Masks */ | ||
1465 | #define RM_COMPTH RM(FM_COMPTH, FB_COMPTH) | ||
1466 | |||
1467 | /* Register Values */ | ||
1468 | #define RV_COMPTH_0DB RV(FV_COMPTH_0DB, FB_COMPTH) | ||
1469 | #define RV_COMPTH_N95PT625DB \ | ||
1470 | RV(FV_COMPTH_N95PT625DB, FB_COMPTH) | ||
1471 | |||
1472 | |||
1473 | /***************************** | ||
1474 | * R_CMPRAT (0x28) * | ||
1475 | *****************************/ | ||
1476 | |||
1477 | /* Field Offsets */ | ||
1478 | #define FB_CMPRAT 0 | ||
1479 | |||
1480 | /* Field Masks */ | ||
1481 | #define FM_CMPRAT 0X1F | ||
1482 | |||
1483 | /* Register Masks */ | ||
1484 | #define RM_CMPRAT RM(FM_CMPRAT, FB_CMPRAT) | ||
1485 | |||
1486 | /****************************** | ||
1487 | * R_CATKTCL (0x29) * | ||
1488 | ******************************/ | ||
1489 | |||
1490 | /* Field Offsets */ | ||
1491 | #define FB_CATKTCL 0 | ||
1492 | |||
1493 | /* Field Masks */ | ||
1494 | #define FM_CATKTCL 0XFF | ||
1495 | |||
1496 | /* Register Masks */ | ||
1497 | #define RM_CATKTCL RM(FM_CATKTCL, FB_CATKTCL) | ||
1498 | |||
1499 | /****************************** | ||
1500 | * R_CATKTCH (0x2A) * | ||
1501 | ******************************/ | ||
1502 | |||
1503 | /* Field Offsets */ | ||
1504 | #define FB_CATKTCH 0 | ||
1505 | |||
1506 | /* Field Masks */ | ||
1507 | #define FM_CATKTCH 0XFF | ||
1508 | |||
1509 | /* Register Masks */ | ||
1510 | #define RM_CATKTCH RM(FM_CATKTCH, FB_CATKTCH) | ||
1511 | |||
1512 | /****************************** | ||
1513 | * R_CRELTCL (0x2B) * | ||
1514 | ******************************/ | ||
1515 | |||
1516 | /* Field Offsets */ | ||
1517 | #define FB_CRELTCL 0 | ||
1518 | |||
1519 | /* Field Masks */ | ||
1520 | #define FM_CRELTCL 0XFF | ||
1521 | |||
1522 | /* Register Masks */ | ||
1523 | #define RM_CRELTCL RM(FM_CRELTCL, FB_CRELTCL) | ||
1524 | |||
1525 | /****************************** | ||
1526 | * R_CRELTCH (0x2C) * | ||
1527 | ******************************/ | ||
1528 | |||
1529 | /* Field Offsets */ | ||
1530 | #define FB_CRELTCH 0 | ||
1531 | |||
1532 | /* Field Masks */ | ||
1533 | #define FM_CRELTCH 0XFF | ||
1534 | |||
1535 | /* Register Masks */ | ||
1536 | #define RM_CRELTCH RM(FM_CRELTCH, FB_CRELTCH) | ||
1537 | |||
1538 | /**************************** | ||
1539 | * R_LIMTH (0x2D) * | ||
1540 | ****************************/ | ||
1541 | |||
1542 | /* Field Offsets */ | ||
1543 | #define FB_LIMTH 0 | ||
1544 | |||
1545 | /* Field Masks */ | ||
1546 | #define FM_LIMTH 0XFF | ||
1547 | |||
1548 | /* Field Values */ | ||
1549 | #define FV_LIMTH_0DB 0xFF | ||
1550 | #define FV_LIMTH_N95PT625DB 0x0 | ||
1551 | |||
1552 | /* Register Masks */ | ||
1553 | #define RM_LIMTH RM(FM_LIMTH, FB_LIMTH) | ||
1554 | |||
1555 | /* Register Values */ | ||
1556 | #define RV_LIMTH_0DB RV(FV_LIMTH_0DB, FB_LIMTH) | ||
1557 | #define RV_LIMTH_N95PT625DB RV(FV_LIMTH_N95PT625DB, FB_LIMTH) | ||
1558 | |||
1559 | /***************************** | ||
1560 | * R_LIMTGT (0x2E) * | ||
1561 | *****************************/ | ||
1562 | |||
1563 | /* Field Offsets */ | ||
1564 | #define FB_LIMTGT 0 | ||
1565 | |||
1566 | /* Field Masks */ | ||
1567 | #define FM_LIMTGT 0XFF | ||
1568 | |||
1569 | /* Field Values */ | ||
1570 | #define FV_LIMTGT_0DB 0xFF | ||
1571 | #define FV_LIMTGT_N95PT625DB 0x0 | ||
1572 | |||
1573 | /* Register Masks */ | ||
1574 | #define RM_LIMTGT RM(FM_LIMTGT, FB_LIMTGT) | ||
1575 | |||
1576 | /* Register Values */ | ||
1577 | #define RV_LIMTGT_0DB RV(FV_LIMTGT_0DB, FB_LIMTGT) | ||
1578 | #define RV_LIMTGT_N95PT625DB \ | ||
1579 | RV(FV_LIMTGT_N95PT625DB, FB_LIMTGT) | ||
1580 | |||
1581 | |||
1582 | /****************************** | ||
1583 | * R_LATKTCL (0x2F) * | ||
1584 | ******************************/ | ||
1585 | |||
1586 | /* Field Offsets */ | ||
1587 | #define FB_LATKTCL 0 | ||
1588 | |||
1589 | /* Field Masks */ | ||
1590 | #define FM_LATKTCL 0XFF | ||
1591 | |||
1592 | /* Register Masks */ | ||
1593 | #define RM_LATKTCL RM(FM_LATKTCL, FB_LATKTCL) | ||
1594 | |||
1595 | /****************************** | ||
1596 | * R_LATKTCH (0x30) * | ||
1597 | ******************************/ | ||
1598 | |||
1599 | /* Field Offsets */ | ||
1600 | #define FB_LATKTCH 0 | ||
1601 | |||
1602 | /* Field Masks */ | ||
1603 | #define FM_LATKTCH 0XFF | ||
1604 | |||
1605 | /* Register Masks */ | ||
1606 | #define RM_LATKTCH RM(FM_LATKTCH, FB_LATKTCH) | ||
1607 | |||
1608 | /****************************** | ||
1609 | * R_LRELTCL (0x31) * | ||
1610 | ******************************/ | ||
1611 | |||
1612 | /* Field Offsets */ | ||
1613 | #define FB_LRELTCL 0 | ||
1614 | |||
1615 | /* Field Masks */ | ||
1616 | #define FM_LRELTCL 0XFF | ||
1617 | |||
1618 | /* Register Masks */ | ||
1619 | #define RM_LRELTCL RM(FM_LRELTCL, FB_LRELTCL) | ||
1620 | |||
1621 | /****************************** | ||
1622 | * R_LRELTCH (0x32) * | ||
1623 | ******************************/ | ||
1624 | |||
1625 | /* Field Offsets */ | ||
1626 | #define FB_LRELTCH 0 | ||
1627 | |||
1628 | /* Field Masks */ | ||
1629 | #define FM_LRELTCH 0XFF | ||
1630 | |||
1631 | /* Register Masks */ | ||
1632 | #define RM_LRELTCH RM(FM_LRELTCH, FB_LRELTCH) | ||
1633 | |||
1634 | /**************************** | ||
1635 | * R_EXPTH (0x33) * | ||
1636 | ****************************/ | ||
1637 | |||
1638 | /* Field Offsets */ | ||
1639 | #define FB_EXPTH 0 | ||
1640 | |||
1641 | /* Field Masks */ | ||
1642 | #define FM_EXPTH 0XFF | ||
1643 | |||
1644 | /* Field Values */ | ||
1645 | #define FV_EXPTH_0DB 0xFF | ||
1646 | #define FV_EXPTH_N95PT625DB 0x0 | ||
1647 | |||
1648 | /* Register Masks */ | ||
1649 | #define RM_EXPTH RM(FM_EXPTH, FB_EXPTH) | ||
1650 | |||
1651 | /* Register Values */ | ||
1652 | #define RV_EXPTH_0DB RV(FV_EXPTH_0DB, FB_EXPTH) | ||
1653 | #define RV_EXPTH_N95PT625DB RV(FV_EXPTH_N95PT625DB, FB_EXPTH) | ||
1654 | |||
1655 | /***************************** | ||
1656 | * R_EXPRAT (0x34) * | ||
1657 | *****************************/ | ||
1658 | |||
1659 | /* Field Offsets */ | ||
1660 | #define FB_EXPRAT 0 | ||
1661 | |||
1662 | /* Field Masks */ | ||
1663 | #define FM_EXPRAT 0X7 | ||
1664 | |||
1665 | /* Register Masks */ | ||
1666 | #define RM_EXPRAT RM(FM_EXPRAT, FB_EXPRAT) | ||
1667 | |||
1668 | /****************************** | ||
1669 | * R_XATKTCL (0x35) * | ||
1670 | ******************************/ | ||
1671 | |||
1672 | /* Field Offsets */ | ||
1673 | #define FB_XATKTCL 0 | ||
1674 | |||
1675 | /* Field Masks */ | ||
1676 | #define FM_XATKTCL 0XFF | ||
1677 | |||
1678 | /* Register Masks */ | ||
1679 | #define RM_XATKTCL RM(FM_XATKTCL, FB_XATKTCL) | ||
1680 | |||
1681 | /****************************** | ||
1682 | * R_XATKTCH (0x36) * | ||
1683 | ******************************/ | ||
1684 | |||
1685 | /* Field Offsets */ | ||
1686 | #define FB_XATKTCH 0 | ||
1687 | |||
1688 | /* Field Masks */ | ||
1689 | #define FM_XATKTCH 0XFF | ||
1690 | |||
1691 | /* Register Masks */ | ||
1692 | #define RM_XATKTCH RM(FM_XATKTCH, FB_XATKTCH) | ||
1693 | |||
1694 | /****************************** | ||
1695 | * R_XRELTCL (0x37) * | ||
1696 | ******************************/ | ||
1697 | |||
1698 | /* Field Offsets */ | ||
1699 | #define FB_XRELTCL 0 | ||
1700 | |||
1701 | /* Field Masks */ | ||
1702 | #define FM_XRELTCL 0XFF | ||
1703 | |||
1704 | /* Register Masks */ | ||
1705 | #define RM_XRELTCL RM(FM_XRELTCL, FB_XRELTCL) | ||
1706 | |||
1707 | /****************************** | ||
1708 | * R_XRELTCH (0x38) * | ||
1709 | ******************************/ | ||
1710 | |||
1711 | /* Field Offsets */ | ||
1712 | #define FB_XRELTCH 0 | ||
1713 | |||
1714 | /* Field Masks */ | ||
1715 | #define FM_XRELTCH 0XFF | ||
1716 | |||
1717 | /* Register Masks */ | ||
1718 | #define RM_XRELTCH RM(FM_XRELTCH, FB_XRELTCH) | ||
1719 | |||
1720 | /**************************** | ||
1721 | * R_FXCTL (0x39) * | ||
1722 | ****************************/ | ||
1723 | |||
1724 | /* Field Offsets */ | ||
1725 | #define FB_FXCTL_3DEN 4 | ||
1726 | #define FB_FXCTL_TEEN 3 | ||
1727 | #define FB_FXCTL_TNLFBYPASS 2 | ||
1728 | #define FB_FXCTL_BEEN 1 | ||
1729 | #define FB_FXCTL_BNLFBYPASS 0 | ||
1730 | |||
1731 | /* Field Masks */ | ||
1732 | #define FM_FXCTL_3DEN 0X1 | ||
1733 | #define FM_FXCTL_TEEN 0X1 | ||
1734 | #define FM_FXCTL_TNLFBYPASS 0X1 | ||
1735 | #define FM_FXCTL_BEEN 0X1 | ||
1736 | #define FM_FXCTL_BNLFBYPASS 0X1 | ||
1737 | |||
1738 | /* Field Values */ | ||
1739 | #define FV_FXCTL_3DEN_ENABLE 0x1 | ||
1740 | #define FV_FXCTL_3DEN_DISABLE 0x0 | ||
1741 | #define FV_FXCTL_TEEN_ENABLE 0x1 | ||
1742 | #define FV_FXCTL_TEEN_DISABLE 0x0 | ||
1743 | #define FV_FXCTL_TNLFBYPASS_ENABLE 0x1 | ||
1744 | #define FV_FXCTL_TNLFBYPASS_DISABLE 0x0 | ||
1745 | #define FV_FXCTL_BEEN_ENABLE 0x1 | ||
1746 | #define FV_FXCTL_BEEN_DISABLE 0x0 | ||
1747 | #define FV_FXCTL_BNLFBYPASS_ENABLE 0x1 | ||
1748 | #define FV_FXCTL_BNLFBYPASS_DISABLE 0x0 | ||
1749 | |||
1750 | /* Register Masks */ | ||
1751 | #define RM_FXCTL_3DEN RM(FM_FXCTL_3DEN, FB_FXCTL_3DEN) | ||
1752 | #define RM_FXCTL_TEEN RM(FM_FXCTL_TEEN, FB_FXCTL_TEEN) | ||
1753 | #define RM_FXCTL_TNLFBYPASS \ | ||
1754 | RM(FM_FXCTL_TNLFBYPASS, FB_FXCTL_TNLFBYPASS) | ||
1755 | |||
1756 | #define RM_FXCTL_BEEN RM(FM_FXCTL_BEEN, FB_FXCTL_BEEN) | ||
1757 | #define RM_FXCTL_BNLFBYPASS \ | ||
1758 | RM(FM_FXCTL_BNLFBYPASS, FB_FXCTL_BNLFBYPASS) | ||
1759 | |||
1760 | |||
1761 | /* Register Values */ | ||
1762 | #define RV_FXCTL_3DEN_ENABLE \ | ||
1763 | RV(FV_FXCTL_3DEN_ENABLE, FB_FXCTL_3DEN) | ||
1764 | |||
1765 | #define RV_FXCTL_3DEN_DISABLE \ | ||
1766 | RV(FV_FXCTL_3DEN_DISABLE, FB_FXCTL_3DEN) | ||
1767 | |||
1768 | #define RV_FXCTL_TEEN_ENABLE \ | ||
1769 | RV(FV_FXCTL_TEEN_ENABLE, FB_FXCTL_TEEN) | ||
1770 | |||
1771 | #define RV_FXCTL_TEEN_DISABLE \ | ||
1772 | RV(FV_FXCTL_TEEN_DISABLE, FB_FXCTL_TEEN) | ||
1773 | |||
1774 | #define RV_FXCTL_TNLFBYPASS_ENABLE \ | ||
1775 | RV(FV_FXCTL_TNLFBYPASS_ENABLE, FB_FXCTL_TNLFBYPASS) | ||
1776 | |||
1777 | #define RV_FXCTL_TNLFBYPASS_DISABLE \ | ||
1778 | RV(FV_FXCTL_TNLFBYPASS_DISABLE, FB_FXCTL_TNLFBYPASS) | ||
1779 | |||
1780 | #define RV_FXCTL_BEEN_ENABLE \ | ||
1781 | RV(FV_FXCTL_BEEN_ENABLE, FB_FXCTL_BEEN) | ||
1782 | |||
1783 | #define RV_FXCTL_BEEN_DISABLE \ | ||
1784 | RV(FV_FXCTL_BEEN_DISABLE, FB_FXCTL_BEEN) | ||
1785 | |||
1786 | #define RV_FXCTL_BNLFBYPASS_ENABLE \ | ||
1787 | RV(FV_FXCTL_BNLFBYPASS_ENABLE, FB_FXCTL_BNLFBYPASS) | ||
1788 | |||
1789 | #define RV_FXCTL_BNLFBYPASS_DISABLE \ | ||
1790 | RV(FV_FXCTL_BNLFBYPASS_DISABLE, FB_FXCTL_BNLFBYPASS) | ||
1791 | |||
1792 | |||
1793 | /******************************* | ||
1794 | * R_DACCRWRL (0x3A) * | ||
1795 | *******************************/ | ||
1796 | |||
1797 | /* Field Offsets */ | ||
1798 | #define FB_DACCRWRL_DACCRWDL 0 | ||
1799 | |||
1800 | /* Field Masks */ | ||
1801 | #define FM_DACCRWRL_DACCRWDL 0XFF | ||
1802 | |||
1803 | /* Register Masks */ | ||
1804 | #define RM_DACCRWRL_DACCRWDL \ | ||
1805 | RM(FM_DACCRWRL_DACCRWDL, FB_DACCRWRL_DACCRWDL) | ||
1806 | |||
1807 | |||
1808 | /******************************* | ||
1809 | * R_DACCRWRM (0x3B) * | ||
1810 | *******************************/ | ||
1811 | |||
1812 | /* Field Offsets */ | ||
1813 | #define FB_DACCRWRM_DACCRWDM 0 | ||
1814 | |||
1815 | /* Field Masks */ | ||
1816 | #define FM_DACCRWRM_DACCRWDM 0XFF | ||
1817 | |||
1818 | /* Register Masks */ | ||
1819 | #define RM_DACCRWRM_DACCRWDM \ | ||
1820 | RM(FM_DACCRWRM_DACCRWDM, FB_DACCRWRM_DACCRWDM) | ||
1821 | |||
1822 | |||
1823 | /******************************* | ||
1824 | * R_DACCRWRH (0x3C) * | ||
1825 | *******************************/ | ||
1826 | |||
1827 | /* Field Offsets */ | ||
1828 | #define FB_DACCRWRH_DACCRWDH 0 | ||
1829 | |||
1830 | /* Field Masks */ | ||
1831 | #define FM_DACCRWRH_DACCRWDH 0XFF | ||
1832 | |||
1833 | /* Register Masks */ | ||
1834 | #define RM_DACCRWRH_DACCRWDH \ | ||
1835 | RM(FM_DACCRWRH_DACCRWDH, FB_DACCRWRH_DACCRWDH) | ||
1836 | |||
1837 | |||
1838 | /******************************* | ||
1839 | * R_DACCRRDL (0x3D) * | ||
1840 | *******************************/ | ||
1841 | |||
1842 | /* Field Offsets */ | ||
1843 | #define FB_DACCRRDL 0 | ||
1844 | |||
1845 | /* Field Masks */ | ||
1846 | #define FM_DACCRRDL 0XFF | ||
1847 | |||
1848 | /* Register Masks */ | ||
1849 | #define RM_DACCRRDL RM(FM_DACCRRDL, FB_DACCRRDL) | ||
1850 | |||
1851 | /******************************* | ||
1852 | * R_DACCRRDM (0x3E) * | ||
1853 | *******************************/ | ||
1854 | |||
1855 | /* Field Offsets */ | ||
1856 | #define FB_DACCRRDM 0 | ||
1857 | |||
1858 | /* Field Masks */ | ||
1859 | #define FM_DACCRRDM 0XFF | ||
1860 | |||
1861 | /* Register Masks */ | ||
1862 | #define RM_DACCRRDM RM(FM_DACCRRDM, FB_DACCRRDM) | ||
1863 | |||
1864 | /******************************* | ||
1865 | * R_DACCRRDH (0x3F) * | ||
1866 | *******************************/ | ||
1867 | |||
1868 | /* Field Offsets */ | ||
1869 | #define FB_DACCRRDH 0 | ||
1870 | |||
1871 | /* Field Masks */ | ||
1872 | #define FM_DACCRRDH 0XFF | ||
1873 | |||
1874 | /* Register Masks */ | ||
1875 | #define RM_DACCRRDH RM(FM_DACCRRDH, FB_DACCRRDH) | ||
1876 | |||
1877 | /******************************** | ||
1878 | * R_DACCRADDR (0x40) * | ||
1879 | ********************************/ | ||
1880 | |||
1881 | /* Field Offsets */ | ||
1882 | #define FB_DACCRADDR_DACCRADD 0 | ||
1883 | |||
1884 | /* Field Masks */ | ||
1885 | #define FM_DACCRADDR_DACCRADD 0XFF | ||
1886 | |||
1887 | /* Register Masks */ | ||
1888 | #define RM_DACCRADDR_DACCRADD \ | ||
1889 | RM(FM_DACCRADDR_DACCRADD, FB_DACCRADDR_DACCRADD) | ||
1890 | |||
1891 | |||
1892 | /****************************** | ||
1893 | * R_DCOFSEL (0x41) * | ||
1894 | ******************************/ | ||
1895 | |||
1896 | /* Field Offsets */ | ||
1897 | #define FB_DCOFSEL_DC_COEF_SEL 0 | ||
1898 | |||
1899 | /* Field Masks */ | ||
1900 | #define FM_DCOFSEL_DC_COEF_SEL 0X7 | ||
1901 | |||
1902 | /* Field Values */ | ||
1903 | #define FV_DCOFSEL_DC_COEF_SEL_2_N8 0x0 | ||
1904 | #define FV_DCOFSEL_DC_COEF_SEL_2_N9 0x1 | ||
1905 | #define FV_DCOFSEL_DC_COEF_SEL_2_N10 0x2 | ||
1906 | #define FV_DCOFSEL_DC_COEF_SEL_2_N11 0x3 | ||
1907 | #define FV_DCOFSEL_DC_COEF_SEL_2_N12 0x4 | ||
1908 | #define FV_DCOFSEL_DC_COEF_SEL_2_N13 0x5 | ||
1909 | #define FV_DCOFSEL_DC_COEF_SEL_2_N14 0x6 | ||
1910 | #define FV_DCOFSEL_DC_COEF_SEL_2_N15 0x7 | ||
1911 | |||
1912 | /* Register Masks */ | ||
1913 | #define RM_DCOFSEL_DC_COEF_SEL \ | ||
1914 | RM(FM_DCOFSEL_DC_COEF_SEL, FB_DCOFSEL_DC_COEF_SEL) | ||
1915 | |||
1916 | |||
1917 | /* Register Values */ | ||
1918 | #define RV_DCOFSEL_DC_COEF_SEL_2_N8 \ | ||
1919 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N8, FB_DCOFSEL_DC_COEF_SEL) | ||
1920 | |||
1921 | #define RV_DCOFSEL_DC_COEF_SEL_2_N9 \ | ||
1922 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N9, FB_DCOFSEL_DC_COEF_SEL) | ||
1923 | |||
1924 | #define RV_DCOFSEL_DC_COEF_SEL_2_N10 \ | ||
1925 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N10, FB_DCOFSEL_DC_COEF_SEL) | ||
1926 | |||
1927 | #define RV_DCOFSEL_DC_COEF_SEL_2_N11 \ | ||
1928 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N11, FB_DCOFSEL_DC_COEF_SEL) | ||
1929 | |||
1930 | #define RV_DCOFSEL_DC_COEF_SEL_2_N12 \ | ||
1931 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N12, FB_DCOFSEL_DC_COEF_SEL) | ||
1932 | |||
1933 | #define RV_DCOFSEL_DC_COEF_SEL_2_N13 \ | ||
1934 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N13, FB_DCOFSEL_DC_COEF_SEL) | ||
1935 | |||
1936 | #define RV_DCOFSEL_DC_COEF_SEL_2_N14 \ | ||
1937 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N14, FB_DCOFSEL_DC_COEF_SEL) | ||
1938 | |||
1939 | #define RV_DCOFSEL_DC_COEF_SEL_2_N15 \ | ||
1940 | RV(FV_DCOFSEL_DC_COEF_SEL_2_N15, FB_DCOFSEL_DC_COEF_SEL) | ||
1941 | |||
1942 | |||
1943 | /****************************** | ||
1944 | * R_PLLCTL9 (0x4E) * | ||
1945 | ******************************/ | ||
1946 | |||
1947 | /* Field Offsets */ | ||
1948 | #define FB_PLLCTL9_REFDIV_PLL1 0 | ||
1949 | |||
1950 | /* Field Masks */ | ||
1951 | #define FM_PLLCTL9_REFDIV_PLL1 0XFF | ||
1952 | |||
1953 | /* Register Masks */ | ||
1954 | #define RM_PLLCTL9_REFDIV_PLL1 \ | ||
1955 | RM(FM_PLLCTL9_REFDIV_PLL1, FB_PLLCTL9_REFDIV_PLL1) | ||
1956 | |||
1957 | |||
1958 | /****************************** | ||
1959 | * R_PLLCTLA (0x4F) * | ||
1960 | ******************************/ | ||
1961 | |||
1962 | /* Field Offsets */ | ||
1963 | #define FB_PLLCTLA_OUTDIV_PLL1 0 | ||
1964 | |||
1965 | /* Field Masks */ | ||
1966 | #define FM_PLLCTLA_OUTDIV_PLL1 0XFF | ||
1967 | |||
1968 | /* Register Masks */ | ||
1969 | #define RM_PLLCTLA_OUTDIV_PLL1 \ | ||
1970 | RM(FM_PLLCTLA_OUTDIV_PLL1, FB_PLLCTLA_OUTDIV_PLL1) | ||
1971 | |||
1972 | |||
1973 | /****************************** | ||
1974 | * R_PLLCTLB (0x50) * | ||
1975 | ******************************/ | ||
1976 | |||
1977 | /* Field Offsets */ | ||
1978 | #define FB_PLLCTLB_FBDIV_PLL1L 0 | ||
1979 | |||
1980 | /* Field Masks */ | ||
1981 | #define FM_PLLCTLB_FBDIV_PLL1L 0XFF | ||
1982 | |||
1983 | /* Register Masks */ | ||
1984 | #define RM_PLLCTLB_FBDIV_PLL1L \ | ||
1985 | RM(FM_PLLCTLB_FBDIV_PLL1L, FB_PLLCTLB_FBDIV_PLL1L) | ||
1986 | |||
1987 | |||
1988 | /****************************** | ||
1989 | * R_PLLCTLC (0x51) * | ||
1990 | ******************************/ | ||
1991 | |||
1992 | /* Field Offsets */ | ||
1993 | #define FB_PLLCTLC_FBDIV_PLL1H 0 | ||
1994 | |||
1995 | /* Field Masks */ | ||
1996 | #define FM_PLLCTLC_FBDIV_PLL1H 0X7 | ||
1997 | |||
1998 | /* Register Masks */ | ||
1999 | #define RM_PLLCTLC_FBDIV_PLL1H \ | ||
2000 | RM(FM_PLLCTLC_FBDIV_PLL1H, FB_PLLCTLC_FBDIV_PLL1H) | ||
2001 | |||
2002 | |||
2003 | /****************************** | ||
2004 | * R_PLLCTLD (0x52) * | ||
2005 | ******************************/ | ||
2006 | |||
2007 | /* Field Offsets */ | ||
2008 | #define FB_PLLCTLD_RZ_PLL1 3 | ||
2009 | #define FB_PLLCTLD_CP_PLL1 0 | ||
2010 | |||
2011 | /* Field Masks */ | ||
2012 | #define FM_PLLCTLD_RZ_PLL1 0X7 | ||
2013 | #define FM_PLLCTLD_CP_PLL1 0X7 | ||
2014 | |||
2015 | /* Register Masks */ | ||
2016 | #define RM_PLLCTLD_RZ_PLL1 \ | ||
2017 | RM(FM_PLLCTLD_RZ_PLL1, FB_PLLCTLD_RZ_PLL1) | ||
2018 | |||
2019 | #define RM_PLLCTLD_CP_PLL1 \ | ||
2020 | RM(FM_PLLCTLD_CP_PLL1, FB_PLLCTLD_CP_PLL1) | ||
2021 | |||
2022 | |||
2023 | /****************************** | ||
2024 | * R_PLLCTLE (0x53) * | ||
2025 | ******************************/ | ||
2026 | |||
2027 | /* Field Offsets */ | ||
2028 | #define FB_PLLCTLE_REFDIV_PLL2 0 | ||
2029 | |||
2030 | /* Field Masks */ | ||
2031 | #define FM_PLLCTLE_REFDIV_PLL2 0XFF | ||
2032 | |||
2033 | /* Register Masks */ | ||
2034 | #define RM_PLLCTLE_REFDIV_PLL2 \ | ||
2035 | RM(FM_PLLCTLE_REFDIV_PLL2, FB_PLLCTLE_REFDIV_PLL2) | ||
2036 | |||
2037 | |||
2038 | /****************************** | ||
2039 | * R_PLLCTLF (0x54) * | ||
2040 | ******************************/ | ||
2041 | |||
2042 | /* Field Offsets */ | ||
2043 | #define FB_PLLCTLF_OUTDIV_PLL2 0 | ||
2044 | |||
2045 | /* Field Masks */ | ||
2046 | #define FM_PLLCTLF_OUTDIV_PLL2 0XFF | ||
2047 | |||
2048 | /* Register Masks */ | ||
2049 | #define RM_PLLCTLF_OUTDIV_PLL2 \ | ||
2050 | RM(FM_PLLCTLF_OUTDIV_PLL2, FB_PLLCTLF_OUTDIV_PLL2) | ||
2051 | |||
2052 | |||
2053 | /******************************* | ||
2054 | * R_PLLCTL10 (0x55) * | ||
2055 | *******************************/ | ||
2056 | |||
2057 | /* Field Offsets */ | ||
2058 | #define FB_PLLCTL10_FBDIV_PLL2L 0 | ||
2059 | |||
2060 | /* Field Masks */ | ||
2061 | #define FM_PLLCTL10_FBDIV_PLL2L 0XFF | ||
2062 | |||
2063 | /* Register Masks */ | ||
2064 | #define RM_PLLCTL10_FBDIV_PLL2L \ | ||
2065 | RM(FM_PLLCTL10_FBDIV_PLL2L, FB_PLLCTL10_FBDIV_PLL2L) | ||
2066 | |||
2067 | |||
2068 | /******************************* | ||
2069 | * R_PLLCTL11 (0x56) * | ||
2070 | *******************************/ | ||
2071 | |||
2072 | /* Field Offsets */ | ||
2073 | #define FB_PLLCTL11_FBDIV_PLL2H 0 | ||
2074 | |||
2075 | /* Field Masks */ | ||
2076 | #define FM_PLLCTL11_FBDIV_PLL2H 0X7 | ||
2077 | |||
2078 | /* Register Masks */ | ||
2079 | #define RM_PLLCTL11_FBDIV_PLL2H \ | ||
2080 | RM(FM_PLLCTL11_FBDIV_PLL2H, FB_PLLCTL11_FBDIV_PLL2H) | ||
2081 | |||
2082 | |||
2083 | /******************************* | ||
2084 | * R_PLLCTL12 (0x57) * | ||
2085 | *******************************/ | ||
2086 | |||
2087 | /* Field Offsets */ | ||
2088 | #define FB_PLLCTL12_RZ_PLL2 3 | ||
2089 | #define FB_PLLCTL12_CP_PLL2 0 | ||
2090 | |||
2091 | /* Field Masks */ | ||
2092 | #define FM_PLLCTL12_RZ_PLL2 0X7 | ||
2093 | #define FM_PLLCTL12_CP_PLL2 0X7 | ||
2094 | |||
2095 | /* Register Masks */ | ||
2096 | #define RM_PLLCTL12_RZ_PLL2 \ | ||
2097 | RM(FM_PLLCTL12_RZ_PLL2, FB_PLLCTL12_RZ_PLL2) | ||
2098 | |||
2099 | #define RM_PLLCTL12_CP_PLL2 \ | ||
2100 | RM(FM_PLLCTL12_CP_PLL2, FB_PLLCTL12_CP_PLL2) | ||
2101 | |||
2102 | |||
2103 | /******************************* | ||
2104 | * R_PLLCTL1B (0x60) * | ||
2105 | *******************************/ | ||
2106 | |||
2107 | /* Field Offsets */ | ||
2108 | #define FB_PLLCTL1B_VCOI_PLL2 4 | ||
2109 | #define FB_PLLCTL1B_VCOI_PLL1 2 | ||
2110 | |||
2111 | /* Field Masks */ | ||
2112 | #define FM_PLLCTL1B_VCOI_PLL2 0X3 | ||
2113 | #define FM_PLLCTL1B_VCOI_PLL1 0X3 | ||
2114 | |||
2115 | /* Register Masks */ | ||
2116 | #define RM_PLLCTL1B_VCOI_PLL2 \ | ||
2117 | RM(FM_PLLCTL1B_VCOI_PLL2, FB_PLLCTL1B_VCOI_PLL2) | ||
2118 | |||
2119 | #define RM_PLLCTL1B_VCOI_PLL1 \ | ||
2120 | RM(FM_PLLCTL1B_VCOI_PLL1, FB_PLLCTL1B_VCOI_PLL1) | ||
2121 | |||
2122 | |||
2123 | /******************************* | ||
2124 | * R_PLLCTL1C (0x61) * | ||
2125 | *******************************/ | ||
2126 | |||
2127 | /* Field Offsets */ | ||
2128 | #define FB_PLLCTL1C_PDB_PLL2 2 | ||
2129 | #define FB_PLLCTL1C_PDB_PLL1 1 | ||
2130 | |||
2131 | /* Field Masks */ | ||
2132 | #define FM_PLLCTL1C_PDB_PLL2 0X1 | ||
2133 | #define FM_PLLCTL1C_PDB_PLL1 0X1 | ||
2134 | |||
2135 | /* Field Values */ | ||
2136 | #define FV_PLLCTL1C_PDB_PLL2_ENABLE 0x1 | ||
2137 | #define FV_PLLCTL1C_PDB_PLL2_DISABLE 0x0 | ||
2138 | #define FV_PLLCTL1C_PDB_PLL1_ENABLE 0x1 | ||
2139 | #define FV_PLLCTL1C_PDB_PLL1_DISABLE 0x0 | ||
2140 | |||
2141 | /* Register Masks */ | ||
2142 | #define RM_PLLCTL1C_PDB_PLL2 \ | ||
2143 | RM(FM_PLLCTL1C_PDB_PLL2, FB_PLLCTL1C_PDB_PLL2) | ||
2144 | |||
2145 | #define RM_PLLCTL1C_PDB_PLL1 \ | ||
2146 | RM(FM_PLLCTL1C_PDB_PLL1, FB_PLLCTL1C_PDB_PLL1) | ||
2147 | |||
2148 | |||
2149 | /* Register Values */ | ||
2150 | #define RV_PLLCTL1C_PDB_PLL2_ENABLE \ | ||
2151 | RV(FV_PLLCTL1C_PDB_PLL2_ENABLE, FB_PLLCTL1C_PDB_PLL2) | ||
2152 | |||
2153 | #define RV_PLLCTL1C_PDB_PLL2_DISABLE \ | ||
2154 | RV(FV_PLLCTL1C_PDB_PLL2_DISABLE, FB_PLLCTL1C_PDB_PLL2) | ||
2155 | |||
2156 | #define RV_PLLCTL1C_PDB_PLL1_ENABLE \ | ||
2157 | RV(FV_PLLCTL1C_PDB_PLL1_ENABLE, FB_PLLCTL1C_PDB_PLL1) | ||
2158 | |||
2159 | #define RV_PLLCTL1C_PDB_PLL1_DISABLE \ | ||
2160 | RV(FV_PLLCTL1C_PDB_PLL1_DISABLE, FB_PLLCTL1C_PDB_PLL1) | ||
2161 | |||
2162 | |||
2163 | /******************************* | ||
2164 | * R_TIMEBASE (0x77) * | ||
2165 | *******************************/ | ||
2166 | |||
2167 | /* Field Offsets */ | ||
2168 | #define FB_TIMEBASE_DIVIDER 0 | ||
2169 | |||
2170 | /* Field Masks */ | ||
2171 | #define FM_TIMEBASE_DIVIDER 0XFF | ||
2172 | |||
2173 | /* Register Masks */ | ||
2174 | #define RM_TIMEBASE_DIVIDER \ | ||
2175 | RM(FM_TIMEBASE_DIVIDER, FB_TIMEBASE_DIVIDER) | ||
2176 | |||
2177 | |||
2178 | /***************************** | ||
2179 | * R_DEVIDL (0x7D) * | ||
2180 | *****************************/ | ||
2181 | |||
2182 | /* Field Offsets */ | ||
2183 | #define FB_DEVIDL_DIDL 0 | ||
2184 | |||
2185 | /* Field Masks */ | ||
2186 | #define FM_DEVIDL_DIDL 0XFF | ||
2187 | |||
2188 | /* Register Masks */ | ||
2189 | #define RM_DEVIDL_DIDL RM(FM_DEVIDL_DIDL, FB_DEVIDL_DIDL) | ||
2190 | |||
2191 | /***************************** | ||
2192 | * R_DEVIDH (0x7E) * | ||
2193 | *****************************/ | ||
2194 | |||
2195 | /* Field Offsets */ | ||
2196 | #define FB_DEVIDH_DIDH 0 | ||
2197 | |||
2198 | /* Field Masks */ | ||
2199 | #define FM_DEVIDH_DIDH 0XFF | ||
2200 | |||
2201 | /* Register Masks */ | ||
2202 | #define RM_DEVIDH_DIDH RM(FM_DEVIDH_DIDH, FB_DEVIDH_DIDH) | ||
2203 | |||
2204 | /**************************** | ||
2205 | * R_RESET (0x80) * | ||
2206 | ****************************/ | ||
2207 | |||
2208 | /* Field Offsets */ | ||
2209 | #define FB_RESET 0 | ||
2210 | |||
2211 | /* Field Masks */ | ||
2212 | #define FM_RESET 0XFF | ||
2213 | |||
2214 | /* Field Values */ | ||
2215 | #define FV_RESET_ENABLE 0x85 | ||
2216 | |||
2217 | /* Register Masks */ | ||
2218 | #define RM_RESET RM(FM_RESET, FB_RESET) | ||
2219 | |||
2220 | /* Register Values */ | ||
2221 | #define RV_RESET_ENABLE RV(FV_RESET_ENABLE, FB_RESET) | ||
2222 | |||
2223 | /******************************** | ||
2224 | * R_DACCRSTAT (0x8A) * | ||
2225 | ********************************/ | ||
2226 | |||
2227 | /* Field Offsets */ | ||
2228 | #define FB_DACCRSTAT_DACCR_BUSY 7 | ||
2229 | |||
2230 | /* Field Masks */ | ||
2231 | #define FM_DACCRSTAT_DACCR_BUSY 0X1 | ||
2232 | |||
2233 | /* Register Masks */ | ||
2234 | #define RM_DACCRSTAT_DACCR_BUSY \ | ||
2235 | RM(FM_DACCRSTAT_DACCR_BUSY, FB_DACCRSTAT_DACCR_BUSY) | ||
2236 | |||
2237 | |||
2238 | /****************************** | ||
2239 | * R_PLLCTL0 (0x8E) * | ||
2240 | ******************************/ | ||
2241 | |||
2242 | /* Field Offsets */ | ||
2243 | #define FB_PLLCTL0_PLL2_LOCK 1 | ||
2244 | #define FB_PLLCTL0_PLL1_LOCK 0 | ||
2245 | |||
2246 | /* Field Masks */ | ||
2247 | #define FM_PLLCTL0_PLL2_LOCK 0X1 | ||
2248 | #define FM_PLLCTL0_PLL1_LOCK 0X1 | ||
2249 | |||
2250 | /* Register Masks */ | ||
2251 | #define RM_PLLCTL0_PLL2_LOCK \ | ||
2252 | RM(FM_PLLCTL0_PLL2_LOCK, FB_PLLCTL0_PLL2_LOCK) | ||
2253 | |||
2254 | #define RM_PLLCTL0_PLL1_LOCK \ | ||
2255 | RM(FM_PLLCTL0_PLL1_LOCK, FB_PLLCTL0_PLL1_LOCK) | ||
2256 | |||
2257 | |||
2258 | /******************************** | ||
2259 | * R_PLLREFSEL (0x8F) * | ||
2260 | ********************************/ | ||
2261 | |||
2262 | /* Field Offsets */ | ||
2263 | #define FB_PLLREFSEL_PLL2_REF_SEL 4 | ||
2264 | #define FB_PLLREFSEL_PLL1_REF_SEL 0 | ||
2265 | |||
2266 | /* Field Masks */ | ||
2267 | #define FM_PLLREFSEL_PLL2_REF_SEL 0X7 | ||
2268 | #define FM_PLLREFSEL_PLL1_REF_SEL 0X7 | ||
2269 | |||
2270 | /* Field Values */ | ||
2271 | #define FV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1 0x0 | ||
2272 | #define FV_PLLREFSEL_PLL2_REF_SEL_MCLK2 0x1 | ||
2273 | #define FV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 0x0 | ||
2274 | #define FV_PLLREFSEL_PLL1_REF_SEL_MCLK2 0x1 | ||
2275 | |||
2276 | /* Register Masks */ | ||
2277 | #define RM_PLLREFSEL_PLL2_REF_SEL \ | ||
2278 | RM(FM_PLLREFSEL_PLL2_REF_SEL, FB_PLLREFSEL_PLL2_REF_SEL) | ||
2279 | |||
2280 | #define RM_PLLREFSEL_PLL1_REF_SEL \ | ||
2281 | RM(FM_PLLREFSEL_PLL1_REF_SEL, FB_PLLREFSEL_PLL1_REF_SEL) | ||
2282 | |||
2283 | |||
2284 | /* Register Values */ | ||
2285 | #define RV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1 \ | ||
2286 | RV(FV_PLLREFSEL_PLL2_REF_SEL_XTAL_MCLK1, FB_PLLREFSEL_PLL2_REF_SEL) | ||
2287 | |||
2288 | #define RV_PLLREFSEL_PLL2_REF_SEL_MCLK2 \ | ||
2289 | RV(FV_PLLREFSEL_PLL2_REF_SEL_MCLK2, FB_PLLREFSEL_PLL2_REF_SEL) | ||
2290 | |||
2291 | #define RV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1 \ | ||
2292 | RV(FV_PLLREFSEL_PLL1_REF_SEL_XTAL_MCLK1, FB_PLLREFSEL_PLL1_REF_SEL) | ||
2293 | |||
2294 | #define RV_PLLREFSEL_PLL1_REF_SEL_MCLK2 \ | ||
2295 | RV(FV_PLLREFSEL_PLL1_REF_SEL_MCLK2, FB_PLLREFSEL_PLL1_REF_SEL) | ||
2296 | |||
2297 | |||
2298 | /******************************* | ||
2299 | * R_DACMBCEN (0xC7) * | ||
2300 | *******************************/ | ||
2301 | |||
2302 | /* Field Offsets */ | ||
2303 | #define FB_DACMBCEN_MBCEN3 2 | ||
2304 | #define FB_DACMBCEN_MBCEN2 1 | ||
2305 | #define FB_DACMBCEN_MBCEN1 0 | ||
2306 | |||
2307 | /* Field Masks */ | ||
2308 | #define FM_DACMBCEN_MBCEN3 0X1 | ||
2309 | #define FM_DACMBCEN_MBCEN2 0X1 | ||
2310 | #define FM_DACMBCEN_MBCEN1 0X1 | ||
2311 | |||
2312 | /* Register Masks */ | ||
2313 | #define RM_DACMBCEN_MBCEN3 \ | ||
2314 | RM(FM_DACMBCEN_MBCEN3, FB_DACMBCEN_MBCEN3) | ||
2315 | |||
2316 | #define RM_DACMBCEN_MBCEN2 \ | ||
2317 | RM(FM_DACMBCEN_MBCEN2, FB_DACMBCEN_MBCEN2) | ||
2318 | |||
2319 | #define RM_DACMBCEN_MBCEN1 \ | ||
2320 | RM(FM_DACMBCEN_MBCEN1, FB_DACMBCEN_MBCEN1) | ||
2321 | |||
2322 | |||
2323 | /******************************** | ||
2324 | * R_DACMBCCTL (0xC8) * | ||
2325 | ********************************/ | ||
2326 | |||
2327 | /* Field Offsets */ | ||
2328 | #define FB_DACMBCCTL_LVLMODE3 5 | ||
2329 | #define FB_DACMBCCTL_WINSEL3 4 | ||
2330 | #define FB_DACMBCCTL_LVLMODE2 3 | ||
2331 | #define FB_DACMBCCTL_WINSEL2 2 | ||
2332 | #define FB_DACMBCCTL_LVLMODE1 1 | ||
2333 | #define FB_DACMBCCTL_WINSEL1 0 | ||
2334 | |||
2335 | /* Field Masks */ | ||
2336 | #define FM_DACMBCCTL_LVLMODE3 0X1 | ||
2337 | #define FM_DACMBCCTL_WINSEL3 0X1 | ||
2338 | #define FM_DACMBCCTL_LVLMODE2 0X1 | ||
2339 | #define FM_DACMBCCTL_WINSEL2 0X1 | ||
2340 | #define FM_DACMBCCTL_LVLMODE1 0X1 | ||
2341 | #define FM_DACMBCCTL_WINSEL1 0X1 | ||
2342 | |||
2343 | /* Register Masks */ | ||
2344 | #define RM_DACMBCCTL_LVLMODE3 \ | ||
2345 | RM(FM_DACMBCCTL_LVLMODE3, FB_DACMBCCTL_LVLMODE3) | ||
2346 | |||
2347 | #define RM_DACMBCCTL_WINSEL3 \ | ||
2348 | RM(FM_DACMBCCTL_WINSEL3, FB_DACMBCCTL_WINSEL3) | ||
2349 | |||
2350 | #define RM_DACMBCCTL_LVLMODE2 \ | ||
2351 | RM(FM_DACMBCCTL_LVLMODE2, FB_DACMBCCTL_LVLMODE2) | ||
2352 | |||
2353 | #define RM_DACMBCCTL_WINSEL2 \ | ||
2354 | RM(FM_DACMBCCTL_WINSEL2, FB_DACMBCCTL_WINSEL2) | ||
2355 | |||
2356 | #define RM_DACMBCCTL_LVLMODE1 \ | ||
2357 | RM(FM_DACMBCCTL_LVLMODE1, FB_DACMBCCTL_LVLMODE1) | ||
2358 | |||
2359 | #define RM_DACMBCCTL_WINSEL1 \ | ||
2360 | RM(FM_DACMBCCTL_WINSEL1, FB_DACMBCCTL_WINSEL1) | ||
2361 | |||
2362 | |||
2363 | /********************************* | ||
2364 | * R_DACMBCMUG1 (0xC9) * | ||
2365 | *********************************/ | ||
2366 | |||
2367 | /* Field Offsets */ | ||
2368 | #define FB_DACMBCMUG1_PHASE 5 | ||
2369 | #define FB_DACMBCMUG1_MUGAIN 0 | ||
2370 | |||
2371 | /* Field Masks */ | ||
2372 | #define FM_DACMBCMUG1_PHASE 0X1 | ||
2373 | #define FM_DACMBCMUG1_MUGAIN 0X1F | ||
2374 | |||
2375 | /* Register Masks */ | ||
2376 | #define RM_DACMBCMUG1_PHASE \ | ||
2377 | RM(FM_DACMBCMUG1_PHASE, FB_DACMBCMUG1_PHASE) | ||
2378 | |||
2379 | #define RM_DACMBCMUG1_MUGAIN \ | ||
2380 | RM(FM_DACMBCMUG1_MUGAIN, FB_DACMBCMUG1_MUGAIN) | ||
2381 | |||
2382 | |||
2383 | /********************************* | ||
2384 | * R_DACMBCTHR1 (0xCA) * | ||
2385 | *********************************/ | ||
2386 | |||
2387 | /* Field Offsets */ | ||
2388 | #define FB_DACMBCTHR1_THRESH 0 | ||
2389 | |||
2390 | /* Field Masks */ | ||
2391 | #define FM_DACMBCTHR1_THRESH 0XFF | ||
2392 | |||
2393 | /* Register Masks */ | ||
2394 | #define RM_DACMBCTHR1_THRESH \ | ||
2395 | RM(FM_DACMBCTHR1_THRESH, FB_DACMBCTHR1_THRESH) | ||
2396 | |||
2397 | |||
2398 | /********************************* | ||
2399 | * R_DACMBCRAT1 (0xCB) * | ||
2400 | *********************************/ | ||
2401 | |||
2402 | /* Field Offsets */ | ||
2403 | #define FB_DACMBCRAT1_RATIO 0 | ||
2404 | |||
2405 | /* Field Masks */ | ||
2406 | #define FM_DACMBCRAT1_RATIO 0X1F | ||
2407 | |||
2408 | /* Register Masks */ | ||
2409 | #define RM_DACMBCRAT1_RATIO \ | ||
2410 | RM(FM_DACMBCRAT1_RATIO, FB_DACMBCRAT1_RATIO) | ||
2411 | |||
2412 | |||
2413 | /********************************** | ||
2414 | * R_DACMBCATK1L (0xCC) * | ||
2415 | **********************************/ | ||
2416 | |||
2417 | /* Field Offsets */ | ||
2418 | #define FB_DACMBCATK1L_TCATKL 0 | ||
2419 | |||
2420 | /* Field Masks */ | ||
2421 | #define FM_DACMBCATK1L_TCATKL 0XFF | ||
2422 | |||
2423 | /* Register Masks */ | ||
2424 | #define RM_DACMBCATK1L_TCATKL \ | ||
2425 | RM(FM_DACMBCATK1L_TCATKL, FB_DACMBCATK1L_TCATKL) | ||
2426 | |||
2427 | |||
2428 | /********************************** | ||
2429 | * R_DACMBCATK1H (0xCD) * | ||
2430 | **********************************/ | ||
2431 | |||
2432 | /* Field Offsets */ | ||
2433 | #define FB_DACMBCATK1H_TCATKH 0 | ||
2434 | |||
2435 | /* Field Masks */ | ||
2436 | #define FM_DACMBCATK1H_TCATKH 0XFF | ||
2437 | |||
2438 | /* Register Masks */ | ||
2439 | #define RM_DACMBCATK1H_TCATKH \ | ||
2440 | RM(FM_DACMBCATK1H_TCATKH, FB_DACMBCATK1H_TCATKH) | ||
2441 | |||
2442 | |||
2443 | /********************************** | ||
2444 | * R_DACMBCREL1L (0xCE) * | ||
2445 | **********************************/ | ||
2446 | |||
2447 | /* Field Offsets */ | ||
2448 | #define FB_DACMBCREL1L_TCRELL 0 | ||
2449 | |||
2450 | /* Field Masks */ | ||
2451 | #define FM_DACMBCREL1L_TCRELL 0XFF | ||
2452 | |||
2453 | /* Register Masks */ | ||
2454 | #define RM_DACMBCREL1L_TCRELL \ | ||
2455 | RM(FM_DACMBCREL1L_TCRELL, FB_DACMBCREL1L_TCRELL) | ||
2456 | |||
2457 | |||
2458 | /********************************** | ||
2459 | * R_DACMBCREL1H (0xCF) * | ||
2460 | **********************************/ | ||
2461 | |||
2462 | /* Field Offsets */ | ||
2463 | #define FB_DACMBCREL1H_TCRELH 0 | ||
2464 | |||
2465 | /* Field Masks */ | ||
2466 | #define FM_DACMBCREL1H_TCRELH 0XFF | ||
2467 | |||
2468 | /* Register Masks */ | ||
2469 | #define RM_DACMBCREL1H_TCRELH \ | ||
2470 | RM(FM_DACMBCREL1H_TCRELH, FB_DACMBCREL1H_TCRELH) | ||
2471 | |||
2472 | |||
2473 | /********************************* | ||
2474 | * R_DACMBCMUG2 (0xD0) * | ||
2475 | *********************************/ | ||
2476 | |||
2477 | /* Field Offsets */ | ||
2478 | #define FB_DACMBCMUG2_PHASE 5 | ||
2479 | #define FB_DACMBCMUG2_MUGAIN 0 | ||
2480 | |||
2481 | /* Field Masks */ | ||
2482 | #define FM_DACMBCMUG2_PHASE 0X1 | ||
2483 | #define FM_DACMBCMUG2_MUGAIN 0X1F | ||
2484 | |||
2485 | /* Register Masks */ | ||
2486 | #define RM_DACMBCMUG2_PHASE \ | ||
2487 | RM(FM_DACMBCMUG2_PHASE, FB_DACMBCMUG2_PHASE) | ||
2488 | |||
2489 | #define RM_DACMBCMUG2_MUGAIN \ | ||
2490 | RM(FM_DACMBCMUG2_MUGAIN, FB_DACMBCMUG2_MUGAIN) | ||
2491 | |||
2492 | |||
2493 | /********************************* | ||
2494 | * R_DACMBCTHR2 (0xD1) * | ||
2495 | *********************************/ | ||
2496 | |||
2497 | /* Field Offsets */ | ||
2498 | #define FB_DACMBCTHR2_THRESH 0 | ||
2499 | |||
2500 | /* Field Masks */ | ||
2501 | #define FM_DACMBCTHR2_THRESH 0XFF | ||
2502 | |||
2503 | /* Register Masks */ | ||
2504 | #define RM_DACMBCTHR2_THRESH \ | ||
2505 | RM(FM_DACMBCTHR2_THRESH, FB_DACMBCTHR2_THRESH) | ||
2506 | |||
2507 | |||
2508 | /********************************* | ||
2509 | * R_DACMBCRAT2 (0xD2) * | ||
2510 | *********************************/ | ||
2511 | |||
2512 | /* Field Offsets */ | ||
2513 | #define FB_DACMBCRAT2_RATIO 0 | ||
2514 | |||
2515 | /* Field Masks */ | ||
2516 | #define FM_DACMBCRAT2_RATIO 0X1F | ||
2517 | |||
2518 | /* Register Masks */ | ||
2519 | #define RM_DACMBCRAT2_RATIO \ | ||
2520 | RM(FM_DACMBCRAT2_RATIO, FB_DACMBCRAT2_RATIO) | ||
2521 | |||
2522 | |||
2523 | /********************************** | ||
2524 | * R_DACMBCATK2L (0xD3) * | ||
2525 | **********************************/ | ||
2526 | |||
2527 | /* Field Offsets */ | ||
2528 | #define FB_DACMBCATK2L_TCATKL 0 | ||
2529 | |||
2530 | /* Field Masks */ | ||
2531 | #define FM_DACMBCATK2L_TCATKL 0XFF | ||
2532 | |||
2533 | /* Register Masks */ | ||
2534 | #define RM_DACMBCATK2L_TCATKL \ | ||
2535 | RM(FM_DACMBCATK2L_TCATKL, FB_DACMBCATK2L_TCATKL) | ||
2536 | |||
2537 | |||
2538 | /********************************** | ||
2539 | * R_DACMBCATK2H (0xD4) * | ||
2540 | **********************************/ | ||
2541 | |||
2542 | /* Field Offsets */ | ||
2543 | #define FB_DACMBCATK2H_TCATKH 0 | ||
2544 | |||
2545 | /* Field Masks */ | ||
2546 | #define FM_DACMBCATK2H_TCATKH 0XFF | ||
2547 | |||
2548 | /* Register Masks */ | ||
2549 | #define RM_DACMBCATK2H_TCATKH \ | ||
2550 | RM(FM_DACMBCATK2H_TCATKH, FB_DACMBCATK2H_TCATKH) | ||
2551 | |||
2552 | |||
2553 | /********************************** | ||
2554 | * R_DACMBCREL2L (0xD5) * | ||
2555 | **********************************/ | ||
2556 | |||
2557 | /* Field Offsets */ | ||
2558 | #define FB_DACMBCREL2L_TCRELL 0 | ||
2559 | |||
2560 | /* Field Masks */ | ||
2561 | #define FM_DACMBCREL2L_TCRELL 0XFF | ||
2562 | |||
2563 | /* Register Masks */ | ||
2564 | #define RM_DACMBCREL2L_TCRELL \ | ||
2565 | RM(FM_DACMBCREL2L_TCRELL, FB_DACMBCREL2L_TCRELL) | ||
2566 | |||
2567 | |||
2568 | /********************************** | ||
2569 | * R_DACMBCREL2H (0xD6) * | ||
2570 | **********************************/ | ||
2571 | |||
2572 | /* Field Offsets */ | ||
2573 | #define FB_DACMBCREL2H_TCRELH 0 | ||
2574 | |||
2575 | /* Field Masks */ | ||
2576 | #define FM_DACMBCREL2H_TCRELH 0XFF | ||
2577 | |||
2578 | /* Register Masks */ | ||
2579 | #define RM_DACMBCREL2H_TCRELH \ | ||
2580 | RM(FM_DACMBCREL2H_TCRELH, FB_DACMBCREL2H_TCRELH) | ||
2581 | |||
2582 | |||
2583 | /********************************* | ||
2584 | * R_DACMBCMUG3 (0xD7) * | ||
2585 | *********************************/ | ||
2586 | |||
2587 | /* Field Offsets */ | ||
2588 | #define FB_DACMBCMUG3_PHASE 5 | ||
2589 | #define FB_DACMBCMUG3_MUGAIN 0 | ||
2590 | |||
2591 | /* Field Masks */ | ||
2592 | #define FM_DACMBCMUG3_PHASE 0X1 | ||
2593 | #define FM_DACMBCMUG3_MUGAIN 0X1F | ||
2594 | |||
2595 | /* Register Masks */ | ||
2596 | #define RM_DACMBCMUG3_PHASE \ | ||
2597 | RM(FM_DACMBCMUG3_PHASE, FB_DACMBCMUG3_PHASE) | ||
2598 | |||
2599 | #define RM_DACMBCMUG3_MUGAIN \ | ||
2600 | RM(FM_DACMBCMUG3_MUGAIN, FB_DACMBCMUG3_MUGAIN) | ||
2601 | |||
2602 | |||
2603 | /********************************* | ||
2604 | * R_DACMBCTHR3 (0xD8) * | ||
2605 | *********************************/ | ||
2606 | |||
2607 | /* Field Offsets */ | ||
2608 | #define FB_DACMBCTHR3_THRESH 0 | ||
2609 | |||
2610 | /* Field Masks */ | ||
2611 | #define FM_DACMBCTHR3_THRESH 0XFF | ||
2612 | |||
2613 | /* Register Masks */ | ||
2614 | #define RM_DACMBCTHR3_THRESH \ | ||
2615 | RM(FM_DACMBCTHR3_THRESH, FB_DACMBCTHR3_THRESH) | ||
2616 | |||
2617 | |||
2618 | /********************************* | ||
2619 | * R_DACMBCRAT3 (0xD9) * | ||
2620 | *********************************/ | ||
2621 | |||
2622 | /* Field Offsets */ | ||
2623 | #define FB_DACMBCRAT3_RATIO 0 | ||
2624 | |||
2625 | /* Field Masks */ | ||
2626 | #define FM_DACMBCRAT3_RATIO 0X1F | ||
2627 | |||
2628 | /* Register Masks */ | ||
2629 | #define RM_DACMBCRAT3_RATIO \ | ||
2630 | RM(FM_DACMBCRAT3_RATIO, FB_DACMBCRAT3_RATIO) | ||
2631 | |||
2632 | |||
2633 | /********************************** | ||
2634 | * R_DACMBCATK3L (0xDA) * | ||
2635 | **********************************/ | ||
2636 | |||
2637 | /* Field Offsets */ | ||
2638 | #define FB_DACMBCATK3L_TCATKL 0 | ||
2639 | |||
2640 | /* Field Masks */ | ||
2641 | #define FM_DACMBCATK3L_TCATKL 0XFF | ||
2642 | |||
2643 | /* Register Masks */ | ||
2644 | #define RM_DACMBCATK3L_TCATKL \ | ||
2645 | RM(FM_DACMBCATK3L_TCATKL, FB_DACMBCATK3L_TCATKL) | ||
2646 | |||
2647 | |||
2648 | /********************************** | ||
2649 | * R_DACMBCATK3H (0xDB) * | ||
2650 | **********************************/ | ||
2651 | |||
2652 | /* Field Offsets */ | ||
2653 | #define FB_DACMBCATK3H_TCATKH 0 | ||
2654 | |||
2655 | /* Field Masks */ | ||
2656 | #define FM_DACMBCATK3H_TCATKH 0XFF | ||
2657 | |||
2658 | /* Register Masks */ | ||
2659 | #define RM_DACMBCATK3H_TCATKH \ | ||
2660 | RM(FM_DACMBCATK3H_TCATKH, FB_DACMBCATK3H_TCATKH) | ||
2661 | |||
2662 | |||
2663 | /********************************** | ||
2664 | * R_DACMBCREL3L (0xDC) * | ||
2665 | **********************************/ | ||
2666 | |||
2667 | /* Field Offsets */ | ||
2668 | #define FB_DACMBCREL3L_TCRELL 0 | ||
2669 | |||
2670 | /* Field Masks */ | ||
2671 | #define FM_DACMBCREL3L_TCRELL 0XFF | ||
2672 | |||
2673 | /* Register Masks */ | ||
2674 | #define RM_DACMBCREL3L_TCRELL \ | ||
2675 | RM(FM_DACMBCREL3L_TCRELL, FB_DACMBCREL3L_TCRELL) | ||
2676 | |||
2677 | |||
2678 | /********************************** | ||
2679 | * R_DACMBCREL3H (0xDD) * | ||
2680 | **********************************/ | ||
2681 | |||
2682 | /* Field Offsets */ | ||
2683 | #define FB_DACMBCREL3H_TCRELH 0 | ||
2684 | |||
2685 | /* Field Masks */ | ||
2686 | #define FM_DACMBCREL3H_TCRELH 0XFF | ||
2687 | |||
2688 | /* Register Masks */ | ||
2689 | #define RM_DACMBCREL3H_TCRELH \ | ||
2690 | RM(FM_DACMBCREL3H_TCRELH, FB_DACMBCREL3H_TCRELH) | ||
2691 | |||
2692 | |||
2693 | #endif /* __WOOKIE_H__ */ | ||
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cfe72b9d4356..8798182959c1 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -240,7 +240,6 @@ static struct twl4030_codec_data *twl4030_get_pdata(struct snd_soc_codec *codec) | |||
240 | sizeof(struct twl4030_codec_data), | 240 | sizeof(struct twl4030_codec_data), |
241 | GFP_KERNEL); | 241 | GFP_KERNEL); |
242 | if (!pdata) { | 242 | if (!pdata) { |
243 | dev_err(codec->dev, "Can not allocate memory\n"); | ||
244 | of_node_put(twl4030_codec_node); | 243 | of_node_put(twl4030_codec_node); |
245 | return NULL; | 244 | return NULL; |
246 | } | 245 | } |
@@ -851,14 +850,14 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, | |||
851 | int mask = (1 << fls(max)) - 1; | 850 | int mask = (1 << fls(max)) - 1; |
852 | 851 | ||
853 | ucontrol->value.integer.value[0] = | 852 | ucontrol->value.integer.value[0] = |
854 | (snd_soc_read(codec, reg) >> shift) & mask; | 853 | (twl4030_read(codec, reg) >> shift) & mask; |
855 | if (ucontrol->value.integer.value[0]) | 854 | if (ucontrol->value.integer.value[0]) |
856 | ucontrol->value.integer.value[0] = | 855 | ucontrol->value.integer.value[0] = |
857 | max + 1 - ucontrol->value.integer.value[0]; | 856 | max + 1 - ucontrol->value.integer.value[0]; |
858 | 857 | ||
859 | if (shift != rshift) { | 858 | if (shift != rshift) { |
860 | ucontrol->value.integer.value[1] = | 859 | ucontrol->value.integer.value[1] = |
861 | (snd_soc_read(codec, reg) >> rshift) & mask; | 860 | (twl4030_read(codec, reg) >> rshift) & mask; |
862 | if (ucontrol->value.integer.value[1]) | 861 | if (ucontrol->value.integer.value[1]) |
863 | ucontrol->value.integer.value[1] = | 862 | ucontrol->value.integer.value[1] = |
864 | max + 1 - ucontrol->value.integer.value[1]; | 863 | max + 1 - ucontrol->value.integer.value[1]; |
@@ -909,9 +908,9 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, | |||
909 | int mask = (1<<fls(max))-1; | 908 | int mask = (1<<fls(max))-1; |
910 | 909 | ||
911 | ucontrol->value.integer.value[0] = | 910 | ucontrol->value.integer.value[0] = |
912 | (snd_soc_read(codec, reg) >> shift) & mask; | 911 | (twl4030_read(codec, reg) >> shift) & mask; |
913 | ucontrol->value.integer.value[1] = | 912 | ucontrol->value.integer.value[1] = |
914 | (snd_soc_read(codec, reg2) >> shift) & mask; | 913 | (twl4030_read(codec, reg2) >> shift) & mask; |
915 | 914 | ||
916 | if (ucontrol->value.integer.value[0]) | 915 | if (ucontrol->value.integer.value[0]) |
917 | ucontrol->value.integer.value[0] = | 916 | ucontrol->value.integer.value[0] = |
@@ -2196,8 +2195,6 @@ static int twl4030_soc_remove(struct snd_soc_codec *codec) | |||
2196 | static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | 2195 | static const struct snd_soc_codec_driver soc_codec_dev_twl4030 = { |
2197 | .probe = twl4030_soc_probe, | 2196 | .probe = twl4030_soc_probe, |
2198 | .remove = twl4030_soc_remove, | 2197 | .remove = twl4030_soc_remove, |
2199 | .read = twl4030_read, | ||
2200 | .write = twl4030_write, | ||
2201 | .set_bias_level = twl4030_set_bias_level, | 2198 | .set_bias_level = twl4030_set_bias_level, |
2202 | .idle_bias_off = true, | 2199 | .idle_bias_off = true, |
2203 | 2200 | ||
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 1773ff84ee3b..3b895b4b451c 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -106,10 +106,12 @@ static const struct snd_pcm_hw_constraint_list sysclk_constraints[] = { | |||
106 | { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, | 106 | { .count = ARRAY_SIZE(hp_rates), .list = hp_rates, }, |
107 | }; | 107 | }; |
108 | 108 | ||
109 | #define to_twl6040(codec) dev_get_drvdata((codec)->dev->parent) | ||
110 | |||
109 | static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg) | 111 | static unsigned int twl6040_read(struct snd_soc_codec *codec, unsigned int reg) |
110 | { | 112 | { |
111 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 113 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
112 | struct twl6040 *twl6040 = codec->control_data; | 114 | struct twl6040 *twl6040 = to_twl6040(codec); |
113 | u8 value; | 115 | u8 value; |
114 | 116 | ||
115 | if (reg >= TWL6040_CACHEREGNUM) | 117 | if (reg >= TWL6040_CACHEREGNUM) |
@@ -171,7 +173,7 @@ static inline void twl6040_update_dl12_cache(struct snd_soc_codec *codec, | |||
171 | static int twl6040_write(struct snd_soc_codec *codec, | 173 | static int twl6040_write(struct snd_soc_codec *codec, |
172 | unsigned int reg, unsigned int value) | 174 | unsigned int reg, unsigned int value) |
173 | { | 175 | { |
174 | struct twl6040 *twl6040 = codec->control_data; | 176 | struct twl6040 *twl6040 = to_twl6040(codec); |
175 | 177 | ||
176 | if (reg >= TWL6040_CACHEREGNUM) | 178 | if (reg >= TWL6040_CACHEREGNUM) |
177 | return -EIO; | 179 | return -EIO; |
@@ -541,7 +543,7 @@ int twl6040_get_dl1_gain(struct snd_soc_codec *codec) | |||
541 | if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || | 543 | if (snd_soc_dapm_get_pin_status(dapm, "HSOR") || |
542 | snd_soc_dapm_get_pin_status(dapm, "HSOL")) { | 544 | snd_soc_dapm_get_pin_status(dapm, "HSOL")) { |
543 | 545 | ||
544 | u8 val = snd_soc_read(codec, TWL6040_REG_HSLCTL); | 546 | u8 val = twl6040_read(codec, TWL6040_REG_HSLCTL); |
545 | if (val & TWL6040_HSDACMODE) | 547 | if (val & TWL6040_HSDACMODE) |
546 | /* HSDACL in LP mode */ | 548 | /* HSDACL in LP mode */ |
547 | return -8; /* -8dB */ | 549 | return -8; /* -8dB */ |
@@ -572,7 +574,7 @@ EXPORT_SYMBOL_GPL(twl6040_get_trim_value); | |||
572 | 574 | ||
573 | int twl6040_get_hs_step_size(struct snd_soc_codec *codec) | 575 | int twl6040_get_hs_step_size(struct snd_soc_codec *codec) |
574 | { | 576 | { |
575 | struct twl6040 *twl6040 = codec->control_data; | 577 | struct twl6040 *twl6040 = to_twl6040(codec); |
576 | 578 | ||
577 | if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3) | 579 | if (twl6040_get_revid(twl6040) < TWL6040_REV_ES1_3) |
578 | /* For ES under ES_1.3 HS step is 2 mV */ | 580 | /* For ES under ES_1.3 HS step is 2 mV */ |
@@ -830,7 +832,7 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
830 | static int twl6040_set_bias_level(struct snd_soc_codec *codec, | 832 | static int twl6040_set_bias_level(struct snd_soc_codec *codec, |
831 | enum snd_soc_bias_level level) | 833 | enum snd_soc_bias_level level) |
832 | { | 834 | { |
833 | struct twl6040 *twl6040 = codec->control_data; | 835 | struct twl6040 *twl6040 = to_twl6040(codec); |
834 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 836 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
835 | int ret = 0; | 837 | int ret = 0; |
836 | 838 | ||
@@ -922,7 +924,7 @@ static int twl6040_prepare(struct snd_pcm_substream *substream, | |||
922 | struct snd_soc_dai *dai) | 924 | struct snd_soc_dai *dai) |
923 | { | 925 | { |
924 | struct snd_soc_codec *codec = dai->codec; | 926 | struct snd_soc_codec *codec = dai->codec; |
925 | struct twl6040 *twl6040 = codec->control_data; | 927 | struct twl6040 *twl6040 = to_twl6040(codec); |
926 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 928 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
927 | int ret; | 929 | int ret; |
928 | 930 | ||
@@ -964,7 +966,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
964 | static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id, | 966 | static void twl6040_mute_path(struct snd_soc_codec *codec, enum twl6040_dai_id id, |
965 | int mute) | 967 | int mute) |
966 | { | 968 | { |
967 | struct twl6040 *twl6040 = codec->control_data; | 969 | struct twl6040 *twl6040 = to_twl6040(codec); |
968 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 970 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
969 | int hslctl, hsrctl, earctl; | 971 | int hslctl, hsrctl, earctl; |
970 | int hflctl, hfrctl; | 972 | int hflctl, hfrctl; |
@@ -1108,7 +1110,6 @@ static struct snd_soc_dai_driver twl6040_dai[] = { | |||
1108 | static int twl6040_probe(struct snd_soc_codec *codec) | 1110 | static int twl6040_probe(struct snd_soc_codec *codec) |
1109 | { | 1111 | { |
1110 | struct twl6040_data *priv; | 1112 | struct twl6040_data *priv; |
1111 | struct twl6040 *twl6040 = dev_get_drvdata(codec->dev->parent); | ||
1112 | struct platform_device *pdev = to_platform_device(codec->dev); | 1113 | struct platform_device *pdev = to_platform_device(codec->dev); |
1113 | int ret = 0; | 1114 | int ret = 0; |
1114 | 1115 | ||
@@ -1119,7 +1120,6 @@ static int twl6040_probe(struct snd_soc_codec *codec) | |||
1119 | snd_soc_codec_set_drvdata(codec, priv); | 1120 | snd_soc_codec_set_drvdata(codec, priv); |
1120 | 1121 | ||
1121 | priv->codec = codec; | 1122 | priv->codec = codec; |
1122 | codec->control_data = twl6040; | ||
1123 | 1123 | ||
1124 | priv->plug_irq = platform_get_irq(pdev, 0); | 1124 | priv->plug_irq = platform_get_irq(pdev, 0); |
1125 | if (priv->plug_irq < 0) { | 1125 | if (priv->plug_irq < 0) { |
@@ -1158,8 +1158,6 @@ static int twl6040_remove(struct snd_soc_codec *codec) | |||
1158 | static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { | 1158 | static const struct snd_soc_codec_driver soc_codec_dev_twl6040 = { |
1159 | .probe = twl6040_probe, | 1159 | .probe = twl6040_probe, |
1160 | .remove = twl6040_remove, | 1160 | .remove = twl6040_remove, |
1161 | .read = twl6040_read, | ||
1162 | .write = twl6040_write, | ||
1163 | .set_bias_level = twl6040_set_bias_level, | 1161 | .set_bias_level = twl6040_set_bias_level, |
1164 | .suspend_bias_off = true, | 1162 | .suspend_bias_off = true, |
1165 | .ignore_pmdown_time = true, | 1163 | .ignore_pmdown_time = true, |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 926c81ae8185..c73e6a192224 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -37,7 +37,8 @@ struct uda1380_priv { | |||
37 | struct snd_soc_codec *codec; | 37 | struct snd_soc_codec *codec; |
38 | unsigned int dac_clk; | 38 | unsigned int dac_clk; |
39 | struct work_struct work; | 39 | struct work_struct work; |
40 | void *control_data; | 40 | struct i2c_client *i2c; |
41 | u16 *reg_cache; | ||
41 | }; | 42 | }; |
42 | 43 | ||
43 | /* | 44 | /* |
@@ -63,7 +64,9 @@ static unsigned long uda1380_cache_dirty; | |||
63 | static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, | 64 | static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, |
64 | unsigned int reg) | 65 | unsigned int reg) |
65 | { | 66 | { |
66 | u16 *cache = codec->reg_cache; | 67 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); |
68 | u16 *cache = uda1380->reg_cache; | ||
69 | |||
67 | if (reg == UDA1380_RESET) | 70 | if (reg == UDA1380_RESET) |
68 | return 0; | 71 | return 0; |
69 | if (reg >= UDA1380_CACHEREGNUM) | 72 | if (reg >= UDA1380_CACHEREGNUM) |
@@ -77,7 +80,8 @@ static inline unsigned int uda1380_read_reg_cache(struct snd_soc_codec *codec, | |||
77 | static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, | 80 | static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, |
78 | u16 reg, unsigned int value) | 81 | u16 reg, unsigned int value) |
79 | { | 82 | { |
80 | u16 *cache = codec->reg_cache; | 83 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); |
84 | u16 *cache = uda1380->reg_cache; | ||
81 | 85 | ||
82 | if (reg >= UDA1380_CACHEREGNUM) | 86 | if (reg >= UDA1380_CACHEREGNUM) |
83 | return; | 87 | return; |
@@ -92,6 +96,7 @@ static inline void uda1380_write_reg_cache(struct snd_soc_codec *codec, | |||
92 | static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, | 96 | static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, |
93 | unsigned int value) | 97 | unsigned int value) |
94 | { | 98 | { |
99 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); | ||
95 | u8 data[3]; | 100 | u8 data[3]; |
96 | 101 | ||
97 | /* data is | 102 | /* data is |
@@ -111,10 +116,10 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, | |||
111 | if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) | 116 | if (!snd_soc_codec_is_active(codec) && (reg >= UDA1380_MVOL)) |
112 | return 0; | 117 | return 0; |
113 | pr_debug("uda1380: hw write %x val %x\n", reg, value); | 118 | pr_debug("uda1380: hw write %x val %x\n", reg, value); |
114 | if (codec->hw_write(codec->control_data, data, 3) == 3) { | 119 | if (i2c_master_send(uda1380->i2c, data, 3) == 3) { |
115 | unsigned int val; | 120 | unsigned int val; |
116 | i2c_master_send(codec->control_data, data, 1); | 121 | i2c_master_send(uda1380->i2c, data, 1); |
117 | i2c_master_recv(codec->control_data, data, 2); | 122 | i2c_master_recv(uda1380->i2c, data, 2); |
118 | val = (data[0]<<8) | data[1]; | 123 | val = (data[0]<<8) | data[1]; |
119 | if (val != value) { | 124 | if (val != value) { |
120 | pr_debug("uda1380: READ BACK VAL %x\n", | 125 | pr_debug("uda1380: READ BACK VAL %x\n", |
@@ -130,16 +135,17 @@ static int uda1380_write(struct snd_soc_codec *codec, unsigned int reg, | |||
130 | 135 | ||
131 | static void uda1380_sync_cache(struct snd_soc_codec *codec) | 136 | static void uda1380_sync_cache(struct snd_soc_codec *codec) |
132 | { | 137 | { |
138 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); | ||
133 | int reg; | 139 | int reg; |
134 | u8 data[3]; | 140 | u8 data[3]; |
135 | u16 *cache = codec->reg_cache; | 141 | u16 *cache = uda1380->reg_cache; |
136 | 142 | ||
137 | /* Sync reg_cache with the hardware */ | 143 | /* Sync reg_cache with the hardware */ |
138 | for (reg = 0; reg < UDA1380_MVOL; reg++) { | 144 | for (reg = 0; reg < UDA1380_MVOL; reg++) { |
139 | data[0] = reg; | 145 | data[0] = reg; |
140 | data[1] = (cache[reg] & 0xff00) >> 8; | 146 | data[1] = (cache[reg] & 0xff00) >> 8; |
141 | data[2] = cache[reg] & 0x00ff; | 147 | data[2] = cache[reg] & 0x00ff; |
142 | if (codec->hw_write(codec->control_data, data, 3) != 3) | 148 | if (i2c_master_send(uda1380->i2c, data, 3) != 3) |
143 | dev_err(codec->dev, "%s: write to reg 0x%x failed\n", | 149 | dev_err(codec->dev, "%s: write to reg 0x%x failed\n", |
144 | __func__, reg); | 150 | __func__, reg); |
145 | } | 151 | } |
@@ -148,6 +154,7 @@ static void uda1380_sync_cache(struct snd_soc_codec *codec) | |||
148 | static int uda1380_reset(struct snd_soc_codec *codec) | 154 | static int uda1380_reset(struct snd_soc_codec *codec) |
149 | { | 155 | { |
150 | struct uda1380_platform_data *pdata = codec->dev->platform_data; | 156 | struct uda1380_platform_data *pdata = codec->dev->platform_data; |
157 | struct uda1380_priv *uda1380 = snd_soc_codec_get_drvdata(codec); | ||
151 | 158 | ||
152 | if (gpio_is_valid(pdata->gpio_reset)) { | 159 | if (gpio_is_valid(pdata->gpio_reset)) { |
153 | gpio_set_value(pdata->gpio_reset, 1); | 160 | gpio_set_value(pdata->gpio_reset, 1); |
@@ -160,7 +167,7 @@ static int uda1380_reset(struct snd_soc_codec *codec) | |||
160 | data[1] = 0; | 167 | data[1] = 0; |
161 | data[2] = 0; | 168 | data[2] = 0; |
162 | 169 | ||
163 | if (codec->hw_write(codec->control_data, data, 3) != 3) { | 170 | if (i2c_master_send(uda1380->i2c, data, 3) != 3) { |
164 | dev_err(codec->dev, "%s: failed\n", __func__); | 171 | dev_err(codec->dev, "%s: failed\n", __func__); |
165 | return -EIO; | 172 | return -EIO; |
166 | } | 173 | } |
@@ -695,9 +702,6 @@ static int uda1380_probe(struct snd_soc_codec *codec) | |||
695 | 702 | ||
696 | uda1380->codec = codec; | 703 | uda1380->codec = codec; |
697 | 704 | ||
698 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
699 | codec->control_data = uda1380->control_data; | ||
700 | |||
701 | if (!gpio_is_valid(pdata->gpio_power)) { | 705 | if (!gpio_is_valid(pdata->gpio_power)) { |
702 | ret = uda1380_reset(codec); | 706 | ret = uda1380_reset(codec); |
703 | if (ret) | 707 | if (ret) |
@@ -727,11 +731,6 @@ static const struct snd_soc_codec_driver soc_codec_dev_uda1380 = { | |||
727 | .set_bias_level = uda1380_set_bias_level, | 731 | .set_bias_level = uda1380_set_bias_level, |
728 | .suspend_bias_off = true, | 732 | .suspend_bias_off = true, |
729 | 733 | ||
730 | .reg_cache_size = ARRAY_SIZE(uda1380_reg), | ||
731 | .reg_word_size = sizeof(u16), | ||
732 | .reg_cache_default = uda1380_reg, | ||
733 | .reg_cache_step = 1, | ||
734 | |||
735 | .component_driver = { | 734 | .component_driver = { |
736 | .controls = uda1380_snd_controls, | 735 | .controls = uda1380_snd_controls, |
737 | .num_controls = ARRAY_SIZE(uda1380_snd_controls), | 736 | .num_controls = ARRAY_SIZE(uda1380_snd_controls), |
@@ -771,8 +770,15 @@ static int uda1380_i2c_probe(struct i2c_client *i2c, | |||
771 | return ret; | 770 | return ret; |
772 | } | 771 | } |
773 | 772 | ||
773 | uda1380->reg_cache = devm_kmemdup(&i2c->dev, | ||
774 | uda1380_reg, | ||
775 | ARRAY_SIZE(uda1380_reg) * sizeof(u16), | ||
776 | GFP_KERNEL); | ||
777 | if (!uda1380->reg_cache) | ||
778 | return -ENOMEM; | ||
779 | |||
774 | i2c_set_clientdata(i2c, uda1380); | 780 | i2c_set_clientdata(i2c, uda1380); |
775 | uda1380->control_data = i2c; | 781 | uda1380->i2c = i2c; |
776 | 782 | ||
777 | ret = snd_soc_register_codec(&i2c->dev, | 783 | ret = snd_soc_register_codec(&i2c->dev, |
778 | &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai)); | 784 | &soc_codec_dev_uda1380, uda1380_dai, ARRAY_SIZE(uda1380_dai)); |
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c index 4f5f5710b569..0147d2fb7b0a 100644 --- a/sound/soc/codecs/wm0010.c +++ b/sound/soc/codecs/wm0010.c | |||
@@ -655,11 +655,8 @@ static int wm0010_boot(struct snd_soc_codec *codec) | |||
655 | ret = -ENOMEM; | 655 | ret = -ENOMEM; |
656 | len = pll_rec.length + 8; | 656 | len = pll_rec.length + 8; |
657 | out = kzalloc(len, GFP_KERNEL | GFP_DMA); | 657 | out = kzalloc(len, GFP_KERNEL | GFP_DMA); |
658 | if (!out) { | 658 | if (!out) |
659 | dev_err(codec->dev, | ||
660 | "Failed to allocate RX buffer\n"); | ||
661 | goto abort; | 659 | goto abort; |
662 | } | ||
663 | 660 | ||
664 | img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA); | 661 | img_swap = kzalloc(len, GFP_KERNEL | GFP_DMA); |
665 | if (!img_swap) | 662 | if (!img_swap) |
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 23cde3a0dc11..abfa052c07d8 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * 'wm2000_anc.bin' by default (overridable via platform data) at | 13 | * 'wm2000_anc.bin' by default (overridable via platform data) at |
14 | * runtime and is expected to be in flat binary format. This is | 14 | * runtime and is expected to be in flat binary format. This is |
15 | * generated by Wolfson configuration tools and includes | 15 | * generated by Wolfson configuration tools and includes |
16 | * system-specific callibration information. If supplied as a | 16 | * system-specific calibration information. If supplied as a |
17 | * sequence of ASCII-encoded hexidecimal bytes this can be converted | 17 | * sequence of ASCII-encoded hexidecimal bytes this can be converted |
18 | * into a flat binary with a command such as this on the command line: | 18 | * into a flat binary with a command such as this on the command line: |
19 | * | 19 | * |
@@ -826,8 +826,7 @@ static int wm2000_i2c_probe(struct i2c_client *i2c, | |||
826 | int reg; | 826 | int reg; |
827 | u16 id; | 827 | u16 id; |
828 | 828 | ||
829 | wm2000 = devm_kzalloc(&i2c->dev, sizeof(struct wm2000_priv), | 829 | wm2000 = devm_kzalloc(&i2c->dev, sizeof(*wm2000), GFP_KERNEL); |
830 | GFP_KERNEL); | ||
831 | if (!wm2000) | 830 | if (!wm2000) |
832 | return -ENOMEM; | 831 | return -ENOMEM; |
833 | 832 | ||
@@ -902,7 +901,6 @@ static int wm2000_i2c_probe(struct i2c_client *i2c, | |||
902 | wm2000->anc_download_size, | 901 | wm2000->anc_download_size, |
903 | GFP_KERNEL); | 902 | GFP_KERNEL); |
904 | if (wm2000->anc_download == NULL) { | 903 | if (wm2000->anc_download == NULL) { |
905 | dev_err(&i2c->dev, "Out of memory\n"); | ||
906 | ret = -ENOMEM; | 904 | ret = -ENOMEM; |
907 | goto err_supplies; | 905 | goto err_supplies; |
908 | } | 906 | } |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index d83dab57a1d1..5c2f5727244d 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -98,6 +98,8 @@ struct wm2200_priv { | |||
98 | 98 | ||
99 | int rev; | 99 | int rev; |
100 | int sysclk; | 100 | int sysclk; |
101 | |||
102 | unsigned int symmetric_rates:1; | ||
101 | }; | 103 | }; |
102 | 104 | ||
103 | #define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1) | 105 | #define WM2200_DSP_RANGE_BASE (WM2200_MAX_REGISTER + 1) |
@@ -1550,7 +1552,7 @@ static const struct snd_soc_dapm_route wm2200_dapm_routes[] = { | |||
1550 | 1552 | ||
1551 | static int wm2200_probe(struct snd_soc_codec *codec) | 1553 | static int wm2200_probe(struct snd_soc_codec *codec) |
1552 | { | 1554 | { |
1553 | struct wm2200_priv *wm2200 = dev_get_drvdata(codec->dev); | 1555 | struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); |
1554 | int ret; | 1556 | int ret; |
1555 | 1557 | ||
1556 | wm2200->codec = codec; | 1558 | wm2200->codec = codec; |
@@ -1758,7 +1760,7 @@ static int wm2200_hw_params(struct snd_pcm_substream *substream, | |||
1758 | lrclk = bclk_rates[bclk] / params_rate(params); | 1760 | lrclk = bclk_rates[bclk] / params_rate(params); |
1759 | dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk); | 1761 | dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk); |
1760 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || | 1762 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || |
1761 | dai->symmetric_rates) | 1763 | wm2200->symmetric_rates) |
1762 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7, | 1764 | snd_soc_update_bits(codec, WM2200_AUDIO_IF_1_7, |
1763 | WM2200_AIF1RX_BCPF_MASK, lrclk); | 1765 | WM2200_AIF1RX_BCPF_MASK, lrclk); |
1764 | else | 1766 | else |
@@ -2059,13 +2061,14 @@ static int wm2200_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
2059 | static int wm2200_dai_probe(struct snd_soc_dai *dai) | 2061 | static int wm2200_dai_probe(struct snd_soc_dai *dai) |
2060 | { | 2062 | { |
2061 | struct snd_soc_codec *codec = dai->codec; | 2063 | struct snd_soc_codec *codec = dai->codec; |
2064 | struct wm2200_priv *wm2200 = snd_soc_codec_get_drvdata(codec); | ||
2062 | unsigned int val = 0; | 2065 | unsigned int val = 0; |
2063 | int ret; | 2066 | int ret; |
2064 | 2067 | ||
2065 | ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1); | 2068 | ret = snd_soc_read(codec, WM2200_GPIO_CTRL_1); |
2066 | if (ret >= 0) { | 2069 | if (ret >= 0) { |
2067 | if ((ret & WM2200_GP1_FN_MASK) != 0) { | 2070 | if ((ret & WM2200_GP1_FN_MASK) != 0) { |
2068 | dai->symmetric_rates = true; | 2071 | wm2200->symmetric_rates = true; |
2069 | val = WM2200_AIF1TX_LRCLK_SRC; | 2072 | val = WM2200_AIF1TX_LRCLK_SRC; |
2070 | } | 2073 | } |
2071 | } else { | 2074 | } else { |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 4f0481d3c7a7..fc066caa1918 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -1935,8 +1935,11 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) | |||
1935 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 1935 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); |
1936 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); | 1936 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); |
1937 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1937 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1938 | struct arizona *arizona = priv->core.arizona; | ||
1938 | int ret; | 1939 | int ret; |
1939 | 1940 | ||
1941 | snd_soc_codec_init_regmap(codec, arizona->regmap); | ||
1942 | |||
1940 | ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec); | 1943 | ret = wm_adsp2_codec_probe(&priv->core.adsp[0], codec); |
1941 | if (ret) | 1944 | if (ret) |
1942 | return ret; | 1945 | return ret; |
@@ -1989,17 +1992,9 @@ static unsigned int wm5102_digital_vu[] = { | |||
1989 | ARIZONA_DAC_DIGITAL_VOLUME_5R, | 1992 | ARIZONA_DAC_DIGITAL_VOLUME_5R, |
1990 | }; | 1993 | }; |
1991 | 1994 | ||
1992 | static struct regmap *wm5102_get_regmap(struct device *dev) | ||
1993 | { | ||
1994 | struct wm5102_priv *priv = dev_get_drvdata(dev); | ||
1995 | |||
1996 | return priv->core.arizona->regmap; | ||
1997 | } | ||
1998 | |||
1999 | static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | 1995 | static const struct snd_soc_codec_driver soc_codec_dev_wm5102 = { |
2000 | .probe = wm5102_codec_probe, | 1996 | .probe = wm5102_codec_probe, |
2001 | .remove = wm5102_codec_remove, | 1997 | .remove = wm5102_codec_remove, |
2002 | .get_regmap = wm5102_get_regmap, | ||
2003 | 1998 | ||
2004 | .idle_bias_off = true, | 1999 | .idle_bias_off = true, |
2005 | 2000 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 6ed1e1f9ce51..fb0cf9c61f48 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -2280,9 +2280,11 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) | |||
2280 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 2280 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); |
2281 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); | 2281 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); |
2282 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); | 2282 | struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec); |
2283 | struct arizona *arizona = priv->core.arizona; | ||
2283 | int i, ret; | 2284 | int i, ret; |
2284 | 2285 | ||
2285 | priv->core.arizona->dapm = dapm; | 2286 | arizona->dapm = dapm; |
2287 | snd_soc_codec_init_regmap(codec, arizona->regmap); | ||
2286 | 2288 | ||
2287 | ret = arizona_init_spk(codec); | 2289 | ret = arizona_init_spk(codec); |
2288 | if (ret < 0) | 2290 | if (ret < 0) |
@@ -2344,17 +2346,9 @@ static unsigned int wm5110_digital_vu[] = { | |||
2344 | ARIZONA_DAC_DIGITAL_VOLUME_6R, | 2346 | ARIZONA_DAC_DIGITAL_VOLUME_6R, |
2345 | }; | 2347 | }; |
2346 | 2348 | ||
2347 | static struct regmap *wm5110_get_regmap(struct device *dev) | ||
2348 | { | ||
2349 | struct wm5110_priv *priv = dev_get_drvdata(dev); | ||
2350 | |||
2351 | return priv->core.arizona->regmap; | ||
2352 | } | ||
2353 | |||
2354 | static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 2349 | static const struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
2355 | .probe = wm5110_codec_probe, | 2350 | .probe = wm5110_codec_probe, |
2356 | .remove = wm5110_codec_remove, | 2351 | .remove = wm5110_codec_remove, |
2357 | .get_regmap = wm5110_get_regmap, | ||
2358 | 2352 | ||
2359 | .idle_bias_off = true, | 2353 | .idle_bias_off = true, |
2360 | 2354 | ||
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 2efc5b41ad0f..fc79c6725d06 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -1472,6 +1472,8 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) | |||
1472 | GFP_KERNEL); | 1472 | GFP_KERNEL); |
1473 | if (priv == NULL) | 1473 | if (priv == NULL) |
1474 | return -ENOMEM; | 1474 | return -ENOMEM; |
1475 | |||
1476 | snd_soc_codec_init_regmap(codec, wm8350->regmap); | ||
1475 | snd_soc_codec_set_drvdata(codec, priv); | 1477 | snd_soc_codec_set_drvdata(codec, priv); |
1476 | 1478 | ||
1477 | priv->wm8350 = wm8350; | 1479 | priv->wm8350 = wm8350; |
@@ -1580,17 +1582,9 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) | |||
1580 | return 0; | 1582 | return 0; |
1581 | } | 1583 | } |
1582 | 1584 | ||
1583 | static struct regmap *wm8350_get_regmap(struct device *dev) | ||
1584 | { | ||
1585 | struct wm8350 *wm8350 = dev_get_platdata(dev); | ||
1586 | |||
1587 | return wm8350->regmap; | ||
1588 | } | ||
1589 | |||
1590 | static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = { | 1585 | static const struct snd_soc_codec_driver soc_codec_dev_wm8350 = { |
1591 | .probe = wm8350_codec_probe, | 1586 | .probe = wm8350_codec_probe, |
1592 | .remove = wm8350_codec_remove, | 1587 | .remove = wm8350_codec_remove, |
1593 | .get_regmap = wm8350_get_regmap, | ||
1594 | .set_bias_level = wm8350_set_bias_level, | 1588 | .set_bias_level = wm8350_set_bias_level, |
1595 | .suspend_bias_off = true, | 1589 | .suspend_bias_off = true, |
1596 | 1590 | ||
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 6c59fb933bd6..a36adf881bca 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1285,6 +1285,7 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1285 | if (priv == NULL) | 1285 | if (priv == NULL) |
1286 | return -ENOMEM; | 1286 | return -ENOMEM; |
1287 | 1287 | ||
1288 | snd_soc_codec_init_regmap(codec, wm8400->regmap); | ||
1288 | snd_soc_codec_set_drvdata(codec, priv); | 1289 | snd_soc_codec_set_drvdata(codec, priv); |
1289 | priv->wm8400 = wm8400; | 1290 | priv->wm8400 = wm8400; |
1290 | 1291 | ||
@@ -1325,17 +1326,9 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) | |||
1325 | return 0; | 1326 | return 0; |
1326 | } | 1327 | } |
1327 | 1328 | ||
1328 | static struct regmap *wm8400_get_regmap(struct device *dev) | ||
1329 | { | ||
1330 | struct wm8400 *wm8400 = dev_get_platdata(dev); | ||
1331 | |||
1332 | return wm8400->regmap; | ||
1333 | } | ||
1334 | |||
1335 | static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = { | 1329 | static const struct snd_soc_codec_driver soc_codec_dev_wm8400 = { |
1336 | .probe = wm8400_codec_probe, | 1330 | .probe = wm8400_codec_probe, |
1337 | .remove = wm8400_codec_remove, | 1331 | .remove = wm8400_codec_remove, |
1338 | .get_regmap = wm8400_get_regmap, | ||
1339 | .set_bias_level = wm8400_set_bias_level, | 1332 | .set_bias_level = wm8400_set_bias_level, |
1340 | .suspend_bias_off = true, | 1333 | .suspend_bias_off = true, |
1341 | 1334 | ||
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 237eeb9a8b97..cba90f21161f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -1995,8 +1995,7 @@ static int wm8903_i2c_probe(struct i2c_client *i2c, | |||
1995 | unsigned int val, irq_pol; | 1995 | unsigned int val, irq_pol; |
1996 | int ret, i; | 1996 | int ret, i; |
1997 | 1997 | ||
1998 | wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), | 1998 | wm8903 = devm_kzalloc(&i2c->dev, sizeof(*wm8903), GFP_KERNEL); |
1999 | GFP_KERNEL); | ||
2000 | if (wm8903 == NULL) | 1999 | if (wm8903 == NULL) |
2001 | return -ENOMEM; | 2000 | return -ENOMEM; |
2002 | 2001 | ||
@@ -2017,13 +2016,10 @@ static int wm8903_i2c_probe(struct i2c_client *i2c, | |||
2017 | if (pdata) { | 2016 | if (pdata) { |
2018 | wm8903->pdata = pdata; | 2017 | wm8903->pdata = pdata; |
2019 | } else { | 2018 | } else { |
2020 | wm8903->pdata = devm_kzalloc(&i2c->dev, | 2019 | wm8903->pdata = devm_kzalloc(&i2c->dev, sizeof(*wm8903->pdata), |
2021 | sizeof(struct wm8903_platform_data), | 2020 | GFP_KERNEL); |
2022 | GFP_KERNEL); | 2021 | if (!wm8903->pdata) |
2023 | if (wm8903->pdata == NULL) { | ||
2024 | dev_err(&i2c->dev, "Failed to allocate pdata\n"); | ||
2025 | return -ENOMEM; | 2022 | return -ENOMEM; |
2026 | } | ||
2027 | 2023 | ||
2028 | if (i2c->irq) { | 2024 | if (i2c->irq) { |
2029 | ret = wm8903_set_pdata_irq_trigger(i2c, wm8903->pdata); | 2025 | ret = wm8903_set_pdata_irq_trigger(i2c, wm8903->pdata); |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index f91b49e1ece3..21ffd6403173 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -3993,6 +3993,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3993 | unsigned int reg; | 3993 | unsigned int reg; |
3994 | int ret, i; | 3994 | int ret, i; |
3995 | 3995 | ||
3996 | snd_soc_codec_init_regmap(codec, control->regmap); | ||
3997 | |||
3996 | wm8994->hubs.codec = codec; | 3998 | wm8994->hubs.codec = codec; |
3997 | 3999 | ||
3998 | mutex_init(&wm8994->accdet_lock); | 4000 | mutex_init(&wm8994->accdet_lock); |
@@ -4434,19 +4436,11 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
4434 | return 0; | 4436 | return 0; |
4435 | } | 4437 | } |
4436 | 4438 | ||
4437 | static struct regmap *wm8994_get_regmap(struct device *dev) | ||
4438 | { | ||
4439 | struct wm8994 *control = dev_get_drvdata(dev->parent); | ||
4440 | |||
4441 | return control->regmap; | ||
4442 | } | ||
4443 | |||
4444 | static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = { | 4439 | static const struct snd_soc_codec_driver soc_codec_dev_wm8994 = { |
4445 | .probe = wm8994_codec_probe, | 4440 | .probe = wm8994_codec_probe, |
4446 | .remove = wm8994_codec_remove, | 4441 | .remove = wm8994_codec_remove, |
4447 | .suspend = wm8994_codec_suspend, | 4442 | .suspend = wm8994_codec_suspend, |
4448 | .resume = wm8994_codec_resume, | 4443 | .resume = wm8994_codec_resume, |
4449 | .get_regmap = wm8994_get_regmap, | ||
4450 | .set_bias_level = wm8994_set_bias_level, | 4444 | .set_bias_level = wm8994_set_bias_level, |
4451 | }; | 4445 | }; |
4452 | 4446 | ||
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 77f512767273..cac9b3e7e15d 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -1062,8 +1062,11 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec) | |||
1062 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 1062 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); |
1063 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); | 1063 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); |
1064 | struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); | 1064 | struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); |
1065 | struct arizona *arizona = priv->core.arizona; | ||
1065 | int ret; | 1066 | int ret; |
1066 | 1067 | ||
1068 | snd_soc_codec_init_regmap(codec, arizona->regmap); | ||
1069 | |||
1067 | ret = arizona_init_spk(codec); | 1070 | ret = arizona_init_spk(codec); |
1068 | if (ret < 0) | 1071 | if (ret < 0) |
1069 | return ret; | 1072 | return ret; |
@@ -1095,17 +1098,9 @@ static unsigned int wm8997_digital_vu[] = { | |||
1095 | ARIZONA_DAC_DIGITAL_VOLUME_5R, | 1098 | ARIZONA_DAC_DIGITAL_VOLUME_5R, |
1096 | }; | 1099 | }; |
1097 | 1100 | ||
1098 | static struct regmap *wm8997_get_regmap(struct device *dev) | ||
1099 | { | ||
1100 | struct wm8997_priv *priv = dev_get_drvdata(dev); | ||
1101 | |||
1102 | return priv->core.arizona->regmap; | ||
1103 | } | ||
1104 | |||
1105 | static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = { | 1101 | static const struct snd_soc_codec_driver soc_codec_dev_wm8997 = { |
1106 | .probe = wm8997_codec_probe, | 1102 | .probe = wm8997_codec_probe, |
1107 | .remove = wm8997_codec_remove, | 1103 | .remove = wm8997_codec_remove, |
1108 | .get_regmap = wm8997_get_regmap, | ||
1109 | 1104 | ||
1110 | .idle_bias_off = true, | 1105 | .idle_bias_off = true, |
1111 | 1106 | ||
diff --git a/sound/soc/codecs/wm8998.c b/sound/soc/codecs/wm8998.c index 2d211dbe7422..1288e1f67dcf 100644 --- a/sound/soc/codecs/wm8998.c +++ b/sound/soc/codecs/wm8998.c | |||
@@ -1275,9 +1275,11 @@ static int wm8998_codec_probe(struct snd_soc_codec *codec) | |||
1275 | struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec); | 1275 | struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec); |
1276 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); | 1276 | struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); |
1277 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); | 1277 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm); |
1278 | struct arizona *arizona = priv->core.arizona; | ||
1278 | int ret; | 1279 | int ret; |
1279 | 1280 | ||
1280 | priv->core.arizona->dapm = dapm; | 1281 | arizona->dapm = dapm; |
1282 | snd_soc_codec_init_regmap(codec, arizona->regmap); | ||
1281 | 1283 | ||
1282 | ret = arizona_init_spk(codec); | 1284 | ret = arizona_init_spk(codec); |
1283 | if (ret < 0) | 1285 | if (ret < 0) |
@@ -1313,17 +1315,9 @@ static unsigned int wm8998_digital_vu[] = { | |||
1313 | ARIZONA_DAC_DIGITAL_VOLUME_5R, | 1315 | ARIZONA_DAC_DIGITAL_VOLUME_5R, |
1314 | }; | 1316 | }; |
1315 | 1317 | ||
1316 | static struct regmap *wm8998_get_regmap(struct device *dev) | ||
1317 | { | ||
1318 | struct wm8998_priv *priv = dev_get_drvdata(dev); | ||
1319 | |||
1320 | return priv->core.arizona->regmap; | ||
1321 | } | ||
1322 | |||
1323 | static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = { | 1318 | static const struct snd_soc_codec_driver soc_codec_dev_wm8998 = { |
1324 | .probe = wm8998_codec_probe, | 1319 | .probe = wm8998_codec_probe, |
1325 | .remove = wm8998_codec_remove, | 1320 | .remove = wm8998_codec_remove, |
1326 | .get_regmap = wm8998_get_regmap, | ||
1327 | 1321 | ||
1328 | .idle_bias_off = true, | 1322 | .idle_bias_off = true, |
1329 | 1323 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 804c6f2bcf21..03ba218160ca 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -1242,6 +1242,20 @@ static int davinci_mcasp_hw_rule_format(struct snd_pcm_hw_params *params, | |||
1242 | return snd_mask_refine(fmt, &nfmt); | 1242 | return snd_mask_refine(fmt, &nfmt); |
1243 | } | 1243 | } |
1244 | 1244 | ||
1245 | static int davinci_mcasp_hw_rule_min_periodsize( | ||
1246 | struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) | ||
1247 | { | ||
1248 | struct snd_interval *period_size = hw_param_interval(params, | ||
1249 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | ||
1250 | struct snd_interval frames; | ||
1251 | |||
1252 | snd_interval_any(&frames); | ||
1253 | frames.min = 64; | ||
1254 | frames.integer = 1; | ||
1255 | |||
1256 | return snd_interval_refine(period_size, &frames); | ||
1257 | } | ||
1258 | |||
1245 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | 1259 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, |
1246 | struct snd_soc_dai *cpu_dai) | 1260 | struct snd_soc_dai *cpu_dai) |
1247 | { | 1261 | { |
@@ -1333,6 +1347,11 @@ static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | |||
1333 | return ret; | 1347 | return ret; |
1334 | } | 1348 | } |
1335 | 1349 | ||
1350 | snd_pcm_hw_rule_add(substream->runtime, 0, | ||
1351 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
1352 | davinci_mcasp_hw_rule_min_periodsize, NULL, | ||
1353 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); | ||
1354 | |||
1336 | return 0; | 1355 | return 0; |
1337 | } | 1356 | } |
1338 | 1357 | ||
diff --git a/sound/soc/fsl/eukrea-tlv320.c b/sound/soc/fsl/eukrea-tlv320.c index 84ef6385736c..191426a6d9ad 100644 --- a/sound/soc/fsl/eukrea-tlv320.c +++ b/sound/soc/fsl/eukrea-tlv320.c | |||
@@ -29,7 +29,6 @@ | |||
29 | 29 | ||
30 | #include "../codecs/tlv320aic23.h" | 30 | #include "../codecs/tlv320aic23.h" |
31 | #include "imx-ssi.h" | 31 | #include "imx-ssi.h" |
32 | #include "fsl_ssi.h" | ||
33 | #include "imx-audmux.h" | 32 | #include "imx-audmux.h" |
34 | 33 | ||
35 | #define CODEC_CLOCK 12000000 | 34 | #define CODEC_CLOCK 12000000 |
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index 1225e0399de8..989be518c4ed 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c | |||
@@ -442,8 +442,8 @@ static int fsl_asoc_card_late_probe(struct snd_soc_card *card) | |||
442 | 442 | ||
443 | if (fsl_asoc_card_is_ac97(priv)) { | 443 | if (fsl_asoc_card_is_ac97(priv)) { |
444 | #if IS_ENABLED(CONFIG_SND_AC97_CODEC) | 444 | #if IS_ENABLED(CONFIG_SND_AC97_CODEC) |
445 | struct snd_soc_codec *codec = rtd->codec; | 445 | struct snd_soc_component *component = rtd->codec_dai->component; |
446 | struct snd_ac97 *ac97 = snd_soc_codec_get_drvdata(codec); | 446 | struct snd_ac97 *ac97 = snd_soc_component_get_drvdata(component); |
447 | 447 | ||
448 | /* | 448 | /* |
449 | * Use slots 3/4 for S/PDIF so SSI won't try to enable | 449 | * Use slots 3/4 for S/PDIF so SSI won't try to enable |
diff --git a/sound/soc/fsl/fsl_asrc.h b/sound/soc/fsl/fsl_asrc.h index 52c27a358933..2c5856ac5bc3 100644 --- a/sound/soc/fsl/fsl_asrc.h +++ b/sound/soc/fsl/fsl_asrc.h | |||
@@ -57,7 +57,7 @@ | |||
57 | #define REG_ASRDOC 0x74 | 57 | #define REG_ASRDOC 0x74 |
58 | #define REG_ASRDI(i) (REG_ASRDIA + (i << 3)) | 58 | #define REG_ASRDI(i) (REG_ASRDIA + (i << 3)) |
59 | #define REG_ASRDO(i) (REG_ASRDOA + (i << 3)) | 59 | #define REG_ASRDO(i) (REG_ASRDOA + (i << 3)) |
60 | #define REG_ASRDx(x, i) (x == IN ? REG_ASRDI(i) : REG_ASRDO(i)) | 60 | #define REG_ASRDx(x, i) ((x) == IN ? REG_ASRDI(i) : REG_ASRDO(i)) |
61 | 61 | ||
62 | #define REG_ASRIDRHA 0x80 | 62 | #define REG_ASRIDRHA 0x80 |
63 | #define REG_ASRIDRLA 0x84 | 63 | #define REG_ASRIDRLA 0x84 |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index 0c11f434a374..8c2981b70f64 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
@@ -913,8 +913,8 @@ static int fsl_soc_dma_probe(struct platform_device *pdev) | |||
913 | dma->dai.pcm_free = fsl_dma_free_dma_buffers; | 913 | dma->dai.pcm_free = fsl_dma_free_dma_buffers; |
914 | 914 | ||
915 | /* Store the SSI-specific information that we need */ | 915 | /* Store the SSI-specific information that we need */ |
916 | dma->ssi_stx_phys = res.start + CCSR_SSI_STX0; | 916 | dma->ssi_stx_phys = res.start + REG_SSI_STX0; |
917 | dma->ssi_srx_phys = res.start + CCSR_SSI_SRX0; | 917 | dma->ssi_srx_phys = res.start + REG_SSI_SRX0; |
918 | 918 | ||
919 | iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); | 919 | iprop = of_get_property(ssi_np, "fsl,fifo-depth", NULL); |
920 | if (iprop) | 920 | if (iprop) |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 424bafaf51ef..aecd00f7929d 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -69,21 +69,35 @@ | |||
69 | * samples will be written to STX properly. | 69 | * samples will be written to STX properly. |
70 | */ | 70 | */ |
71 | #ifdef __BIG_ENDIAN | 71 | #ifdef __BIG_ENDIAN |
72 | #define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \ | 72 | #define FSLSSI_I2S_FORMATS \ |
73 | SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_S20_3BE | \ | 73 | (SNDRV_PCM_FMTBIT_S8 | \ |
74 | SNDRV_PCM_FMTBIT_S24_3BE | SNDRV_PCM_FMTBIT_S24_BE) | 74 | SNDRV_PCM_FMTBIT_S16_BE | \ |
75 | SNDRV_PCM_FMTBIT_S18_3BE | \ | ||
76 | SNDRV_PCM_FMTBIT_S20_3BE | \ | ||
77 | SNDRV_PCM_FMTBIT_S24_3BE | \ | ||
78 | SNDRV_PCM_FMTBIT_S24_BE) | ||
75 | #else | 79 | #else |
76 | #define FSLSSI_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \ | 80 | #define FSLSSI_I2S_FORMATS \ |
77 | SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | 81 | (SNDRV_PCM_FMTBIT_S8 | \ |
78 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) | 82 | SNDRV_PCM_FMTBIT_S16_LE | \ |
83 | SNDRV_PCM_FMTBIT_S18_3LE | \ | ||
84 | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
85 | SNDRV_PCM_FMTBIT_S24_3LE | \ | ||
86 | SNDRV_PCM_FMTBIT_S24_LE) | ||
79 | #endif | 87 | #endif |
80 | 88 | ||
81 | #define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \ | 89 | #define FSLSSI_SIER_DBG_RX_FLAGS \ |
82 | CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \ | 90 | (SSI_SIER_RFF0_EN | \ |
83 | CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN) | 91 | SSI_SIER_RLS_EN | \ |
84 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ | 92 | SSI_SIER_RFS_EN | \ |
85 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ | 93 | SSI_SIER_ROE0_EN | \ |
86 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) | 94 | SSI_SIER_RFRC_EN) |
95 | #define FSLSSI_SIER_DBG_TX_FLAGS \ | ||
96 | (SSI_SIER_TFE0_EN | \ | ||
97 | SSI_SIER_TLS_EN | \ | ||
98 | SSI_SIER_TFS_EN | \ | ||
99 | SSI_SIER_TUE0_EN | \ | ||
100 | SSI_SIER_TFRC_EN) | ||
87 | 101 | ||
88 | enum fsl_ssi_type { | 102 | enum fsl_ssi_type { |
89 | FSL_SSI_MCP8610, | 103 | FSL_SSI_MCP8610, |
@@ -92,23 +106,18 @@ enum fsl_ssi_type { | |||
92 | FSL_SSI_MX51, | 106 | FSL_SSI_MX51, |
93 | }; | 107 | }; |
94 | 108 | ||
95 | struct fsl_ssi_reg_val { | 109 | struct fsl_ssi_regvals { |
96 | u32 sier; | 110 | u32 sier; |
97 | u32 srcr; | 111 | u32 srcr; |
98 | u32 stcr; | 112 | u32 stcr; |
99 | u32 scr; | 113 | u32 scr; |
100 | }; | 114 | }; |
101 | 115 | ||
102 | struct fsl_ssi_rxtx_reg_val { | ||
103 | struct fsl_ssi_reg_val rx; | ||
104 | struct fsl_ssi_reg_val tx; | ||
105 | }; | ||
106 | |||
107 | static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) | 116 | static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) |
108 | { | 117 | { |
109 | switch (reg) { | 118 | switch (reg) { |
110 | case CCSR_SSI_SACCEN: | 119 | case REG_SSI_SACCEN: |
111 | case CCSR_SSI_SACCDIS: | 120 | case REG_SSI_SACCDIS: |
112 | return false; | 121 | return false; |
113 | default: | 122 | default: |
114 | return true; | 123 | return true; |
@@ -118,18 +127,18 @@ static bool fsl_ssi_readable_reg(struct device *dev, unsigned int reg) | |||
118 | static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) | 127 | static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) |
119 | { | 128 | { |
120 | switch (reg) { | 129 | switch (reg) { |
121 | case CCSR_SSI_STX0: | 130 | case REG_SSI_STX0: |
122 | case CCSR_SSI_STX1: | 131 | case REG_SSI_STX1: |
123 | case CCSR_SSI_SRX0: | 132 | case REG_SSI_SRX0: |
124 | case CCSR_SSI_SRX1: | 133 | case REG_SSI_SRX1: |
125 | case CCSR_SSI_SISR: | 134 | case REG_SSI_SISR: |
126 | case CCSR_SSI_SFCSR: | 135 | case REG_SSI_SFCSR: |
127 | case CCSR_SSI_SACNT: | 136 | case REG_SSI_SACNT: |
128 | case CCSR_SSI_SACADD: | 137 | case REG_SSI_SACADD: |
129 | case CCSR_SSI_SACDAT: | 138 | case REG_SSI_SACDAT: |
130 | case CCSR_SSI_SATAG: | 139 | case REG_SSI_SATAG: |
131 | case CCSR_SSI_SACCST: | 140 | case REG_SSI_SACCST: |
132 | case CCSR_SSI_SOR: | 141 | case REG_SSI_SOR: |
133 | return true; | 142 | return true; |
134 | default: | 143 | default: |
135 | return false; | 144 | return false; |
@@ -139,12 +148,12 @@ static bool fsl_ssi_volatile_reg(struct device *dev, unsigned int reg) | |||
139 | static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg) | 148 | static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg) |
140 | { | 149 | { |
141 | switch (reg) { | 150 | switch (reg) { |
142 | case CCSR_SSI_SRX0: | 151 | case REG_SSI_SRX0: |
143 | case CCSR_SSI_SRX1: | 152 | case REG_SSI_SRX1: |
144 | case CCSR_SSI_SISR: | 153 | case REG_SSI_SISR: |
145 | case CCSR_SSI_SACADD: | 154 | case REG_SSI_SACADD: |
146 | case CCSR_SSI_SACDAT: | 155 | case REG_SSI_SACDAT: |
147 | case CCSR_SSI_SATAG: | 156 | case REG_SSI_SATAG: |
148 | return true; | 157 | return true; |
149 | default: | 158 | default: |
150 | return false; | 159 | return false; |
@@ -154,9 +163,9 @@ static bool fsl_ssi_precious_reg(struct device *dev, unsigned int reg) | |||
154 | static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) | 163 | static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) |
155 | { | 164 | { |
156 | switch (reg) { | 165 | switch (reg) { |
157 | case CCSR_SSI_SRX0: | 166 | case REG_SSI_SRX0: |
158 | case CCSR_SSI_SRX1: | 167 | case REG_SSI_SRX1: |
159 | case CCSR_SSI_SACCST: | 168 | case REG_SSI_SACCST: |
160 | return false; | 169 | return false; |
161 | default: | 170 | default: |
162 | return true; | 171 | return true; |
@@ -164,12 +173,12 @@ static bool fsl_ssi_writeable_reg(struct device *dev, unsigned int reg) | |||
164 | } | 173 | } |
165 | 174 | ||
166 | static const struct regmap_config fsl_ssi_regconfig = { | 175 | static const struct regmap_config fsl_ssi_regconfig = { |
167 | .max_register = CCSR_SSI_SACCDIS, | 176 | .max_register = REG_SSI_SACCDIS, |
168 | .reg_bits = 32, | 177 | .reg_bits = 32, |
169 | .val_bits = 32, | 178 | .val_bits = 32, |
170 | .reg_stride = 4, | 179 | .reg_stride = 4, |
171 | .val_format_endian = REGMAP_ENDIAN_NATIVE, | 180 | .val_format_endian = REGMAP_ENDIAN_NATIVE, |
172 | .num_reg_defaults_raw = CCSR_SSI_SACCDIS / sizeof(uint32_t) + 1, | 181 | .num_reg_defaults_raw = REG_SSI_SACCDIS / sizeof(uint32_t) + 1, |
173 | .readable_reg = fsl_ssi_readable_reg, | 182 | .readable_reg = fsl_ssi_readable_reg, |
174 | .volatile_reg = fsl_ssi_volatile_reg, | 183 | .volatile_reg = fsl_ssi_volatile_reg, |
175 | .precious_reg = fsl_ssi_precious_reg, | 184 | .precious_reg = fsl_ssi_precious_reg, |
@@ -185,78 +194,79 @@ struct fsl_ssi_soc_data { | |||
185 | }; | 194 | }; |
186 | 195 | ||
187 | /** | 196 | /** |
188 | * fsl_ssi_private: per-SSI private data | 197 | * fsl_ssi: per-SSI private data |
189 | * | 198 | * |
190 | * @reg: Pointer to the regmap registers | 199 | * @regs: Pointer to the regmap registers |
191 | * @irq: IRQ of this SSI | 200 | * @irq: IRQ of this SSI |
192 | * @cpu_dai_drv: CPU DAI driver for this device | 201 | * @cpu_dai_drv: CPU DAI driver for this device |
193 | * | 202 | * |
194 | * @dai_fmt: DAI configuration this device is currently used with | 203 | * @dai_fmt: DAI configuration this device is currently used with |
195 | * @i2s_mode: i2s and network mode configuration of the device. Is used to | 204 | * @i2s_net: I2S and Network mode configurations of SCR register |
196 | * switch between normal and i2s/network mode | ||
197 | * mode depending on the number of channels | ||
198 | * @use_dma: DMA is used or FIQ with stream filter | 205 | * @use_dma: DMA is used or FIQ with stream filter |
199 | * @use_dual_fifo: DMA with support for both FIFOs used | 206 | * @use_dual_fifo: DMA with support for dual FIFO mode |
200 | * @fifo_deph: Depth of the SSI FIFOs | 207 | * @has_ipg_clk_name: If "ipg" is in the clock name list of device tree |
201 | * @slot_width: width of each DAI slot | 208 | * @fifo_depth: Depth of the SSI FIFOs |
202 | * @slots: number of slots | 209 | * @slot_width: Width of each DAI slot |
203 | * @rxtx_reg_val: Specific register settings for receive/transmit configuration | 210 | * @slots: Number of slots |
211 | * @regvals: Specific RX/TX register settings | ||
204 | * | 212 | * |
205 | * @clk: SSI clock | 213 | * @clk: Clock source to access register |
206 | * @baudclk: SSI baud clock for master mode | 214 | * @baudclk: Clock source to generate bit and frame-sync clocks |
207 | * @baudclk_streams: Active streams that are using baudclk | 215 | * @baudclk_streams: Active streams that are using baudclk |
208 | * | 216 | * |
217 | * @regcache_sfcsr: Cache sfcsr register value during suspend and resume | ||
218 | * @regcache_sacnt: Cache sacnt register value during suspend and resume | ||
219 | * | ||
209 | * @dma_params_tx: DMA transmit parameters | 220 | * @dma_params_tx: DMA transmit parameters |
210 | * @dma_params_rx: DMA receive parameters | 221 | * @dma_params_rx: DMA receive parameters |
211 | * @ssi_phys: physical address of the SSI registers | 222 | * @ssi_phys: physical address of the SSI registers |
212 | * | 223 | * |
213 | * @fiq_params: FIQ stream filtering parameters | 224 | * @fiq_params: FIQ stream filtering parameters |
214 | * | 225 | * |
215 | * @pdev: Pointer to pdev used for deprecated fsl-ssi sound card | 226 | * @pdev: Pointer to pdev when using fsl-ssi as sound card (ppc only) |
227 | * TODO: Should be replaced with simple-sound-card | ||
216 | * | 228 | * |
217 | * @dbg_stats: Debugging statistics | 229 | * @dbg_stats: Debugging statistics |
218 | * | 230 | * |
219 | * @soc: SoC specific data | 231 | * @soc: SoC specific data |
232 | * @dev: Pointer to &pdev->dev | ||
220 | * | 233 | * |
221 | * @fifo_watermark: the FIFO watermark setting. Notifies DMA when | 234 | * @fifo_watermark: The FIFO watermark setting. Notifies DMA when there are |
222 | * there are @fifo_watermark or fewer words in TX fifo or | 235 | * @fifo_watermark or fewer words in TX fifo or |
223 | * @fifo_watermark or more empty words in RX fifo. | 236 | * @fifo_watermark or more empty words in RX fifo. |
224 | * @dma_maxburst: max number of words to transfer in one go. So far, | 237 | * @dma_maxburst: Max number of words to transfer in one go. So far, |
225 | * this is always the same as fifo_watermark. | 238 | * this is always the same as fifo_watermark. |
239 | * | ||
240 | * @ac97_reg_lock: Mutex lock to serialize AC97 register access operations | ||
226 | */ | 241 | */ |
227 | struct fsl_ssi_private { | 242 | struct fsl_ssi { |
228 | struct regmap *regs; | 243 | struct regmap *regs; |
229 | int irq; | 244 | int irq; |
230 | struct snd_soc_dai_driver cpu_dai_drv; | 245 | struct snd_soc_dai_driver cpu_dai_drv; |
231 | 246 | ||
232 | unsigned int dai_fmt; | 247 | unsigned int dai_fmt; |
233 | u8 i2s_mode; | 248 | u8 i2s_net; |
234 | bool use_dma; | 249 | bool use_dma; |
235 | bool use_dual_fifo; | 250 | bool use_dual_fifo; |
236 | bool has_ipg_clk_name; | 251 | bool has_ipg_clk_name; |
237 | unsigned int fifo_depth; | 252 | unsigned int fifo_depth; |
238 | unsigned int slot_width; | 253 | unsigned int slot_width; |
239 | unsigned int slots; | 254 | unsigned int slots; |
240 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; | 255 | struct fsl_ssi_regvals regvals[2]; |
241 | 256 | ||
242 | struct clk *clk; | 257 | struct clk *clk; |
243 | struct clk *baudclk; | 258 | struct clk *baudclk; |
244 | unsigned int baudclk_streams; | 259 | unsigned int baudclk_streams; |
245 | 260 | ||
246 | /* regcache for volatile regs */ | ||
247 | u32 regcache_sfcsr; | 261 | u32 regcache_sfcsr; |
248 | u32 regcache_sacnt; | 262 | u32 regcache_sacnt; |
249 | 263 | ||
250 | /* DMA params */ | ||
251 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 264 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
252 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 265 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
253 | dma_addr_t ssi_phys; | 266 | dma_addr_t ssi_phys; |
254 | 267 | ||
255 | /* params for non-dma FIQ stream filtered mode */ | ||
256 | struct imx_pcm_fiq_params fiq_params; | 268 | struct imx_pcm_fiq_params fiq_params; |
257 | 269 | ||
258 | /* Used when using fsl-ssi as sound-card. This is only used by ppc and | ||
259 | * should be replaced with simple-sound-card. */ | ||
260 | struct platform_device *pdev; | 270 | struct platform_device *pdev; |
261 | 271 | ||
262 | struct fsl_ssi_dbg dbg_stats; | 272 | struct fsl_ssi_dbg dbg_stats; |
@@ -271,27 +281,27 @@ struct fsl_ssi_private { | |||
271 | }; | 281 | }; |
272 | 282 | ||
273 | /* | 283 | /* |
274 | * imx51 and later SoCs have a slightly different IP that allows the | 284 | * SoC specific data |
275 | * SSI configuration while the SSI unit is running. | ||
276 | * | ||
277 | * More important, it is necessary on those SoCs to configure the | ||
278 | * sperate TX/RX DMA bits just before starting the stream | ||
279 | * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi | ||
280 | * sends any DMA requests to the SDMA unit, otherwise it is not defined | ||
281 | * how the SDMA unit handles the DMA request. | ||
282 | * | 285 | * |
283 | * SDMA units are present on devices starting at imx35 but the imx35 | 286 | * Notes: |
284 | * reference manual states that the DMA bits should not be changed | 287 | * 1) SSI in earlier SoCS has critical bits in control registers that |
285 | * while the SSI unit is running (SSIEN). So we support the necessary | 288 | * cannot be changed after SSI starts running -- a software reset |
286 | * online configuration of fsl-ssi starting at imx51. | 289 | * (set SSIEN to 0) is required to change their values. So adding |
290 | * an offline_config flag for these SoCs. | ||
291 | * 2) SDMA is available since imx35. However, imx35 does not support | ||
292 | * DMA bits changing when SSI is running, so set offline_config. | ||
293 | * 3) imx51 and later versions support register configurations when | ||
294 | * SSI is running (SSIEN); For these versions, DMA needs to be | ||
295 | * configured before SSI sends DMA request to avoid an undefined | ||
296 | * DMA request on the SDMA side. | ||
287 | */ | 297 | */ |
288 | 298 | ||
289 | static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = { | 299 | static struct fsl_ssi_soc_data fsl_ssi_mpc8610 = { |
290 | .imx = false, | 300 | .imx = false, |
291 | .offline_config = true, | 301 | .offline_config = true, |
292 | .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | 302 | .sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC | |
293 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | 303 | SSI_SISR_ROE0 | SSI_SISR_ROE1 | |
294 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, | 304 | SSI_SISR_TUE0 | SSI_SISR_TUE1, |
295 | }; | 305 | }; |
296 | 306 | ||
297 | static struct fsl_ssi_soc_data fsl_ssi_imx21 = { | 307 | static struct fsl_ssi_soc_data fsl_ssi_imx21 = { |
@@ -304,16 +314,16 @@ static struct fsl_ssi_soc_data fsl_ssi_imx21 = { | |||
304 | static struct fsl_ssi_soc_data fsl_ssi_imx35 = { | 314 | static struct fsl_ssi_soc_data fsl_ssi_imx35 = { |
305 | .imx = true, | 315 | .imx = true, |
306 | .offline_config = true, | 316 | .offline_config = true, |
307 | .sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC | | 317 | .sisr_write_mask = SSI_SISR_RFRC | SSI_SISR_TFRC | |
308 | CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | 318 | SSI_SISR_ROE0 | SSI_SISR_ROE1 | |
309 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, | 319 | SSI_SISR_TUE0 | SSI_SISR_TUE1, |
310 | }; | 320 | }; |
311 | 321 | ||
312 | static struct fsl_ssi_soc_data fsl_ssi_imx51 = { | 322 | static struct fsl_ssi_soc_data fsl_ssi_imx51 = { |
313 | .imx = true, | 323 | .imx = true, |
314 | .offline_config = false, | 324 | .offline_config = false, |
315 | .sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 | | 325 | .sisr_write_mask = SSI_SISR_ROE0 | SSI_SISR_ROE1 | |
316 | CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1, | 326 | SSI_SISR_TUE0 | SSI_SISR_TUE1, |
317 | }; | 327 | }; |
318 | 328 | ||
319 | static const struct of_device_id fsl_ssi_ids[] = { | 329 | static const struct of_device_id fsl_ssi_ids[] = { |
@@ -325,108 +335,86 @@ static const struct of_device_id fsl_ssi_ids[] = { | |||
325 | }; | 335 | }; |
326 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | 336 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); |
327 | 337 | ||
328 | static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) | 338 | static bool fsl_ssi_is_ac97(struct fsl_ssi *ssi) |
329 | { | 339 | { |
330 | return (ssi_private->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == | 340 | return (ssi->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == |
331 | SND_SOC_DAIFMT_AC97; | 341 | SND_SOC_DAIFMT_AC97; |
332 | } | 342 | } |
333 | 343 | ||
334 | static bool fsl_ssi_is_i2s_master(struct fsl_ssi_private *ssi_private) | 344 | static bool fsl_ssi_is_i2s_master(struct fsl_ssi *ssi) |
335 | { | 345 | { |
336 | return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == | 346 | return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == |
337 | SND_SOC_DAIFMT_CBS_CFS; | 347 | SND_SOC_DAIFMT_CBS_CFS; |
338 | } | 348 | } |
339 | 349 | ||
340 | static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi_private *ssi_private) | 350 | static bool fsl_ssi_is_i2s_cbm_cfs(struct fsl_ssi *ssi) |
341 | { | 351 | { |
342 | return (ssi_private->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == | 352 | return (ssi->dai_fmt & SND_SOC_DAIFMT_MASTER_MASK) == |
343 | SND_SOC_DAIFMT_CBM_CFS; | 353 | SND_SOC_DAIFMT_CBM_CFS; |
344 | } | 354 | } |
355 | |||
345 | /** | 356 | /** |
346 | * fsl_ssi_isr: SSI interrupt handler | 357 | * Interrupt handler to gather states |
347 | * | ||
348 | * Although it's possible to use the interrupt handler to send and receive | ||
349 | * data to/from the SSI, we use the DMA instead. Programming is more | ||
350 | * complicated, but the performance is much better. | ||
351 | * | ||
352 | * This interrupt handler is used only to gather statistics. | ||
353 | * | ||
354 | * @irq: IRQ of the SSI device | ||
355 | * @dev_id: pointer to the ssi_private structure for this SSI device | ||
356 | */ | 358 | */ |
357 | static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | 359 | static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) |
358 | { | 360 | { |
359 | struct fsl_ssi_private *ssi_private = dev_id; | 361 | struct fsl_ssi *ssi = dev_id; |
360 | struct regmap *regs = ssi_private->regs; | 362 | struct regmap *regs = ssi->regs; |
361 | __be32 sisr; | 363 | __be32 sisr; |
362 | __be32 sisr2; | 364 | __be32 sisr2; |
363 | 365 | ||
364 | /* We got an interrupt, so read the status register to see what we | 366 | regmap_read(regs, REG_SSI_SISR, &sisr); |
365 | were interrupted for. We mask it with the Interrupt Enable register | ||
366 | so that we only check for events that we're interested in. | ||
367 | */ | ||
368 | regmap_read(regs, CCSR_SSI_SISR, &sisr); | ||
369 | 367 | ||
370 | sisr2 = sisr & ssi_private->soc->sisr_write_mask; | 368 | sisr2 = sisr & ssi->soc->sisr_write_mask; |
371 | /* Clear the bits that we set */ | 369 | /* Clear the bits that we set */ |
372 | if (sisr2) | 370 | if (sisr2) |
373 | regmap_write(regs, CCSR_SSI_SISR, sisr2); | 371 | regmap_write(regs, REG_SSI_SISR, sisr2); |
374 | 372 | ||
375 | fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr); | 373 | fsl_ssi_dbg_isr(&ssi->dbg_stats, sisr); |
376 | 374 | ||
377 | return IRQ_HANDLED; | 375 | return IRQ_HANDLED; |
378 | } | 376 | } |
379 | 377 | ||
380 | /* | 378 | /** |
381 | * Enable/Disable all rx/tx config flags at once. | 379 | * Enable or disable all rx/tx config flags at once |
382 | */ | 380 | */ |
383 | static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, | 381 | static void fsl_ssi_rxtx_config(struct fsl_ssi *ssi, bool enable) |
384 | bool enable) | ||
385 | { | 382 | { |
386 | struct regmap *regs = ssi_private->regs; | 383 | struct regmap *regs = ssi->regs; |
387 | struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val; | 384 | struct fsl_ssi_regvals *vals = ssi->regvals; |
388 | 385 | ||
389 | if (enable) { | 386 | if (enable) { |
390 | regmap_update_bits(regs, CCSR_SSI_SIER, | 387 | regmap_update_bits(regs, REG_SSI_SIER, |
391 | vals->rx.sier | vals->tx.sier, | 388 | vals[RX].sier | vals[TX].sier, |
392 | vals->rx.sier | vals->tx.sier); | 389 | vals[RX].sier | vals[TX].sier); |
393 | regmap_update_bits(regs, CCSR_SSI_SRCR, | 390 | regmap_update_bits(regs, REG_SSI_SRCR, |
394 | vals->rx.srcr | vals->tx.srcr, | 391 | vals[RX].srcr | vals[TX].srcr, |
395 | vals->rx.srcr | vals->tx.srcr); | 392 | vals[RX].srcr | vals[TX].srcr); |
396 | regmap_update_bits(regs, CCSR_SSI_STCR, | 393 | regmap_update_bits(regs, REG_SSI_STCR, |
397 | vals->rx.stcr | vals->tx.stcr, | 394 | vals[RX].stcr | vals[TX].stcr, |
398 | vals->rx.stcr | vals->tx.stcr); | 395 | vals[RX].stcr | vals[TX].stcr); |
399 | } else { | 396 | } else { |
400 | regmap_update_bits(regs, CCSR_SSI_SRCR, | 397 | regmap_update_bits(regs, REG_SSI_SRCR, |
401 | vals->rx.srcr | vals->tx.srcr, 0); | 398 | vals[RX].srcr | vals[TX].srcr, 0); |
402 | regmap_update_bits(regs, CCSR_SSI_STCR, | 399 | regmap_update_bits(regs, REG_SSI_STCR, |
403 | vals->rx.stcr | vals->tx.stcr, 0); | 400 | vals[RX].stcr | vals[TX].stcr, 0); |
404 | regmap_update_bits(regs, CCSR_SSI_SIER, | 401 | regmap_update_bits(regs, REG_SSI_SIER, |
405 | vals->rx.sier | vals->tx.sier, 0); | 402 | vals[RX].sier | vals[TX].sier, 0); |
406 | } | 403 | } |
407 | } | 404 | } |
408 | 405 | ||
409 | /* | 406 | /** |
410 | * Clear RX or TX FIFO to remove samples from the previous | 407 | * Clear remaining data in the FIFO to avoid dirty data or channel slipping |
411 | * stream session which may be still present in the FIFO and | ||
412 | * may introduce bad samples and/or channel slipping. | ||
413 | * | ||
414 | * Note: The SOR is not documented in recent IMX datasheet, but | ||
415 | * is described in IMX51 reference manual at section 56.3.3.15. | ||
416 | */ | 408 | */ |
417 | static void fsl_ssi_fifo_clear(struct fsl_ssi_private *ssi_private, | 409 | static void fsl_ssi_fifo_clear(struct fsl_ssi *ssi, bool is_rx) |
418 | bool is_rx) | ||
419 | { | 410 | { |
420 | if (is_rx) { | 411 | bool tx = !is_rx; |
421 | regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR, | 412 | |
422 | CCSR_SSI_SOR_RX_CLR, CCSR_SSI_SOR_RX_CLR); | 413 | regmap_update_bits(ssi->regs, REG_SSI_SOR, |
423 | } else { | 414 | SSI_SOR_xX_CLR(tx), SSI_SOR_xX_CLR(tx)); |
424 | regmap_update_bits(ssi_private->regs, CCSR_SSI_SOR, | ||
425 | CCSR_SSI_SOR_TX_CLR, CCSR_SSI_SOR_TX_CLR); | ||
426 | } | ||
427 | } | 415 | } |
428 | 416 | ||
429 | /* | 417 | /** |
430 | * Calculate the bits that have to be disabled for the current stream that is | 418 | * Calculate the bits that have to be disabled for the current stream that is |
431 | * getting disabled. This keeps the bits enabled that are necessary for the | 419 | * getting disabled. This keeps the bits enabled that are necessary for the |
432 | * second stream to work if 'stream_active' is true. | 420 | * second stream to work if 'stream_active' is true. |
@@ -446,261 +434,239 @@ static void fsl_ssi_fifo_clear(struct fsl_ssi_private *ssi_private, | |||
446 | ((vals_disable) & \ | 434 | ((vals_disable) & \ |
447 | ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active)))) | 435 | ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active)))) |
448 | 436 | ||
449 | /* | 437 | /** |
450 | * Enable/Disable a ssi configuration. You have to pass either | 438 | * Enable or disable SSI configuration. |
451 | * ssi_private->rxtx_reg_val.rx or tx as vals parameter. | ||
452 | */ | 439 | */ |
453 | static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | 440 | static void fsl_ssi_config(struct fsl_ssi *ssi, bool enable, |
454 | struct fsl_ssi_reg_val *vals) | 441 | struct fsl_ssi_regvals *vals) |
455 | { | 442 | { |
456 | struct regmap *regs = ssi_private->regs; | 443 | struct regmap *regs = ssi->regs; |
457 | struct fsl_ssi_reg_val *avals; | 444 | struct fsl_ssi_regvals *avals; |
458 | int nr_active_streams; | 445 | int nr_active_streams; |
459 | u32 scr_val; | 446 | u32 scr; |
460 | int keep_active; | 447 | int keep_active; |
461 | 448 | ||
462 | regmap_read(regs, CCSR_SSI_SCR, &scr_val); | 449 | regmap_read(regs, REG_SSI_SCR, &scr); |
463 | 450 | ||
464 | nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + | 451 | nr_active_streams = !!(scr & SSI_SCR_TE) + !!(scr & SSI_SCR_RE); |
465 | !!(scr_val & CCSR_SSI_SCR_RE); | ||
466 | 452 | ||
467 | if (nr_active_streams - 1 > 0) | 453 | if (nr_active_streams - 1 > 0) |
468 | keep_active = 1; | 454 | keep_active = 1; |
469 | else | 455 | else |
470 | keep_active = 0; | 456 | keep_active = 0; |
471 | 457 | ||
472 | /* Find the other direction values rx or tx which we do not want to | 458 | /* Get the opposite direction to keep its values untouched */ |
473 | * modify */ | 459 | if (&ssi->regvals[RX] == vals) |
474 | if (&ssi_private->rxtx_reg_val.rx == vals) | 460 | avals = &ssi->regvals[TX]; |
475 | avals = &ssi_private->rxtx_reg_val.tx; | ||
476 | else | 461 | else |
477 | avals = &ssi_private->rxtx_reg_val.rx; | 462 | avals = &ssi->regvals[RX]; |
478 | 463 | ||
479 | /* If vals should be disabled, start with disabling the unit */ | ||
480 | if (!enable) { | 464 | if (!enable) { |
465 | /* | ||
466 | * To keep the other stream safe, exclude shared bits between | ||
467 | * both streams, and get safe bits to disable current stream | ||
468 | */ | ||
481 | u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr, | 469 | u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr, |
482 | keep_active); | 470 | keep_active); |
483 | regmap_update_bits(regs, CCSR_SSI_SCR, scr, 0); | 471 | /* Safely disable SCR register for the stream */ |
472 | regmap_update_bits(regs, REG_SSI_SCR, scr, 0); | ||
484 | } | 473 | } |
485 | 474 | ||
486 | /* | 475 | /* |
487 | * We are running on a SoC which does not support online SSI | 476 | * For cases where online configuration is not supported, |
488 | * reconfiguration, so we have to enable all necessary flags at once | 477 | * 1) Enable all necessary bits of both streams when 1st stream starts |
489 | * even if we do not use them later (capture and playback configuration) | 478 | * even if the opposite stream will not start |
479 | * 2) Disable all remaining bits of both streams when last stream ends | ||
490 | */ | 480 | */ |
491 | if (ssi_private->soc->offline_config) { | 481 | if (ssi->soc->offline_config) { |
492 | if ((enable && !nr_active_streams) || | 482 | if ((enable && !nr_active_streams) || (!enable && !keep_active)) |
493 | (!enable && !keep_active)) | 483 | fsl_ssi_rxtx_config(ssi, enable); |
494 | fsl_ssi_rxtx_config(ssi_private, enable); | ||
495 | 484 | ||
496 | goto config_done; | 485 | goto config_done; |
497 | } | 486 | } |
498 | 487 | ||
499 | /* | 488 | /* Online configure single direction while SSI is running */ |
500 | * Configure single direction units while the SSI unit is running | ||
501 | * (online configuration) | ||
502 | */ | ||
503 | if (enable) { | 489 | if (enable) { |
504 | fsl_ssi_fifo_clear(ssi_private, vals->scr & CCSR_SSI_SCR_RE); | 490 | fsl_ssi_fifo_clear(ssi, vals->scr & SSI_SCR_RE); |
505 | 491 | ||
506 | regmap_update_bits(regs, CCSR_SSI_SRCR, vals->srcr, vals->srcr); | 492 | regmap_update_bits(regs, REG_SSI_SRCR, vals->srcr, vals->srcr); |
507 | regmap_update_bits(regs, CCSR_SSI_STCR, vals->stcr, vals->stcr); | 493 | regmap_update_bits(regs, REG_SSI_STCR, vals->stcr, vals->stcr); |
508 | regmap_update_bits(regs, CCSR_SSI_SIER, vals->sier, vals->sier); | 494 | regmap_update_bits(regs, REG_SSI_SIER, vals->sier, vals->sier); |
509 | } else { | 495 | } else { |
510 | u32 sier; | 496 | u32 sier; |
511 | u32 srcr; | 497 | u32 srcr; |
512 | u32 stcr; | 498 | u32 stcr; |
513 | 499 | ||
514 | /* | 500 | /* |
515 | * Disabling the necessary flags for one of rx/tx while the | 501 | * To keep the other stream safe, exclude shared bits between |
516 | * other stream is active is a little bit more difficult. We | 502 | * both streams, and get safe bits to disable current stream |
517 | * have to disable only those flags that differ between both | ||
518 | * streams (rx XOR tx) and that are set in the stream that is | ||
519 | * disabled now. Otherwise we could alter flags of the other | ||
520 | * stream | ||
521 | */ | 503 | */ |
522 | |||
523 | /* These assignments are simply vals without bits set in avals*/ | ||
524 | sier = fsl_ssi_disable_val(vals->sier, avals->sier, | 504 | sier = fsl_ssi_disable_val(vals->sier, avals->sier, |
525 | keep_active); | 505 | keep_active); |
526 | srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr, | 506 | srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr, |
527 | keep_active); | 507 | keep_active); |
528 | stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr, | 508 | stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr, |
529 | keep_active); | 509 | keep_active); |
530 | 510 | ||
531 | regmap_update_bits(regs, CCSR_SSI_SRCR, srcr, 0); | 511 | /* Safely disable other control registers for the stream */ |
532 | regmap_update_bits(regs, CCSR_SSI_STCR, stcr, 0); | 512 | regmap_update_bits(regs, REG_SSI_SRCR, srcr, 0); |
533 | regmap_update_bits(regs, CCSR_SSI_SIER, sier, 0); | 513 | regmap_update_bits(regs, REG_SSI_STCR, stcr, 0); |
514 | regmap_update_bits(regs, REG_SSI_SIER, sier, 0); | ||
534 | } | 515 | } |
535 | 516 | ||
536 | config_done: | 517 | config_done: |
537 | /* Enabling of subunits is done after configuration */ | 518 | /* Enabling of subunits is done after configuration */ |
538 | if (enable) { | 519 | if (enable) { |
539 | if (ssi_private->use_dma && (vals->scr & CCSR_SSI_SCR_TE)) { | 520 | /* |
540 | /* | 521 | * Start DMA before setting TE to avoid FIFO underrun |
541 | * Be sure the Tx FIFO is filled when TE is set. | 522 | * which may cause a channel slip or a channel swap |
542 | * Otherwise, there are some chances to start the | 523 | * |
543 | * playback with some void samples inserted first, | 524 | * TODO: FIQ cases might also need this upon testing |
544 | * generating a channel slip. | 525 | */ |
545 | * | 526 | if (ssi->use_dma && (vals->scr & SSI_SCR_TE)) { |
546 | * First, SSIEN must be set, to let the FIFO be filled. | ||
547 | * | ||
548 | * Notes: | ||
549 | * - Limit this fix to the DMA case until FIQ cases can | ||
550 | * be tested. | ||
551 | * - Limit the length of the busy loop to not lock the | ||
552 | * system too long, even if 1-2 loops are sufficient | ||
553 | * in general. | ||
554 | */ | ||
555 | int i; | 527 | int i; |
556 | int max_loop = 100; | 528 | int max_loop = 100; |
557 | regmap_update_bits(regs, CCSR_SSI_SCR, | 529 | |
558 | CCSR_SSI_SCR_SSIEN, CCSR_SSI_SCR_SSIEN); | 530 | /* Enable SSI first to send TX DMA request */ |
531 | regmap_update_bits(regs, REG_SSI_SCR, | ||
532 | SSI_SCR_SSIEN, SSI_SCR_SSIEN); | ||
533 | |||
534 | /* Busy wait until TX FIFO not empty -- DMA working */ | ||
559 | for (i = 0; i < max_loop; i++) { | 535 | for (i = 0; i < max_loop; i++) { |
560 | u32 sfcsr; | 536 | u32 sfcsr; |
561 | regmap_read(regs, CCSR_SSI_SFCSR, &sfcsr); | 537 | regmap_read(regs, REG_SSI_SFCSR, &sfcsr); |
562 | if (CCSR_SSI_SFCSR_TFCNT0(sfcsr)) | 538 | if (SSI_SFCSR_TFCNT0(sfcsr)) |
563 | break; | 539 | break; |
564 | } | 540 | } |
565 | if (i == max_loop) { | 541 | if (i == max_loop) { |
566 | dev_err(ssi_private->dev, | 542 | dev_err(ssi->dev, |
567 | "Timeout waiting TX FIFO filling\n"); | 543 | "Timeout waiting TX FIFO filling\n"); |
568 | } | 544 | } |
569 | } | 545 | } |
570 | regmap_update_bits(regs, CCSR_SSI_SCR, vals->scr, vals->scr); | 546 | /* Enable all remaining bits */ |
547 | regmap_update_bits(regs, REG_SSI_SCR, vals->scr, vals->scr); | ||
571 | } | 548 | } |
572 | } | 549 | } |
573 | 550 | ||
551 | static void fsl_ssi_rx_config(struct fsl_ssi *ssi, bool enable) | ||
552 | { | ||
553 | fsl_ssi_config(ssi, enable, &ssi->regvals[RX]); | ||
554 | } | ||
574 | 555 | ||
575 | static void fsl_ssi_rx_config(struct fsl_ssi_private *ssi_private, bool enable) | 556 | static void fsl_ssi_tx_ac97_saccst_setup(struct fsl_ssi *ssi) |
576 | { | 557 | { |
577 | fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.rx); | 558 | struct regmap *regs = ssi->regs; |
559 | |||
560 | /* no SACC{ST,EN,DIS} regs on imx21-class SSI */ | ||
561 | if (!ssi->soc->imx21regs) { | ||
562 | /* Disable all channel slots */ | ||
563 | regmap_write(regs, REG_SSI_SACCDIS, 0xff); | ||
564 | /* Enable slots 3 & 4 -- PCM Playback Left & Right channels */ | ||
565 | regmap_write(regs, REG_SSI_SACCEN, 0x300); | ||
566 | } | ||
578 | } | 567 | } |
579 | 568 | ||
580 | static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable) | 569 | static void fsl_ssi_tx_config(struct fsl_ssi *ssi, bool enable) |
581 | { | 570 | { |
582 | fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx); | 571 | /* |
572 | * SACCST might be modified via AC Link by a CODEC if it sends | ||
573 | * extra bits in their SLOTREQ requests, which'll accidentally | ||
574 | * send valid data to slots other than normal playback slots. | ||
575 | * | ||
576 | * To be safe, configure SACCST right before TX starts. | ||
577 | */ | ||
578 | if (enable && fsl_ssi_is_ac97(ssi)) | ||
579 | fsl_ssi_tx_ac97_saccst_setup(ssi); | ||
580 | |||
581 | fsl_ssi_config(ssi, enable, &ssi->regvals[TX]); | ||
583 | } | 582 | } |
584 | 583 | ||
585 | /* | 584 | /** |
586 | * Setup rx/tx register values used to enable/disable the streams. These will | 585 | * Cache critical bits of SIER, SRCR, STCR and SCR to later set them safely |
587 | * be used later in fsl_ssi_config to setup the streams without the need to | ||
588 | * check for all different SSI modes. | ||
589 | */ | 586 | */ |
590 | static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private) | 587 | static void fsl_ssi_setup_regvals(struct fsl_ssi *ssi) |
591 | { | 588 | { |
592 | struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val; | 589 | struct fsl_ssi_regvals *vals = ssi->regvals; |
593 | 590 | ||
594 | reg->rx.sier = CCSR_SSI_SIER_RFF0_EN; | 591 | vals[RX].sier = SSI_SIER_RFF0_EN; |
595 | reg->rx.srcr = CCSR_SSI_SRCR_RFEN0; | 592 | vals[RX].srcr = SSI_SRCR_RFEN0; |
596 | reg->rx.scr = 0; | 593 | vals[RX].scr = 0; |
597 | reg->tx.sier = CCSR_SSI_SIER_TFE0_EN; | 594 | vals[TX].sier = SSI_SIER_TFE0_EN; |
598 | reg->tx.stcr = CCSR_SSI_STCR_TFEN0; | 595 | vals[TX].stcr = SSI_STCR_TFEN0; |
599 | reg->tx.scr = 0; | 596 | vals[TX].scr = 0; |
600 | 597 | ||
601 | if (!fsl_ssi_is_ac97(ssi_private)) { | 598 | /* AC97 has already enabled SSIEN, RE and TE, so ignore them */ |
602 | reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE; | 599 | if (!fsl_ssi_is_ac97(ssi)) { |
603 | reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN; | 600 | vals[RX].scr = SSI_SCR_SSIEN | SSI_SCR_RE; |
604 | reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE; | 601 | vals[TX].scr = SSI_SCR_SSIEN | SSI_SCR_TE; |
605 | reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN; | ||
606 | } | 602 | } |
607 | 603 | ||
608 | if (ssi_private->use_dma) { | 604 | if (ssi->use_dma) { |
609 | reg->rx.sier |= CCSR_SSI_SIER_RDMAE; | 605 | vals[RX].sier |= SSI_SIER_RDMAE; |
610 | reg->tx.sier |= CCSR_SSI_SIER_TDMAE; | 606 | vals[TX].sier |= SSI_SIER_TDMAE; |
611 | } else { | 607 | } else { |
612 | reg->rx.sier |= CCSR_SSI_SIER_RIE; | 608 | vals[RX].sier |= SSI_SIER_RIE; |
613 | reg->tx.sier |= CCSR_SSI_SIER_TIE; | 609 | vals[TX].sier |= SSI_SIER_TIE; |
614 | } | 610 | } |
615 | 611 | ||
616 | reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS; | 612 | vals[RX].sier |= FSLSSI_SIER_DBG_RX_FLAGS; |
617 | reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS; | 613 | vals[TX].sier |= FSLSSI_SIER_DBG_TX_FLAGS; |
618 | } | 614 | } |
619 | 615 | ||
620 | static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) | 616 | static void fsl_ssi_setup_ac97(struct fsl_ssi *ssi) |
621 | { | 617 | { |
622 | struct regmap *regs = ssi_private->regs; | 618 | struct regmap *regs = ssi->regs; |
623 | |||
624 | /* | ||
625 | * Setup the clock control register | ||
626 | */ | ||
627 | regmap_write(regs, CCSR_SSI_STCCR, | ||
628 | CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13)); | ||
629 | regmap_write(regs, CCSR_SSI_SRCCR, | ||
630 | CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13)); | ||
631 | 619 | ||
632 | /* | 620 | /* Setup the clock control register */ |
633 | * Enable AC97 mode and startup the SSI | 621 | regmap_write(regs, REG_SSI_STCCR, SSI_SxCCR_WL(17) | SSI_SxCCR_DC(13)); |
634 | */ | 622 | regmap_write(regs, REG_SSI_SRCCR, SSI_SxCCR_WL(17) | SSI_SxCCR_DC(13)); |
635 | regmap_write(regs, CCSR_SSI_SACNT, | ||
636 | CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV); | ||
637 | 623 | ||
638 | /* no SACC{ST,EN,DIS} regs on imx21-class SSI */ | 624 | /* Enable AC97 mode and startup the SSI */ |
639 | if (!ssi_private->soc->imx21regs) { | 625 | regmap_write(regs, REG_SSI_SACNT, SSI_SACNT_AC97EN | SSI_SACNT_FV); |
640 | regmap_write(regs, CCSR_SSI_SACCDIS, 0xff); | ||
641 | regmap_write(regs, CCSR_SSI_SACCEN, 0x300); | ||
642 | } | ||
643 | 626 | ||
644 | /* | 627 | /* AC97 has to communicate with codec before starting a stream */ |
645 | * Enable SSI, Transmit and Receive. AC97 has to communicate with the | 628 | regmap_update_bits(regs, REG_SSI_SCR, |
646 | * codec before a stream is started. | 629 | SSI_SCR_SSIEN | SSI_SCR_TE | SSI_SCR_RE, |
647 | */ | 630 | SSI_SCR_SSIEN | SSI_SCR_TE | SSI_SCR_RE); |
648 | regmap_update_bits(regs, CCSR_SSI_SCR, | ||
649 | CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE, | ||
650 | CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE); | ||
651 | 631 | ||
652 | regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_WAIT(3)); | 632 | regmap_write(regs, REG_SSI_SOR, SSI_SOR_WAIT(3)); |
653 | } | 633 | } |
654 | 634 | ||
655 | /** | ||
656 | * fsl_ssi_startup: create a new substream | ||
657 | * | ||
658 | * This is the first function called when a stream is opened. | ||
659 | * | ||
660 | * If this is the first stream open, then grab the IRQ and program most of | ||
661 | * the SSI registers. | ||
662 | */ | ||
663 | static int fsl_ssi_startup(struct snd_pcm_substream *substream, | 635 | static int fsl_ssi_startup(struct snd_pcm_substream *substream, |
664 | struct snd_soc_dai *dai) | 636 | struct snd_soc_dai *dai) |
665 | { | 637 | { |
666 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 638 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
667 | struct fsl_ssi_private *ssi_private = | 639 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); |
668 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
669 | int ret; | 640 | int ret; |
670 | 641 | ||
671 | ret = clk_prepare_enable(ssi_private->clk); | 642 | ret = clk_prepare_enable(ssi->clk); |
672 | if (ret) | 643 | if (ret) |
673 | return ret; | 644 | return ret; |
674 | 645 | ||
675 | /* When using dual fifo mode, it is safer to ensure an even period | 646 | /* |
647 | * When using dual fifo mode, it is safer to ensure an even period | ||
676 | * size. If appearing to an odd number while DMA always starts its | 648 | * size. If appearing to an odd number while DMA always starts its |
677 | * task from fifo0, fifo1 would be neglected at the end of each | 649 | * task from fifo0, fifo1 would be neglected at the end of each |
678 | * period. But SSI would still access fifo1 with an invalid data. | 650 | * period. But SSI would still access fifo1 with an invalid data. |
679 | */ | 651 | */ |
680 | if (ssi_private->use_dual_fifo) | 652 | if (ssi->use_dual_fifo) |
681 | snd_pcm_hw_constraint_step(substream->runtime, 0, | 653 | snd_pcm_hw_constraint_step(substream->runtime, 0, |
682 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); | 654 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); |
683 | 655 | ||
684 | return 0; | 656 | return 0; |
685 | } | 657 | } |
686 | 658 | ||
687 | /** | ||
688 | * fsl_ssi_shutdown: shutdown the SSI | ||
689 | * | ||
690 | */ | ||
691 | static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, | 659 | static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, |
692 | struct snd_soc_dai *dai) | 660 | struct snd_soc_dai *dai) |
693 | { | 661 | { |
694 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 662 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
695 | struct fsl_ssi_private *ssi_private = | 663 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); |
696 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
697 | |||
698 | clk_disable_unprepare(ssi_private->clk); | ||
699 | 664 | ||
665 | clk_disable_unprepare(ssi->clk); | ||
700 | } | 666 | } |
701 | 667 | ||
702 | /** | 668 | /** |
703 | * fsl_ssi_set_bclk - configure Digital Audio Interface bit clock | 669 | * Configure Digital Audio Interface bit clock |
704 | * | 670 | * |
705 | * Note: This function can be only called when using SSI as DAI master | 671 | * Note: This function can be only called when using SSI as DAI master |
706 | * | 672 | * |
@@ -709,12 +675,13 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, | |||
709 | * (In 2-channel I2S Master mode, slot_width is fixed 32) | 675 | * (In 2-channel I2S Master mode, slot_width is fixed 32) |
710 | */ | 676 | */ |
711 | static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, | 677 | static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, |
712 | struct snd_soc_dai *cpu_dai, | 678 | struct snd_soc_dai *dai, |
713 | struct snd_pcm_hw_params *hw_params) | 679 | struct snd_pcm_hw_params *hw_params) |
714 | { | 680 | { |
715 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 681 | bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
716 | struct regmap *regs = ssi_private->regs; | 682 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); |
717 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; | 683 | struct regmap *regs = ssi->regs; |
684 | int synchronous = ssi->cpu_dai_drv.symmetric_rates, ret; | ||
718 | u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; | 685 | u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; |
719 | unsigned long clkrate, baudrate, tmprate; | 686 | unsigned long clkrate, baudrate, tmprate; |
720 | unsigned int slots = params_channels(hw_params); | 687 | unsigned int slots = params_channels(hw_params); |
@@ -724,29 +691,29 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, | |||
724 | bool baudclk_is_used; | 691 | bool baudclk_is_used; |
725 | 692 | ||
726 | /* Override slots and slot_width if being specifically set... */ | 693 | /* Override slots and slot_width if being specifically set... */ |
727 | if (ssi_private->slots) | 694 | if (ssi->slots) |
728 | slots = ssi_private->slots; | 695 | slots = ssi->slots; |
729 | /* ...but keep 32 bits if slots is 2 -- I2S Master mode */ | 696 | /* ...but keep 32 bits if slots is 2 -- I2S Master mode */ |
730 | if (ssi_private->slot_width && slots != 2) | 697 | if (ssi->slot_width && slots != 2) |
731 | slot_width = ssi_private->slot_width; | 698 | slot_width = ssi->slot_width; |
732 | 699 | ||
733 | /* Generate bit clock based on the slot number and slot width */ | 700 | /* Generate bit clock based on the slot number and slot width */ |
734 | freq = slots * slot_width * params_rate(hw_params); | 701 | freq = slots * slot_width * params_rate(hw_params); |
735 | 702 | ||
736 | /* Don't apply it to any non-baudclk circumstance */ | 703 | /* Don't apply it to any non-baudclk circumstance */ |
737 | if (IS_ERR(ssi_private->baudclk)) | 704 | if (IS_ERR(ssi->baudclk)) |
738 | return -EINVAL; | 705 | return -EINVAL; |
739 | 706 | ||
740 | /* | 707 | /* |
741 | * Hardware limitation: The bclk rate must be | 708 | * Hardware limitation: The bclk rate must be |
742 | * never greater than 1/5 IPG clock rate | 709 | * never greater than 1/5 IPG clock rate |
743 | */ | 710 | */ |
744 | if (freq * 5 > clk_get_rate(ssi_private->clk)) { | 711 | if (freq * 5 > clk_get_rate(ssi->clk)) { |
745 | dev_err(cpu_dai->dev, "bitclk > ipgclk/5\n"); | 712 | dev_err(dai->dev, "bitclk > ipgclk / 5\n"); |
746 | return -EINVAL; | 713 | return -EINVAL; |
747 | } | 714 | } |
748 | 715 | ||
749 | baudclk_is_used = ssi_private->baudclk_streams & ~(BIT(substream->stream)); | 716 | baudclk_is_used = ssi->baudclk_streams & ~(BIT(substream->stream)); |
750 | 717 | ||
751 | /* It should be already enough to divide clock by setting pm alone */ | 718 | /* It should be already enough to divide clock by setting pm alone */ |
752 | psr = 0; | 719 | psr = 0; |
@@ -758,9 +725,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, | |||
758 | tmprate = freq * factor * (i + 1); | 725 | tmprate = freq * factor * (i + 1); |
759 | 726 | ||
760 | if (baudclk_is_used) | 727 | if (baudclk_is_used) |
761 | clkrate = clk_get_rate(ssi_private->baudclk); | 728 | clkrate = clk_get_rate(ssi->baudclk); |
762 | else | 729 | else |
763 | clkrate = clk_round_rate(ssi_private->baudclk, tmprate); | 730 | clkrate = clk_round_rate(ssi->baudclk, tmprate); |
764 | 731 | ||
765 | clkrate /= factor; | 732 | clkrate /= factor; |
766 | afreq = clkrate / (i + 1); | 733 | afreq = clkrate / (i + 1); |
@@ -791,24 +758,22 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, | |||
791 | 758 | ||
792 | /* No proper pm found if it is still remaining the initial value */ | 759 | /* No proper pm found if it is still remaining the initial value */ |
793 | if (pm == 999) { | 760 | if (pm == 999) { |
794 | dev_err(cpu_dai->dev, "failed to handle the required sysclk\n"); | 761 | dev_err(dai->dev, "failed to handle the required sysclk\n"); |
795 | return -EINVAL; | 762 | return -EINVAL; |
796 | } | 763 | } |
797 | 764 | ||
798 | stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) | | 765 | stccr = SSI_SxCCR_PM(pm + 1) | (div2 ? SSI_SxCCR_DIV2 : 0) | |
799 | (psr ? CCSR_SSI_SxCCR_PSR : 0); | 766 | (psr ? SSI_SxCCR_PSR : 0); |
800 | mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | | 767 | mask = SSI_SxCCR_PM_MASK | SSI_SxCCR_DIV2 | SSI_SxCCR_PSR; |
801 | CCSR_SSI_SxCCR_PSR; | ||
802 | 768 | ||
803 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || synchronous) | 769 | /* STCCR is used for RX in synchronous mode */ |
804 | regmap_update_bits(regs, CCSR_SSI_STCCR, mask, stccr); | 770 | tx2 = tx || synchronous; |
805 | else | 771 | regmap_update_bits(regs, REG_SSI_SxCCR(tx2), mask, stccr); |
806 | regmap_update_bits(regs, CCSR_SSI_SRCCR, mask, stccr); | ||
807 | 772 | ||
808 | if (!baudclk_is_used) { | 773 | if (!baudclk_is_used) { |
809 | ret = clk_set_rate(ssi_private->baudclk, baudrate); | 774 | ret = clk_set_rate(ssi->baudclk, baudrate); |
810 | if (ret) { | 775 | if (ret) { |
811 | dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); | 776 | dev_err(dai->dev, "failed to set baudclk rate\n"); |
812 | return -EINVAL; | 777 | return -EINVAL; |
813 | } | 778 | } |
814 | } | 779 | } |
@@ -817,185 +782,165 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream *substream, | |||
817 | } | 782 | } |
818 | 783 | ||
819 | /** | 784 | /** |
820 | * fsl_ssi_hw_params - program the sample size | 785 | * Configure SSI based on PCM hardware parameters |
821 | * | ||
822 | * Most of the SSI registers have been programmed in the startup function, | ||
823 | * but the word length must be programmed here. Unfortunately, programming | ||
824 | * the SxCCR.WL bits requires the SSI to be temporarily disabled. This can | ||
825 | * cause a problem with supporting simultaneous playback and capture. If | ||
826 | * the SSI is already playing a stream, then that stream may be temporarily | ||
827 | * stopped when you start capture. | ||
828 | * | 786 | * |
829 | * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the | 787 | * Notes: |
830 | * clock master. | 788 | * 1) SxCCR.WL bits are critical bits that require SSI to be temporarily |
789 | * disabled on offline_config SoCs. Even for online configurable SoCs | ||
790 | * running in synchronous mode (both TX and RX use STCCR), it is not | ||
791 | * safe to re-configure them when both two streams start running. | ||
792 | * 2) SxCCR.PM, SxCCR.DIV2 and SxCCR.PSR bits will be configured in the | ||
793 | * fsl_ssi_set_bclk() if SSI is the DAI clock master. | ||
831 | */ | 794 | */ |
832 | static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | 795 | static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, |
833 | struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) | 796 | struct snd_pcm_hw_params *hw_params, |
797 | struct snd_soc_dai *dai) | ||
834 | { | 798 | { |
835 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 799 | bool tx2, tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
836 | struct regmap *regs = ssi_private->regs; | 800 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); |
801 | struct regmap *regs = ssi->regs; | ||
837 | unsigned int channels = params_channels(hw_params); | 802 | unsigned int channels = params_channels(hw_params); |
838 | unsigned int sample_size = params_width(hw_params); | 803 | unsigned int sample_size = params_width(hw_params); |
839 | u32 wl = CCSR_SSI_SxCCR_WL(sample_size); | 804 | u32 wl = SSI_SxCCR_WL(sample_size); |
840 | int ret; | 805 | int ret; |
841 | u32 scr_val; | 806 | u32 scr; |
842 | int enabled; | 807 | int enabled; |
843 | 808 | ||
844 | regmap_read(regs, CCSR_SSI_SCR, &scr_val); | 809 | regmap_read(regs, REG_SSI_SCR, &scr); |
845 | enabled = scr_val & CCSR_SSI_SCR_SSIEN; | 810 | enabled = scr & SSI_SCR_SSIEN; |
846 | 811 | ||
847 | /* | 812 | /* |
848 | * If we're in synchronous mode, and the SSI is already enabled, | 813 | * SSI is properly configured if it is enabled and running in |
849 | * then STCCR is already set properly. | 814 | * the synchronous mode; Note that AC97 mode is an exception |
815 | * that should set separate configurations for STCCR and SRCCR | ||
816 | * despite running in the synchronous mode. | ||
850 | */ | 817 | */ |
851 | if (enabled && ssi_private->cpu_dai_drv.symmetric_rates) | 818 | if (enabled && ssi->cpu_dai_drv.symmetric_rates) |
852 | return 0; | 819 | return 0; |
853 | 820 | ||
854 | if (fsl_ssi_is_i2s_master(ssi_private)) { | 821 | if (fsl_ssi_is_i2s_master(ssi)) { |
855 | ret = fsl_ssi_set_bclk(substream, cpu_dai, hw_params); | 822 | ret = fsl_ssi_set_bclk(substream, dai, hw_params); |
856 | if (ret) | 823 | if (ret) |
857 | return ret; | 824 | return ret; |
858 | 825 | ||
859 | /* Do not enable the clock if it is already enabled */ | 826 | /* Do not enable the clock if it is already enabled */ |
860 | if (!(ssi_private->baudclk_streams & BIT(substream->stream))) { | 827 | if (!(ssi->baudclk_streams & BIT(substream->stream))) { |
861 | ret = clk_prepare_enable(ssi_private->baudclk); | 828 | ret = clk_prepare_enable(ssi->baudclk); |
862 | if (ret) | 829 | if (ret) |
863 | return ret; | 830 | return ret; |
864 | 831 | ||
865 | ssi_private->baudclk_streams |= BIT(substream->stream); | 832 | ssi->baudclk_streams |= BIT(substream->stream); |
866 | } | 833 | } |
867 | } | 834 | } |
868 | 835 | ||
869 | if (!fsl_ssi_is_ac97(ssi_private)) { | 836 | if (!fsl_ssi_is_ac97(ssi)) { |
870 | u8 i2smode; | 837 | u8 i2s_net; |
871 | /* | 838 | /* Normal + Network mode to send 16-bit data in 32-bit frames */ |
872 | * Switch to normal net mode in order to have a frame sync | 839 | if (fsl_ssi_is_i2s_cbm_cfs(ssi) && sample_size == 16) |
873 | * signal every 32 bits instead of 16 bits | 840 | i2s_net = SSI_SCR_I2S_MODE_NORMAL | SSI_SCR_NET; |
874 | */ | ||
875 | if (fsl_ssi_is_i2s_cbm_cfs(ssi_private) && sample_size == 16) | ||
876 | i2smode = CCSR_SSI_SCR_I2S_MODE_NORMAL | | ||
877 | CCSR_SSI_SCR_NET; | ||
878 | else | 841 | else |
879 | i2smode = ssi_private->i2s_mode; | 842 | i2s_net = ssi->i2s_net; |
880 | 843 | ||
881 | regmap_update_bits(regs, CCSR_SSI_SCR, | 844 | regmap_update_bits(regs, REG_SSI_SCR, |
882 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, | 845 | SSI_SCR_I2S_NET_MASK, |
883 | channels == 1 ? 0 : i2smode); | 846 | channels == 1 ? 0 : i2s_net); |
884 | } | 847 | } |
885 | 848 | ||
886 | /* | ||
887 | * FIXME: The documentation says that SxCCR[WL] should not be | ||
888 | * modified while the SSI is enabled. The only time this can | ||
889 | * happen is if we're trying to do simultaneous playback and | ||
890 | * capture in asynchronous mode. Unfortunately, I have been enable | ||
891 | * to get that to work at all on the P1022DS. Therefore, we don't | ||
892 | * bother to disable/enable the SSI when setting SxCCR[WL], because | ||
893 | * the SSI will stop anyway. Maybe one day, this will get fixed. | ||
894 | */ | ||
895 | |||
896 | /* In synchronous mode, the SSI uses STCCR for capture */ | 849 | /* In synchronous mode, the SSI uses STCCR for capture */ |
897 | if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || | 850 | tx2 = tx || ssi->cpu_dai_drv.symmetric_rates; |
898 | ssi_private->cpu_dai_drv.symmetric_rates) | 851 | regmap_update_bits(regs, REG_SSI_SxCCR(tx2), SSI_SxCCR_WL_MASK, wl); |
899 | regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_WL_MASK, | ||
900 | wl); | ||
901 | else | ||
902 | regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_WL_MASK, | ||
903 | wl); | ||
904 | 852 | ||
905 | return 0; | 853 | return 0; |
906 | } | 854 | } |
907 | 855 | ||
908 | static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, | 856 | static int fsl_ssi_hw_free(struct snd_pcm_substream *substream, |
909 | struct snd_soc_dai *cpu_dai) | 857 | struct snd_soc_dai *dai) |
910 | { | 858 | { |
911 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 859 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
912 | struct fsl_ssi_private *ssi_private = | 860 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); |
913 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
914 | 861 | ||
915 | if (fsl_ssi_is_i2s_master(ssi_private) && | 862 | if (fsl_ssi_is_i2s_master(ssi) && |
916 | ssi_private->baudclk_streams & BIT(substream->stream)) { | 863 | ssi->baudclk_streams & BIT(substream->stream)) { |
917 | clk_disable_unprepare(ssi_private->baudclk); | 864 | clk_disable_unprepare(ssi->baudclk); |
918 | ssi_private->baudclk_streams &= ~BIT(substream->stream); | 865 | ssi->baudclk_streams &= ~BIT(substream->stream); |
919 | } | 866 | } |
920 | 867 | ||
921 | return 0; | 868 | return 0; |
922 | } | 869 | } |
923 | 870 | ||
924 | static int _fsl_ssi_set_dai_fmt(struct device *dev, | 871 | static int _fsl_ssi_set_dai_fmt(struct device *dev, |
925 | struct fsl_ssi_private *ssi_private, | 872 | struct fsl_ssi *ssi, unsigned int fmt) |
926 | unsigned int fmt) | ||
927 | { | 873 | { |
928 | struct regmap *regs = ssi_private->regs; | 874 | struct regmap *regs = ssi->regs; |
929 | u32 strcr = 0, stcr, srcr, scr, mask; | 875 | u32 strcr = 0, stcr, srcr, scr, mask; |
930 | u8 wm; | 876 | u8 wm; |
931 | 877 | ||
932 | ssi_private->dai_fmt = fmt; | 878 | ssi->dai_fmt = fmt; |
933 | 879 | ||
934 | if (fsl_ssi_is_i2s_master(ssi_private) && IS_ERR(ssi_private->baudclk)) { | 880 | if (fsl_ssi_is_i2s_master(ssi) && IS_ERR(ssi->baudclk)) { |
935 | dev_err(dev, "baudclk is missing which is necessary for master mode\n"); | 881 | dev_err(dev, "missing baudclk for master mode\n"); |
936 | return -EINVAL; | 882 | return -EINVAL; |
937 | } | 883 | } |
938 | 884 | ||
939 | fsl_ssi_setup_reg_vals(ssi_private); | 885 | fsl_ssi_setup_regvals(ssi); |
940 | 886 | ||
941 | regmap_read(regs, CCSR_SSI_SCR, &scr); | 887 | regmap_read(regs, REG_SSI_SCR, &scr); |
942 | scr &= ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); | 888 | scr &= ~(SSI_SCR_SYN | SSI_SCR_I2S_MODE_MASK); |
943 | scr |= CCSR_SSI_SCR_SYNC_TX_FS; | 889 | /* Synchronize frame sync clock for TE to avoid data slipping */ |
890 | scr |= SSI_SCR_SYNC_TX_FS; | ||
944 | 891 | ||
945 | mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | | 892 | mask = SSI_STCR_TXBIT0 | SSI_STCR_TFDIR | SSI_STCR_TXDIR | |
946 | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | | 893 | SSI_STCR_TSCKP | SSI_STCR_TFSI | SSI_STCR_TFSL | SSI_STCR_TEFS; |
947 | CCSR_SSI_STCR_TEFS; | 894 | regmap_read(regs, REG_SSI_STCR, &stcr); |
948 | regmap_read(regs, CCSR_SSI_STCR, &stcr); | 895 | regmap_read(regs, REG_SSI_SRCR, &srcr); |
949 | regmap_read(regs, CCSR_SSI_SRCR, &srcr); | ||
950 | stcr &= ~mask; | 896 | stcr &= ~mask; |
951 | srcr &= ~mask; | 897 | srcr &= ~mask; |
952 | 898 | ||
953 | ssi_private->i2s_mode = CCSR_SSI_SCR_NET; | 899 | /* Use Network mode as default */ |
900 | ssi->i2s_net = SSI_SCR_NET; | ||
954 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 901 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
955 | case SND_SOC_DAIFMT_I2S: | 902 | case SND_SOC_DAIFMT_I2S: |
956 | regmap_update_bits(regs, CCSR_SSI_STCCR, | 903 | regmap_update_bits(regs, REG_SSI_STCCR, |
957 | CCSR_SSI_SxCCR_DC_MASK, | 904 | SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); |
958 | CCSR_SSI_SxCCR_DC(2)); | 905 | regmap_update_bits(regs, REG_SSI_SRCCR, |
959 | regmap_update_bits(regs, CCSR_SSI_SRCCR, | 906 | SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(2)); |
960 | CCSR_SSI_SxCCR_DC_MASK, | ||
961 | CCSR_SSI_SxCCR_DC(2)); | ||
962 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 907 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
963 | case SND_SOC_DAIFMT_CBM_CFS: | 908 | case SND_SOC_DAIFMT_CBM_CFS: |
964 | case SND_SOC_DAIFMT_CBS_CFS: | 909 | case SND_SOC_DAIFMT_CBS_CFS: |
965 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; | 910 | ssi->i2s_net |= SSI_SCR_I2S_MODE_MASTER; |
966 | break; | 911 | break; |
967 | case SND_SOC_DAIFMT_CBM_CFM: | 912 | case SND_SOC_DAIFMT_CBM_CFM: |
968 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; | 913 | ssi->i2s_net |= SSI_SCR_I2S_MODE_SLAVE; |
969 | break; | 914 | break; |
970 | default: | 915 | default: |
971 | return -EINVAL; | 916 | return -EINVAL; |
972 | } | 917 | } |
973 | 918 | ||
974 | /* Data on rising edge of bclk, frame low, 1clk before data */ | 919 | /* Data on rising edge of bclk, frame low, 1clk before data */ |
975 | strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | | 920 | strcr |= SSI_STCR_TFSI | SSI_STCR_TSCKP | |
976 | CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS; | 921 | SSI_STCR_TXBIT0 | SSI_STCR_TEFS; |
977 | break; | 922 | break; |
978 | case SND_SOC_DAIFMT_LEFT_J: | 923 | case SND_SOC_DAIFMT_LEFT_J: |
979 | /* Data on rising edge of bclk, frame high */ | 924 | /* Data on rising edge of bclk, frame high */ |
980 | strcr |= CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TSCKP; | 925 | strcr |= SSI_STCR_TXBIT0 | SSI_STCR_TSCKP; |
981 | break; | 926 | break; |
982 | case SND_SOC_DAIFMT_DSP_A: | 927 | case SND_SOC_DAIFMT_DSP_A: |
983 | /* Data on rising edge of bclk, frame high, 1clk before data */ | 928 | /* Data on rising edge of bclk, frame high, 1clk before data */ |
984 | strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | | 929 | strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | |
985 | CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS; | 930 | SSI_STCR_TXBIT0 | SSI_STCR_TEFS; |
986 | break; | 931 | break; |
987 | case SND_SOC_DAIFMT_DSP_B: | 932 | case SND_SOC_DAIFMT_DSP_B: |
988 | /* Data on rising edge of bclk, frame high */ | 933 | /* Data on rising edge of bclk, frame high */ |
989 | strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | | 934 | strcr |= SSI_STCR_TFSL | SSI_STCR_TSCKP | SSI_STCR_TXBIT0; |
990 | CCSR_SSI_STCR_TXBIT0; | ||
991 | break; | 935 | break; |
992 | case SND_SOC_DAIFMT_AC97: | 936 | case SND_SOC_DAIFMT_AC97: |
993 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL; | 937 | /* Data on falling edge of bclk, frame high, 1clk before data */ |
938 | ssi->i2s_net |= SSI_SCR_I2S_MODE_NORMAL; | ||
994 | break; | 939 | break; |
995 | default: | 940 | default: |
996 | return -EINVAL; | 941 | return -EINVAL; |
997 | } | 942 | } |
998 | scr |= ssi_private->i2s_mode; | 943 | scr |= ssi->i2s_net; |
999 | 944 | ||
1000 | /* DAI clock inversion */ | 945 | /* DAI clock inversion */ |
1001 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 946 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -1004,16 +949,16 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, | |||
1004 | break; | 949 | break; |
1005 | case SND_SOC_DAIFMT_IB_NF: | 950 | case SND_SOC_DAIFMT_IB_NF: |
1006 | /* Invert bit clock */ | 951 | /* Invert bit clock */ |
1007 | strcr ^= CCSR_SSI_STCR_TSCKP; | 952 | strcr ^= SSI_STCR_TSCKP; |
1008 | break; | 953 | break; |
1009 | case SND_SOC_DAIFMT_NB_IF: | 954 | case SND_SOC_DAIFMT_NB_IF: |
1010 | /* Invert frame clock */ | 955 | /* Invert frame clock */ |
1011 | strcr ^= CCSR_SSI_STCR_TFSI; | 956 | strcr ^= SSI_STCR_TFSI; |
1012 | break; | 957 | break; |
1013 | case SND_SOC_DAIFMT_IB_IF: | 958 | case SND_SOC_DAIFMT_IB_IF: |
1014 | /* Invert both clocks */ | 959 | /* Invert both clocks */ |
1015 | strcr ^= CCSR_SSI_STCR_TSCKP; | 960 | strcr ^= SSI_STCR_TSCKP; |
1016 | strcr ^= CCSR_SSI_STCR_TFSI; | 961 | strcr ^= SSI_STCR_TFSI; |
1017 | break; | 962 | break; |
1018 | default: | 963 | default: |
1019 | return -EINVAL; | 964 | return -EINVAL; |
@@ -1022,123 +967,122 @@ static int _fsl_ssi_set_dai_fmt(struct device *dev, | |||
1022 | /* DAI clock master masks */ | 967 | /* DAI clock master masks */ |
1023 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 968 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
1024 | case SND_SOC_DAIFMT_CBS_CFS: | 969 | case SND_SOC_DAIFMT_CBS_CFS: |
1025 | strcr |= CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR; | 970 | /* Output bit and frame sync clocks */ |
1026 | scr |= CCSR_SSI_SCR_SYS_CLK_EN; | 971 | strcr |= SSI_STCR_TFDIR | SSI_STCR_TXDIR; |
972 | scr |= SSI_SCR_SYS_CLK_EN; | ||
1027 | break; | 973 | break; |
1028 | case SND_SOC_DAIFMT_CBM_CFM: | 974 | case SND_SOC_DAIFMT_CBM_CFM: |
1029 | scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; | 975 | /* Input bit or frame sync clocks */ |
976 | scr &= ~SSI_SCR_SYS_CLK_EN; | ||
1030 | break; | 977 | break; |
1031 | case SND_SOC_DAIFMT_CBM_CFS: | 978 | case SND_SOC_DAIFMT_CBM_CFS: |
1032 | strcr &= ~CCSR_SSI_STCR_TXDIR; | 979 | /* Input bit clock but output frame sync clock */ |
1033 | strcr |= CCSR_SSI_STCR_TFDIR; | 980 | strcr &= ~SSI_STCR_TXDIR; |
1034 | scr &= ~CCSR_SSI_SCR_SYS_CLK_EN; | 981 | strcr |= SSI_STCR_TFDIR; |
982 | scr &= ~SSI_SCR_SYS_CLK_EN; | ||
1035 | break; | 983 | break; |
1036 | default: | 984 | default: |
1037 | if (!fsl_ssi_is_ac97(ssi_private)) | 985 | if (!fsl_ssi_is_ac97(ssi)) |
1038 | return -EINVAL; | 986 | return -EINVAL; |
1039 | } | 987 | } |
1040 | 988 | ||
1041 | stcr |= strcr; | 989 | stcr |= strcr; |
1042 | srcr |= strcr; | 990 | srcr |= strcr; |
1043 | 991 | ||
1044 | if (ssi_private->cpu_dai_drv.symmetric_rates | 992 | /* Set SYN mode and clear RXDIR bit when using SYN or AC97 mode */ |
1045 | || fsl_ssi_is_ac97(ssi_private)) { | 993 | if (ssi->cpu_dai_drv.symmetric_rates || fsl_ssi_is_ac97(ssi)) { |
1046 | /* Need to clear RXDIR when using SYNC or AC97 mode */ | 994 | srcr &= ~SSI_SRCR_RXDIR; |
1047 | srcr &= ~CCSR_SSI_SRCR_RXDIR; | 995 | scr |= SSI_SCR_SYN; |
1048 | scr |= CCSR_SSI_SCR_SYN; | ||
1049 | } | 996 | } |
1050 | 997 | ||
1051 | regmap_write(regs, CCSR_SSI_STCR, stcr); | 998 | regmap_write(regs, REG_SSI_STCR, stcr); |
1052 | regmap_write(regs, CCSR_SSI_SRCR, srcr); | 999 | regmap_write(regs, REG_SSI_SRCR, srcr); |
1053 | regmap_write(regs, CCSR_SSI_SCR, scr); | 1000 | regmap_write(regs, REG_SSI_SCR, scr); |
1054 | 1001 | ||
1055 | wm = ssi_private->fifo_watermark; | 1002 | wm = ssi->fifo_watermark; |
1056 | 1003 | ||
1057 | regmap_write(regs, CCSR_SSI_SFCSR, | 1004 | regmap_write(regs, REG_SSI_SFCSR, |
1058 | CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | | 1005 | SSI_SFCSR_TFWM0(wm) | SSI_SFCSR_RFWM0(wm) | |
1059 | CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm)); | 1006 | SSI_SFCSR_TFWM1(wm) | SSI_SFCSR_RFWM1(wm)); |
1060 | 1007 | ||
1061 | if (ssi_private->use_dual_fifo) { | 1008 | if (ssi->use_dual_fifo) { |
1062 | regmap_update_bits(regs, CCSR_SSI_SRCR, CCSR_SSI_SRCR_RFEN1, | 1009 | regmap_update_bits(regs, REG_SSI_SRCR, |
1063 | CCSR_SSI_SRCR_RFEN1); | 1010 | SSI_SRCR_RFEN1, SSI_SRCR_RFEN1); |
1064 | regmap_update_bits(regs, CCSR_SSI_STCR, CCSR_SSI_STCR_TFEN1, | 1011 | regmap_update_bits(regs, REG_SSI_STCR, |
1065 | CCSR_SSI_STCR_TFEN1); | 1012 | SSI_STCR_TFEN1, SSI_STCR_TFEN1); |
1066 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_TCH_EN, | 1013 | regmap_update_bits(regs, REG_SSI_SCR, |
1067 | CCSR_SSI_SCR_TCH_EN); | 1014 | SSI_SCR_TCH_EN, SSI_SCR_TCH_EN); |
1068 | } | 1015 | } |
1069 | 1016 | ||
1070 | if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97) | 1017 | if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_AC97) |
1071 | fsl_ssi_setup_ac97(ssi_private); | 1018 | fsl_ssi_setup_ac97(ssi); |
1072 | 1019 | ||
1073 | return 0; | 1020 | return 0; |
1074 | |||
1075 | } | 1021 | } |
1076 | 1022 | ||
1077 | /** | 1023 | /** |
1078 | * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format. | 1024 | * Configure Digital Audio Interface (DAI) Format |
1079 | */ | 1025 | */ |
1080 | static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | 1026 | static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
1081 | { | 1027 | { |
1082 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 1028 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); |
1083 | 1029 | ||
1084 | return _fsl_ssi_set_dai_fmt(cpu_dai->dev, ssi_private, fmt); | 1030 | /* AC97 configured DAIFMT earlier in the probe() */ |
1031 | if (fsl_ssi_is_ac97(ssi)) | ||
1032 | return 0; | ||
1033 | |||
1034 | return _fsl_ssi_set_dai_fmt(dai->dev, ssi, fmt); | ||
1085 | } | 1035 | } |
1086 | 1036 | ||
1087 | /** | 1037 | /** |
1088 | * fsl_ssi_set_dai_tdm_slot - set TDM slot number | 1038 | * Set TDM slot number and slot width |
1089 | * | ||
1090 | * Note: This function can be only called when using SSI as DAI master | ||
1091 | */ | 1039 | */ |
1092 | static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, | 1040 | static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, |
1093 | u32 rx_mask, int slots, int slot_width) | 1041 | u32 rx_mask, int slots, int slot_width) |
1094 | { | 1042 | { |
1095 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 1043 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); |
1096 | struct regmap *regs = ssi_private->regs; | 1044 | struct regmap *regs = ssi->regs; |
1097 | u32 val; | 1045 | u32 val; |
1098 | 1046 | ||
1099 | /* The word length should be 8, 10, 12, 16, 18, 20, 22 or 24 */ | 1047 | /* The word length should be 8, 10, 12, 16, 18, 20, 22 or 24 */ |
1100 | if (slot_width & 1 || slot_width < 8 || slot_width > 24) { | 1048 | if (slot_width & 1 || slot_width < 8 || slot_width > 24) { |
1101 | dev_err(cpu_dai->dev, "invalid slot width: %d\n", slot_width); | 1049 | dev_err(dai->dev, "invalid slot width: %d\n", slot_width); |
1102 | return -EINVAL; | 1050 | return -EINVAL; |
1103 | } | 1051 | } |
1104 | 1052 | ||
1105 | /* The slot number should be >= 2 if using Network mode or I2S mode */ | 1053 | /* The slot number should be >= 2 if using Network mode or I2S mode */ |
1106 | regmap_read(regs, CCSR_SSI_SCR, &val); | 1054 | regmap_read(regs, REG_SSI_SCR, &val); |
1107 | val &= CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET; | 1055 | val &= SSI_SCR_I2S_MODE_MASK | SSI_SCR_NET; |
1108 | if (val && slots < 2) { | 1056 | if (val && slots < 2) { |
1109 | dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n"); | 1057 | dev_err(dai->dev, "slot number should be >= 2 in I2S or NET\n"); |
1110 | return -EINVAL; | 1058 | return -EINVAL; |
1111 | } | 1059 | } |
1112 | 1060 | ||
1113 | regmap_update_bits(regs, CCSR_SSI_STCCR, CCSR_SSI_SxCCR_DC_MASK, | 1061 | regmap_update_bits(regs, REG_SSI_STCCR, |
1114 | CCSR_SSI_SxCCR_DC(slots)); | 1062 | SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); |
1115 | regmap_update_bits(regs, CCSR_SSI_SRCCR, CCSR_SSI_SxCCR_DC_MASK, | 1063 | regmap_update_bits(regs, REG_SSI_SRCCR, |
1116 | CCSR_SSI_SxCCR_DC(slots)); | 1064 | SSI_SxCCR_DC_MASK, SSI_SxCCR_DC(slots)); |
1117 | 1065 | ||
1118 | /* The register SxMSKs needs SSI to provide essential clock due to | 1066 | /* Save SSIEN bit of the SCR register */ |
1119 | * hardware design. So we here temporarily enable SSI to set them. | 1067 | regmap_read(regs, REG_SSI_SCR, &val); |
1120 | */ | 1068 | val &= SSI_SCR_SSIEN; |
1121 | regmap_read(regs, CCSR_SSI_SCR, &val); | 1069 | /* Temporarily enable SSI to allow SxMSKs to be configurable */ |
1122 | val &= CCSR_SSI_SCR_SSIEN; | 1070 | regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, SSI_SCR_SSIEN); |
1123 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, | ||
1124 | CCSR_SSI_SCR_SSIEN); | ||
1125 | 1071 | ||
1126 | regmap_write(regs, CCSR_SSI_STMSK, ~tx_mask); | 1072 | regmap_write(regs, REG_SSI_STMSK, ~tx_mask); |
1127 | regmap_write(regs, CCSR_SSI_SRMSK, ~rx_mask); | 1073 | regmap_write(regs, REG_SSI_SRMSK, ~rx_mask); |
1128 | 1074 | ||
1129 | regmap_update_bits(regs, CCSR_SSI_SCR, CCSR_SSI_SCR_SSIEN, val); | 1075 | /* Restore the value of SSIEN bit */ |
1076 | regmap_update_bits(regs, REG_SSI_SCR, SSI_SCR_SSIEN, val); | ||
1130 | 1077 | ||
1131 | ssi_private->slot_width = slot_width; | 1078 | ssi->slot_width = slot_width; |
1132 | ssi_private->slots = slots; | 1079 | ssi->slots = slots; |
1133 | 1080 | ||
1134 | return 0; | 1081 | return 0; |
1135 | } | 1082 | } |
1136 | 1083 | ||
1137 | /** | 1084 | /** |
1138 | * fsl_ssi_trigger: start and stop the DMA transfer. | 1085 | * Start or stop SSI and corresponding DMA transaction. |
1139 | * | ||
1140 | * This function is called by ALSA to start, stop, pause, and resume the DMA | ||
1141 | * transfer of data. | ||
1142 | * | 1086 | * |
1143 | * The DMA channel is in external master start and pause mode, which | 1087 | * The DMA channel is in external master start and pause mode, which |
1144 | * means the SSI completely controls the flow of data. | 1088 | * means the SSI completely controls the flow of data. |
@@ -1147,37 +1091,38 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1147 | struct snd_soc_dai *dai) | 1091 | struct snd_soc_dai *dai) |
1148 | { | 1092 | { |
1149 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1093 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1150 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); | 1094 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(rtd->cpu_dai); |
1151 | struct regmap *regs = ssi_private->regs; | 1095 | struct regmap *regs = ssi->regs; |
1152 | 1096 | ||
1153 | switch (cmd) { | 1097 | switch (cmd) { |
1154 | case SNDRV_PCM_TRIGGER_START: | 1098 | case SNDRV_PCM_TRIGGER_START: |
1155 | case SNDRV_PCM_TRIGGER_RESUME: | 1099 | case SNDRV_PCM_TRIGGER_RESUME: |
1156 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 1100 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
1157 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1101 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1158 | fsl_ssi_tx_config(ssi_private, true); | 1102 | fsl_ssi_tx_config(ssi, true); |
1159 | else | 1103 | else |
1160 | fsl_ssi_rx_config(ssi_private, true); | 1104 | fsl_ssi_rx_config(ssi, true); |
1161 | break; | 1105 | break; |
1162 | 1106 | ||
1163 | case SNDRV_PCM_TRIGGER_STOP: | 1107 | case SNDRV_PCM_TRIGGER_STOP: |
1164 | case SNDRV_PCM_TRIGGER_SUSPEND: | 1108 | case SNDRV_PCM_TRIGGER_SUSPEND: |
1165 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 1109 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
1166 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1110 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1167 | fsl_ssi_tx_config(ssi_private, false); | 1111 | fsl_ssi_tx_config(ssi, false); |
1168 | else | 1112 | else |
1169 | fsl_ssi_rx_config(ssi_private, false); | 1113 | fsl_ssi_rx_config(ssi, false); |
1170 | break; | 1114 | break; |
1171 | 1115 | ||
1172 | default: | 1116 | default: |
1173 | return -EINVAL; | 1117 | return -EINVAL; |
1174 | } | 1118 | } |
1175 | 1119 | ||
1176 | if (fsl_ssi_is_ac97(ssi_private)) { | 1120 | /* Clear corresponding FIFO */ |
1121 | if (fsl_ssi_is_ac97(ssi)) { | ||
1177 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 1122 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1178 | regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_TX_CLR); | 1123 | regmap_write(regs, REG_SSI_SOR, SSI_SOR_TX_CLR); |
1179 | else | 1124 | else |
1180 | regmap_write(regs, CCSR_SSI_SOR, CCSR_SSI_SOR_RX_CLR); | 1125 | regmap_write(regs, REG_SSI_SOR, SSI_SOR_RX_CLR); |
1181 | } | 1126 | } |
1182 | 1127 | ||
1183 | return 0; | 1128 | return 0; |
@@ -1185,27 +1130,26 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1185 | 1130 | ||
1186 | static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) | 1131 | static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) |
1187 | { | 1132 | { |
1188 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); | 1133 | struct fsl_ssi *ssi = snd_soc_dai_get_drvdata(dai); |
1189 | 1134 | ||
1190 | if (ssi_private->soc->imx && ssi_private->use_dma) { | 1135 | if (ssi->soc->imx && ssi->use_dma) { |
1191 | dai->playback_dma_data = &ssi_private->dma_params_tx; | 1136 | dai->playback_dma_data = &ssi->dma_params_tx; |
1192 | dai->capture_dma_data = &ssi_private->dma_params_rx; | 1137 | dai->capture_dma_data = &ssi->dma_params_rx; |
1193 | } | 1138 | } |
1194 | 1139 | ||
1195 | return 0; | 1140 | return 0; |
1196 | } | 1141 | } |
1197 | 1142 | ||
1198 | static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { | 1143 | static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { |
1199 | .startup = fsl_ssi_startup, | 1144 | .startup = fsl_ssi_startup, |
1200 | .shutdown = fsl_ssi_shutdown, | 1145 | .shutdown = fsl_ssi_shutdown, |
1201 | .hw_params = fsl_ssi_hw_params, | 1146 | .hw_params = fsl_ssi_hw_params, |
1202 | .hw_free = fsl_ssi_hw_free, | 1147 | .hw_free = fsl_ssi_hw_free, |
1203 | .set_fmt = fsl_ssi_set_dai_fmt, | 1148 | .set_fmt = fsl_ssi_set_dai_fmt, |
1204 | .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, | 1149 | .set_tdm_slot = fsl_ssi_set_dai_tdm_slot, |
1205 | .trigger = fsl_ssi_trigger, | 1150 | .trigger = fsl_ssi_trigger, |
1206 | }; | 1151 | }; |
1207 | 1152 | ||
1208 | /* Template for the CPU dai driver structure */ | ||
1209 | static struct snd_soc_dai_driver fsl_ssi_dai_template = { | 1153 | static struct snd_soc_dai_driver fsl_ssi_dai_template = { |
1210 | .probe = fsl_ssi_dai_probe, | 1154 | .probe = fsl_ssi_dai_probe, |
1211 | .playback = { | 1155 | .playback = { |
@@ -1226,7 +1170,7 @@ static struct snd_soc_dai_driver fsl_ssi_dai_template = { | |||
1226 | }; | 1170 | }; |
1227 | 1171 | ||
1228 | static const struct snd_soc_component_driver fsl_ssi_component = { | 1172 | static const struct snd_soc_component_driver fsl_ssi_component = { |
1229 | .name = "fsl-ssi", | 1173 | .name = "fsl-ssi", |
1230 | }; | 1174 | }; |
1231 | 1175 | ||
1232 | static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { | 1176 | static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { |
@@ -1237,23 +1181,23 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { | |||
1237 | .channels_min = 2, | 1181 | .channels_min = 2, |
1238 | .channels_max = 2, | 1182 | .channels_max = 2, |
1239 | .rates = SNDRV_PCM_RATE_8000_48000, | 1183 | .rates = SNDRV_PCM_RATE_8000_48000, |
1240 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1184 | .formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S20, |
1241 | }, | 1185 | }, |
1242 | .capture = { | 1186 | .capture = { |
1243 | .stream_name = "AC97 Capture", | 1187 | .stream_name = "AC97 Capture", |
1244 | .channels_min = 2, | 1188 | .channels_min = 2, |
1245 | .channels_max = 2, | 1189 | .channels_max = 2, |
1246 | .rates = SNDRV_PCM_RATE_48000, | 1190 | .rates = SNDRV_PCM_RATE_48000, |
1247 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 1191 | /* 16-bit capture is broken (errata ERR003778) */ |
1192 | .formats = SNDRV_PCM_FMTBIT_S20, | ||
1248 | }, | 1193 | }, |
1249 | .ops = &fsl_ssi_dai_ops, | 1194 | .ops = &fsl_ssi_dai_ops, |
1250 | }; | 1195 | }; |
1251 | 1196 | ||
1252 | 1197 | static struct fsl_ssi *fsl_ac97_data; | |
1253 | static struct fsl_ssi_private *fsl_ac97_data; | ||
1254 | 1198 | ||
1255 | static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | 1199 | static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, |
1256 | unsigned short val) | 1200 | unsigned short val) |
1257 | { | 1201 | { |
1258 | struct regmap *regs = fsl_ac97_data->regs; | 1202 | struct regmap *regs = fsl_ac97_data->regs; |
1259 | unsigned int lreg; | 1203 | unsigned int lreg; |
@@ -1273,13 +1217,13 @@ static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
1273 | } | 1217 | } |
1274 | 1218 | ||
1275 | lreg = reg << 12; | 1219 | lreg = reg << 12; |
1276 | regmap_write(regs, CCSR_SSI_SACADD, lreg); | 1220 | regmap_write(regs, REG_SSI_SACADD, lreg); |
1277 | 1221 | ||
1278 | lval = val << 4; | 1222 | lval = val << 4; |
1279 | regmap_write(regs, CCSR_SSI_SACDAT, lval); | 1223 | regmap_write(regs, REG_SSI_SACDAT, lval); |
1280 | 1224 | ||
1281 | regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK, | 1225 | regmap_update_bits(regs, REG_SSI_SACNT, |
1282 | CCSR_SSI_SACNT_WR); | 1226 | SSI_SACNT_RDWR_MASK, SSI_SACNT_WR); |
1283 | udelay(100); | 1227 | udelay(100); |
1284 | 1228 | ||
1285 | clk_disable_unprepare(fsl_ac97_data->clk); | 1229 | clk_disable_unprepare(fsl_ac97_data->clk); |
@@ -1289,10 +1233,9 @@ ret_unlock: | |||
1289 | } | 1233 | } |
1290 | 1234 | ||
1291 | static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, | 1235 | static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, |
1292 | unsigned short reg) | 1236 | unsigned short reg) |
1293 | { | 1237 | { |
1294 | struct regmap *regs = fsl_ac97_data->regs; | 1238 | struct regmap *regs = fsl_ac97_data->regs; |
1295 | |||
1296 | unsigned short val = 0; | 1239 | unsigned short val = 0; |
1297 | u32 reg_val; | 1240 | u32 reg_val; |
1298 | unsigned int lreg; | 1241 | unsigned int lreg; |
@@ -1302,19 +1245,18 @@ static unsigned short fsl_ssi_ac97_read(struct snd_ac97 *ac97, | |||
1302 | 1245 | ||
1303 | ret = clk_prepare_enable(fsl_ac97_data->clk); | 1246 | ret = clk_prepare_enable(fsl_ac97_data->clk); |
1304 | if (ret) { | 1247 | if (ret) { |
1305 | pr_err("ac97 read clk_prepare_enable failed: %d\n", | 1248 | pr_err("ac97 read clk_prepare_enable failed: %d\n", ret); |
1306 | ret); | ||
1307 | goto ret_unlock; | 1249 | goto ret_unlock; |
1308 | } | 1250 | } |
1309 | 1251 | ||
1310 | lreg = (reg & 0x7f) << 12; | 1252 | lreg = (reg & 0x7f) << 12; |
1311 | regmap_write(regs, CCSR_SSI_SACADD, lreg); | 1253 | regmap_write(regs, REG_SSI_SACADD, lreg); |
1312 | regmap_update_bits(regs, CCSR_SSI_SACNT, CCSR_SSI_SACNT_RDWR_MASK, | 1254 | regmap_update_bits(regs, REG_SSI_SACNT, |
1313 | CCSR_SSI_SACNT_RD); | 1255 | SSI_SACNT_RDWR_MASK, SSI_SACNT_RD); |
1314 | 1256 | ||
1315 | udelay(100); | 1257 | udelay(100); |
1316 | 1258 | ||
1317 | regmap_read(regs, CCSR_SSI_SACDAT, ®_val); | 1259 | regmap_read(regs, REG_SSI_SACDAT, ®_val); |
1318 | val = (reg_val >> 4) & 0xffff; | 1260 | val = (reg_val >> 4) & 0xffff; |
1319 | 1261 | ||
1320 | clk_disable_unprepare(fsl_ac97_data->clk); | 1262 | clk_disable_unprepare(fsl_ac97_data->clk); |
@@ -1325,8 +1267,8 @@ ret_unlock: | |||
1325 | } | 1267 | } |
1326 | 1268 | ||
1327 | static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = { | 1269 | static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = { |
1328 | .read = fsl_ssi_ac97_read, | 1270 | .read = fsl_ssi_ac97_read, |
1329 | .write = fsl_ssi_ac97_write, | 1271 | .write = fsl_ssi_ac97_write, |
1330 | }; | 1272 | }; |
1331 | 1273 | ||
1332 | /** | 1274 | /** |
@@ -1341,70 +1283,67 @@ static void make_lowercase(char *s) | |||
1341 | } | 1283 | } |
1342 | 1284 | ||
1343 | static int fsl_ssi_imx_probe(struct platform_device *pdev, | 1285 | static int fsl_ssi_imx_probe(struct platform_device *pdev, |
1344 | struct fsl_ssi_private *ssi_private, void __iomem *iomem) | 1286 | struct fsl_ssi *ssi, void __iomem *iomem) |
1345 | { | 1287 | { |
1346 | struct device_node *np = pdev->dev.of_node; | 1288 | struct device_node *np = pdev->dev.of_node; |
1289 | struct device *dev = &pdev->dev; | ||
1347 | u32 dmas[4]; | 1290 | u32 dmas[4]; |
1348 | int ret; | 1291 | int ret; |
1349 | 1292 | ||
1350 | if (ssi_private->has_ipg_clk_name) | 1293 | /* Backward compatible for a DT without ipg clock name assigned */ |
1351 | ssi_private->clk = devm_clk_get(&pdev->dev, "ipg"); | 1294 | if (ssi->has_ipg_clk_name) |
1295 | ssi->clk = devm_clk_get(dev, "ipg"); | ||
1352 | else | 1296 | else |
1353 | ssi_private->clk = devm_clk_get(&pdev->dev, NULL); | 1297 | ssi->clk = devm_clk_get(dev, NULL); |
1354 | if (IS_ERR(ssi_private->clk)) { | 1298 | if (IS_ERR(ssi->clk)) { |
1355 | ret = PTR_ERR(ssi_private->clk); | 1299 | ret = PTR_ERR(ssi->clk); |
1356 | dev_err(&pdev->dev, "could not get clock: %d\n", ret); | 1300 | dev_err(dev, "failed to get clock: %d\n", ret); |
1357 | return ret; | 1301 | return ret; |
1358 | } | 1302 | } |
1359 | 1303 | ||
1360 | if (!ssi_private->has_ipg_clk_name) { | 1304 | /* Enable the clock since regmap will not handle it in this case */ |
1361 | ret = clk_prepare_enable(ssi_private->clk); | 1305 | if (!ssi->has_ipg_clk_name) { |
1306 | ret = clk_prepare_enable(ssi->clk); | ||
1362 | if (ret) { | 1307 | if (ret) { |
1363 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); | 1308 | dev_err(dev, "clk_prepare_enable failed: %d\n", ret); |
1364 | return ret; | 1309 | return ret; |
1365 | } | 1310 | } |
1366 | } | 1311 | } |
1367 | 1312 | ||
1368 | /* For those SLAVE implementations, we ignore non-baudclk cases | 1313 | /* Do not error out for slave cases that live without a baud clock */ |
1369 | * and, instead, abandon MASTER mode that needs baud clock. | 1314 | ssi->baudclk = devm_clk_get(dev, "baud"); |
1370 | */ | 1315 | if (IS_ERR(ssi->baudclk)) |
1371 | ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); | 1316 | dev_dbg(dev, "failed to get baud clock: %ld\n", |
1372 | if (IS_ERR(ssi_private->baudclk)) | 1317 | PTR_ERR(ssi->baudclk)); |
1373 | dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", | ||
1374 | PTR_ERR(ssi_private->baudclk)); | ||
1375 | 1318 | ||
1376 | ssi_private->dma_params_tx.maxburst = ssi_private->dma_maxburst; | 1319 | ssi->dma_params_tx.maxburst = ssi->dma_maxburst; |
1377 | ssi_private->dma_params_rx.maxburst = ssi_private->dma_maxburst; | 1320 | ssi->dma_params_rx.maxburst = ssi->dma_maxburst; |
1378 | ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + CCSR_SSI_STX0; | 1321 | ssi->dma_params_tx.addr = ssi->ssi_phys + REG_SSI_STX0; |
1379 | ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + CCSR_SSI_SRX0; | 1322 | ssi->dma_params_rx.addr = ssi->ssi_phys + REG_SSI_SRX0; |
1380 | 1323 | ||
1324 | /* Set to dual FIFO mode according to the SDMA sciprt */ | ||
1381 | ret = of_property_read_u32_array(np, "dmas", dmas, 4); | 1325 | ret = of_property_read_u32_array(np, "dmas", dmas, 4); |
1382 | if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { | 1326 | if (ssi->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { |
1383 | ssi_private->use_dual_fifo = true; | 1327 | ssi->use_dual_fifo = true; |
1384 | /* When using dual fifo mode, we need to keep watermark | 1328 | /* |
1385 | * as even numbers due to dma script limitation. | 1329 | * Use even numbers to avoid channel swap due to SDMA |
1330 | * script design | ||
1386 | */ | 1331 | */ |
1387 | ssi_private->dma_params_tx.maxburst &= ~0x1; | 1332 | ssi->dma_params_tx.maxburst &= ~0x1; |
1388 | ssi_private->dma_params_rx.maxburst &= ~0x1; | 1333 | ssi->dma_params_rx.maxburst &= ~0x1; |
1389 | } | 1334 | } |
1390 | 1335 | ||
1391 | if (!ssi_private->use_dma) { | 1336 | if (!ssi->use_dma) { |
1392 | |||
1393 | /* | 1337 | /* |
1394 | * Some boards use an incompatible codec. To get it | 1338 | * Some boards use an incompatible codec. Use imx-fiq-pcm-audio |
1395 | * working, we are using imx-fiq-pcm-audio, that | 1339 | * to get it working, as DMA is not possible in this situation. |
1396 | * can handle those codecs. DMA is not possible in this | ||
1397 | * situation. | ||
1398 | */ | 1340 | */ |
1341 | ssi->fiq_params.irq = ssi->irq; | ||
1342 | ssi->fiq_params.base = iomem; | ||
1343 | ssi->fiq_params.dma_params_rx = &ssi->dma_params_rx; | ||
1344 | ssi->fiq_params.dma_params_tx = &ssi->dma_params_tx; | ||
1399 | 1345 | ||
1400 | ssi_private->fiq_params.irq = ssi_private->irq; | 1346 | ret = imx_pcm_fiq_init(pdev, &ssi->fiq_params); |
1401 | ssi_private->fiq_params.base = iomem; | ||
1402 | ssi_private->fiq_params.dma_params_rx = | ||
1403 | &ssi_private->dma_params_rx; | ||
1404 | ssi_private->fiq_params.dma_params_tx = | ||
1405 | &ssi_private->dma_params_tx; | ||
1406 | |||
1407 | ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); | ||
1408 | if (ret) | 1347 | if (ret) |
1409 | goto error_pcm; | 1348 | goto error_pcm; |
1410 | } else { | 1349 | } else { |
@@ -1416,26 +1355,26 @@ static int fsl_ssi_imx_probe(struct platform_device *pdev, | |||
1416 | return 0; | 1355 | return 0; |
1417 | 1356 | ||
1418 | error_pcm: | 1357 | error_pcm: |
1358 | if (!ssi->has_ipg_clk_name) | ||
1359 | clk_disable_unprepare(ssi->clk); | ||
1419 | 1360 | ||
1420 | if (!ssi_private->has_ipg_clk_name) | ||
1421 | clk_disable_unprepare(ssi_private->clk); | ||
1422 | return ret; | 1361 | return ret; |
1423 | } | 1362 | } |
1424 | 1363 | ||
1425 | static void fsl_ssi_imx_clean(struct platform_device *pdev, | 1364 | static void fsl_ssi_imx_clean(struct platform_device *pdev, struct fsl_ssi *ssi) |
1426 | struct fsl_ssi_private *ssi_private) | ||
1427 | { | 1365 | { |
1428 | if (!ssi_private->use_dma) | 1366 | if (!ssi->use_dma) |
1429 | imx_pcm_fiq_exit(pdev); | 1367 | imx_pcm_fiq_exit(pdev); |
1430 | if (!ssi_private->has_ipg_clk_name) | 1368 | if (!ssi->has_ipg_clk_name) |
1431 | clk_disable_unprepare(ssi_private->clk); | 1369 | clk_disable_unprepare(ssi->clk); |
1432 | } | 1370 | } |
1433 | 1371 | ||
1434 | static int fsl_ssi_probe(struct platform_device *pdev) | 1372 | static int fsl_ssi_probe(struct platform_device *pdev) |
1435 | { | 1373 | { |
1436 | struct fsl_ssi_private *ssi_private; | 1374 | struct fsl_ssi *ssi; |
1437 | int ret = 0; | 1375 | int ret = 0; |
1438 | struct device_node *np = pdev->dev.of_node; | 1376 | struct device_node *np = pdev->dev.of_node; |
1377 | struct device *dev = &pdev->dev; | ||
1439 | const struct of_device_id *of_id; | 1378 | const struct of_device_id *of_id; |
1440 | const char *p, *sprop; | 1379 | const char *p, *sprop; |
1441 | const uint32_t *iprop; | 1380 | const uint32_t *iprop; |
@@ -1444,185 +1383,159 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1444 | char name[64]; | 1383 | char name[64]; |
1445 | struct regmap_config regconfig = fsl_ssi_regconfig; | 1384 | struct regmap_config regconfig = fsl_ssi_regconfig; |
1446 | 1385 | ||
1447 | of_id = of_match_device(fsl_ssi_ids, &pdev->dev); | 1386 | of_id = of_match_device(fsl_ssi_ids, dev); |
1448 | if (!of_id || !of_id->data) | 1387 | if (!of_id || !of_id->data) |
1449 | return -EINVAL; | 1388 | return -EINVAL; |
1450 | 1389 | ||
1451 | ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private), | 1390 | ssi = devm_kzalloc(dev, sizeof(*ssi), GFP_KERNEL); |
1452 | GFP_KERNEL); | 1391 | if (!ssi) |
1453 | if (!ssi_private) | ||
1454 | return -ENOMEM; | 1392 | return -ENOMEM; |
1455 | 1393 | ||
1456 | ssi_private->soc = of_id->data; | 1394 | ssi->soc = of_id->data; |
1457 | ssi_private->dev = &pdev->dev; | 1395 | ssi->dev = dev; |
1458 | 1396 | ||
1397 | /* Check if being used in AC97 mode */ | ||
1459 | sprop = of_get_property(np, "fsl,mode", NULL); | 1398 | sprop = of_get_property(np, "fsl,mode", NULL); |
1460 | if (sprop) { | 1399 | if (sprop) { |
1461 | if (!strcmp(sprop, "ac97-slave")) | 1400 | if (!strcmp(sprop, "ac97-slave")) |
1462 | ssi_private->dai_fmt = SND_SOC_DAIFMT_AC97; | 1401 | ssi->dai_fmt = SND_SOC_DAIFMT_AC97; |
1463 | } | 1402 | } |
1464 | 1403 | ||
1465 | ssi_private->use_dma = !of_property_read_bool(np, | 1404 | /* Select DMA or FIQ */ |
1466 | "fsl,fiq-stream-filter"); | 1405 | ssi->use_dma = !of_property_read_bool(np, "fsl,fiq-stream-filter"); |
1467 | |||
1468 | if (fsl_ssi_is_ac97(ssi_private)) { | ||
1469 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, | ||
1470 | sizeof(fsl_ssi_ac97_dai)); | ||
1471 | 1406 | ||
1472 | fsl_ac97_data = ssi_private; | 1407 | if (fsl_ssi_is_ac97(ssi)) { |
1408 | memcpy(&ssi->cpu_dai_drv, &fsl_ssi_ac97_dai, | ||
1409 | sizeof(fsl_ssi_ac97_dai)); | ||
1410 | fsl_ac97_data = ssi; | ||
1473 | } else { | 1411 | } else { |
1474 | /* Initialize this copy of the CPU DAI driver structure */ | 1412 | memcpy(&ssi->cpu_dai_drv, &fsl_ssi_dai_template, |
1475 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, | ||
1476 | sizeof(fsl_ssi_dai_template)); | 1413 | sizeof(fsl_ssi_dai_template)); |
1477 | } | 1414 | } |
1478 | ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev); | 1415 | ssi->cpu_dai_drv.name = dev_name(dev); |
1479 | 1416 | ||
1480 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1417 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1481 | iomem = devm_ioremap_resource(&pdev->dev, res); | 1418 | iomem = devm_ioremap_resource(dev, res); |
1482 | if (IS_ERR(iomem)) | 1419 | if (IS_ERR(iomem)) |
1483 | return PTR_ERR(iomem); | 1420 | return PTR_ERR(iomem); |
1484 | ssi_private->ssi_phys = res->start; | 1421 | ssi->ssi_phys = res->start; |
1485 | 1422 | ||
1486 | if (ssi_private->soc->imx21regs) { | 1423 | if (ssi->soc->imx21regs) { |
1487 | /* | 1424 | /* No SACC{ST,EN,DIS} regs in imx21-class SSI */ |
1488 | * According to datasheet imx21-class SSI | 1425 | regconfig.max_register = REG_SSI_SRMSK; |
1489 | * don't have SACC{ST,EN,DIS} regs. | ||
1490 | */ | ||
1491 | regconfig.max_register = CCSR_SSI_SRMSK; | ||
1492 | regconfig.num_reg_defaults_raw = | 1426 | regconfig.num_reg_defaults_raw = |
1493 | CCSR_SSI_SRMSK / sizeof(uint32_t) + 1; | 1427 | REG_SSI_SRMSK / sizeof(uint32_t) + 1; |
1494 | } | 1428 | } |
1495 | 1429 | ||
1496 | ret = of_property_match_string(np, "clock-names", "ipg"); | 1430 | ret = of_property_match_string(np, "clock-names", "ipg"); |
1497 | if (ret < 0) { | 1431 | if (ret < 0) { |
1498 | ssi_private->has_ipg_clk_name = false; | 1432 | ssi->has_ipg_clk_name = false; |
1499 | ssi_private->regs = devm_regmap_init_mmio(&pdev->dev, iomem, | 1433 | ssi->regs = devm_regmap_init_mmio(dev, iomem, ®config); |
1500 | ®config); | ||
1501 | } else { | 1434 | } else { |
1502 | ssi_private->has_ipg_clk_name = true; | 1435 | ssi->has_ipg_clk_name = true; |
1503 | ssi_private->regs = devm_regmap_init_mmio_clk(&pdev->dev, | 1436 | ssi->regs = devm_regmap_init_mmio_clk(dev, "ipg", iomem, |
1504 | "ipg", iomem, ®config); | 1437 | ®config); |
1505 | } | 1438 | } |
1506 | if (IS_ERR(ssi_private->regs)) { | 1439 | if (IS_ERR(ssi->regs)) { |
1507 | dev_err(&pdev->dev, "Failed to init register map\n"); | 1440 | dev_err(dev, "failed to init register map\n"); |
1508 | return PTR_ERR(ssi_private->regs); | 1441 | return PTR_ERR(ssi->regs); |
1509 | } | 1442 | } |
1510 | 1443 | ||
1511 | ssi_private->irq = platform_get_irq(pdev, 0); | 1444 | ssi->irq = platform_get_irq(pdev, 0); |
1512 | if (ssi_private->irq < 0) { | 1445 | if (ssi->irq < 0) { |
1513 | dev_err(&pdev->dev, "no irq for node %s\n", pdev->name); | 1446 | dev_err(dev, "no irq for node %s\n", pdev->name); |
1514 | return ssi_private->irq; | 1447 | return ssi->irq; |
1515 | } | 1448 | } |
1516 | 1449 | ||
1517 | /* Are the RX and the TX clocks locked? */ | 1450 | /* Set software limitations for synchronous mode */ |
1518 | if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) { | 1451 | if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) { |
1519 | if (!fsl_ssi_is_ac97(ssi_private)) | 1452 | if (!fsl_ssi_is_ac97(ssi)) { |
1520 | ssi_private->cpu_dai_drv.symmetric_rates = 1; | 1453 | ssi->cpu_dai_drv.symmetric_rates = 1; |
1454 | ssi->cpu_dai_drv.symmetric_samplebits = 1; | ||
1455 | } | ||
1521 | 1456 | ||
1522 | ssi_private->cpu_dai_drv.symmetric_channels = 1; | 1457 | ssi->cpu_dai_drv.symmetric_channels = 1; |
1523 | ssi_private->cpu_dai_drv.symmetric_samplebits = 1; | ||
1524 | } | 1458 | } |
1525 | 1459 | ||
1526 | /* Determine the FIFO depth. */ | 1460 | /* Fetch FIFO depth; Set to 8 for older DT without this property */ |
1527 | iprop = of_get_property(np, "fsl,fifo-depth", NULL); | 1461 | iprop = of_get_property(np, "fsl,fifo-depth", NULL); |
1528 | if (iprop) | 1462 | if (iprop) |
1529 | ssi_private->fifo_depth = be32_to_cpup(iprop); | 1463 | ssi->fifo_depth = be32_to_cpup(iprop); |
1530 | else | 1464 | else |
1531 | /* Older 8610 DTs didn't have the fifo-depth property */ | 1465 | ssi->fifo_depth = 8; |
1532 | ssi_private->fifo_depth = 8; | ||
1533 | 1466 | ||
1534 | /* | 1467 | /* |
1535 | * Set the watermark for transmit FIFO 0 and receive FIFO 0. We don't | 1468 | * Configure TX and RX DMA watermarks -- when to send a DMA request |
1536 | * use FIFO 1 but set the watermark appropriately nontheless. | ||
1537 | * We program the transmit water to signal a DMA transfer | ||
1538 | * if there are N elements left in the FIFO. For chips with 15-deep | ||
1539 | * FIFOs, set watermark to 8. This allows the SSI to operate at a | ||
1540 | * high data rate without channel slipping. Behavior is unchanged | ||
1541 | * for the older chips with a fifo depth of only 8. A value of 4 | ||
1542 | * might be appropriate for the older chips, but is left at | ||
1543 | * fifo_depth-2 until sombody has a chance to test. | ||
1544 | * | 1469 | * |
1545 | * We set the watermark on the same level as the DMA burstsize. For | 1470 | * Values should be tested to avoid FIFO under/over run. Set maxburst |
1546 | * fiq it is probably better to use the biggest possible watermark | 1471 | * to fifo_watermark to maxiumize DMA transaction to reduce overhead. |
1547 | * size. | ||
1548 | */ | 1472 | */ |
1549 | switch (ssi_private->fifo_depth) { | 1473 | switch (ssi->fifo_depth) { |
1550 | case 15: | 1474 | case 15: |
1551 | /* | 1475 | /* |
1552 | * 2 samples is not enough when running at high data | 1476 | * Set to 8 as a balanced configuration -- When TX FIFO has 8 |
1553 | * rates (like 48kHz @ 16 bits/channel, 16 channels) | 1477 | * empty slots, send a DMA request to fill these 8 slots. The |
1554 | * 8 seems to split things evenly and leave enough time | 1478 | * remaining 7 slots should be able to allow DMA to finish the |
1555 | * for the DMA to fill the FIFO before it's over/under | 1479 | * transaction before TX FIFO underruns; Same applies to RX. |
1556 | * run. | 1480 | * |
1481 | * Tested with cases running at 48kHz @ 16 bits x 16 channels | ||
1557 | */ | 1482 | */ |
1558 | ssi_private->fifo_watermark = 8; | 1483 | ssi->fifo_watermark = 8; |
1559 | ssi_private->dma_maxburst = 8; | 1484 | ssi->dma_maxburst = 8; |
1560 | break; | 1485 | break; |
1561 | case 8: | 1486 | case 8: |
1562 | default: | 1487 | default: |
1563 | /* | 1488 | /* Safely use old watermark configurations for older chips */ |
1564 | * maintain old behavior for older chips. | 1489 | ssi->fifo_watermark = ssi->fifo_depth - 2; |
1565 | * Keeping it the same because I don't have an older | 1490 | ssi->dma_maxburst = ssi->fifo_depth - 2; |
1566 | * board to test with. | ||
1567 | * I suspect this could be changed to be something to | ||
1568 | * leave some more space in the fifo. | ||
1569 | */ | ||
1570 | ssi_private->fifo_watermark = ssi_private->fifo_depth - 2; | ||
1571 | ssi_private->dma_maxburst = ssi_private->fifo_depth - 2; | ||
1572 | break; | 1491 | break; |
1573 | } | 1492 | } |
1574 | 1493 | ||
1575 | dev_set_drvdata(&pdev->dev, ssi_private); | 1494 | dev_set_drvdata(dev, ssi); |
1576 | 1495 | ||
1577 | if (ssi_private->soc->imx) { | 1496 | if (ssi->soc->imx) { |
1578 | ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem); | 1497 | ret = fsl_ssi_imx_probe(pdev, ssi, iomem); |
1579 | if (ret) | 1498 | if (ret) |
1580 | return ret; | 1499 | return ret; |
1581 | } | 1500 | } |
1582 | 1501 | ||
1583 | if (fsl_ssi_is_ac97(ssi_private)) { | 1502 | if (fsl_ssi_is_ac97(ssi)) { |
1584 | mutex_init(&ssi_private->ac97_reg_lock); | 1503 | mutex_init(&ssi->ac97_reg_lock); |
1585 | ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); | 1504 | ret = snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); |
1586 | if (ret) { | 1505 | if (ret) { |
1587 | dev_err(&pdev->dev, "could not set AC'97 ops\n"); | 1506 | dev_err(dev, "failed to set AC'97 ops\n"); |
1588 | goto error_ac97_ops; | 1507 | goto error_ac97_ops; |
1589 | } | 1508 | } |
1590 | } | 1509 | } |
1591 | 1510 | ||
1592 | ret = devm_snd_soc_register_component(&pdev->dev, &fsl_ssi_component, | 1511 | ret = devm_snd_soc_register_component(dev, &fsl_ssi_component, |
1593 | &ssi_private->cpu_dai_drv, 1); | 1512 | &ssi->cpu_dai_drv, 1); |
1594 | if (ret) { | 1513 | if (ret) { |
1595 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | 1514 | dev_err(dev, "failed to register DAI: %d\n", ret); |
1596 | goto error_asoc_register; | 1515 | goto error_asoc_register; |
1597 | } | 1516 | } |
1598 | 1517 | ||
1599 | if (ssi_private->use_dma) { | 1518 | if (ssi->use_dma) { |
1600 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, | 1519 | ret = devm_request_irq(dev, ssi->irq, fsl_ssi_isr, 0, |
1601 | fsl_ssi_isr, 0, dev_name(&pdev->dev), | 1520 | dev_name(dev), ssi); |
1602 | ssi_private); | ||
1603 | if (ret < 0) { | 1521 | if (ret < 0) { |
1604 | dev_err(&pdev->dev, "could not claim irq %u\n", | 1522 | dev_err(dev, "failed to claim irq %u\n", ssi->irq); |
1605 | ssi_private->irq); | ||
1606 | goto error_asoc_register; | 1523 | goto error_asoc_register; |
1607 | } | 1524 | } |
1608 | } | 1525 | } |
1609 | 1526 | ||
1610 | ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); | 1527 | ret = fsl_ssi_debugfs_create(&ssi->dbg_stats, dev); |
1611 | if (ret) | 1528 | if (ret) |
1612 | goto error_asoc_register; | 1529 | goto error_asoc_register; |
1613 | 1530 | ||
1614 | /* | 1531 | /* Bypass it if using newer DT bindings of ASoC machine drivers */ |
1615 | * If codec-handle property is missing from SSI node, we assume | ||
1616 | * that the machine driver uses new binding which does not require | ||
1617 | * SSI driver to trigger machine driver's probe. | ||
1618 | */ | ||
1619 | if (!of_get_property(np, "codec-handle", NULL)) | 1532 | if (!of_get_property(np, "codec-handle", NULL)) |
1620 | goto done; | 1533 | goto done; |
1621 | 1534 | ||
1622 | /* Trigger the machine driver's probe function. The platform driver | 1535 | /* |
1623 | * name of the machine driver is taken from /compatible property of the | 1536 | * Backward compatible for older bindings by manually triggering the |
1624 | * device tree. We also pass the address of the CPU DAI driver | 1537 | * machine driver's probe(). Use /compatible property, including the |
1625 | * structure. | 1538 | * address of CPU DAI driver structure, as the name of machine driver. |
1626 | */ | 1539 | */ |
1627 | sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL); | 1540 | sprop = of_get_property(of_find_node_by_path("/"), "compatible", NULL); |
1628 | /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */ | 1541 | /* Sometimes the compatible name has a "fsl," prefix, so we strip it. */ |
@@ -1632,34 +1545,31 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1632 | snprintf(name, sizeof(name), "snd-soc-%s", sprop); | 1545 | snprintf(name, sizeof(name), "snd-soc-%s", sprop); |
1633 | make_lowercase(name); | 1546 | make_lowercase(name); |
1634 | 1547 | ||
1635 | ssi_private->pdev = | 1548 | ssi->pdev = platform_device_register_data(dev, name, 0, NULL, 0); |
1636 | platform_device_register_data(&pdev->dev, name, 0, NULL, 0); | 1549 | if (IS_ERR(ssi->pdev)) { |
1637 | if (IS_ERR(ssi_private->pdev)) { | 1550 | ret = PTR_ERR(ssi->pdev); |
1638 | ret = PTR_ERR(ssi_private->pdev); | 1551 | dev_err(dev, "failed to register platform: %d\n", ret); |
1639 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); | ||
1640 | goto error_sound_card; | 1552 | goto error_sound_card; |
1641 | } | 1553 | } |
1642 | 1554 | ||
1643 | done: | 1555 | done: |
1644 | if (ssi_private->dai_fmt) | 1556 | if (ssi->dai_fmt) |
1645 | _fsl_ssi_set_dai_fmt(&pdev->dev, ssi_private, | 1557 | _fsl_ssi_set_dai_fmt(dev, ssi, ssi->dai_fmt); |
1646 | ssi_private->dai_fmt); | ||
1647 | 1558 | ||
1648 | if (fsl_ssi_is_ac97(ssi_private)) { | 1559 | if (fsl_ssi_is_ac97(ssi)) { |
1649 | u32 ssi_idx; | 1560 | u32 ssi_idx; |
1650 | 1561 | ||
1651 | ret = of_property_read_u32(np, "cell-index", &ssi_idx); | 1562 | ret = of_property_read_u32(np, "cell-index", &ssi_idx); |
1652 | if (ret) { | 1563 | if (ret) { |
1653 | dev_err(&pdev->dev, "cannot get SSI index property\n"); | 1564 | dev_err(dev, "failed to get SSI index property\n"); |
1654 | goto error_sound_card; | 1565 | goto error_sound_card; |
1655 | } | 1566 | } |
1656 | 1567 | ||
1657 | ssi_private->pdev = | 1568 | ssi->pdev = platform_device_register_data(NULL, "ac97-codec", |
1658 | platform_device_register_data(NULL, | 1569 | ssi_idx, NULL, 0); |
1659 | "ac97-codec", ssi_idx, NULL, 0); | 1570 | if (IS_ERR(ssi->pdev)) { |
1660 | if (IS_ERR(ssi_private->pdev)) { | 1571 | ret = PTR_ERR(ssi->pdev); |
1661 | ret = PTR_ERR(ssi_private->pdev); | 1572 | dev_err(dev, |
1662 | dev_err(&pdev->dev, | ||
1663 | "failed to register AC97 codec platform: %d\n", | 1573 | "failed to register AC97 codec platform: %d\n", |
1664 | ret); | 1574 | ret); |
1665 | goto error_sound_card; | 1575 | goto error_sound_card; |
@@ -1669,37 +1579,35 @@ done: | |||
1669 | return 0; | 1579 | return 0; |
1670 | 1580 | ||
1671 | error_sound_card: | 1581 | error_sound_card: |
1672 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); | 1582 | fsl_ssi_debugfs_remove(&ssi->dbg_stats); |
1673 | |||
1674 | error_asoc_register: | 1583 | error_asoc_register: |
1675 | if (fsl_ssi_is_ac97(ssi_private)) | 1584 | if (fsl_ssi_is_ac97(ssi)) |
1676 | snd_soc_set_ac97_ops(NULL); | 1585 | snd_soc_set_ac97_ops(NULL); |
1677 | |||
1678 | error_ac97_ops: | 1586 | error_ac97_ops: |
1679 | if (fsl_ssi_is_ac97(ssi_private)) | 1587 | if (fsl_ssi_is_ac97(ssi)) |
1680 | mutex_destroy(&ssi_private->ac97_reg_lock); | 1588 | mutex_destroy(&ssi->ac97_reg_lock); |
1681 | 1589 | ||
1682 | if (ssi_private->soc->imx) | 1590 | if (ssi->soc->imx) |
1683 | fsl_ssi_imx_clean(pdev, ssi_private); | 1591 | fsl_ssi_imx_clean(pdev, ssi); |
1684 | 1592 | ||
1685 | return ret; | 1593 | return ret; |
1686 | } | 1594 | } |
1687 | 1595 | ||
1688 | static int fsl_ssi_remove(struct platform_device *pdev) | 1596 | static int fsl_ssi_remove(struct platform_device *pdev) |
1689 | { | 1597 | { |
1690 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); | 1598 | struct fsl_ssi *ssi = dev_get_drvdata(&pdev->dev); |
1691 | 1599 | ||
1692 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); | 1600 | fsl_ssi_debugfs_remove(&ssi->dbg_stats); |
1693 | 1601 | ||
1694 | if (ssi_private->pdev) | 1602 | if (ssi->pdev) |
1695 | platform_device_unregister(ssi_private->pdev); | 1603 | platform_device_unregister(ssi->pdev); |
1696 | 1604 | ||
1697 | if (ssi_private->soc->imx) | 1605 | if (ssi->soc->imx) |
1698 | fsl_ssi_imx_clean(pdev, ssi_private); | 1606 | fsl_ssi_imx_clean(pdev, ssi); |
1699 | 1607 | ||
1700 | if (fsl_ssi_is_ac97(ssi_private)) { | 1608 | if (fsl_ssi_is_ac97(ssi)) { |
1701 | snd_soc_set_ac97_ops(NULL); | 1609 | snd_soc_set_ac97_ops(NULL); |
1702 | mutex_destroy(&ssi_private->ac97_reg_lock); | 1610 | mutex_destroy(&ssi->ac97_reg_lock); |
1703 | } | 1611 | } |
1704 | 1612 | ||
1705 | return 0; | 1613 | return 0; |
@@ -1708,13 +1616,11 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1708 | #ifdef CONFIG_PM_SLEEP | 1616 | #ifdef CONFIG_PM_SLEEP |
1709 | static int fsl_ssi_suspend(struct device *dev) | 1617 | static int fsl_ssi_suspend(struct device *dev) |
1710 | { | 1618 | { |
1711 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); | 1619 | struct fsl_ssi *ssi = dev_get_drvdata(dev); |
1712 | struct regmap *regs = ssi_private->regs; | 1620 | struct regmap *regs = ssi->regs; |
1713 | 1621 | ||
1714 | regmap_read(regs, CCSR_SSI_SFCSR, | 1622 | regmap_read(regs, REG_SSI_SFCSR, &ssi->regcache_sfcsr); |
1715 | &ssi_private->regcache_sfcsr); | 1623 | regmap_read(regs, REG_SSI_SACNT, &ssi->regcache_sacnt); |
1716 | regmap_read(regs, CCSR_SSI_SACNT, | ||
1717 | &ssi_private->regcache_sacnt); | ||
1718 | 1624 | ||
1719 | regcache_cache_only(regs, true); | 1625 | regcache_cache_only(regs, true); |
1720 | regcache_mark_dirty(regs); | 1626 | regcache_mark_dirty(regs); |
@@ -1724,17 +1630,16 @@ static int fsl_ssi_suspend(struct device *dev) | |||
1724 | 1630 | ||
1725 | static int fsl_ssi_resume(struct device *dev) | 1631 | static int fsl_ssi_resume(struct device *dev) |
1726 | { | 1632 | { |
1727 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(dev); | 1633 | struct fsl_ssi *ssi = dev_get_drvdata(dev); |
1728 | struct regmap *regs = ssi_private->regs; | 1634 | struct regmap *regs = ssi->regs; |
1729 | 1635 | ||
1730 | regcache_cache_only(regs, false); | 1636 | regcache_cache_only(regs, false); |
1731 | 1637 | ||
1732 | regmap_update_bits(regs, CCSR_SSI_SFCSR, | 1638 | regmap_update_bits(regs, REG_SSI_SFCSR, |
1733 | CCSR_SSI_SFCSR_RFWM1_MASK | CCSR_SSI_SFCSR_TFWM1_MASK | | 1639 | SSI_SFCSR_RFWM1_MASK | SSI_SFCSR_TFWM1_MASK | |
1734 | CCSR_SSI_SFCSR_RFWM0_MASK | CCSR_SSI_SFCSR_TFWM0_MASK, | 1640 | SSI_SFCSR_RFWM0_MASK | SSI_SFCSR_TFWM0_MASK, |
1735 | ssi_private->regcache_sfcsr); | 1641 | ssi->regcache_sfcsr); |
1736 | regmap_write(regs, CCSR_SSI_SACNT, | 1642 | regmap_write(regs, REG_SSI_SACNT, ssi->regcache_sacnt); |
1737 | ssi_private->regcache_sacnt); | ||
1738 | 1643 | ||
1739 | return regcache_sync(regs); | 1644 | return regcache_sync(regs); |
1740 | } | 1645 | } |
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index 506510540d0a..de2fdc5db726 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * fsl_ssi.h - ALSA SSI interface for the Freescale MPC8610 SoC | 2 | * fsl_ssi.h - ALSA SSI interface for the Freescale MPC8610 and i.MX SoC |
3 | * | 3 | * |
4 | * Author: Timur Tabi <timur@freescale.com> | 4 | * Author: Timur Tabi <timur@freescale.com> |
5 | * | 5 | * |
@@ -12,198 +12,261 @@ | |||
12 | #ifndef _MPC8610_I2S_H | 12 | #ifndef _MPC8610_I2S_H |
13 | #define _MPC8610_I2S_H | 13 | #define _MPC8610_I2S_H |
14 | 14 | ||
15 | /* SSI registers */ | 15 | #define RX 0 |
16 | #define CCSR_SSI_STX0 0x00 | 16 | #define TX 1 |
17 | #define CCSR_SSI_STX1 0x04 | ||
18 | #define CCSR_SSI_SRX0 0x08 | ||
19 | #define CCSR_SSI_SRX1 0x0c | ||
20 | #define CCSR_SSI_SCR 0x10 | ||
21 | #define CCSR_SSI_SISR 0x14 | ||
22 | #define CCSR_SSI_SIER 0x18 | ||
23 | #define CCSR_SSI_STCR 0x1c | ||
24 | #define CCSR_SSI_SRCR 0x20 | ||
25 | #define CCSR_SSI_STCCR 0x24 | ||
26 | #define CCSR_SSI_SRCCR 0x28 | ||
27 | #define CCSR_SSI_SFCSR 0x2c | ||
28 | #define CCSR_SSI_STR 0x30 | ||
29 | #define CCSR_SSI_SOR 0x34 | ||
30 | #define CCSR_SSI_SACNT 0x38 | ||
31 | #define CCSR_SSI_SACADD 0x3c | ||
32 | #define CCSR_SSI_SACDAT 0x40 | ||
33 | #define CCSR_SSI_SATAG 0x44 | ||
34 | #define CCSR_SSI_STMSK 0x48 | ||
35 | #define CCSR_SSI_SRMSK 0x4c | ||
36 | #define CCSR_SSI_SACCST 0x50 | ||
37 | #define CCSR_SSI_SACCEN 0x54 | ||
38 | #define CCSR_SSI_SACCDIS 0x58 | ||
39 | 17 | ||
40 | #define CCSR_SSI_SCR_SYNC_TX_FS 0x00001000 | 18 | /* -- SSI Register Map -- */ |
41 | #define CCSR_SSI_SCR_RFR_CLK_DIS 0x00000800 | ||
42 | #define CCSR_SSI_SCR_TFR_CLK_DIS 0x00000400 | ||
43 | #define CCSR_SSI_SCR_TCH_EN 0x00000100 | ||
44 | #define CCSR_SSI_SCR_SYS_CLK_EN 0x00000080 | ||
45 | #define CCSR_SSI_SCR_I2S_MODE_MASK 0x00000060 | ||
46 | #define CCSR_SSI_SCR_I2S_MODE_NORMAL 0x00000000 | ||
47 | #define CCSR_SSI_SCR_I2S_MODE_MASTER 0x00000020 | ||
48 | #define CCSR_SSI_SCR_I2S_MODE_SLAVE 0x00000040 | ||
49 | #define CCSR_SSI_SCR_SYN 0x00000010 | ||
50 | #define CCSR_SSI_SCR_NET 0x00000008 | ||
51 | #define CCSR_SSI_SCR_RE 0x00000004 | ||
52 | #define CCSR_SSI_SCR_TE 0x00000002 | ||
53 | #define CCSR_SSI_SCR_SSIEN 0x00000001 | ||
54 | 19 | ||
55 | #define CCSR_SSI_SISR_RFRC 0x01000000 | 20 | /* SSI Transmit Data Register 0 */ |
56 | #define CCSR_SSI_SISR_TFRC 0x00800000 | 21 | #define REG_SSI_STX0 0x00 |
57 | #define CCSR_SSI_SISR_CMDAU 0x00040000 | 22 | /* SSI Transmit Data Register 1 */ |
58 | #define CCSR_SSI_SISR_CMDDU 0x00020000 | 23 | #define REG_SSI_STX1 0x04 |
59 | #define CCSR_SSI_SISR_RXT 0x00010000 | 24 | /* SSI Receive Data Register 0 */ |
60 | #define CCSR_SSI_SISR_RDR1 0x00008000 | 25 | #define REG_SSI_SRX0 0x08 |
61 | #define CCSR_SSI_SISR_RDR0 0x00004000 | 26 | /* SSI Receive Data Register 1 */ |
62 | #define CCSR_SSI_SISR_TDE1 0x00002000 | 27 | #define REG_SSI_SRX1 0x0c |
63 | #define CCSR_SSI_SISR_TDE0 0x00001000 | 28 | /* SSI Control Register */ |
64 | #define CCSR_SSI_SISR_ROE1 0x00000800 | 29 | #define REG_SSI_SCR 0x10 |
65 | #define CCSR_SSI_SISR_ROE0 0x00000400 | 30 | /* SSI Interrupt Status Register */ |
66 | #define CCSR_SSI_SISR_TUE1 0x00000200 | 31 | #define REG_SSI_SISR 0x14 |
67 | #define CCSR_SSI_SISR_TUE0 0x00000100 | 32 | /* SSI Interrupt Enable Register */ |
68 | #define CCSR_SSI_SISR_TFS 0x00000080 | 33 | #define REG_SSI_SIER 0x18 |
69 | #define CCSR_SSI_SISR_RFS 0x00000040 | 34 | /* SSI Transmit Configuration Register */ |
70 | #define CCSR_SSI_SISR_TLS 0x00000020 | 35 | #define REG_SSI_STCR 0x1c |
71 | #define CCSR_SSI_SISR_RLS 0x00000010 | 36 | /* SSI Receive Configuration Register */ |
72 | #define CCSR_SSI_SISR_RFF1 0x00000008 | 37 | #define REG_SSI_SRCR 0x20 |
73 | #define CCSR_SSI_SISR_RFF0 0x00000004 | 38 | #define REG_SSI_SxCR(tx) ((tx) ? REG_SSI_STCR : REG_SSI_SRCR) |
74 | #define CCSR_SSI_SISR_TFE1 0x00000002 | 39 | /* SSI Transmit Clock Control Register */ |
75 | #define CCSR_SSI_SISR_TFE0 0x00000001 | 40 | #define REG_SSI_STCCR 0x24 |
41 | /* SSI Receive Clock Control Register */ | ||
42 | #define REG_SSI_SRCCR 0x28 | ||
43 | #define REG_SSI_SxCCR(tx) ((tx) ? REG_SSI_STCCR : REG_SSI_SRCCR) | ||
44 | /* SSI FIFO Control/Status Register */ | ||
45 | #define REG_SSI_SFCSR 0x2c | ||
46 | /* | ||
47 | * SSI Test Register (Intended for debugging purposes only) | ||
48 | * | ||
49 | * Note: STR is not documented in recent IMX datasheet, but | ||
50 | * is described in IMX51 reference manual at section 56.3.3.14 | ||
51 | */ | ||
52 | #define REG_SSI_STR 0x30 | ||
53 | /* | ||
54 | * SSI Option Register (Intended for internal use only) | ||
55 | * | ||
56 | * Note: SOR is not documented in recent IMX datasheet, but | ||
57 | * is described in IMX51 reference manual at section 56.3.3.15 | ||
58 | */ | ||
59 | #define REG_SSI_SOR 0x34 | ||
60 | /* SSI AC97 Control Register */ | ||
61 | #define REG_SSI_SACNT 0x38 | ||
62 | /* SSI AC97 Command Address Register */ | ||
63 | #define REG_SSI_SACADD 0x3c | ||
64 | /* SSI AC97 Command Data Register */ | ||
65 | #define REG_SSI_SACDAT 0x40 | ||
66 | /* SSI AC97 Tag Register */ | ||
67 | #define REG_SSI_SATAG 0x44 | ||
68 | /* SSI Transmit Time Slot Mask Register */ | ||
69 | #define REG_SSI_STMSK 0x48 | ||
70 | /* SSI Receive Time Slot Mask Register */ | ||
71 | #define REG_SSI_SRMSK 0x4c | ||
72 | #define REG_SSI_SxMSK(tx) ((tx) ? REG_SSI_STMSK : REG_SSI_SRMSK) | ||
73 | /* | ||
74 | * SSI AC97 Channel Status Register | ||
75 | * | ||
76 | * The status could be changed by: | ||
77 | * 1) Writing a '1' bit at some position in SACCEN sets relevant bit in SACCST | ||
78 | * 2) Writing a '1' bit at some position in SACCDIS unsets the relevant bit | ||
79 | * 3) Receivng a '1' in SLOTREQ bit from external CODEC via AC Link | ||
80 | */ | ||
81 | #define REG_SSI_SACCST 0x50 | ||
82 | /* SSI AC97 Channel Enable Register -- Set bits in SACCST */ | ||
83 | #define REG_SSI_SACCEN 0x54 | ||
84 | /* SSI AC97 Channel Disable Register -- Clear bits in SACCST */ | ||
85 | #define REG_SSI_SACCDIS 0x58 | ||
86 | |||
87 | /* -- SSI Register Field Maps -- */ | ||
76 | 88 | ||
77 | #define CCSR_SSI_SIER_RFRC_EN 0x01000000 | 89 | /* SSI Control Register -- REG_SSI_SCR 0x10 */ |
78 | #define CCSR_SSI_SIER_TFRC_EN 0x00800000 | 90 | #define SSI_SCR_SYNC_TX_FS 0x00001000 |
79 | #define CCSR_SSI_SIER_RDMAE 0x00400000 | 91 | #define SSI_SCR_RFR_CLK_DIS 0x00000800 |
80 | #define CCSR_SSI_SIER_RIE 0x00200000 | 92 | #define SSI_SCR_TFR_CLK_DIS 0x00000400 |
81 | #define CCSR_SSI_SIER_TDMAE 0x00100000 | 93 | #define SSI_SCR_TCH_EN 0x00000100 |
82 | #define CCSR_SSI_SIER_TIE 0x00080000 | 94 | #define SSI_SCR_SYS_CLK_EN 0x00000080 |
83 | #define CCSR_SSI_SIER_CMDAU_EN 0x00040000 | 95 | #define SSI_SCR_I2S_MODE_MASK 0x00000060 |
84 | #define CCSR_SSI_SIER_CMDDU_EN 0x00020000 | 96 | #define SSI_SCR_I2S_MODE_NORMAL 0x00000000 |
85 | #define CCSR_SSI_SIER_RXT_EN 0x00010000 | 97 | #define SSI_SCR_I2S_MODE_MASTER 0x00000020 |
86 | #define CCSR_SSI_SIER_RDR1_EN 0x00008000 | 98 | #define SSI_SCR_I2S_MODE_SLAVE 0x00000040 |
87 | #define CCSR_SSI_SIER_RDR0_EN 0x00004000 | 99 | #define SSI_SCR_SYN 0x00000010 |
88 | #define CCSR_SSI_SIER_TDE1_EN 0x00002000 | 100 | #define SSI_SCR_NET 0x00000008 |
89 | #define CCSR_SSI_SIER_TDE0_EN 0x00001000 | 101 | #define SSI_SCR_I2S_NET_MASK (SSI_SCR_NET | SSI_SCR_I2S_MODE_MASK) |
90 | #define CCSR_SSI_SIER_ROE1_EN 0x00000800 | 102 | #define SSI_SCR_RE 0x00000004 |
91 | #define CCSR_SSI_SIER_ROE0_EN 0x00000400 | 103 | #define SSI_SCR_TE 0x00000002 |
92 | #define CCSR_SSI_SIER_TUE1_EN 0x00000200 | 104 | #define SSI_SCR_SSIEN 0x00000001 |
93 | #define CCSR_SSI_SIER_TUE0_EN 0x00000100 | ||
94 | #define CCSR_SSI_SIER_TFS_EN 0x00000080 | ||
95 | #define CCSR_SSI_SIER_RFS_EN 0x00000040 | ||
96 | #define CCSR_SSI_SIER_TLS_EN 0x00000020 | ||
97 | #define CCSR_SSI_SIER_RLS_EN 0x00000010 | ||
98 | #define CCSR_SSI_SIER_RFF1_EN 0x00000008 | ||
99 | #define CCSR_SSI_SIER_RFF0_EN 0x00000004 | ||
100 | #define CCSR_SSI_SIER_TFE1_EN 0x00000002 | ||
101 | #define CCSR_SSI_SIER_TFE0_EN 0x00000001 | ||
102 | 105 | ||
103 | #define CCSR_SSI_STCR_TXBIT0 0x00000200 | 106 | /* SSI Interrupt Status Register -- REG_SSI_SISR 0x14 */ |
104 | #define CCSR_SSI_STCR_TFEN1 0x00000100 | 107 | #define SSI_SISR_RFRC 0x01000000 |
105 | #define CCSR_SSI_STCR_TFEN0 0x00000080 | 108 | #define SSI_SISR_TFRC 0x00800000 |
106 | #define CCSR_SSI_STCR_TFDIR 0x00000040 | 109 | #define SSI_SISR_CMDAU 0x00040000 |
107 | #define CCSR_SSI_STCR_TXDIR 0x00000020 | 110 | #define SSI_SISR_CMDDU 0x00020000 |
108 | #define CCSR_SSI_STCR_TSHFD 0x00000010 | 111 | #define SSI_SISR_RXT 0x00010000 |
109 | #define CCSR_SSI_STCR_TSCKP 0x00000008 | 112 | #define SSI_SISR_RDR1 0x00008000 |
110 | #define CCSR_SSI_STCR_TFSI 0x00000004 | 113 | #define SSI_SISR_RDR0 0x00004000 |
111 | #define CCSR_SSI_STCR_TFSL 0x00000002 | 114 | #define SSI_SISR_TDE1 0x00002000 |
112 | #define CCSR_SSI_STCR_TEFS 0x00000001 | 115 | #define SSI_SISR_TDE0 0x00001000 |
116 | #define SSI_SISR_ROE1 0x00000800 | ||
117 | #define SSI_SISR_ROE0 0x00000400 | ||
118 | #define SSI_SISR_TUE1 0x00000200 | ||
119 | #define SSI_SISR_TUE0 0x00000100 | ||
120 | #define SSI_SISR_TFS 0x00000080 | ||
121 | #define SSI_SISR_RFS 0x00000040 | ||
122 | #define SSI_SISR_TLS 0x00000020 | ||
123 | #define SSI_SISR_RLS 0x00000010 | ||
124 | #define SSI_SISR_RFF1 0x00000008 | ||
125 | #define SSI_SISR_RFF0 0x00000004 | ||
126 | #define SSI_SISR_TFE1 0x00000002 | ||
127 | #define SSI_SISR_TFE0 0x00000001 | ||
113 | 128 | ||
114 | #define CCSR_SSI_SRCR_RXEXT 0x00000400 | 129 | /* SSI Interrupt Enable Register -- REG_SSI_SIER 0x18 */ |
115 | #define CCSR_SSI_SRCR_RXBIT0 0x00000200 | 130 | #define SSI_SIER_RFRC_EN 0x01000000 |
116 | #define CCSR_SSI_SRCR_RFEN1 0x00000100 | 131 | #define SSI_SIER_TFRC_EN 0x00800000 |
117 | #define CCSR_SSI_SRCR_RFEN0 0x00000080 | 132 | #define SSI_SIER_RDMAE 0x00400000 |
118 | #define CCSR_SSI_SRCR_RFDIR 0x00000040 | 133 | #define SSI_SIER_RIE 0x00200000 |
119 | #define CCSR_SSI_SRCR_RXDIR 0x00000020 | 134 | #define SSI_SIER_TDMAE 0x00100000 |
120 | #define CCSR_SSI_SRCR_RSHFD 0x00000010 | 135 | #define SSI_SIER_TIE 0x00080000 |
121 | #define CCSR_SSI_SRCR_RSCKP 0x00000008 | 136 | #define SSI_SIER_CMDAU_EN 0x00040000 |
122 | #define CCSR_SSI_SRCR_RFSI 0x00000004 | 137 | #define SSI_SIER_CMDDU_EN 0x00020000 |
123 | #define CCSR_SSI_SRCR_RFSL 0x00000002 | 138 | #define SSI_SIER_RXT_EN 0x00010000 |
124 | #define CCSR_SSI_SRCR_REFS 0x00000001 | 139 | #define SSI_SIER_RDR1_EN 0x00008000 |
140 | #define SSI_SIER_RDR0_EN 0x00004000 | ||
141 | #define SSI_SIER_TDE1_EN 0x00002000 | ||
142 | #define SSI_SIER_TDE0_EN 0x00001000 | ||
143 | #define SSI_SIER_ROE1_EN 0x00000800 | ||
144 | #define SSI_SIER_ROE0_EN 0x00000400 | ||
145 | #define SSI_SIER_TUE1_EN 0x00000200 | ||
146 | #define SSI_SIER_TUE0_EN 0x00000100 | ||
147 | #define SSI_SIER_TFS_EN 0x00000080 | ||
148 | #define SSI_SIER_RFS_EN 0x00000040 | ||
149 | #define SSI_SIER_TLS_EN 0x00000020 | ||
150 | #define SSI_SIER_RLS_EN 0x00000010 | ||
151 | #define SSI_SIER_RFF1_EN 0x00000008 | ||
152 | #define SSI_SIER_RFF0_EN 0x00000004 | ||
153 | #define SSI_SIER_TFE1_EN 0x00000002 | ||
154 | #define SSI_SIER_TFE0_EN 0x00000001 | ||
125 | 155 | ||
126 | /* STCCR and SRCCR */ | 156 | /* SSI Transmit Configuration Register -- REG_SSI_STCR 0x1C */ |
127 | #define CCSR_SSI_SxCCR_DIV2_SHIFT 18 | 157 | #define SSI_STCR_TXBIT0 0x00000200 |
128 | #define CCSR_SSI_SxCCR_DIV2 0x00040000 | 158 | #define SSI_STCR_TFEN1 0x00000100 |
129 | #define CCSR_SSI_SxCCR_PSR_SHIFT 17 | 159 | #define SSI_STCR_TFEN0 0x00000080 |
130 | #define CCSR_SSI_SxCCR_PSR 0x00020000 | 160 | #define SSI_STCR_TFDIR 0x00000040 |
131 | #define CCSR_SSI_SxCCR_WL_SHIFT 13 | 161 | #define SSI_STCR_TXDIR 0x00000020 |
132 | #define CCSR_SSI_SxCCR_WL_MASK 0x0001E000 | 162 | #define SSI_STCR_TSHFD 0x00000010 |
133 | #define CCSR_SSI_SxCCR_WL(x) \ | 163 | #define SSI_STCR_TSCKP 0x00000008 |
134 | (((((x) / 2) - 1) << CCSR_SSI_SxCCR_WL_SHIFT) & CCSR_SSI_SxCCR_WL_MASK) | 164 | #define SSI_STCR_TFSI 0x00000004 |
135 | #define CCSR_SSI_SxCCR_DC_SHIFT 8 | 165 | #define SSI_STCR_TFSL 0x00000002 |
136 | #define CCSR_SSI_SxCCR_DC_MASK 0x00001F00 | 166 | #define SSI_STCR_TEFS 0x00000001 |
137 | #define CCSR_SSI_SxCCR_DC(x) \ | 167 | |
138 | ((((x) - 1) << CCSR_SSI_SxCCR_DC_SHIFT) & CCSR_SSI_SxCCR_DC_MASK) | 168 | /* SSI Receive Configuration Register -- REG_SSI_SRCR 0x20 */ |
139 | #define CCSR_SSI_SxCCR_PM_SHIFT 0 | 169 | #define SSI_SRCR_RXEXT 0x00000400 |
140 | #define CCSR_SSI_SxCCR_PM_MASK 0x000000FF | 170 | #define SSI_SRCR_RXBIT0 0x00000200 |
141 | #define CCSR_SSI_SxCCR_PM(x) \ | 171 | #define SSI_SRCR_RFEN1 0x00000100 |
142 | ((((x) - 1) << CCSR_SSI_SxCCR_PM_SHIFT) & CCSR_SSI_SxCCR_PM_MASK) | 172 | #define SSI_SRCR_RFEN0 0x00000080 |
173 | #define SSI_SRCR_RFDIR 0x00000040 | ||
174 | #define SSI_SRCR_RXDIR 0x00000020 | ||
175 | #define SSI_SRCR_RSHFD 0x00000010 | ||
176 | #define SSI_SRCR_RSCKP 0x00000008 | ||
177 | #define SSI_SRCR_RFSI 0x00000004 | ||
178 | #define SSI_SRCR_RFSL 0x00000002 | ||
179 | #define SSI_SRCR_REFS 0x00000001 | ||
143 | 180 | ||
144 | /* | 181 | /* |
145 | * The xFCNT bits are read-only, and the xFWM bits are read/write. Use the | 182 | * SSI Transmit Clock Control Register -- REG_SSI_STCCR 0x24 |
146 | * CCSR_SSI_SFCSR_xFCNTy() macros to read the FIFO counters, and use the | 183 | * SSI Receive Clock Control Register -- REG_SSI_SRCCR 0x28 |
147 | * CCSR_SSI_SFCSR_xFWMy() macros to set the watermarks. | 184 | */ |
185 | #define SSI_SxCCR_DIV2_SHIFT 18 | ||
186 | #define SSI_SxCCR_DIV2 0x00040000 | ||
187 | #define SSI_SxCCR_PSR_SHIFT 17 | ||
188 | #define SSI_SxCCR_PSR 0x00020000 | ||
189 | #define SSI_SxCCR_WL_SHIFT 13 | ||
190 | #define SSI_SxCCR_WL_MASK 0x0001E000 | ||
191 | #define SSI_SxCCR_WL(x) \ | ||
192 | (((((x) / 2) - 1) << SSI_SxCCR_WL_SHIFT) & SSI_SxCCR_WL_MASK) | ||
193 | #define SSI_SxCCR_DC_SHIFT 8 | ||
194 | #define SSI_SxCCR_DC_MASK 0x00001F00 | ||
195 | #define SSI_SxCCR_DC(x) \ | ||
196 | ((((x) - 1) << SSI_SxCCR_DC_SHIFT) & SSI_SxCCR_DC_MASK) | ||
197 | #define SSI_SxCCR_PM_SHIFT 0 | ||
198 | #define SSI_SxCCR_PM_MASK 0x000000FF | ||
199 | #define SSI_SxCCR_PM(x) \ | ||
200 | ((((x) - 1) << SSI_SxCCR_PM_SHIFT) & SSI_SxCCR_PM_MASK) | ||
201 | |||
202 | /* | ||
203 | * SSI FIFO Control/Status Register -- REG_SSI_SFCSR 0x2c | ||
204 | * | ||
205 | * Tx or Rx FIFO Counter -- SSI_SFCSR_xFCNTy Read-Only | ||
206 | * Tx or Rx FIFO Watermarks -- SSI_SFCSR_xFWMy Read/Write | ||
148 | */ | 207 | */ |
149 | #define CCSR_SSI_SFCSR_RFCNT1_SHIFT 28 | 208 | #define SSI_SFCSR_RFCNT1_SHIFT 28 |
150 | #define CCSR_SSI_SFCSR_RFCNT1_MASK 0xF0000000 | 209 | #define SSI_SFCSR_RFCNT1_MASK 0xF0000000 |
151 | #define CCSR_SSI_SFCSR_RFCNT1(x) \ | 210 | #define SSI_SFCSR_RFCNT1(x) \ |
152 | (((x) & CCSR_SSI_SFCSR_RFCNT1_MASK) >> CCSR_SSI_SFCSR_RFCNT1_SHIFT) | 211 | (((x) & SSI_SFCSR_RFCNT1_MASK) >> SSI_SFCSR_RFCNT1_SHIFT) |
153 | #define CCSR_SSI_SFCSR_TFCNT1_SHIFT 24 | 212 | #define SSI_SFCSR_TFCNT1_SHIFT 24 |
154 | #define CCSR_SSI_SFCSR_TFCNT1_MASK 0x0F000000 | 213 | #define SSI_SFCSR_TFCNT1_MASK 0x0F000000 |
155 | #define CCSR_SSI_SFCSR_TFCNT1(x) \ | 214 | #define SSI_SFCSR_TFCNT1(x) \ |
156 | (((x) & CCSR_SSI_SFCSR_TFCNT1_MASK) >> CCSR_SSI_SFCSR_TFCNT1_SHIFT) | 215 | (((x) & SSI_SFCSR_TFCNT1_MASK) >> SSI_SFCSR_TFCNT1_SHIFT) |
157 | #define CCSR_SSI_SFCSR_RFWM1_SHIFT 20 | 216 | #define SSI_SFCSR_RFWM1_SHIFT 20 |
158 | #define CCSR_SSI_SFCSR_RFWM1_MASK 0x00F00000 | 217 | #define SSI_SFCSR_RFWM1_MASK 0x00F00000 |
159 | #define CCSR_SSI_SFCSR_RFWM1(x) \ | 218 | #define SSI_SFCSR_RFWM1(x) \ |
160 | (((x) << CCSR_SSI_SFCSR_RFWM1_SHIFT) & CCSR_SSI_SFCSR_RFWM1_MASK) | 219 | (((x) << SSI_SFCSR_RFWM1_SHIFT) & SSI_SFCSR_RFWM1_MASK) |
161 | #define CCSR_SSI_SFCSR_TFWM1_SHIFT 16 | 220 | #define SSI_SFCSR_TFWM1_SHIFT 16 |
162 | #define CCSR_SSI_SFCSR_TFWM1_MASK 0x000F0000 | 221 | #define SSI_SFCSR_TFWM1_MASK 0x000F0000 |
163 | #define CCSR_SSI_SFCSR_TFWM1(x) \ | 222 | #define SSI_SFCSR_TFWM1(x) \ |
164 | (((x) << CCSR_SSI_SFCSR_TFWM1_SHIFT) & CCSR_SSI_SFCSR_TFWM1_MASK) | 223 | (((x) << SSI_SFCSR_TFWM1_SHIFT) & SSI_SFCSR_TFWM1_MASK) |
165 | #define CCSR_SSI_SFCSR_RFCNT0_SHIFT 12 | 224 | #define SSI_SFCSR_RFCNT0_SHIFT 12 |
166 | #define CCSR_SSI_SFCSR_RFCNT0_MASK 0x0000F000 | 225 | #define SSI_SFCSR_RFCNT0_MASK 0x0000F000 |
167 | #define CCSR_SSI_SFCSR_RFCNT0(x) \ | 226 | #define SSI_SFCSR_RFCNT0(x) \ |
168 | (((x) & CCSR_SSI_SFCSR_RFCNT0_MASK) >> CCSR_SSI_SFCSR_RFCNT0_SHIFT) | 227 | (((x) & SSI_SFCSR_RFCNT0_MASK) >> SSI_SFCSR_RFCNT0_SHIFT) |
169 | #define CCSR_SSI_SFCSR_TFCNT0_SHIFT 8 | 228 | #define SSI_SFCSR_TFCNT0_SHIFT 8 |
170 | #define CCSR_SSI_SFCSR_TFCNT0_MASK 0x00000F00 | 229 | #define SSI_SFCSR_TFCNT0_MASK 0x00000F00 |
171 | #define CCSR_SSI_SFCSR_TFCNT0(x) \ | 230 | #define SSI_SFCSR_TFCNT0(x) \ |
172 | (((x) & CCSR_SSI_SFCSR_TFCNT0_MASK) >> CCSR_SSI_SFCSR_TFCNT0_SHIFT) | 231 | (((x) & SSI_SFCSR_TFCNT0_MASK) >> SSI_SFCSR_TFCNT0_SHIFT) |
173 | #define CCSR_SSI_SFCSR_RFWM0_SHIFT 4 | 232 | #define SSI_SFCSR_RFWM0_SHIFT 4 |
174 | #define CCSR_SSI_SFCSR_RFWM0_MASK 0x000000F0 | 233 | #define SSI_SFCSR_RFWM0_MASK 0x000000F0 |
175 | #define CCSR_SSI_SFCSR_RFWM0(x) \ | 234 | #define SSI_SFCSR_RFWM0(x) \ |
176 | (((x) << CCSR_SSI_SFCSR_RFWM0_SHIFT) & CCSR_SSI_SFCSR_RFWM0_MASK) | 235 | (((x) << SSI_SFCSR_RFWM0_SHIFT) & SSI_SFCSR_RFWM0_MASK) |
177 | #define CCSR_SSI_SFCSR_TFWM0_SHIFT 0 | 236 | #define SSI_SFCSR_TFWM0_SHIFT 0 |
178 | #define CCSR_SSI_SFCSR_TFWM0_MASK 0x0000000F | 237 | #define SSI_SFCSR_TFWM0_MASK 0x0000000F |
179 | #define CCSR_SSI_SFCSR_TFWM0(x) \ | 238 | #define SSI_SFCSR_TFWM0(x) \ |
180 | (((x) << CCSR_SSI_SFCSR_TFWM0_SHIFT) & CCSR_SSI_SFCSR_TFWM0_MASK) | 239 | (((x) << SSI_SFCSR_TFWM0_SHIFT) & SSI_SFCSR_TFWM0_MASK) |
181 | 240 | ||
182 | #define CCSR_SSI_STR_TEST 0x00008000 | 241 | /* SSI Test Register -- REG_SSI_STR 0x30 */ |
183 | #define CCSR_SSI_STR_RCK2TCK 0x00004000 | 242 | #define SSI_STR_TEST 0x00008000 |
184 | #define CCSR_SSI_STR_RFS2TFS 0x00002000 | 243 | #define SSI_STR_RCK2TCK 0x00004000 |
185 | #define CCSR_SSI_STR_RXSTATE(x) (((x) >> 8) & 0x1F) | 244 | #define SSI_STR_RFS2TFS 0x00002000 |
186 | #define CCSR_SSI_STR_TXD2RXD 0x00000080 | 245 | #define SSI_STR_RXSTATE(x) (((x) >> 8) & 0x1F) |
187 | #define CCSR_SSI_STR_TCK2RCK 0x00000040 | 246 | #define SSI_STR_TXD2RXD 0x00000080 |
188 | #define CCSR_SSI_STR_TFS2RFS 0x00000020 | 247 | #define SSI_STR_TCK2RCK 0x00000040 |
189 | #define CCSR_SSI_STR_TXSTATE(x) ((x) & 0x1F) | 248 | #define SSI_STR_TFS2RFS 0x00000020 |
249 | #define SSI_STR_TXSTATE(x) ((x) & 0x1F) | ||
190 | 250 | ||
191 | #define CCSR_SSI_SOR_CLKOFF 0x00000040 | 251 | /* SSI Option Register -- REG_SSI_SOR 0x34 */ |
192 | #define CCSR_SSI_SOR_RX_CLR 0x00000020 | 252 | #define SSI_SOR_CLKOFF 0x00000040 |
193 | #define CCSR_SSI_SOR_TX_CLR 0x00000010 | 253 | #define SSI_SOR_RX_CLR 0x00000020 |
194 | #define CCSR_SSI_SOR_INIT 0x00000008 | 254 | #define SSI_SOR_TX_CLR 0x00000010 |
195 | #define CCSR_SSI_SOR_WAIT_SHIFT 1 | 255 | #define SSI_SOR_xX_CLR(tx) ((tx) ? SSI_SOR_TX_CLR : SSI_SOR_RX_CLR) |
196 | #define CCSR_SSI_SOR_WAIT_MASK 0x00000006 | 256 | #define SSI_SOR_INIT 0x00000008 |
197 | #define CCSR_SSI_SOR_WAIT(x) (((x) & 3) << CCSR_SSI_SOR_WAIT_SHIFT) | 257 | #define SSI_SOR_WAIT_SHIFT 1 |
198 | #define CCSR_SSI_SOR_SYNRST 0x00000001 | 258 | #define SSI_SOR_WAIT_MASK 0x00000006 |
259 | #define SSI_SOR_WAIT(x) (((x) & 3) << SSI_SOR_WAIT_SHIFT) | ||
260 | #define SSI_SOR_SYNRST 0x00000001 | ||
199 | 261 | ||
200 | #define CCSR_SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5) | 262 | /* SSI AC97 Control Register -- REG_SSI_SACNT 0x38 */ |
201 | #define CCSR_SSI_SACNT_WR 0x00000010 | 263 | #define SSI_SACNT_FRDIV(x) (((x) & 0x3f) << 5) |
202 | #define CCSR_SSI_SACNT_RD 0x00000008 | 264 | #define SSI_SACNT_WR 0x00000010 |
203 | #define CCSR_SSI_SACNT_RDWR_MASK 0x00000018 | 265 | #define SSI_SACNT_RD 0x00000008 |
204 | #define CCSR_SSI_SACNT_TIF 0x00000004 | 266 | #define SSI_SACNT_RDWR_MASK 0x00000018 |
205 | #define CCSR_SSI_SACNT_FV 0x00000002 | 267 | #define SSI_SACNT_TIF 0x00000004 |
206 | #define CCSR_SSI_SACNT_AC97EN 0x00000001 | 268 | #define SSI_SACNT_FV 0x00000002 |
269 | #define SSI_SACNT_AC97EN 0x00000001 | ||
207 | 270 | ||
208 | 271 | ||
209 | struct device; | 272 | struct device; |
@@ -255,7 +318,7 @@ static inline void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *stats, u32 sisr) | |||
255 | } | 318 | } |
256 | 319 | ||
257 | static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, | 320 | static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, |
258 | struct device *dev) | 321 | struct device *dev) |
259 | { | 322 | { |
260 | return 0; | 323 | return 0; |
261 | } | 324 | } |
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c index 5469ffbc0253..7aac63e2c561 100644 --- a/sound/soc/fsl/fsl_ssi_dbg.c +++ b/sound/soc/fsl/fsl_ssi_dbg.c | |||
@@ -18,86 +18,86 @@ | |||
18 | 18 | ||
19 | void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr) | 19 | void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr) |
20 | { | 20 | { |
21 | if (sisr & CCSR_SSI_SISR_RFRC) | 21 | if (sisr & SSI_SISR_RFRC) |
22 | dbg->stats.rfrc++; | 22 | dbg->stats.rfrc++; |
23 | 23 | ||
24 | if (sisr & CCSR_SSI_SISR_TFRC) | 24 | if (sisr & SSI_SISR_TFRC) |
25 | dbg->stats.tfrc++; | 25 | dbg->stats.tfrc++; |
26 | 26 | ||
27 | if (sisr & CCSR_SSI_SISR_CMDAU) | 27 | if (sisr & SSI_SISR_CMDAU) |
28 | dbg->stats.cmdau++; | 28 | dbg->stats.cmdau++; |
29 | 29 | ||
30 | if (sisr & CCSR_SSI_SISR_CMDDU) | 30 | if (sisr & SSI_SISR_CMDDU) |
31 | dbg->stats.cmddu++; | 31 | dbg->stats.cmddu++; |
32 | 32 | ||
33 | if (sisr & CCSR_SSI_SISR_RXT) | 33 | if (sisr & SSI_SISR_RXT) |
34 | dbg->stats.rxt++; | 34 | dbg->stats.rxt++; |
35 | 35 | ||
36 | if (sisr & CCSR_SSI_SISR_RDR1) | 36 | if (sisr & SSI_SISR_RDR1) |
37 | dbg->stats.rdr1++; | 37 | dbg->stats.rdr1++; |
38 | 38 | ||
39 | if (sisr & CCSR_SSI_SISR_RDR0) | 39 | if (sisr & SSI_SISR_RDR0) |
40 | dbg->stats.rdr0++; | 40 | dbg->stats.rdr0++; |
41 | 41 | ||
42 | if (sisr & CCSR_SSI_SISR_TDE1) | 42 | if (sisr & SSI_SISR_TDE1) |
43 | dbg->stats.tde1++; | 43 | dbg->stats.tde1++; |
44 | 44 | ||
45 | if (sisr & CCSR_SSI_SISR_TDE0) | 45 | if (sisr & SSI_SISR_TDE0) |
46 | dbg->stats.tde0++; | 46 | dbg->stats.tde0++; |
47 | 47 | ||
48 | if (sisr & CCSR_SSI_SISR_ROE1) | 48 | if (sisr & SSI_SISR_ROE1) |
49 | dbg->stats.roe1++; | 49 | dbg->stats.roe1++; |
50 | 50 | ||
51 | if (sisr & CCSR_SSI_SISR_ROE0) | 51 | if (sisr & SSI_SISR_ROE0) |
52 | dbg->stats.roe0++; | 52 | dbg->stats.roe0++; |
53 | 53 | ||
54 | if (sisr & CCSR_SSI_SISR_TUE1) | 54 | if (sisr & SSI_SISR_TUE1) |
55 | dbg->stats.tue1++; | 55 | dbg->stats.tue1++; |
56 | 56 | ||
57 | if (sisr & CCSR_SSI_SISR_TUE0) | 57 | if (sisr & SSI_SISR_TUE0) |
58 | dbg->stats.tue0++; | 58 | dbg->stats.tue0++; |
59 | 59 | ||
60 | if (sisr & CCSR_SSI_SISR_TFS) | 60 | if (sisr & SSI_SISR_TFS) |
61 | dbg->stats.tfs++; | 61 | dbg->stats.tfs++; |
62 | 62 | ||
63 | if (sisr & CCSR_SSI_SISR_RFS) | 63 | if (sisr & SSI_SISR_RFS) |
64 | dbg->stats.rfs++; | 64 | dbg->stats.rfs++; |
65 | 65 | ||
66 | if (sisr & CCSR_SSI_SISR_TLS) | 66 | if (sisr & SSI_SISR_TLS) |
67 | dbg->stats.tls++; | 67 | dbg->stats.tls++; |
68 | 68 | ||
69 | if (sisr & CCSR_SSI_SISR_RLS) | 69 | if (sisr & SSI_SISR_RLS) |
70 | dbg->stats.rls++; | 70 | dbg->stats.rls++; |
71 | 71 | ||
72 | if (sisr & CCSR_SSI_SISR_RFF1) | 72 | if (sisr & SSI_SISR_RFF1) |
73 | dbg->stats.rff1++; | 73 | dbg->stats.rff1++; |
74 | 74 | ||
75 | if (sisr & CCSR_SSI_SISR_RFF0) | 75 | if (sisr & SSI_SISR_RFF0) |
76 | dbg->stats.rff0++; | 76 | dbg->stats.rff0++; |
77 | 77 | ||
78 | if (sisr & CCSR_SSI_SISR_TFE1) | 78 | if (sisr & SSI_SISR_TFE1) |
79 | dbg->stats.tfe1++; | 79 | dbg->stats.tfe1++; |
80 | 80 | ||
81 | if (sisr & CCSR_SSI_SISR_TFE0) | 81 | if (sisr & SSI_SISR_TFE0) |
82 | dbg->stats.tfe0++; | 82 | dbg->stats.tfe0++; |
83 | } | 83 | } |
84 | 84 | ||
85 | /* Show the statistics of a flag only if its interrupt is enabled. The | 85 | /** |
86 | * compiler will optimze this code to a no-op if the interrupt is not | 86 | * Show the statistics of a flag only if its interrupt is enabled |
87 | * enabled. | 87 | * |
88 | * Compilers will optimize it to a no-op if the interrupt is disabled | ||
88 | */ | 89 | */ |
89 | #define SIER_SHOW(flag, name) \ | 90 | #define SIER_SHOW(flag, name) \ |
90 | do { \ | 91 | do { \ |
91 | if (CCSR_SSI_SIER_##flag) \ | 92 | if (SSI_SIER_##flag) \ |
92 | seq_printf(s, #name "=%u\n", ssi_dbg->stats.name); \ | 93 | seq_printf(s, #name "=%u\n", ssi_dbg->stats.name); \ |
93 | } while (0) | 94 | } while (0) |
94 | 95 | ||
95 | 96 | ||
96 | /** | 97 | /** |
97 | * fsl_sysfs_ssi_show: display SSI statistics | 98 | * Display the statistics for the current SSI device |
98 | * | 99 | * |
99 | * Display the statistics for the current SSI device. To avoid confusion, | 100 | * To avoid confusion, only show those counts that are enabled |
100 | * we only show those counts that are enabled. | ||
101 | */ | 101 | */ |
102 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) | 102 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) |
103 | { | 103 | { |
@@ -147,7 +147,8 @@ int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev) | |||
147 | return -ENOMEM; | 147 | return -ENOMEM; |
148 | 148 | ||
149 | ssi_dbg->dbg_stats = debugfs_create_file("stats", S_IRUGO, | 149 | ssi_dbg->dbg_stats = debugfs_create_file("stats", S_IRUGO, |
150 | ssi_dbg->dbg_dir, ssi_dbg, &fsl_ssi_stats_ops); | 150 | ssi_dbg->dbg_dir, ssi_dbg, |
151 | &fsl_ssi_stats_ops); | ||
151 | if (!ssi_dbg->dbg_stats) { | 152 | if (!ssi_dbg->dbg_stats) { |
152 | debugfs_remove(ssi_dbg->dbg_dir); | 153 | debugfs_remove(ssi_dbg->dbg_dir); |
153 | return -ENOMEM; | 154 | return -ENOMEM; |
diff --git a/sound/soc/hisilicon/hi6210-i2s.c b/sound/soc/hisilicon/hi6210-i2s.c index 0c8f86d4020e..07a57209e055 100644 --- a/sound/soc/hisilicon/hi6210-i2s.c +++ b/sound/soc/hisilicon/hi6210-i2s.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/of_irq.h> | 36 | #include <linux/of_irq.h> |
37 | #include <linux/mfd/syscon.h> | 37 | #include <linux/mfd/syscon.h> |
38 | #include <linux/reset-controller.h> | 38 | #include <linux/reset-controller.h> |
39 | #include <linux/clk.h> | ||
40 | 39 | ||
41 | #include "hi6210-i2s.h" | 40 | #include "hi6210-i2s.h" |
42 | 41 | ||
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig index 7b49d04e3c60..f2c9e8c5970a 100644 --- a/sound/soc/intel/Kconfig +++ b/sound/soc/intel/Kconfig | |||
@@ -1,71 +1,122 @@ | |||
1 | config SND_SOC_INTEL_SST_TOPLEVEL | ||
2 | bool "Intel ASoC SST drivers" | ||
3 | default y | ||
4 | depends on X86 || COMPILE_TEST | ||
5 | select SND_SOC_INTEL_MACH | ||
6 | help | ||
7 | Intel ASoC SST Platform Drivers. If you have a Intel machine that | ||
8 | has an audio controller with a DSP and I2S or DMIC port, then | ||
9 | enable this option by saying Y | ||
10 | |||
11 | Note that the answer to this question doesn't directly affect the | ||
12 | kernel: saying N will just cause the configurator to skip all | ||
13 | the questions about Intel SST drivers. | ||
14 | |||
15 | if SND_SOC_INTEL_SST_TOPLEVEL | ||
16 | |||
1 | config SND_SST_IPC | 17 | config SND_SST_IPC |
2 | tristate | 18 | tristate |
19 | # This option controls the IPC core for HiFi2 platforms | ||
3 | 20 | ||
4 | config SND_SST_IPC_PCI | 21 | config SND_SST_IPC_PCI |
5 | tristate | 22 | tristate |
6 | select SND_SST_IPC | 23 | select SND_SST_IPC |
24 | # This option controls the PCI-based IPC for HiFi2 platforms | ||
25 | # (Medfield, Merrifield). | ||
7 | 26 | ||
8 | config SND_SST_IPC_ACPI | 27 | config SND_SST_IPC_ACPI |
9 | tristate | 28 | tristate |
10 | select SND_SST_IPC | 29 | select SND_SST_IPC |
11 | select SND_SOC_INTEL_SST | 30 | # This option controls the ACPI-based IPC for HiFi2 platforms |
12 | select IOSF_MBI | 31 | # (Baytrail, Cherrytrail) |
13 | 32 | ||
14 | config SND_SOC_INTEL_COMMON | 33 | config SND_SOC_INTEL_SST_ACPI |
15 | tristate | 34 | tristate |
35 | # This option controls ACPI-based probing on | ||
36 | # Haswell/Broadwell/Baytrail legacy and will be set | ||
37 | # when these platforms are enabled | ||
16 | 38 | ||
17 | config SND_SOC_INTEL_SST | 39 | config SND_SOC_INTEL_SST |
18 | tristate | 40 | tristate |
19 | select SND_SOC_INTEL_SST_ACPI if ACPI | ||
20 | 41 | ||
21 | config SND_SOC_INTEL_SST_FIRMWARE | 42 | config SND_SOC_INTEL_SST_FIRMWARE |
22 | tristate | 43 | tristate |
23 | select DW_DMAC_CORE | 44 | select DW_DMAC_CORE |
24 | 45 | # This option controls firmware download on | |
25 | config SND_SOC_INTEL_SST_ACPI | 46 | # Haswell/Broadwell/Baytrail legacy and will be set |
26 | tristate | 47 | # when these platforms are enabled |
27 | |||
28 | config SND_SOC_ACPI_INTEL_MATCH | ||
29 | tristate | ||
30 | select SND_SOC_ACPI if ACPI | ||
31 | |||
32 | config SND_SOC_INTEL_SST_TOPLEVEL | ||
33 | tristate "Intel ASoC SST drivers" | ||
34 | depends on X86 || COMPILE_TEST | ||
35 | select SND_SOC_INTEL_MACH | ||
36 | select SND_SOC_INTEL_COMMON | ||
37 | help | ||
38 | Intel ASoC Audio Drivers. If you have a Intel machine that | ||
39 | has audio controller with a DSP and I2S or DMIC port, then | ||
40 | enable this option by saying Y or M | ||
41 | If unsure select "N". | ||
42 | 48 | ||
43 | config SND_SOC_INTEL_HASWELL | 49 | config SND_SOC_INTEL_HASWELL |
44 | tristate "Intel ASoC SST driver for Haswell/Broadwell" | 50 | tristate "Haswell/Broadwell Platforms" |
45 | depends on SND_SOC_INTEL_SST_TOPLEVEL && SND_DMA_SGBUF | 51 | depends on SND_DMA_SGBUF |
46 | depends on DMADEVICES | 52 | depends on DMADEVICES && ACPI |
47 | select SND_SOC_INTEL_SST | 53 | select SND_SOC_INTEL_SST |
54 | select SND_SOC_INTEL_SST_ACPI | ||
48 | select SND_SOC_INTEL_SST_FIRMWARE | 55 | select SND_SOC_INTEL_SST_FIRMWARE |
56 | select SND_SOC_ACPI_INTEL_MATCH | ||
57 | help | ||
58 | If you have a Intel Haswell or Broadwell platform connected to | ||
59 | an I2S codec, then enable this option by saying Y or m. This is | ||
60 | typically used for Chromebooks. This is a recommended option. | ||
49 | 61 | ||
50 | config SND_SOC_INTEL_BAYTRAIL | 62 | config SND_SOC_INTEL_BAYTRAIL |
51 | tristate "Intel ASoC SST driver for Baytrail (legacy)" | 63 | tristate "Baytrail (legacy) Platforms" |
52 | depends on SND_SOC_INTEL_SST_TOPLEVEL | 64 | depends on DMADEVICES && ACPI |
53 | depends on DMADEVICES | ||
54 | select SND_SOC_INTEL_SST | 65 | select SND_SOC_INTEL_SST |
66 | select SND_SOC_INTEL_SST_ACPI | ||
55 | select SND_SOC_INTEL_SST_FIRMWARE | 67 | select SND_SOC_INTEL_SST_FIRMWARE |
68 | select SND_SOC_ACPI_INTEL_MATCH | ||
69 | help | ||
70 | If you have a Intel Baytrail platform connected to an I2S codec, | ||
71 | then enable this option by saying Y or m. This was typically used | ||
72 | for Baytrail Chromebooks but this option is now deprecated and is | ||
73 | not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead. | ||
74 | |||
75 | config SND_SST_ATOM_HIFI2_PLATFORM_PCI | ||
76 | tristate "PCI HiFi2 (Medfield, Merrifield) Platforms" | ||
77 | depends on X86 && PCI | ||
78 | select SND_SST_IPC_PCI | ||
79 | select SND_SOC_COMPRESS | ||
80 | help | ||
81 | If you have a Intel Medfield or Merrifield/Edison platform, then | ||
82 | enable this option by saying Y or m. Distros will typically not | ||
83 | enable this option: Medfield devices are not available to | ||
84 | developers and while Merrifield/Edison can run a mainline kernel with | ||
85 | limited functionality it will require a firmware file which | ||
86 | is not in the standard firmware tree | ||
56 | 87 | ||
57 | config SND_SST_ATOM_HIFI2_PLATFORM | 88 | config SND_SST_ATOM_HIFI2_PLATFORM |
58 | tristate "Intel ASoC SST driver for HiFi2 platforms (*field, *trail)" | 89 | tristate "ACPI HiFi2 (Baytrail, Cherrytrail) Platforms" |
59 | depends on SND_SOC_INTEL_SST_TOPLEVEL && X86 | 90 | depends on X86 && ACPI |
91 | select SND_SST_IPC_ACPI | ||
60 | select SND_SOC_COMPRESS | 92 | select SND_SOC_COMPRESS |
93 | select SND_SOC_ACPI_INTEL_MATCH | ||
94 | select IOSF_MBI | ||
95 | help | ||
96 | If you have a Intel Baytrail or Cherrytrail platform with an I2S | ||
97 | codec, then enable this option by saying Y or m. This is a | ||
98 | recommended option | ||
61 | 99 | ||
62 | config SND_SOC_INTEL_SKYLAKE | 100 | config SND_SOC_INTEL_SKYLAKE |
63 | tristate "Intel ASoC SST driver for SKL/BXT/KBL/GLK/CNL" | 101 | tristate "SKL/BXT/KBL/GLK/CNL... Platforms" |
64 | depends on SND_SOC_INTEL_SST_TOPLEVEL && PCI && ACPI | 102 | depends on PCI && ACPI |
65 | select SND_HDA_EXT_CORE | 103 | select SND_HDA_EXT_CORE |
66 | select SND_HDA_DSP_LOADER | 104 | select SND_HDA_DSP_LOADER |
67 | select SND_SOC_TOPOLOGY | 105 | select SND_SOC_TOPOLOGY |
68 | select SND_SOC_INTEL_SST | 106 | select SND_SOC_INTEL_SST |
107 | select SND_SOC_ACPI_INTEL_MATCH | ||
108 | help | ||
109 | If you have a Intel Skylake/Broxton/ApolloLake/KabyLake/ | ||
110 | GeminiLake or CannonLake platform with the DSP enabled in the BIOS | ||
111 | then enable this option by saying Y or m. | ||
112 | |||
113 | config SND_SOC_ACPI_INTEL_MATCH | ||
114 | tristate | ||
115 | select SND_SOC_ACPI if ACPI | ||
116 | # this option controls the compilation of ACPI matching tables and | ||
117 | # helpers and is not meant to be selected by the user. | ||
118 | |||
119 | endif ## SND_SOC_INTEL_SST_TOPLEVEL | ||
69 | 120 | ||
70 | # ASoC codec drivers | 121 | # ASoC codec drivers |
71 | source "sound/soc/intel/boards/Kconfig" | 122 | source "sound/soc/intel/boards/Kconfig" |
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index b973d457e834..8160520fd74c 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | # Core support | 2 | # Core support |
3 | obj-$(CONFIG_SND_SOC_INTEL_COMMON) += common/ | 3 | obj-$(CONFIG_SND_SOC) += common/ |
4 | 4 | ||
5 | # Platform Support | 5 | # Platform Support |
6 | obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/ | 6 | obj-$(CONFIG_SND_SOC_INTEL_HASWELL) += haswell/ |
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index 32d6e02e2104..6cd481bec275 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c | |||
@@ -236,6 +236,9 @@ static int sst_platform_get_resources(struct intel_sst_drv *ctx) | |||
236 | /* Find the IRQ */ | 236 | /* Find the IRQ */ |
237 | ctx->irq_num = platform_get_irq(pdev, | 237 | ctx->irq_num = platform_get_irq(pdev, |
238 | ctx->pdata->res_info->acpi_ipc_irq_index); | 238 | ctx->pdata->res_info->acpi_ipc_irq_index); |
239 | if (ctx->irq_num <= 0) | ||
240 | return ctx->irq_num < 0 ? ctx->irq_num : -EIO; | ||
241 | |||
239 | return 0; | 242 | return 0; |
240 | } | 243 | } |
241 | 244 | ||
diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c index 65e257b17a7e..7ee6aeb7e0af 100644 --- a/sound/soc/intel/atom/sst/sst_stream.c +++ b/sound/soc/intel/atom/sst/sst_stream.c | |||
@@ -220,10 +220,10 @@ int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, | |||
220 | sst_free_block(sst_drv_ctx, block); | 220 | sst_free_block(sst_drv_ctx, block); |
221 | out: | 221 | out: |
222 | test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id); | 222 | test_and_clear_bit(pvt_id, &sst_drv_ctx->pvt_id); |
223 | return 0; | 223 | return ret; |
224 | } | 224 | } |
225 | 225 | ||
226 | /* | 226 | /** |
227 | * sst_pause_stream - Send msg for a pausing stream | 227 | * sst_pause_stream - Send msg for a pausing stream |
228 | * @str_id: stream ID | 228 | * @str_id: stream ID |
229 | * | 229 | * |
@@ -261,7 +261,7 @@ int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) | |||
261 | } | 261 | } |
262 | } else { | 262 | } else { |
263 | retval = -EBADRQC; | 263 | retval = -EBADRQC; |
264 | dev_dbg(sst_drv_ctx->dev, "SST DBG:BADRQC for stream\n "); | 264 | dev_dbg(sst_drv_ctx->dev, "SST DBG:BADRQC for stream\n"); |
265 | } | 265 | } |
266 | 266 | ||
267 | return retval; | 267 | return retval; |
@@ -284,7 +284,7 @@ int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id) | |||
284 | if (!str_info) | 284 | if (!str_info) |
285 | return -EINVAL; | 285 | return -EINVAL; |
286 | if (str_info->status == STREAM_RUNNING) | 286 | if (str_info->status == STREAM_RUNNING) |
287 | return 0; | 287 | return 0; |
288 | if (str_info->status == STREAM_PAUSED) { | 288 | if (str_info->status == STREAM_PAUSED) { |
289 | retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, | 289 | retval = sst_prepare_and_post_msg(sst_drv_ctx, str_info->task_id, |
290 | IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD, | 290 | IPC_CMD, IPC_IA_RESUME_STREAM_MRFLD, |
diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 6f754708a48c..d4e103615f51 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig | |||
@@ -1,183 +1,183 @@ | |||
1 | config SND_SOC_INTEL_MACH | 1 | menuconfig SND_SOC_INTEL_MACH |
2 | tristate "Intel Audio machine drivers" | 2 | bool "Intel Machine drivers" |
3 | depends on SND_SOC_INTEL_SST_TOPLEVEL | 3 | depends on SND_SOC_INTEL_SST_TOPLEVEL |
4 | select SND_SOC_ACPI_INTEL_MATCH if ACPI | 4 | help |
5 | Intel ASoC Machine Drivers. If you have a Intel machine that | ||
6 | has an audio controller with a DSP and I2S or DMIC port, then | ||
7 | enable this option by saying Y | ||
8 | |||
9 | Note that the answer to this question doesn't directly affect the | ||
10 | kernel: saying N will just cause the configurator to skip all | ||
11 | the questions about Intel ASoC machine drivers. | ||
5 | 12 | ||
6 | if SND_SOC_INTEL_MACH | 13 | if SND_SOC_INTEL_MACH |
7 | 14 | ||
8 | config SND_MFLD_MACHINE | 15 | if SND_SOC_INTEL_HASWELL |
9 | tristate "SOC Machine Audio driver for Intel Medfield MID platform" | ||
10 | depends on INTEL_SCU_IPC | ||
11 | select SND_SOC_SN95031 | ||
12 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
13 | select SND_SST_IPC_PCI | ||
14 | help | ||
15 | This adds support for ASoC machine driver for Intel(R) MID Medfield platform | ||
16 | used as alsa device in audio substem in Intel(R) MID devices | ||
17 | Say Y if you have such a device. | ||
18 | If unsure select "N". | ||
19 | 16 | ||
20 | config SND_SOC_INTEL_HASWELL_MACH | 17 | config SND_SOC_INTEL_HASWELL_MACH |
21 | tristate "ASoC Audio DSP support for Intel Haswell Lynxpoint" | 18 | tristate "Haswell Lynxpoint" |
22 | depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM | 19 | depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM |
23 | depends on SND_SOC_INTEL_HASWELL | ||
24 | select SND_SOC_RT5640 | 20 | select SND_SOC_RT5640 |
25 | help | 21 | help |
26 | This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell | 22 | This adds support for the Lynxpoint Audio DSP on Intel(R) Haswell |
27 | Ultrabook platforms. | 23 | Ultrabook platforms. This is a recommended option. |
28 | Say Y if you have such a device. | 24 | Say Y or m if you have such a device. |
29 | If unsure select "N". | 25 | If unsure select "N". |
30 | 26 | ||
31 | config SND_SOC_INTEL_BDW_RT5677_MACH | 27 | config SND_SOC_INTEL_BDW_RT5677_MACH |
32 | tristate "ASoC Audio driver for Intel Broadwell with RT5677 codec" | 28 | tristate "Broadwell with RT5677 codec" |
33 | depends on X86_INTEL_LPSS && GPIOLIB && I2C | 29 | depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM && GPIOLIB |
34 | depends on SND_SOC_INTEL_HASWELL | ||
35 | select SND_SOC_RT5677 | 30 | select SND_SOC_RT5677 |
36 | help | 31 | help |
37 | This adds support for Intel Broadwell platform based boards with | 32 | This adds support for Intel Broadwell platform based boards with |
38 | the RT5677 audio codec. | 33 | the RT5677 audio codec. This is a recommended option. |
34 | Say Y or m if you have such a device. | ||
35 | If unsure select "N". | ||
39 | 36 | ||
40 | config SND_SOC_INTEL_BROADWELL_MACH | 37 | config SND_SOC_INTEL_BROADWELL_MACH |
41 | tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint" | 38 | tristate "Broadwell Wildcatpoint" |
42 | depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM | 39 | depends on X86_INTEL_LPSS && I2C && I2C_DESIGNWARE_PLATFORM |
43 | depends on SND_SOC_INTEL_HASWELL | ||
44 | select SND_SOC_RT286 | 40 | select SND_SOC_RT286 |
45 | help | 41 | help |
46 | This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell | 42 | This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell |
47 | Ultrabook platforms. | 43 | Ultrabook platforms. |
48 | Say Y if you have such a device. | 44 | Say Y or m if you have such a device. This is a recommended option. |
49 | If unsure select "N". | 45 | If unsure select "N". |
46 | endif ## SND_SOC_INTEL_HASWELL | ||
47 | |||
48 | if SND_SOC_INTEL_BAYTRAIL | ||
50 | 49 | ||
51 | config SND_SOC_INTEL_BYT_MAX98090_MACH | 50 | config SND_SOC_INTEL_BYT_MAX98090_MACH |
52 | tristate "ASoC Audio driver for Intel Baytrail with MAX98090 codec" | 51 | tristate "Baytrail with MAX98090 codec" |
53 | depends on X86_INTEL_LPSS && I2C | 52 | depends on X86_INTEL_LPSS && I2C |
54 | depends on SND_SST_IPC_ACPI = n | ||
55 | depends on SND_SOC_INTEL_BAYTRAIL | ||
56 | select SND_SOC_MAX98090 | 53 | select SND_SOC_MAX98090 |
57 | help | 54 | help |
58 | This adds audio driver for Intel Baytrail platform based boards | 55 | This adds audio driver for Intel Baytrail platform based boards |
59 | with the MAX98090 audio codec. | 56 | with the MAX98090 audio codec. This driver is deprecated, use |
57 | SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH instead for better | ||
58 | functionality. | ||
60 | 59 | ||
61 | config SND_SOC_INTEL_BYT_RT5640_MACH | 60 | config SND_SOC_INTEL_BYT_RT5640_MACH |
62 | tristate "ASoC Audio driver for Intel Baytrail with RT5640 codec" | 61 | tristate "Baytrail with RT5640 codec" |
63 | depends on X86_INTEL_LPSS && I2C | 62 | depends on X86_INTEL_LPSS && I2C |
64 | depends on SND_SST_IPC_ACPI = n | ||
65 | depends on SND_SOC_INTEL_BAYTRAIL | ||
66 | select SND_SOC_RT5640 | 63 | select SND_SOC_RT5640 |
67 | help | 64 | help |
68 | This adds audio driver for Intel Baytrail platform based boards | 65 | This adds audio driver for Intel Baytrail platform based boards |
69 | with the RT5640 audio codec. This driver is deprecated, use | 66 | with the RT5640 audio codec. This driver is deprecated, use |
70 | SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality. | 67 | SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality. |
71 | 68 | ||
69 | endif ## SND_SOC_INTEL_BAYTRAIL | ||
70 | |||
71 | if SND_SST_ATOM_HIFI2_PLATFORM | ||
72 | |||
72 | config SND_SOC_INTEL_BYTCR_RT5640_MACH | 73 | config SND_SOC_INTEL_BYTCR_RT5640_MACH |
73 | tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5640 codec" | 74 | tristate "Baytrail and Baytrail-CR with RT5640 codec" |
74 | depends on X86 && I2C && ACPI | 75 | depends on X86_INTEL_LPSS && I2C && ACPI |
76 | select SND_SOC_ACPI | ||
75 | select SND_SOC_RT5640 | 77 | select SND_SOC_RT5640 |
76 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
77 | select SND_SST_IPC_ACPI | ||
78 | help | 78 | help |
79 | This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR | 79 | This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR |
80 | platforms with RT5640 audio codec. | 80 | platforms with RT5640 audio codec. |
81 | Say Y if you have such a device. | 81 | Say Y or m if you have such a device. This is a recommended option. |
82 | If unsure select "N". | 82 | If unsure select "N". |
83 | 83 | ||
84 | config SND_SOC_INTEL_BYTCR_RT5651_MACH | 84 | config SND_SOC_INTEL_BYTCR_RT5651_MACH |
85 | tristate "ASoC Audio driver for Intel Baytrail and Baytrail-CR with RT5651 codec" | 85 | tristate "Baytrail and Baytrail-CR with RT5651 codec" |
86 | depends on X86 && I2C && ACPI | 86 | depends on X86_INTEL_LPSS && I2C && ACPI |
87 | select SND_SOC_ACPI | ||
87 | select SND_SOC_RT5651 | 88 | select SND_SOC_RT5651 |
88 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
89 | select SND_SST_IPC_ACPI | ||
90 | help | 89 | help |
91 | This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR | 90 | This adds support for ASoC machine driver for Intel(R) Baytrail and Baytrail-CR |
92 | platforms with RT5651 audio codec. | 91 | platforms with RT5651 audio codec. |
93 | Say Y if you have such a device. | 92 | Say Y or m if you have such a device. This is a recommended option. |
94 | If unsure select "N". | 93 | If unsure select "N". |
95 | 94 | ||
96 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH | 95 | config SND_SOC_INTEL_CHT_BSW_RT5672_MACH |
97 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5672 codec" | 96 | tristate "Cherrytrail & Braswell with RT5672 codec" |
98 | depends on X86_INTEL_LPSS && I2C && ACPI | 97 | depends on X86_INTEL_LPSS && I2C && ACPI |
99 | select SND_SOC_RT5670 | 98 | select SND_SOC_ACPI |
100 | depends on SND_SST_ATOM_HIFI2_PLATFORM | 99 | select SND_SOC_RT5670 |
101 | select SND_SST_IPC_ACPI | ||
102 | help | 100 | help |
103 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell | 101 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell |
104 | platforms with RT5672 audio codec. | 102 | platforms with RT5672 audio codec. |
105 | Say Y if you have such a device. | 103 | Say Y or m if you have such a device. This is a recommended option. |
106 | If unsure select "N". | 104 | If unsure select "N". |
107 | 105 | ||
108 | config SND_SOC_INTEL_CHT_BSW_RT5645_MACH | 106 | config SND_SOC_INTEL_CHT_BSW_RT5645_MACH |
109 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with RT5645/5650 codec" | 107 | tristate "Cherrytrail & Braswell with RT5645/5650 codec" |
110 | depends on X86_INTEL_LPSS && I2C && ACPI | 108 | depends on X86_INTEL_LPSS && I2C && ACPI |
109 | select SND_SOC_ACPI | ||
111 | select SND_SOC_RT5645 | 110 | select SND_SOC_RT5645 |
112 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
113 | select SND_SST_IPC_ACPI | ||
114 | help | 111 | help |
115 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell | 112 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell |
116 | platforms with RT5645/5650 audio codec. | 113 | platforms with RT5645/5650 audio codec. |
114 | Say Y or m if you have such a device. This is a recommended option. | ||
117 | If unsure select "N". | 115 | If unsure select "N". |
118 | 116 | ||
119 | config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH | 117 | config SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH |
120 | tristate "ASoC Audio driver for Intel Cherrytrail & Braswell with MAX98090 & TI codec" | 118 | tristate "Cherrytrail & Braswell with MAX98090 & TI codec" |
121 | depends on X86_INTEL_LPSS && I2C && ACPI | 119 | depends on X86_INTEL_LPSS && I2C && ACPI |
122 | select SND_SOC_MAX98090 | 120 | select SND_SOC_MAX98090 |
123 | select SND_SOC_TS3A227E | 121 | select SND_SOC_TS3A227E |
124 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
125 | select SND_SST_IPC_ACPI | ||
126 | help | 122 | help |
127 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell | 123 | This adds support for ASoC machine driver for Intel(R) Cherrytrail & Braswell |
128 | platforms with MAX98090 audio codec it also can support TI jack chip as aux device. | 124 | platforms with MAX98090 audio codec it also can support TI jack chip as aux device. |
125 | Say Y or m if you have such a device. This is a recommended option. | ||
129 | If unsure select "N". | 126 | If unsure select "N". |
130 | 127 | ||
131 | config SND_SOC_INTEL_BYT_CHT_DA7213_MACH | 128 | config SND_SOC_INTEL_BYT_CHT_DA7213_MACH |
132 | tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with DA7212/7213 codec" | 129 | tristate "Baytrail & Cherrytrail with DA7212/7213 codec" |
133 | depends on X86_INTEL_LPSS && I2C && ACPI | 130 | depends on X86_INTEL_LPSS && I2C && ACPI |
131 | select SND_SOC_ACPI | ||
134 | select SND_SOC_DA7213 | 132 | select SND_SOC_DA7213 |
135 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
136 | select SND_SST_IPC_ACPI | ||
137 | help | 133 | help |
138 | This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail | 134 | This adds support for ASoC machine driver for Intel(R) Baytrail & CherryTrail |
139 | platforms with DA7212/7213 audio codec. | 135 | platforms with DA7212/7213 audio codec. |
136 | Say Y or m if you have such a device. This is a recommended option. | ||
140 | If unsure select "N". | 137 | If unsure select "N". |
141 | 138 | ||
142 | config SND_SOC_INTEL_BYT_CHT_ES8316_MACH | 139 | config SND_SOC_INTEL_BYT_CHT_ES8316_MACH |
143 | tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail with ES8316 codec" | 140 | tristate "Baytrail & Cherrytrail with ES8316 codec" |
144 | depends on X86_INTEL_LPSS && I2C && ACPI | 141 | depends on X86_INTEL_LPSS && I2C && ACPI |
142 | select SND_SOC_ACPI | ||
145 | select SND_SOC_ES8316 | 143 | select SND_SOC_ES8316 |
146 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
147 | select SND_SST_IPC_ACPI | ||
148 | help | 144 | help |
149 | This adds support for ASoC machine driver for Intel(R) Baytrail & | 145 | This adds support for ASoC machine driver for Intel(R) Baytrail & |
150 | Cherrytrail platforms with ES8316 audio codec. | 146 | Cherrytrail platforms with ES8316 audio codec. |
147 | Say Y or m if you have such a device. This is a recommended option. | ||
151 | If unsure select "N". | 148 | If unsure select "N". |
152 | 149 | ||
153 | config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH | 150 | config SND_SOC_INTEL_BYT_CHT_NOCODEC_MACH |
154 | tristate "ASoC Audio driver for Intel Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)" | 151 | tristate "Baytrail & Cherrytrail platform with no codec (MinnowBoard MAX, Up)" |
155 | depends on X86_INTEL_LPSS && I2C && ACPI | 152 | depends on X86_INTEL_LPSS && I2C && ACPI |
156 | depends on SND_SST_ATOM_HIFI2_PLATFORM | ||
157 | select SND_SST_IPC_ACPI | ||
158 | help | 153 | help |
159 | This adds support for ASoC machine driver for the MinnowBoard Max or | 154 | This adds support for ASoC machine driver for the MinnowBoard Max or |
160 | Up boards and provides access to I2S signals on the Low-Speed | 155 | Up boards and provides access to I2S signals on the Low-Speed |
161 | connector | 156 | connector. This is not a recommended option outside of these cases. |
157 | It is not intended to be enabled by distros by default. | ||
158 | Say Y or m if you have such a device. | ||
159 | |||
162 | If unsure select "N". | 160 | If unsure select "N". |
163 | 161 | ||
162 | endif ## SND_SST_ATOM_HIFI2_PLATFORM | ||
163 | |||
164 | if SND_SOC_INTEL_SKYLAKE | ||
165 | |||
164 | config SND_SOC_INTEL_SKL_RT286_MACH | 166 | config SND_SOC_INTEL_SKL_RT286_MACH |
165 | tristate "ASoC Audio driver for SKL with RT286 I2S mode" | 167 | tristate "SKL with RT286 I2S mode" |
166 | depends on X86 && ACPI && I2C | 168 | depends on MFD_INTEL_LPSS && I2C && ACPI |
167 | depends on SND_SOC_INTEL_SKYLAKE | ||
168 | select SND_SOC_RT286 | 169 | select SND_SOC_RT286 |
169 | select SND_SOC_DMIC | 170 | select SND_SOC_DMIC |
170 | select SND_SOC_HDAC_HDMI | 171 | select SND_SOC_HDAC_HDMI |
171 | help | 172 | help |
172 | This adds support for ASoC machine driver for Skylake platforms | 173 | This adds support for ASoC machine driver for Skylake platforms |
173 | with RT286 I2S audio codec. | 174 | with RT286 I2S audio codec. |
174 | Say Y if you have such a device. | 175 | Say Y or m if you have such a device. |
175 | If unsure select "N". | 176 | If unsure select "N". |
176 | 177 | ||
177 | config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH | 178 | config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH |
178 | tristate "ASoC Audio driver for SKL with NAU88L25 and SSM4567 in I2S Mode" | 179 | tristate "SKL with NAU88L25 and SSM4567 in I2S Mode" |
179 | depends on X86_INTEL_LPSS && I2C | 180 | depends on MFD_INTEL_LPSS && I2C && ACPI |
180 | depends on SND_SOC_INTEL_SKYLAKE | ||
181 | select SND_SOC_NAU8825 | 181 | select SND_SOC_NAU8825 |
182 | select SND_SOC_SSM4567 | 182 | select SND_SOC_SSM4567 |
183 | select SND_SOC_DMIC | 183 | select SND_SOC_DMIC |
@@ -185,13 +185,12 @@ config SND_SOC_INTEL_SKL_NAU88L25_SSM4567_MACH | |||
185 | help | 185 | help |
186 | This adds support for ASoC Onboard Codec I2S machine driver. This will | 186 | This adds support for ASoC Onboard Codec I2S machine driver. This will |
187 | create an alsa sound card for NAU88L25 + SSM4567. | 187 | create an alsa sound card for NAU88L25 + SSM4567. |
188 | Say Y if you have such a device. | 188 | Say Y or m if you have such a device. This is a recommended option. |
189 | If unsure select "N". | 189 | If unsure select "N". |
190 | 190 | ||
191 | config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH | 191 | config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH |
192 | tristate "ASoC Audio driver for SKL with NAU88L25 and MAX98357A in I2S Mode" | 192 | tristate "SKL with NAU88L25 and MAX98357A in I2S Mode" |
193 | depends on X86_INTEL_LPSS && I2C | 193 | depends on MFD_INTEL_LPSS && I2C && ACPI |
194 | depends on SND_SOC_INTEL_SKYLAKE | ||
195 | select SND_SOC_NAU8825 | 194 | select SND_SOC_NAU8825 |
196 | select SND_SOC_MAX98357A | 195 | select SND_SOC_MAX98357A |
197 | select SND_SOC_DMIC | 196 | select SND_SOC_DMIC |
@@ -199,13 +198,12 @@ config SND_SOC_INTEL_SKL_NAU88L25_MAX98357A_MACH | |||
199 | help | 198 | help |
200 | This adds support for ASoC Onboard Codec I2S machine driver. This will | 199 | This adds support for ASoC Onboard Codec I2S machine driver. This will |
201 | create an alsa sound card for NAU88L25 + MAX98357A. | 200 | create an alsa sound card for NAU88L25 + MAX98357A. |
202 | Say Y if you have such a device. | 201 | Say Y or m if you have such a device. This is a recommended option. |
203 | If unsure select "N". | 202 | If unsure select "N". |
204 | 203 | ||
205 | config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH | 204 | config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH |
206 | tristate "ASoC Audio driver for Broxton with DA7219 and MAX98357A in I2S Mode" | 205 | tristate "Broxton with DA7219 and MAX98357A in I2S Mode" |
207 | depends on X86 && ACPI && I2C | 206 | depends on MFD_INTEL_LPSS && I2C && ACPI |
208 | depends on SND_SOC_INTEL_SKYLAKE | ||
209 | select SND_SOC_DA7219 | 207 | select SND_SOC_DA7219 |
210 | select SND_SOC_MAX98357A | 208 | select SND_SOC_MAX98357A |
211 | select SND_SOC_DMIC | 209 | select SND_SOC_DMIC |
@@ -214,13 +212,12 @@ config SND_SOC_INTEL_BXT_DA7219_MAX98357A_MACH | |||
214 | help | 212 | help |
215 | This adds support for ASoC machine driver for Broxton-P platforms | 213 | This adds support for ASoC machine driver for Broxton-P platforms |
216 | with DA7219 + MAX98357A I2S audio codec. | 214 | with DA7219 + MAX98357A I2S audio codec. |
217 | Say Y if you have such a device. | 215 | Say Y or m if you have such a device. This is a recommended option. |
218 | If unsure select "N". | 216 | If unsure select "N". |
219 | 217 | ||
220 | config SND_SOC_INTEL_BXT_RT298_MACH | 218 | config SND_SOC_INTEL_BXT_RT298_MACH |
221 | tristate "ASoC Audio driver for Broxton with RT298 I2S mode" | 219 | tristate "Broxton with RT298 I2S mode" |
222 | depends on X86 && ACPI && I2C | 220 | depends on MFD_INTEL_LPSS && I2C && ACPI |
223 | depends on SND_SOC_INTEL_SKYLAKE | ||
224 | select SND_SOC_RT298 | 221 | select SND_SOC_RT298 |
225 | select SND_SOC_DMIC | 222 | select SND_SOC_DMIC |
226 | select SND_SOC_HDAC_HDMI | 223 | select SND_SOC_HDAC_HDMI |
@@ -228,14 +225,12 @@ config SND_SOC_INTEL_BXT_RT298_MACH | |||
228 | help | 225 | help |
229 | This adds support for ASoC machine driver for Broxton platforms | 226 | This adds support for ASoC machine driver for Broxton platforms |
230 | with RT286 I2S audio codec. | 227 | with RT286 I2S audio codec. |
231 | Say Y if you have such a device. | 228 | Say Y or m if you have such a device. This is a recommended option. |
232 | If unsure select "N". | 229 | If unsure select "N". |
233 | 230 | ||
234 | config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH | 231 | config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH |
235 | tristate "ASoC Audio driver for KBL with RT5663 and MAX98927 in I2S Mode" | 232 | tristate "KBL with RT5663 and MAX98927 in I2S Mode" |
236 | depends on X86_INTEL_LPSS && I2C | 233 | depends on MFD_INTEL_LPSS && I2C && ACPI |
237 | select SND_SOC_INTEL_SST | ||
238 | depends on SND_SOC_INTEL_SKYLAKE | ||
239 | select SND_SOC_RT5663 | 234 | select SND_SOC_RT5663 |
240 | select SND_SOC_MAX98927 | 235 | select SND_SOC_MAX98927 |
241 | select SND_SOC_DMIC | 236 | select SND_SOC_DMIC |
@@ -243,14 +238,13 @@ config SND_SOC_INTEL_KBL_RT5663_MAX98927_MACH | |||
243 | help | 238 | help |
244 | This adds support for ASoC Onboard Codec I2S machine driver. This will | 239 | This adds support for ASoC Onboard Codec I2S machine driver. This will |
245 | create an alsa sound card for RT5663 + MAX98927. | 240 | create an alsa sound card for RT5663 + MAX98927. |
246 | Say Y if you have such a device. | 241 | Say Y or m if you have such a device. This is a recommended option. |
247 | If unsure select "N". | 242 | If unsure select "N". |
248 | 243 | ||
249 | config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH | 244 | config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH |
250 | tristate "ASoC Audio driver for KBL with RT5663, RT5514 and MAX98927 in I2S Mode" | 245 | tristate "KBL with RT5663, RT5514 and MAX98927 in I2S Mode" |
251 | depends on X86_INTEL_LPSS && I2C && SPI | 246 | depends on MFD_INTEL_LPSS && I2C && ACPI |
252 | select SND_SOC_INTEL_SST | 247 | depends on SPI |
253 | depends on SND_SOC_INTEL_SKYLAKE | ||
254 | select SND_SOC_RT5663 | 248 | select SND_SOC_RT5663 |
255 | select SND_SOC_RT5514 | 249 | select SND_SOC_RT5514 |
256 | select SND_SOC_RT5514_SPI | 250 | select SND_SOC_RT5514_SPI |
@@ -259,7 +253,8 @@ config SND_SOC_INTEL_KBL_RT5663_RT5514_MAX98927_MACH | |||
259 | help | 253 | help |
260 | This adds support for ASoC Onboard Codec I2S machine driver. This will | 254 | This adds support for ASoC Onboard Codec I2S machine driver. This will |
261 | create an alsa sound card for RT5663 + RT5514 + MAX98927. | 255 | create an alsa sound card for RT5663 + RT5514 + MAX98927. |
262 | Say Y if you have such a device. | 256 | Say Y or m if you have such a device. This is a recommended option. |
263 | If unsure select "N". | 257 | If unsure select "N". |
258 | endif ## SND_SOC_INTEL_SKYLAKE | ||
264 | 259 | ||
265 | endif | 260 | endif ## SND_SOC_INTEL_MACH |
diff --git a/sound/soc/intel/boards/bytcht_da7213.c b/sound/soc/intel/boards/bytcht_da7213.c index c4d82ad41bd7..2179dedb28ad 100644 --- a/sound/soc/intel/boards/bytcht_da7213.c +++ b/sound/soc/intel/boards/bytcht_da7213.c | |||
@@ -219,7 +219,7 @@ static struct snd_soc_card bytcht_da7213_card = { | |||
219 | .num_dapm_routes = ARRAY_SIZE(audio_map), | 219 | .num_dapm_routes = ARRAY_SIZE(audio_map), |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static char codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 222 | static char codec_name[SND_ACPI_I2C_ID_LEN]; |
223 | 223 | ||
224 | static int bytcht_da7213_probe(struct platform_device *pdev) | 224 | static int bytcht_da7213_probe(struct platform_device *pdev) |
225 | { | 225 | { |
@@ -243,7 +243,7 @@ static int bytcht_da7213_probe(struct platform_device *pdev) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | /* fixup codec name based on HID */ | 245 | /* fixup codec name based on HID */ |
246 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 246 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
247 | if (i2c_name) { | 247 | if (i2c_name) { |
248 | snprintf(codec_name, sizeof(codec_name), | 248 | snprintf(codec_name, sizeof(codec_name), |
249 | "%s%s", "i2c-", i2c_name); | 249 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 8088396717e3..305e7f4fe55a 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c | |||
@@ -232,15 +232,39 @@ static struct snd_soc_card byt_cht_es8316_card = { | |||
232 | .fully_routed = true, | 232 | .fully_routed = true, |
233 | }; | 233 | }; |
234 | 234 | ||
235 | static char codec_name[SND_ACPI_I2C_ID_LEN]; | ||
236 | |||
235 | static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) | 237 | static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) |
236 | { | 238 | { |
237 | int ret = 0; | ||
238 | struct byt_cht_es8316_private *priv; | 239 | struct byt_cht_es8316_private *priv; |
240 | struct snd_soc_acpi_mach *mach; | ||
241 | const char *i2c_name = NULL; | ||
242 | int dai_index = 0; | ||
243 | int i; | ||
244 | int ret = 0; | ||
239 | 245 | ||
240 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); | 246 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC); |
241 | if (!priv) | 247 | if (!priv) |
242 | return -ENOMEM; | 248 | return -ENOMEM; |
243 | 249 | ||
250 | mach = (&pdev->dev)->platform_data; | ||
251 | /* fix index of codec dai */ | ||
252 | for (i = 0; i < ARRAY_SIZE(byt_cht_es8316_dais); i++) { | ||
253 | if (!strcmp(byt_cht_es8316_dais[i].codec_name, | ||
254 | "i2c-ESSX8316:00")) { | ||
255 | dai_index = i; | ||
256 | break; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | /* fixup codec name based on HID */ | ||
261 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); | ||
262 | if (i2c_name) { | ||
263 | snprintf(codec_name, sizeof(codec_name), | ||
264 | "%s%s", "i2c-", i2c_name); | ||
265 | byt_cht_es8316_dais[dai_index].codec_name = codec_name; | ||
266 | } | ||
267 | |||
244 | /* register the soc card */ | 268 | /* register the soc card */ |
245 | byt_cht_es8316_card.dev = &pdev->dev; | 269 | byt_cht_es8316_card.dev = &pdev->dev; |
246 | snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv); | 270 | snd_soc_card_set_drvdata(&byt_cht_es8316_card, priv); |
diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index f2c0fc415e52..b6a1cfeec830 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c | |||
@@ -713,7 +713,7 @@ static struct snd_soc_card byt_rt5640_card = { | |||
713 | .fully_routed = true, | 713 | .fully_routed = true, |
714 | }; | 714 | }; |
715 | 715 | ||
716 | static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 716 | static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN]; |
717 | static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ | 717 | static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */ |
718 | static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ | 718 | static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ |
719 | 719 | ||
@@ -762,7 +762,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) | |||
762 | } | 762 | } |
763 | 763 | ||
764 | /* fixup codec name based on HID */ | 764 | /* fixup codec name based on HID */ |
765 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 765 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
766 | if (i2c_name) { | 766 | if (i2c_name) { |
767 | snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), | 767 | snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), |
768 | "%s%s", "i2c-", i2c_name); | 768 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index d955836c6870..456526a93dd5 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c | |||
@@ -38,6 +38,8 @@ enum { | |||
38 | BYT_RT5651_DMIC_MAP, | 38 | BYT_RT5651_DMIC_MAP, |
39 | BYT_RT5651_IN1_MAP, | 39 | BYT_RT5651_IN1_MAP, |
40 | BYT_RT5651_IN2_MAP, | 40 | BYT_RT5651_IN2_MAP, |
41 | BYT_RT5651_IN1_IN2_MAP, | ||
42 | BYT_RT5651_IN3_MAP, | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | #define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(7, 0)) | 45 | #define BYT_RT5651_MAP(quirk) ((quirk) & GENMASK(7, 0)) |
@@ -62,6 +64,8 @@ static void log_quirks(struct device *dev) | |||
62 | dev_info(dev, "quirk IN1_MAP enabled"); | 64 | dev_info(dev, "quirk IN1_MAP enabled"); |
63 | if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP) | 65 | if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN2_MAP) |
64 | dev_info(dev, "quirk IN2_MAP enabled"); | 66 | dev_info(dev, "quirk IN2_MAP enabled"); |
67 | if (BYT_RT5651_MAP(byt_rt5651_quirk) == BYT_RT5651_IN3_MAP) | ||
68 | dev_info(dev, "quirk IN3_MAP enabled"); | ||
65 | if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN) | 69 | if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN) |
66 | dev_info(dev, "quirk DMIC enabled"); | 70 | dev_info(dev, "quirk DMIC enabled"); |
67 | if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) | 71 | if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) |
@@ -127,6 +131,7 @@ static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = { | |||
127 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 131 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
128 | SND_SOC_DAPM_MIC("Internal Mic", NULL), | 132 | SND_SOC_DAPM_MIC("Internal Mic", NULL), |
129 | SND_SOC_DAPM_SPK("Speaker", NULL), | 133 | SND_SOC_DAPM_SPK("Speaker", NULL), |
134 | SND_SOC_DAPM_LINE("Line In", NULL), | ||
130 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, | 135 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, |
131 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | | 136 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | |
132 | SND_SOC_DAPM_POST_PMD), | 137 | SND_SOC_DAPM_POST_PMD), |
@@ -138,6 +143,7 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { | |||
138 | {"Headset Mic", NULL, "Platform Clock"}, | 143 | {"Headset Mic", NULL, "Platform Clock"}, |
139 | {"Internal Mic", NULL, "Platform Clock"}, | 144 | {"Internal Mic", NULL, "Platform Clock"}, |
140 | {"Speaker", NULL, "Platform Clock"}, | 145 | {"Speaker", NULL, "Platform Clock"}, |
146 | {"Line In", NULL, "Platform Clock"}, | ||
141 | 147 | ||
142 | {"AIF1 Playback", NULL, "ssp2 Tx"}, | 148 | {"AIF1 Playback", NULL, "ssp2 Tx"}, |
143 | {"ssp2 Tx", NULL, "codec_out0"}, | 149 | {"ssp2 Tx", NULL, "codec_out0"}, |
@@ -151,6 +157,9 @@ static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = { | |||
151 | {"Headphone", NULL, "HPOR"}, | 157 | {"Headphone", NULL, "HPOR"}, |
152 | {"Speaker", NULL, "LOUTL"}, | 158 | {"Speaker", NULL, "LOUTL"}, |
153 | {"Speaker", NULL, "LOUTR"}, | 159 | {"Speaker", NULL, "LOUTR"}, |
160 | {"IN2P", NULL, "Line In"}, | ||
161 | {"IN2N", NULL, "Line In"}, | ||
162 | |||
154 | }; | 163 | }; |
155 | 164 | ||
156 | static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = { | 165 | static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = { |
@@ -171,11 +180,25 @@ static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = { | |||
171 | {"IN2P", NULL, "Internal Mic"}, | 180 | {"IN2P", NULL, "Internal Mic"}, |
172 | }; | 181 | }; |
173 | 182 | ||
183 | static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map[] = { | ||
184 | {"Internal Mic", NULL, "micbias1"}, | ||
185 | {"IN1P", NULL, "Internal Mic"}, | ||
186 | {"IN2P", NULL, "Internal Mic"}, | ||
187 | {"IN3P", NULL, "Headset Mic"}, | ||
188 | }; | ||
189 | |||
190 | static const struct snd_soc_dapm_route byt_rt5651_intmic_in3_map[] = { | ||
191 | {"Internal Mic", NULL, "micbias1"}, | ||
192 | {"IN3P", NULL, "Headset Mic"}, | ||
193 | {"IN1P", NULL, "Internal Mic"}, | ||
194 | }; | ||
195 | |||
174 | static const struct snd_kcontrol_new byt_rt5651_controls[] = { | 196 | static const struct snd_kcontrol_new byt_rt5651_controls[] = { |
175 | SOC_DAPM_PIN_SWITCH("Headphone"), | 197 | SOC_DAPM_PIN_SWITCH("Headphone"), |
176 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 198 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
177 | SOC_DAPM_PIN_SWITCH("Internal Mic"), | 199 | SOC_DAPM_PIN_SWITCH("Internal Mic"), |
178 | SOC_DAPM_PIN_SWITCH("Speaker"), | 200 | SOC_DAPM_PIN_SWITCH("Speaker"), |
201 | SOC_DAPM_PIN_SWITCH("Line In"), | ||
179 | }; | 202 | }; |
180 | 203 | ||
181 | static struct snd_soc_jack_pin bytcr_jack_pins[] = { | 204 | static struct snd_soc_jack_pin bytcr_jack_pins[] = { |
@@ -247,8 +270,16 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { | |||
247 | DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), | 270 | DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"), |
248 | DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), | 271 | DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"), |
249 | }, | 272 | }, |
250 | .driver_data = (void *)(BYT_RT5651_DMIC_MAP | | 273 | .driver_data = (void *)(BYT_RT5651_IN3_MAP), |
251 | BYT_RT5651_DMIC_EN), | 274 | }, |
275 | { | ||
276 | .callback = byt_rt5651_quirk_cb, | ||
277 | .matches = { | ||
278 | DMI_MATCH(DMI_SYS_VENDOR, "ADI"), | ||
279 | DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"), | ||
280 | }, | ||
281 | .driver_data = (void *)(BYT_RT5651_MCLK_EN | | ||
282 | BYT_RT5651_IN3_MAP), | ||
252 | }, | 283 | }, |
253 | { | 284 | { |
254 | .callback = byt_rt5651_quirk_cb, | 285 | .callback = byt_rt5651_quirk_cb, |
@@ -256,7 +287,8 @@ static const struct dmi_system_id byt_rt5651_quirk_table[] = { | |||
256 | DMI_MATCH(DMI_SYS_VENDOR, "KIANO"), | 287 | DMI_MATCH(DMI_SYS_VENDOR, "KIANO"), |
257 | DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"), | 288 | DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"), |
258 | }, | 289 | }, |
259 | .driver_data = (void *)(BYT_RT5651_IN2_MAP), | 290 | .driver_data = (void *)(BYT_RT5651_MCLK_EN | |
291 | BYT_RT5651_IN1_IN2_MAP), | ||
260 | }, | 292 | }, |
261 | {} | 293 | {} |
262 | }; | 294 | }; |
@@ -281,6 +313,14 @@ static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime) | |||
281 | custom_map = byt_rt5651_intmic_in2_map; | 313 | custom_map = byt_rt5651_intmic_in2_map; |
282 | num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map); | 314 | num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map); |
283 | break; | 315 | break; |
316 | case BYT_RT5651_IN1_IN2_MAP: | ||
317 | custom_map = byt_rt5651_intmic_in1_in2_map; | ||
318 | num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map); | ||
319 | break; | ||
320 | case BYT_RT5651_IN3_MAP: | ||
321 | custom_map = byt_rt5651_intmic_in3_map; | ||
322 | num_routes = ARRAY_SIZE(byt_rt5651_intmic_in3_map); | ||
323 | break; | ||
284 | default: | 324 | default: |
285 | custom_map = byt_rt5651_intmic_dmic_map; | 325 | custom_map = byt_rt5651_intmic_dmic_map; |
286 | num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map); | 326 | num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map); |
@@ -469,7 +509,7 @@ static struct snd_soc_card byt_rt5651_card = { | |||
469 | .fully_routed = true, | 509 | .fully_routed = true, |
470 | }; | 510 | }; |
471 | 511 | ||
472 | static char byt_rt5651_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 512 | static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN]; |
473 | 513 | ||
474 | static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) | 514 | static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) |
475 | { | 515 | { |
@@ -499,7 +539,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) | |||
499 | } | 539 | } |
500 | 540 | ||
501 | /* fixup codec name based on HID */ | 541 | /* fixup codec name based on HID */ |
502 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 542 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
503 | if (i2c_name) { | 543 | if (i2c_name) { |
504 | snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), | 544 | snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), |
505 | "%s%s", "i2c-", i2c_name); | 545 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/cht_bsw_rt5645.c b/sound/soc/intel/boards/cht_bsw_rt5645.c index 18d129caa974..31641aab62cd 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5645.c +++ b/sound/soc/intel/boards/cht_bsw_rt5645.c | |||
@@ -49,7 +49,7 @@ struct cht_acpi_card { | |||
49 | struct cht_mc_private { | 49 | struct cht_mc_private { |
50 | struct snd_soc_jack jack; | 50 | struct snd_soc_jack jack; |
51 | struct cht_acpi_card *acpi_card; | 51 | struct cht_acpi_card *acpi_card; |
52 | char codec_name[16]; | 52 | char codec_name[SND_ACPI_I2C_ID_LEN]; |
53 | struct clk *mclk; | 53 | struct clk *mclk; |
54 | }; | 54 | }; |
55 | 55 | ||
@@ -118,6 +118,7 @@ static const struct snd_soc_dapm_widget cht_dapm_widgets[] = { | |||
118 | SND_SOC_DAPM_HP("Headphone", NULL), | 118 | SND_SOC_DAPM_HP("Headphone", NULL), |
119 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 119 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
120 | SND_SOC_DAPM_MIC("Int Mic", NULL), | 120 | SND_SOC_DAPM_MIC("Int Mic", NULL), |
121 | SND_SOC_DAPM_MIC("Int Analog Mic", NULL), | ||
121 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | 122 | SND_SOC_DAPM_SPK("Ext Spk", NULL), |
122 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, | 123 | SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0, |
123 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 124 | platform_clock_control, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
@@ -128,6 +129,8 @@ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { | |||
128 | {"IN1N", NULL, "Headset Mic"}, | 129 | {"IN1N", NULL, "Headset Mic"}, |
129 | {"DMIC L1", NULL, "Int Mic"}, | 130 | {"DMIC L1", NULL, "Int Mic"}, |
130 | {"DMIC R1", NULL, "Int Mic"}, | 131 | {"DMIC R1", NULL, "Int Mic"}, |
132 | {"IN2P", NULL, "Int Analog Mic"}, | ||
133 | {"IN2N", NULL, "Int Analog Mic"}, | ||
131 | {"Headphone", NULL, "HPOL"}, | 134 | {"Headphone", NULL, "HPOL"}, |
132 | {"Headphone", NULL, "HPOR"}, | 135 | {"Headphone", NULL, "HPOR"}, |
133 | {"Ext Spk", NULL, "SPOL"}, | 136 | {"Ext Spk", NULL, "SPOL"}, |
@@ -135,6 +138,9 @@ static const struct snd_soc_dapm_route cht_rt5645_audio_map[] = { | |||
135 | {"Headphone", NULL, "Platform Clock"}, | 138 | {"Headphone", NULL, "Platform Clock"}, |
136 | {"Headset Mic", NULL, "Platform Clock"}, | 139 | {"Headset Mic", NULL, "Platform Clock"}, |
137 | {"Int Mic", NULL, "Platform Clock"}, | 140 | {"Int Mic", NULL, "Platform Clock"}, |
141 | {"Int Analog Mic", NULL, "Platform Clock"}, | ||
142 | {"Int Analog Mic", NULL, "micbias1"}, | ||
143 | {"Int Analog Mic", NULL, "micbias2"}, | ||
138 | {"Ext Spk", NULL, "Platform Clock"}, | 144 | {"Ext Spk", NULL, "Platform Clock"}, |
139 | }; | 145 | }; |
140 | 146 | ||
@@ -189,6 +195,7 @@ static const struct snd_kcontrol_new cht_mc_controls[] = { | |||
189 | SOC_DAPM_PIN_SWITCH("Headphone"), | 195 | SOC_DAPM_PIN_SWITCH("Headphone"), |
190 | SOC_DAPM_PIN_SWITCH("Headset Mic"), | 196 | SOC_DAPM_PIN_SWITCH("Headset Mic"), |
191 | SOC_DAPM_PIN_SWITCH("Int Mic"), | 197 | SOC_DAPM_PIN_SWITCH("Int Mic"), |
198 | SOC_DAPM_PIN_SWITCH("Int Analog Mic"), | ||
192 | SOC_DAPM_PIN_SWITCH("Ext Spk"), | 199 | SOC_DAPM_PIN_SWITCH("Ext Spk"), |
193 | }; | 200 | }; |
194 | 201 | ||
@@ -499,7 +506,7 @@ static struct cht_acpi_card snd_soc_cards[] = { | |||
499 | {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650}, | 506 | {"10EC5650", CODEC_TYPE_RT5650, &snd_soc_card_chtrt5650}, |
500 | }; | 507 | }; |
501 | 508 | ||
502 | static char cht_rt5645_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */ | 509 | static char cht_rt5645_codec_name[SND_ACPI_I2C_ID_LEN]; |
503 | static char cht_rt5645_codec_aif_name[12]; /* = "rt5645-aif[1|2]" */ | 510 | static char cht_rt5645_codec_aif_name[12]; /* = "rt5645-aif[1|2]" */ |
504 | static char cht_rt5645_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ | 511 | static char cht_rt5645_cpu_dai_name[10]; /* = "ssp[0|2]-port" */ |
505 | 512 | ||
@@ -566,7 +573,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
566 | } | 573 | } |
567 | 574 | ||
568 | /* fixup codec name based on HID */ | 575 | /* fixup codec name based on HID */ |
569 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 576 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
570 | if (i2c_name) { | 577 | if (i2c_name) { |
571 | snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), | 578 | snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name), |
572 | "%s%s", "i2c-", i2c_name); | 579 | "%s%s", "i2c-", i2c_name); |
diff --git a/sound/soc/intel/boards/cht_bsw_rt5672.c b/sound/soc/intel/boards/cht_bsw_rt5672.c index f8f21eee9b2d..c14a52d2f714 100644 --- a/sound/soc/intel/boards/cht_bsw_rt5672.c +++ b/sound/soc/intel/boards/cht_bsw_rt5672.c | |||
@@ -35,7 +35,7 @@ | |||
35 | 35 | ||
36 | struct cht_mc_private { | 36 | struct cht_mc_private { |
37 | struct snd_soc_jack headset; | 37 | struct snd_soc_jack headset; |
38 | char codec_name[16]; | 38 | char codec_name[SND_ACPI_I2C_ID_LEN]; |
39 | struct clk *mclk; | 39 | struct clk *mclk; |
40 | }; | 40 | }; |
41 | 41 | ||
@@ -396,7 +396,7 @@ static int snd_cht_mc_probe(struct platform_device *pdev) | |||
396 | 396 | ||
397 | /* fixup codec name based on HID */ | 397 | /* fixup codec name based on HID */ |
398 | if (mach) { | 398 | if (mach) { |
399 | i2c_name = snd_soc_acpi_find_name_from_hid(mach->id); | 399 | i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1); |
400 | if (i2c_name) { | 400 | if (i2c_name) { |
401 | snprintf(drv->codec_name, sizeof(drv->codec_name), | 401 | snprintf(drv->codec_name, sizeof(drv->codec_name), |
402 | "i2c-%s", i2c_name); | 402 | "i2c-%s", i2c_name); |
diff --git a/sound/soc/intel/boards/haswell.c b/sound/soc/intel/boards/haswell.c index 5e1ea0371c90..3c5160779204 100644 --- a/sound/soc/intel/boards/haswell.c +++ b/sound/soc/intel/boards/haswell.c | |||
@@ -76,7 +76,7 @@ static int haswell_rt5640_hw_params(struct snd_pcm_substream *substream, | |||
76 | } | 76 | } |
77 | 77 | ||
78 | /* set correct codec filter for DAI format and clock config */ | 78 | /* set correct codec filter for DAI format and clock config */ |
79 | snd_soc_update_bits(rtd->codec, 0x83, 0xffff, 0x8000); | 79 | snd_soc_component_update_bits(codec_dai->component, 0x83, 0xffff, 0x8000); |
80 | 80 | ||
81 | return ret; | 81 | return ret; |
82 | } | 82 | } |
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 6dcad0a8a0d0..bf7014ca486f 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c | |||
@@ -225,7 +225,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | jack = &ctx->kabylake_headset; | 227 | jack = &ctx->kabylake_headset; |
228 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); | 228 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
229 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); | 229 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
230 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | 230 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
231 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | 231 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); |
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 271ae3c2c535..90ea98f01c4c 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | |||
@@ -195,7 +195,7 @@ static int kabylake_rt5663_codec_init(struct snd_soc_pcm_runtime *rtd) | |||
195 | } | 195 | } |
196 | 196 | ||
197 | jack = &ctx->kabylake_headset; | 197 | jack = &ctx->kabylake_headset; |
198 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_MEDIA); | 198 | snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
199 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); | 199 | snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
200 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | 200 | snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
201 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | 201 | snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); |
diff --git a/sound/soc/intel/boards/mfld_machine.c b/sound/soc/intel/boards/mfld_machine.c deleted file mode 100644 index 6f44acfb4aae..000000000000 --- a/sound/soc/intel/boards/mfld_machine.c +++ /dev/null | |||
@@ -1,428 +0,0 @@ | |||
1 | /* | ||
2 | * mfld_machine.c - ASoc Machine driver for Intel Medfield MID platform | ||
3 | * | ||
4 | * Copyright (C) 2010 Intel Corp | ||
5 | * Author: Vinod Koul <vinod.koul@intel.com> | ||
6 | * Author: Harsha Priya <priya.harsha@intel.com> | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License along | ||
19 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
21 | * | ||
22 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
23 | */ | ||
24 | |||
25 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
26 | |||
27 | #include <linux/init.h> | ||
28 | #include <linux/device.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/io.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <sound/pcm.h> | ||
33 | #include <sound/pcm_params.h> | ||
34 | #include <sound/soc.h> | ||
35 | #include <sound/jack.h> | ||
36 | #include "../codecs/sn95031.h" | ||
37 | |||
38 | #define MID_MONO 1 | ||
39 | #define MID_STEREO 2 | ||
40 | #define MID_MAX_CAP 5 | ||
41 | #define MFLD_JACK_INSERT 0x04 | ||
42 | |||
43 | enum soc_mic_bias_zones { | ||
44 | MFLD_MV_START = 0, | ||
45 | /* mic bias volutage range for Headphones*/ | ||
46 | MFLD_MV_HP = 400, | ||
47 | /* mic bias volutage range for American Headset*/ | ||
48 | MFLD_MV_AM_HS = 650, | ||
49 | /* mic bias volutage range for Headset*/ | ||
50 | MFLD_MV_HS = 2000, | ||
51 | MFLD_MV_UNDEFINED, | ||
52 | }; | ||
53 | |||
54 | static unsigned int hs_switch; | ||
55 | static unsigned int lo_dac; | ||
56 | static struct snd_soc_codec *mfld_codec; | ||
57 | |||
58 | struct mfld_mc_private { | ||
59 | void __iomem *int_base; | ||
60 | u8 interrupt_status; | ||
61 | }; | ||
62 | |||
63 | struct snd_soc_jack mfld_jack; | ||
64 | |||
65 | /*Headset jack detection DAPM pins */ | ||
66 | static struct snd_soc_jack_pin mfld_jack_pins[] = { | ||
67 | { | ||
68 | .pin = "Headphones", | ||
69 | .mask = SND_JACK_HEADPHONE, | ||
70 | }, | ||
71 | { | ||
72 | .pin = "AMIC1", | ||
73 | .mask = SND_JACK_MICROPHONE, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | /* jack detection voltage zones */ | ||
78 | static struct snd_soc_jack_zone mfld_zones[] = { | ||
79 | {MFLD_MV_START, MFLD_MV_AM_HS, SND_JACK_HEADPHONE}, | ||
80 | {MFLD_MV_AM_HS, MFLD_MV_HS, SND_JACK_HEADSET}, | ||
81 | }; | ||
82 | |||
83 | /* sound card controls */ | ||
84 | static const char * const headset_switch_text[] = {"Earpiece", "Headset"}; | ||
85 | |||
86 | static const char * const lo_text[] = {"Vibra", "Headset", "IHF", "None"}; | ||
87 | |||
88 | static const struct soc_enum headset_enum = | ||
89 | SOC_ENUM_SINGLE_EXT(2, headset_switch_text); | ||
90 | |||
91 | static const struct soc_enum lo_enum = | ||
92 | SOC_ENUM_SINGLE_EXT(4, lo_text); | ||
93 | |||
94 | static int headset_get_switch(struct snd_kcontrol *kcontrol, | ||
95 | struct snd_ctl_elem_value *ucontrol) | ||
96 | { | ||
97 | ucontrol->value.enumerated.item[0] = hs_switch; | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int headset_set_switch(struct snd_kcontrol *kcontrol, | ||
102 | struct snd_ctl_elem_value *ucontrol) | ||
103 | { | ||
104 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); | ||
105 | struct snd_soc_dapm_context *dapm = &card->dapm; | ||
106 | |||
107 | if (ucontrol->value.enumerated.item[0] == hs_switch) | ||
108 | return 0; | ||
109 | |||
110 | snd_soc_dapm_mutex_lock(dapm); | ||
111 | |||
112 | if (ucontrol->value.enumerated.item[0]) { | ||
113 | pr_debug("hs_set HS path\n"); | ||
114 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones"); | ||
115 | snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); | ||
116 | } else { | ||
117 | pr_debug("hs_set EP path\n"); | ||
118 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); | ||
119 | snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT"); | ||
120 | } | ||
121 | |||
122 | snd_soc_dapm_sync_unlocked(dapm); | ||
123 | |||
124 | snd_soc_dapm_mutex_unlock(dapm); | ||
125 | |||
126 | hs_switch = ucontrol->value.enumerated.item[0]; | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static void lo_enable_out_pins(struct snd_soc_dapm_context *dapm) | ||
132 | { | ||
133 | snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTL"); | ||
134 | snd_soc_dapm_enable_pin_unlocked(dapm, "IHFOUTR"); | ||
135 | snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTL"); | ||
136 | snd_soc_dapm_enable_pin_unlocked(dapm, "LINEOUTR"); | ||
137 | snd_soc_dapm_enable_pin_unlocked(dapm, "VIB1OUT"); | ||
138 | snd_soc_dapm_enable_pin_unlocked(dapm, "VIB2OUT"); | ||
139 | if (hs_switch) { | ||
140 | snd_soc_dapm_enable_pin_unlocked(dapm, "Headphones"); | ||
141 | snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); | ||
142 | } else { | ||
143 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); | ||
144 | snd_soc_dapm_enable_pin_unlocked(dapm, "EPOUT"); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | static int lo_get_switch(struct snd_kcontrol *kcontrol, | ||
149 | struct snd_ctl_elem_value *ucontrol) | ||
150 | { | ||
151 | ucontrol->value.enumerated.item[0] = lo_dac; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static int lo_set_switch(struct snd_kcontrol *kcontrol, | ||
156 | struct snd_ctl_elem_value *ucontrol) | ||
157 | { | ||
158 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); | ||
159 | struct snd_soc_dapm_context *dapm = &card->dapm; | ||
160 | |||
161 | if (ucontrol->value.enumerated.item[0] == lo_dac) | ||
162 | return 0; | ||
163 | |||
164 | snd_soc_dapm_mutex_lock(dapm); | ||
165 | |||
166 | /* we dont want to work with last state of lineout so just enable all | ||
167 | * pins and then disable pins not required | ||
168 | */ | ||
169 | lo_enable_out_pins(dapm); | ||
170 | |||
171 | switch (ucontrol->value.enumerated.item[0]) { | ||
172 | case 0: | ||
173 | pr_debug("set vibra path\n"); | ||
174 | snd_soc_dapm_disable_pin_unlocked(dapm, "VIB1OUT"); | ||
175 | snd_soc_dapm_disable_pin_unlocked(dapm, "VIB2OUT"); | ||
176 | snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0); | ||
177 | break; | ||
178 | |||
179 | case 1: | ||
180 | pr_debug("set hs path\n"); | ||
181 | snd_soc_dapm_disable_pin_unlocked(dapm, "Headphones"); | ||
182 | snd_soc_dapm_disable_pin_unlocked(dapm, "EPOUT"); | ||
183 | snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x22); | ||
184 | break; | ||
185 | |||
186 | case 2: | ||
187 | pr_debug("set spkr path\n"); | ||
188 | snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTL"); | ||
189 | snd_soc_dapm_disable_pin_unlocked(dapm, "IHFOUTR"); | ||
190 | snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x44); | ||
191 | break; | ||
192 | |||
193 | case 3: | ||
194 | pr_debug("set null path\n"); | ||
195 | snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTL"); | ||
196 | snd_soc_dapm_disable_pin_unlocked(dapm, "LINEOUTR"); | ||
197 | snd_soc_update_bits(mfld_codec, SN95031_LOCTL, 0x66, 0x66); | ||
198 | break; | ||
199 | } | ||
200 | |||
201 | snd_soc_dapm_sync_unlocked(dapm); | ||
202 | |||
203 | snd_soc_dapm_mutex_unlock(dapm); | ||
204 | |||
205 | lo_dac = ucontrol->value.enumerated.item[0]; | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static const struct snd_kcontrol_new mfld_snd_controls[] = { | ||
210 | SOC_ENUM_EXT("Playback Switch", headset_enum, | ||
211 | headset_get_switch, headset_set_switch), | ||
212 | SOC_ENUM_EXT("Lineout Mux", lo_enum, | ||
213 | lo_get_switch, lo_set_switch), | ||
214 | }; | ||
215 | |||
216 | static const struct snd_soc_dapm_widget mfld_widgets[] = { | ||
217 | SND_SOC_DAPM_HP("Headphones", NULL), | ||
218 | SND_SOC_DAPM_MIC("Mic", NULL), | ||
219 | }; | ||
220 | |||
221 | static const struct snd_soc_dapm_route mfld_map[] = { | ||
222 | {"Headphones", NULL, "HPOUTR"}, | ||
223 | {"Headphones", NULL, "HPOUTL"}, | ||
224 | {"Mic", NULL, "AMIC1"}, | ||
225 | }; | ||
226 | |||
227 | static void mfld_jack_check(unsigned int intr_status) | ||
228 | { | ||
229 | struct mfld_jack_data jack_data; | ||
230 | |||
231 | if (!mfld_codec) | ||
232 | return; | ||
233 | |||
234 | jack_data.mfld_jack = &mfld_jack; | ||
235 | jack_data.intr_id = intr_status; | ||
236 | |||
237 | sn95031_jack_detection(mfld_codec, &jack_data); | ||
238 | /* TODO: add american headset detection post gpiolib support */ | ||
239 | } | ||
240 | |||
241 | static int mfld_init(struct snd_soc_pcm_runtime *runtime) | ||
242 | { | ||
243 | struct snd_soc_dapm_context *dapm = &runtime->card->dapm; | ||
244 | int ret_val; | ||
245 | |||
246 | /* default is earpiece pin, userspace sets it explcitly */ | ||
247 | snd_soc_dapm_disable_pin(dapm, "Headphones"); | ||
248 | /* default is lineout NC, userspace sets it explcitly */ | ||
249 | snd_soc_dapm_disable_pin(dapm, "LINEOUTL"); | ||
250 | snd_soc_dapm_disable_pin(dapm, "LINEOUTR"); | ||
251 | lo_dac = 3; | ||
252 | hs_switch = 0; | ||
253 | /* we dont use linein in this so set to NC */ | ||
254 | snd_soc_dapm_disable_pin(dapm, "LINEINL"); | ||
255 | snd_soc_dapm_disable_pin(dapm, "LINEINR"); | ||
256 | |||
257 | /* Headset and button jack detection */ | ||
258 | ret_val = snd_soc_card_jack_new(runtime->card, | ||
259 | "Intel(R) MID Audio Jack", SND_JACK_HEADSET | | ||
260 | SND_JACK_BTN_0 | SND_JACK_BTN_1, &mfld_jack, | ||
261 | mfld_jack_pins, ARRAY_SIZE(mfld_jack_pins)); | ||
262 | if (ret_val) { | ||
263 | pr_err("jack creation failed\n"); | ||
264 | return ret_val; | ||
265 | } | ||
266 | |||
267 | ret_val = snd_soc_jack_add_zones(&mfld_jack, | ||
268 | ARRAY_SIZE(mfld_zones), mfld_zones); | ||
269 | if (ret_val) { | ||
270 | pr_err("adding jack zones failed\n"); | ||
271 | return ret_val; | ||
272 | } | ||
273 | |||
274 | mfld_codec = runtime->codec; | ||
275 | |||
276 | /* we want to check if anything is inserted at boot, | ||
277 | * so send a fake event to codec and it will read adc | ||
278 | * to find if anything is there or not */ | ||
279 | mfld_jack_check(MFLD_JACK_INSERT); | ||
280 | return ret_val; | ||
281 | } | ||
282 | |||
283 | static struct snd_soc_dai_link mfld_msic_dailink[] = { | ||
284 | { | ||
285 | .name = "Medfield Headset", | ||
286 | .stream_name = "Headset", | ||
287 | .cpu_dai_name = "Headset-cpu-dai", | ||
288 | .codec_dai_name = "SN95031 Headset", | ||
289 | .codec_name = "sn95031", | ||
290 | .platform_name = "sst-platform", | ||
291 | .init = mfld_init, | ||
292 | }, | ||
293 | { | ||
294 | .name = "Medfield Speaker", | ||
295 | .stream_name = "Speaker", | ||
296 | .cpu_dai_name = "Speaker-cpu-dai", | ||
297 | .codec_dai_name = "SN95031 Speaker", | ||
298 | .codec_name = "sn95031", | ||
299 | .platform_name = "sst-platform", | ||
300 | .init = NULL, | ||
301 | }, | ||
302 | { | ||
303 | .name = "Medfield Vibra", | ||
304 | .stream_name = "Vibra1", | ||
305 | .cpu_dai_name = "Vibra1-cpu-dai", | ||
306 | .codec_dai_name = "SN95031 Vibra1", | ||
307 | .codec_name = "sn95031", | ||
308 | .platform_name = "sst-platform", | ||
309 | .init = NULL, | ||
310 | }, | ||
311 | { | ||
312 | .name = "Medfield Haptics", | ||
313 | .stream_name = "Vibra2", | ||
314 | .cpu_dai_name = "Vibra2-cpu-dai", | ||
315 | .codec_dai_name = "SN95031 Vibra2", | ||
316 | .codec_name = "sn95031", | ||
317 | .platform_name = "sst-platform", | ||
318 | .init = NULL, | ||
319 | }, | ||
320 | { | ||
321 | .name = "Medfield Compress", | ||
322 | .stream_name = "Speaker", | ||
323 | .cpu_dai_name = "Compress-cpu-dai", | ||
324 | .codec_dai_name = "SN95031 Speaker", | ||
325 | .codec_name = "sn95031", | ||
326 | .platform_name = "sst-platform", | ||
327 | .init = NULL, | ||
328 | }, | ||
329 | }; | ||
330 | |||
331 | /* SoC card */ | ||
332 | static struct snd_soc_card snd_soc_card_mfld = { | ||
333 | .name = "medfield_audio", | ||
334 | .owner = THIS_MODULE, | ||
335 | .dai_link = mfld_msic_dailink, | ||
336 | .num_links = ARRAY_SIZE(mfld_msic_dailink), | ||
337 | |||
338 | .controls = mfld_snd_controls, | ||
339 | .num_controls = ARRAY_SIZE(mfld_snd_controls), | ||
340 | .dapm_widgets = mfld_widgets, | ||
341 | .num_dapm_widgets = ARRAY_SIZE(mfld_widgets), | ||
342 | .dapm_routes = mfld_map, | ||
343 | .num_dapm_routes = ARRAY_SIZE(mfld_map), | ||
344 | }; | ||
345 | |||
346 | static irqreturn_t snd_mfld_jack_intr_handler(int irq, void *dev) | ||
347 | { | ||
348 | struct mfld_mc_private *mc_private = (struct mfld_mc_private *) dev; | ||
349 | |||
350 | memcpy_fromio(&mc_private->interrupt_status, | ||
351 | ((void *)(mc_private->int_base)), | ||
352 | sizeof(u8)); | ||
353 | return IRQ_WAKE_THREAD; | ||
354 | } | ||
355 | |||
356 | static irqreturn_t snd_mfld_jack_detection(int irq, void *data) | ||
357 | { | ||
358 | struct mfld_mc_private *mc_drv_ctx = (struct mfld_mc_private *) data; | ||
359 | |||
360 | mfld_jack_check(mc_drv_ctx->interrupt_status); | ||
361 | |||
362 | return IRQ_HANDLED; | ||
363 | } | ||
364 | |||
365 | static int snd_mfld_mc_probe(struct platform_device *pdev) | ||
366 | { | ||
367 | int ret_val = 0, irq; | ||
368 | struct mfld_mc_private *mc_drv_ctx; | ||
369 | struct resource *irq_mem; | ||
370 | |||
371 | pr_debug("snd_mfld_mc_probe called\n"); | ||
372 | |||
373 | /* retrive the irq number */ | ||
374 | irq = platform_get_irq(pdev, 0); | ||
375 | |||
376 | /* audio interrupt base of SRAM location where | ||
377 | * interrupts are stored by System FW */ | ||
378 | mc_drv_ctx = devm_kzalloc(&pdev->dev, sizeof(*mc_drv_ctx), GFP_ATOMIC); | ||
379 | if (!mc_drv_ctx) | ||
380 | return -ENOMEM; | ||
381 | |||
382 | irq_mem = platform_get_resource_byname( | ||
383 | pdev, IORESOURCE_MEM, "IRQ_BASE"); | ||
384 | if (!irq_mem) { | ||
385 | pr_err("no mem resource given\n"); | ||
386 | return -ENODEV; | ||
387 | } | ||
388 | mc_drv_ctx->int_base = devm_ioremap_nocache(&pdev->dev, irq_mem->start, | ||
389 | resource_size(irq_mem)); | ||
390 | if (!mc_drv_ctx->int_base) { | ||
391 | pr_err("Mapping of cache failed\n"); | ||
392 | return -ENOMEM; | ||
393 | } | ||
394 | /* register for interrupt */ | ||
395 | ret_val = devm_request_threaded_irq(&pdev->dev, irq, | ||
396 | snd_mfld_jack_intr_handler, | ||
397 | snd_mfld_jack_detection, | ||
398 | IRQF_SHARED, pdev->dev.driver->name, mc_drv_ctx); | ||
399 | if (ret_val) { | ||
400 | pr_err("cannot register IRQ\n"); | ||
401 | return ret_val; | ||
402 | } | ||
403 | /* register the soc card */ | ||
404 | snd_soc_card_mfld.dev = &pdev->dev; | ||
405 | ret_val = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_mfld); | ||
406 | if (ret_val) { | ||
407 | pr_debug("snd_soc_register_card failed %d\n", ret_val); | ||
408 | return ret_val; | ||
409 | } | ||
410 | platform_set_drvdata(pdev, mc_drv_ctx); | ||
411 | pr_debug("successfully exited probe\n"); | ||
412 | return 0; | ||
413 | } | ||
414 | |||
415 | static struct platform_driver snd_mfld_mc_driver = { | ||
416 | .driver = { | ||
417 | .name = "msic_audio", | ||
418 | }, | ||
419 | .probe = snd_mfld_mc_probe, | ||
420 | }; | ||
421 | |||
422 | module_platform_driver(snd_mfld_mc_driver); | ||
423 | |||
424 | MODULE_DESCRIPTION("ASoC Intel(R) MID Machine driver"); | ||
425 | MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>"); | ||
426 | MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>"); | ||
427 | MODULE_LICENSE("GPL v2"); | ||
428 | MODULE_ALIAS("platform:msic-audio"); | ||
diff --git a/sound/soc/intel/common/sst-dsp.c b/sound/soc/intel/common/sst-dsp.c index 11c0805393ff..fd82f4b1d4a0 100644 --- a/sound/soc/intel/common/sst-dsp.c +++ b/sound/soc/intel/common/sst-dsp.c | |||
@@ -269,7 +269,7 @@ int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, | |||
269 | */ | 269 | */ |
270 | 270 | ||
271 | timeout = jiffies + msecs_to_jiffies(time); | 271 | timeout = jiffies + msecs_to_jiffies(time); |
272 | while (((sst_dsp_shim_read_unlocked(ctx, offset) & mask) != target) | 272 | while ((((reg = sst_dsp_shim_read_unlocked(ctx, offset)) & mask) != target) |
273 | && time_before(jiffies, timeout)) { | 273 | && time_before(jiffies, timeout)) { |
274 | k++; | 274 | k++; |
275 | if (k > 10) | 275 | if (k > 10) |
@@ -278,8 +278,6 @@ int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask, | |||
278 | usleep_range(s, 2*s); | 278 | usleep_range(s, 2*s); |
279 | } | 279 | } |
280 | 280 | ||
281 | reg = sst_dsp_shim_read_unlocked(ctx, offset); | ||
282 | |||
283 | if ((reg & mask) == target) { | 281 | if ((reg & mask) == target) { |
284 | dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n", | 282 | dev_dbg(ctx->dev, "FW Poll Status: reg=%#x %s successful\n", |
285 | reg, operation); | 283 | reg, operation); |
diff --git a/sound/soc/intel/skylake/bxt-sst.c b/sound/soc/intel/skylake/bxt-sst.c index 4524211960e4..440bca7afbf1 100644 --- a/sound/soc/intel/skylake/bxt-sst.c +++ b/sound/soc/intel/skylake/bxt-sst.c | |||
@@ -595,7 +595,7 @@ int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
595 | INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); | 595 | INIT_DELAYED_WORK(&skl->d0i3.work, bxt_set_dsp_D0i3); |
596 | skl->d0i3.state = SKL_DSP_D0I3_NONE; | 596 | skl->d0i3.state = SKL_DSP_D0I3_NONE; |
597 | 597 | ||
598 | return 0; | 598 | return skl_dsp_acquire_irq(sst); |
599 | } | 599 | } |
600 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); | 600 | EXPORT_SYMBOL_GPL(bxt_sst_dsp_init); |
601 | 601 | ||
diff --git a/sound/soc/intel/skylake/cnl-sst.c b/sound/soc/intel/skylake/cnl-sst.c index 387de388ce29..245df1067ba8 100644 --- a/sound/soc/intel/skylake/cnl-sst.c +++ b/sound/soc/intel/skylake/cnl-sst.c | |||
@@ -458,7 +458,7 @@ int cnl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
458 | cnl->boot_complete = false; | 458 | cnl->boot_complete = false; |
459 | init_waitqueue_head(&cnl->boot_wait); | 459 | init_waitqueue_head(&cnl->boot_wait); |
460 | 460 | ||
461 | return 0; | 461 | return skl_dsp_acquire_irq(sst); |
462 | } | 462 | } |
463 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); | 463 | EXPORT_SYMBOL_GPL(cnl_sst_dsp_init); |
464 | 464 | ||
diff --git a/sound/soc/intel/skylake/skl-i2s.h b/sound/soc/intel/skylake/skl-i2s.h new file mode 100644 index 000000000000..dcf819bc688f --- /dev/null +++ b/sound/soc/intel/skylake/skl-i2s.h | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * skl-i2s.h - i2s blob mapping | ||
3 | * | ||
4 | * Copyright (C) 2017 Intel Corp | ||
5 | * Author: Subhransu S. Prusty < subhransu.s.prusty@intel.com> | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | #ifndef __SOUND_SOC_SKL_I2S_H | ||
21 | #define __SOUND_SOC_SKL_I2S_H | ||
22 | |||
23 | #define SKL_I2S_MAX_TIME_SLOTS 8 | ||
24 | #define SKL_MCLK_DIV_CLK_SRC_MASK GENMASK(17, 16) | ||
25 | |||
26 | #define SKL_MNDSS_DIV_CLK_SRC_MASK GENMASK(21, 20) | ||
27 | #define SKL_SHIFT(x) (ffs(x) - 1) | ||
28 | #define SKL_MCLK_DIV_RATIO_MASK GENMASK(11, 0) | ||
29 | |||
30 | struct skl_i2s_config { | ||
31 | u32 ssc0; | ||
32 | u32 ssc1; | ||
33 | u32 sscto; | ||
34 | u32 sspsp; | ||
35 | u32 sstsa; | ||
36 | u32 ssrsa; | ||
37 | u32 ssc2; | ||
38 | u32 sspsp2; | ||
39 | u32 ssc3; | ||
40 | u32 ssioc; | ||
41 | } __packed; | ||
42 | |||
43 | struct skl_i2s_config_mclk { | ||
44 | u32 mdivctrl; | ||
45 | u32 mdivr; | ||
46 | }; | ||
47 | |||
48 | /** | ||
49 | * struct skl_i2s_config_blob_legacy - Structure defines I2S Gateway | ||
50 | * configuration legacy blob | ||
51 | * | ||
52 | * @gtw_attr: Gateway attribute for the I2S Gateway | ||
53 | * @tdm_ts_group: TDM slot mapping against channels in the Gateway. | ||
54 | * @i2s_cfg: I2S HW registers | ||
55 | * @mclk: MCLK clock source and divider values | ||
56 | */ | ||
57 | struct skl_i2s_config_blob_legacy { | ||
58 | u32 gtw_attr; | ||
59 | u32 tdm_ts_group[SKL_I2S_MAX_TIME_SLOTS]; | ||
60 | struct skl_i2s_config i2s_cfg; | ||
61 | struct skl_i2s_config_mclk mclk; | ||
62 | }; | ||
63 | |||
64 | #endif /* __SOUND_SOC_SKL_I2S_H */ | ||
diff --git a/sound/soc/intel/skylake/skl-messages.c b/sound/soc/intel/skylake/skl-messages.c index 61b5bfa79d13..8cbf080c38b3 100644 --- a/sound/soc/intel/skylake/skl-messages.c +++ b/sound/soc/intel/skylake/skl-messages.c | |||
@@ -55,6 +55,19 @@ static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab) | |||
55 | return 0; | 55 | return 0; |
56 | } | 56 | } |
57 | 57 | ||
58 | #define SKL_ASTATE_PARAM_ID 4 | ||
59 | |||
60 | void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data) | ||
61 | { | ||
62 | struct skl_ipc_large_config_msg msg = {0}; | ||
63 | |||
64 | msg.large_param_id = SKL_ASTATE_PARAM_ID; | ||
65 | msg.param_data_size = (cnt * sizeof(struct skl_astate_param) + | ||
66 | sizeof(cnt)); | ||
67 | |||
68 | skl_ipc_set_large_config(&ctx->ipc, &msg, data); | ||
69 | } | ||
70 | |||
58 | #define NOTIFICATION_PARAM_ID 3 | 71 | #define NOTIFICATION_PARAM_ID 3 |
59 | #define NOTIFICATION_MASK 0xf | 72 | #define NOTIFICATION_MASK 0xf |
60 | 73 | ||
@@ -404,11 +417,20 @@ int skl_resume_dsp(struct skl *skl) | |||
404 | if (skl->skl_sst->is_first_boot == true) | 417 | if (skl->skl_sst->is_first_boot == true) |
405 | return 0; | 418 | return 0; |
406 | 419 | ||
420 | /* disable dynamic clock gating during fw and lib download */ | ||
421 | ctx->enable_miscbdcge(ctx->dev, false); | ||
422 | |||
407 | ret = skl_dsp_wake(ctx->dsp); | 423 | ret = skl_dsp_wake(ctx->dsp); |
424 | ctx->enable_miscbdcge(ctx->dev, true); | ||
408 | if (ret < 0) | 425 | if (ret < 0) |
409 | return ret; | 426 | return ret; |
410 | 427 | ||
411 | skl_dsp_enable_notification(skl->skl_sst, false); | 428 | skl_dsp_enable_notification(skl->skl_sst, false); |
429 | |||
430 | if (skl->cfg.astate_cfg != NULL) { | ||
431 | skl_dsp_set_astate_cfg(skl->skl_sst, skl->cfg.astate_cfg->count, | ||
432 | skl->cfg.astate_cfg); | ||
433 | } | ||
412 | return ret; | 434 | return ret; |
413 | } | 435 | } |
414 | 436 | ||
diff --git a/sound/soc/intel/skylake/skl-nhlt.c b/sound/soc/intel/skylake/skl-nhlt.c index 3eaac41090ca..3b1d2b828c1b 100644 --- a/sound/soc/intel/skylake/skl-nhlt.c +++ b/sound/soc/intel/skylake/skl-nhlt.c | |||
@@ -19,6 +19,7 @@ | |||
19 | */ | 19 | */ |
20 | #include <linux/pci.h> | 20 | #include <linux/pci.h> |
21 | #include "skl.h" | 21 | #include "skl.h" |
22 | #include "skl-i2s.h" | ||
22 | 23 | ||
23 | #define NHLT_ACPI_HEADER_SIG "NHLT" | 24 | #define NHLT_ACPI_HEADER_SIG "NHLT" |
24 | 25 | ||
@@ -43,7 +44,8 @@ struct nhlt_acpi_table *skl_nhlt_init(struct device *dev) | |||
43 | obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL); | 44 | obj = acpi_evaluate_dsm(handle, &osc_guid, 1, 1, NULL); |
44 | if (obj && obj->type == ACPI_TYPE_BUFFER) { | 45 | if (obj && obj->type == ACPI_TYPE_BUFFER) { |
45 | nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; | 46 | nhlt_ptr = (struct nhlt_resource_desc *)obj->buffer.pointer; |
46 | nhlt_table = (struct nhlt_acpi_table *) | 47 | if (nhlt_ptr->length) |
48 | nhlt_table = (struct nhlt_acpi_table *) | ||
47 | memremap(nhlt_ptr->min_addr, nhlt_ptr->length, | 49 | memremap(nhlt_ptr->min_addr, nhlt_ptr->length, |
48 | MEMREMAP_WB); | 50 | MEMREMAP_WB); |
49 | ACPI_FREE(obj); | 51 | ACPI_FREE(obj); |
@@ -276,3 +278,157 @@ void skl_nhlt_remove_sysfs(struct skl *skl) | |||
276 | 278 | ||
277 | sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr); | 279 | sysfs_remove_file(&dev->kobj, &dev_attr_platform_id.attr); |
278 | } | 280 | } |
281 | |||
282 | /* | ||
283 | * Queries NHLT for all the fmt configuration for a particular endpoint and | ||
284 | * stores all possible rates supported in a rate table for the corresponding | ||
285 | * sclk/sclkfs. | ||
286 | */ | ||
287 | static void skl_get_ssp_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks, | ||
288 | struct nhlt_fmt *fmt, u8 id) | ||
289 | { | ||
290 | struct skl_i2s_config_blob_legacy *i2s_config; | ||
291 | struct skl_clk_parent_src *parent; | ||
292 | struct skl_ssp_clk *sclk, *sclkfs; | ||
293 | struct nhlt_fmt_cfg *fmt_cfg; | ||
294 | struct wav_fmt_ext *wav_fmt; | ||
295 | unsigned long rate = 0; | ||
296 | bool present = false; | ||
297 | int rate_index = 0; | ||
298 | u16 channels, bps; | ||
299 | u8 clk_src; | ||
300 | int i, j; | ||
301 | u32 fs; | ||
302 | |||
303 | sclk = &ssp_clks[SKL_SCLK_OFS]; | ||
304 | sclkfs = &ssp_clks[SKL_SCLKFS_OFS]; | ||
305 | |||
306 | if (fmt->fmt_count == 0) | ||
307 | return; | ||
308 | |||
309 | for (i = 0; i < fmt->fmt_count; i++) { | ||
310 | fmt_cfg = &fmt->fmt_config[i]; | ||
311 | wav_fmt = &fmt_cfg->fmt_ext; | ||
312 | |||
313 | channels = wav_fmt->fmt.channels; | ||
314 | bps = wav_fmt->fmt.bits_per_sample; | ||
315 | fs = wav_fmt->fmt.samples_per_sec; | ||
316 | |||
317 | /* | ||
318 | * In case of TDM configuration on a ssp, there can | ||
319 | * be more than one blob in which channel masks are | ||
320 | * different for each usecase for a specific rate and bps. | ||
321 | * But the sclk rate will be generated for the total | ||
322 | * number of channels used for that endpoint. | ||
323 | * | ||
324 | * So for the given fs and bps, choose blob which has | ||
325 | * the superset of all channels for that endpoint and | ||
326 | * derive the rate. | ||
327 | */ | ||
328 | for (j = i; j < fmt->fmt_count; j++) { | ||
329 | fmt_cfg = &fmt->fmt_config[j]; | ||
330 | wav_fmt = &fmt_cfg->fmt_ext; | ||
331 | if ((fs == wav_fmt->fmt.samples_per_sec) && | ||
332 | (bps == wav_fmt->fmt.bits_per_sample)) | ||
333 | channels = max_t(u16, channels, | ||
334 | wav_fmt->fmt.channels); | ||
335 | } | ||
336 | |||
337 | rate = channels * bps * fs; | ||
338 | |||
339 | /* check if the rate is added already to the given SSP's sclk */ | ||
340 | for (j = 0; (j < SKL_MAX_CLK_RATES) && | ||
341 | (sclk[id].rate_cfg[j].rate != 0); j++) { | ||
342 | if (sclk[id].rate_cfg[j].rate == rate) { | ||
343 | present = true; | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | |||
348 | /* Fill rate and parent for sclk/sclkfs */ | ||
349 | if (!present) { | ||
350 | /* MCLK Divider Source Select */ | ||
351 | i2s_config = (struct skl_i2s_config_blob_legacy *) | ||
352 | fmt->fmt_config[0].config.caps; | ||
353 | clk_src = ((i2s_config->mclk.mdivctrl) | ||
354 | & SKL_MNDSS_DIV_CLK_SRC_MASK) >> | ||
355 | SKL_SHIFT(SKL_MNDSS_DIV_CLK_SRC_MASK); | ||
356 | |||
357 | parent = skl_get_parent_clk(clk_src); | ||
358 | |||
359 | /* | ||
360 | * Do not copy the config data if there is no parent | ||
361 | * clock available for this clock source select | ||
362 | */ | ||
363 | if (!parent) | ||
364 | continue; | ||
365 | |||
366 | sclk[id].rate_cfg[rate_index].rate = rate; | ||
367 | sclk[id].rate_cfg[rate_index].config = fmt_cfg; | ||
368 | sclkfs[id].rate_cfg[rate_index].rate = rate; | ||
369 | sclkfs[id].rate_cfg[rate_index].config = fmt_cfg; | ||
370 | sclk[id].parent_name = parent->name; | ||
371 | sclkfs[id].parent_name = parent->name; | ||
372 | |||
373 | rate_index++; | ||
374 | } | ||
375 | } | ||
376 | } | ||
377 | |||
378 | static void skl_get_mclk(struct skl *skl, struct skl_ssp_clk *mclk, | ||
379 | struct nhlt_fmt *fmt, u8 id) | ||
380 | { | ||
381 | struct skl_i2s_config_blob_legacy *i2s_config; | ||
382 | struct nhlt_specific_cfg *fmt_cfg; | ||
383 | struct skl_clk_parent_src *parent; | ||
384 | u32 clkdiv, div_ratio; | ||
385 | u8 clk_src; | ||
386 | |||
387 | fmt_cfg = &fmt->fmt_config[0].config; | ||
388 | i2s_config = (struct skl_i2s_config_blob_legacy *)fmt_cfg->caps; | ||
389 | |||
390 | /* MCLK Divider Source Select */ | ||
391 | clk_src = ((i2s_config->mclk.mdivctrl) & SKL_MCLK_DIV_CLK_SRC_MASK) >> | ||
392 | SKL_SHIFT(SKL_MCLK_DIV_CLK_SRC_MASK); | ||
393 | |||
394 | clkdiv = i2s_config->mclk.mdivr & SKL_MCLK_DIV_RATIO_MASK; | ||
395 | |||
396 | /* bypass divider */ | ||
397 | div_ratio = 1; | ||
398 | |||
399 | if (clkdiv != SKL_MCLK_DIV_RATIO_MASK) | ||
400 | /* Divider is 2 + clkdiv */ | ||
401 | div_ratio = clkdiv + 2; | ||
402 | |||
403 | /* Calculate MCLK rate from source using div value */ | ||
404 | parent = skl_get_parent_clk(clk_src); | ||
405 | if (!parent) | ||
406 | return; | ||
407 | |||
408 | mclk[id].rate_cfg[0].rate = parent->rate/div_ratio; | ||
409 | mclk[id].rate_cfg[0].config = &fmt->fmt_config[0]; | ||
410 | mclk[id].parent_name = parent->name; | ||
411 | } | ||
412 | |||
413 | void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks) | ||
414 | { | ||
415 | struct nhlt_acpi_table *nhlt = (struct nhlt_acpi_table *)skl->nhlt; | ||
416 | struct nhlt_endpoint *epnt; | ||
417 | struct nhlt_fmt *fmt; | ||
418 | int i; | ||
419 | u8 id; | ||
420 | |||
421 | epnt = (struct nhlt_endpoint *)nhlt->desc; | ||
422 | for (i = 0; i < nhlt->endpoint_count; i++) { | ||
423 | if (epnt->linktype == NHLT_LINK_SSP) { | ||
424 | id = epnt->virtual_bus_id; | ||
425 | |||
426 | fmt = (struct nhlt_fmt *)(epnt->config.caps | ||
427 | + epnt->config.size); | ||
428 | |||
429 | skl_get_ssp_clks(skl, ssp_clks, fmt, id); | ||
430 | skl_get_mclk(skl, ssp_clks, fmt, id); | ||
431 | } | ||
432 | epnt = (struct nhlt_endpoint *)((u8 *)epnt + epnt->length); | ||
433 | } | ||
434 | } | ||
diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c index 1dd97479e0c0..e46828533826 100644 --- a/sound/soc/intel/skylake/skl-pcm.c +++ b/sound/soc/intel/skylake/skl-pcm.c | |||
@@ -537,7 +537,7 @@ static int skl_link_hw_params(struct snd_pcm_substream *substream, | |||
537 | 537 | ||
538 | snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); | 538 | snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); |
539 | 539 | ||
540 | link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name); | 540 | link = snd_hdac_ext_bus_get_link(ebus, codec_dai->component->name); |
541 | if (!link) | 541 | if (!link) |
542 | return -EINVAL; | 542 | return -EINVAL; |
543 | 543 | ||
@@ -620,7 +620,7 @@ static int skl_link_hw_free(struct snd_pcm_substream *substream, | |||
620 | 620 | ||
621 | link_dev->link_prepared = 0; | 621 | link_dev->link_prepared = 0; |
622 | 622 | ||
623 | link = snd_hdac_ext_bus_get_link(ebus, rtd->codec->component.name); | 623 | link = snd_hdac_ext_bus_get_link(ebus, rtd->codec_dai->component->name); |
624 | if (!link) | 624 | if (!link) |
625 | return -EINVAL; | 625 | return -EINVAL; |
626 | 626 | ||
@@ -1343,7 +1343,11 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) | |||
1343 | return -EIO; | 1343 | return -EIO; |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | /* disable dynamic clock gating during fw and lib download */ | ||
1347 | skl->skl_sst->enable_miscbdcge(platform->dev, false); | ||
1348 | |||
1346 | ret = ops->init_fw(platform->dev, skl->skl_sst); | 1349 | ret = ops->init_fw(platform->dev, skl->skl_sst); |
1350 | skl->skl_sst->enable_miscbdcge(platform->dev, true); | ||
1347 | if (ret < 0) { | 1351 | if (ret < 0) { |
1348 | dev_err(platform->dev, "Failed to boot first fw: %d\n", ret); | 1352 | dev_err(platform->dev, "Failed to boot first fw: %d\n", ret); |
1349 | return ret; | 1353 | return ret; |
@@ -1351,6 +1355,12 @@ static int skl_platform_soc_probe(struct snd_soc_platform *platform) | |||
1351 | skl_populate_modules(skl); | 1355 | skl_populate_modules(skl); |
1352 | skl->skl_sst->update_d0i3c = skl_update_d0i3c; | 1356 | skl->skl_sst->update_d0i3c = skl_update_d0i3c; |
1353 | skl_dsp_enable_notification(skl->skl_sst, false); | 1357 | skl_dsp_enable_notification(skl->skl_sst, false); |
1358 | |||
1359 | if (skl->cfg.astate_cfg != NULL) { | ||
1360 | skl_dsp_set_astate_cfg(skl->skl_sst, | ||
1361 | skl->cfg.astate_cfg->count, | ||
1362 | skl->cfg.astate_cfg); | ||
1363 | } | ||
1354 | } | 1364 | } |
1355 | pm_runtime_mark_last_busy(platform->dev); | 1365 | pm_runtime_mark_last_busy(platform->dev); |
1356 | pm_runtime_put_autosuspend(platform->dev); | 1366 | pm_runtime_put_autosuspend(platform->dev); |
diff --git a/sound/soc/intel/skylake/skl-ssp-clk.h b/sound/soc/intel/skylake/skl-ssp-clk.h new file mode 100644 index 000000000000..c9ea84004260 --- /dev/null +++ b/sound/soc/intel/skylake/skl-ssp-clk.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * skl-ssp-clk.h - Skylake ssp clock information and ipc structure | ||
3 | * | ||
4 | * Copyright (C) 2017 Intel Corp | ||
5 | * Author: Jaikrishna Nemallapudi <jaikrishnax.nemallapudi@intel.com> | ||
6 | * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com> | ||
7 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef SOUND_SOC_SKL_SSP_CLK_H | ||
23 | #define SOUND_SOC_SKL_SSP_CLK_H | ||
24 | |||
25 | #define SKL_MAX_SSP 6 | ||
26 | /* xtal/cardinal/pll, parent of ssp clocks and mclk */ | ||
27 | #define SKL_MAX_CLK_SRC 3 | ||
28 | #define SKL_MAX_SSP_CLK_TYPES 3 /* mclk, sclk, sclkfs */ | ||
29 | |||
30 | #define SKL_MAX_CLK_CNT (SKL_MAX_SSP * SKL_MAX_SSP_CLK_TYPES) | ||
31 | |||
32 | /* Max number of configurations supported for each clock */ | ||
33 | #define SKL_MAX_CLK_RATES 10 | ||
34 | |||
35 | #define SKL_SCLK_OFS SKL_MAX_SSP | ||
36 | #define SKL_SCLKFS_OFS (SKL_SCLK_OFS + SKL_MAX_SSP) | ||
37 | |||
38 | enum skl_clk_type { | ||
39 | SKL_MCLK, | ||
40 | SKL_SCLK, | ||
41 | SKL_SCLK_FS, | ||
42 | }; | ||
43 | |||
44 | enum skl_clk_src_type { | ||
45 | SKL_XTAL, | ||
46 | SKL_CARDINAL, | ||
47 | SKL_PLL, | ||
48 | }; | ||
49 | |||
50 | struct skl_clk_parent_src { | ||
51 | u8 clk_id; | ||
52 | const char *name; | ||
53 | unsigned long rate; | ||
54 | const char *parent_name; | ||
55 | }; | ||
56 | |||
57 | struct skl_clk_rate_cfg_table { | ||
58 | unsigned long rate; | ||
59 | void *config; | ||
60 | }; | ||
61 | |||
62 | /* | ||
63 | * rate for mclk will be in rates[0]. For sclk and sclkfs, rates[] store | ||
64 | * all possible clocks ssp can generate for that platform. | ||
65 | */ | ||
66 | struct skl_ssp_clk { | ||
67 | const char *name; | ||
68 | const char *parent_name; | ||
69 | struct skl_clk_rate_cfg_table rate_cfg[SKL_MAX_CLK_RATES]; | ||
70 | }; | ||
71 | |||
72 | struct skl_clk_pdata { | ||
73 | struct skl_clk_parent_src *parent_clks; | ||
74 | int num_clks; | ||
75 | struct skl_ssp_clk *ssp_clks; | ||
76 | void *pvt_data; | ||
77 | }; | ||
78 | |||
79 | #endif /* SOUND_SOC_SKL_SSP_CLK_H */ | ||
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.c b/sound/soc/intel/skylake/skl-sst-dsp.c index 19ee1d4f3bdf..71e31ad0bb3f 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.c +++ b/sound/soc/intel/skylake/skl-sst-dsp.c | |||
@@ -435,16 +435,22 @@ struct sst_dsp *skl_dsp_ctx_init(struct device *dev, | |||
435 | return NULL; | 435 | return NULL; |
436 | } | 436 | } |
437 | 437 | ||
438 | return sst; | ||
439 | } | ||
440 | |||
441 | int skl_dsp_acquire_irq(struct sst_dsp *sst) | ||
442 | { | ||
443 | struct sst_dsp_device *sst_dev = sst->sst_dev; | ||
444 | int ret; | ||
445 | |||
438 | /* Register the ISR */ | 446 | /* Register the ISR */ |
439 | ret = request_threaded_irq(sst->irq, sst->ops->irq_handler, | 447 | ret = request_threaded_irq(sst->irq, sst->ops->irq_handler, |
440 | sst_dev->thread, IRQF_SHARED, "AudioDSP", sst); | 448 | sst_dev->thread, IRQF_SHARED, "AudioDSP", sst); |
441 | if (ret) { | 449 | if (ret) |
442 | dev_err(sst->dev, "unable to grab threaded IRQ %d, disabling device\n", | 450 | dev_err(sst->dev, "unable to grab threaded IRQ %d, disabling device\n", |
443 | sst->irq); | 451 | sst->irq); |
444 | return NULL; | ||
445 | } | ||
446 | 452 | ||
447 | return sst; | 453 | return ret; |
448 | } | 454 | } |
449 | 455 | ||
450 | void skl_dsp_free(struct sst_dsp *dsp) | 456 | void skl_dsp_free(struct sst_dsp *dsp) |
diff --git a/sound/soc/intel/skylake/skl-sst-dsp.h b/sound/soc/intel/skylake/skl-sst-dsp.h index eba20d37ba8c..12fc9a73dc8a 100644 --- a/sound/soc/intel/skylake/skl-sst-dsp.h +++ b/sound/soc/intel/skylake/skl-sst-dsp.h | |||
@@ -206,6 +206,7 @@ int skl_cldma_wait_interruptible(struct sst_dsp *ctx); | |||
206 | void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); | 206 | void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); |
207 | struct sst_dsp *skl_dsp_ctx_init(struct device *dev, | 207 | struct sst_dsp *skl_dsp_ctx_init(struct device *dev, |
208 | struct sst_dsp_device *sst_dev, int irq); | 208 | struct sst_dsp_device *sst_dev, int irq); |
209 | int skl_dsp_acquire_irq(struct sst_dsp *sst); | ||
209 | bool is_skl_dsp_running(struct sst_dsp *ctx); | 210 | bool is_skl_dsp_running(struct sst_dsp *ctx); |
210 | 211 | ||
211 | unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx); | 212 | unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx); |
@@ -251,6 +252,9 @@ void skl_freeup_uuid_list(struct skl_sst *ctx); | |||
251 | 252 | ||
252 | int skl_dsp_strip_extended_manifest(struct firmware *fw); | 253 | int skl_dsp_strip_extended_manifest(struct firmware *fw); |
253 | void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable); | 254 | void skl_dsp_enable_notification(struct skl_sst *ctx, bool enable); |
255 | |||
256 | void skl_dsp_set_astate_cfg(struct skl_sst *ctx, u32 cnt, void *data); | ||
257 | |||
254 | int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, | 258 | int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, |
255 | struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, | 259 | struct skl_dsp_loader_ops dsp_ops, struct skl_sst **dsp, |
256 | struct sst_dsp_device *skl_dev); | 260 | struct sst_dsp_device *skl_dev); |
diff --git a/sound/soc/intel/skylake/skl-sst-utils.c b/sound/soc/intel/skylake/skl-sst-utils.c index 8ff89280d9fd..2ae405617876 100644 --- a/sound/soc/intel/skylake/skl-sst-utils.c +++ b/sound/soc/intel/skylake/skl-sst-utils.c | |||
@@ -178,7 +178,8 @@ static inline int skl_pvtid_128(struct uuid_module *module) | |||
178 | * skl_get_pvt_id: generate a private id for use as module id | 178 | * skl_get_pvt_id: generate a private id for use as module id |
179 | * | 179 | * |
180 | * @ctx: driver context | 180 | * @ctx: driver context |
181 | * @mconfig: module configuration data | 181 | * @uuid_mod: module's uuid |
182 | * @instance_id: module's instance id | ||
182 | * | 183 | * |
183 | * This generates a 128 bit private unique id for a module TYPE so that | 184 | * This generates a 128 bit private unique id for a module TYPE so that |
184 | * module instance is unique | 185 | * module instance is unique |
@@ -208,7 +209,8 @@ EXPORT_SYMBOL_GPL(skl_get_pvt_id); | |||
208 | * skl_put_pvt_id: free up the private id allocated | 209 | * skl_put_pvt_id: free up the private id allocated |
209 | * | 210 | * |
210 | * @ctx: driver context | 211 | * @ctx: driver context |
211 | * @mconfig: module configuration data | 212 | * @uuid_mod: module's uuid |
213 | * @pvt_id: module pvt id | ||
212 | * | 214 | * |
213 | * This frees a 128 bit private unique id previously generated | 215 | * This frees a 128 bit private unique id previously generated |
214 | */ | 216 | */ |
diff --git a/sound/soc/intel/skylake/skl-sst.c b/sound/soc/intel/skylake/skl-sst.c index a436abf2fe3f..5a7e41b65ef3 100644 --- a/sound/soc/intel/skylake/skl-sst.c +++ b/sound/soc/intel/skylake/skl-sst.c | |||
@@ -569,7 +569,7 @@ int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, | |||
569 | 569 | ||
570 | sst->fw_ops = skl_fw_ops; | 570 | sst->fw_ops = skl_fw_ops; |
571 | 571 | ||
572 | return 0; | 572 | return skl_dsp_acquire_irq(sst); |
573 | } | 573 | } |
574 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); | 574 | EXPORT_SYMBOL_GPL(skl_sst_dsp_init); |
575 | 575 | ||
diff --git a/sound/soc/intel/skylake/skl-topology.c b/sound/soc/intel/skylake/skl-topology.c index 81923da18ac2..73af6e19ebbd 100644 --- a/sound/soc/intel/skylake/skl-topology.c +++ b/sound/soc/intel/skylake/skl-topology.c | |||
@@ -190,7 +190,6 @@ skl_tplg_free_pipe_mcps(struct skl *skl, struct skl_module_cfg *mconfig) | |||
190 | u8 res_idx = mconfig->res_idx; | 190 | u8 res_idx = mconfig->res_idx; |
191 | struct skl_module_res *res = &mconfig->module->resources[res_idx]; | 191 | struct skl_module_res *res = &mconfig->module->resources[res_idx]; |
192 | 192 | ||
193 | res = &mconfig->module->resources[res_idx]; | ||
194 | skl->resource.mcps -= res->cps; | 193 | skl->resource.mcps -= res->cps; |
195 | } | 194 | } |
196 | 195 | ||
@@ -3056,11 +3055,13 @@ static int skl_tplg_get_int_tkn(struct device *dev, | |||
3056 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, | 3055 | struct snd_soc_tplg_vendor_value_elem *tkn_elem, |
3057 | struct skl *skl) | 3056 | struct skl *skl) |
3058 | { | 3057 | { |
3059 | int tkn_count = 0, ret; | 3058 | int tkn_count = 0, ret, size; |
3060 | static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; | 3059 | static int mod_idx, res_val_idx, intf_val_idx, dir, pin_idx; |
3061 | struct skl_module_res *res = NULL; | 3060 | struct skl_module_res *res = NULL; |
3062 | struct skl_module_iface *fmt = NULL; | 3061 | struct skl_module_iface *fmt = NULL; |
3063 | struct skl_module *mod = NULL; | 3062 | struct skl_module *mod = NULL; |
3063 | static struct skl_astate_param *astate_table; | ||
3064 | static int astate_cfg_idx, count; | ||
3064 | int i; | 3065 | int i; |
3065 | 3066 | ||
3066 | if (skl->modules) { | 3067 | if (skl->modules) { |
@@ -3093,6 +3094,46 @@ static int skl_tplg_get_int_tkn(struct device *dev, | |||
3093 | mod_idx = tkn_elem->value; | 3094 | mod_idx = tkn_elem->value; |
3094 | break; | 3095 | break; |
3095 | 3096 | ||
3097 | case SKL_TKN_U32_ASTATE_COUNT: | ||
3098 | if (astate_table != NULL) { | ||
3099 | dev_err(dev, "More than one entry for A-State count"); | ||
3100 | return -EINVAL; | ||
3101 | } | ||
3102 | |||
3103 | if (tkn_elem->value > SKL_MAX_ASTATE_CFG) { | ||
3104 | dev_err(dev, "Invalid A-State count %d\n", | ||
3105 | tkn_elem->value); | ||
3106 | return -EINVAL; | ||
3107 | } | ||
3108 | |||
3109 | size = tkn_elem->value * sizeof(struct skl_astate_param) + | ||
3110 | sizeof(count); | ||
3111 | skl->cfg.astate_cfg = devm_kzalloc(dev, size, GFP_KERNEL); | ||
3112 | if (!skl->cfg.astate_cfg) | ||
3113 | return -ENOMEM; | ||
3114 | |||
3115 | astate_table = skl->cfg.astate_cfg->astate_table; | ||
3116 | count = skl->cfg.astate_cfg->count = tkn_elem->value; | ||
3117 | break; | ||
3118 | |||
3119 | case SKL_TKN_U32_ASTATE_IDX: | ||
3120 | if (tkn_elem->value >= count) { | ||
3121 | dev_err(dev, "Invalid A-State index %d\n", | ||
3122 | tkn_elem->value); | ||
3123 | return -EINVAL; | ||
3124 | } | ||
3125 | |||
3126 | astate_cfg_idx = tkn_elem->value; | ||
3127 | break; | ||
3128 | |||
3129 | case SKL_TKN_U32_ASTATE_KCPS: | ||
3130 | astate_table[astate_cfg_idx].kcps = tkn_elem->value; | ||
3131 | break; | ||
3132 | |||
3133 | case SKL_TKN_U32_ASTATE_CLK_SRC: | ||
3134 | astate_table[astate_cfg_idx].clk_src = tkn_elem->value; | ||
3135 | break; | ||
3136 | |||
3096 | case SKL_TKN_U8_IN_PIN_TYPE: | 3137 | case SKL_TKN_U8_IN_PIN_TYPE: |
3097 | case SKL_TKN_U8_OUT_PIN_TYPE: | 3138 | case SKL_TKN_U8_OUT_PIN_TYPE: |
3098 | case SKL_TKN_U8_IN_QUEUE_COUNT: | 3139 | case SKL_TKN_U8_IN_QUEUE_COUNT: |
diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c index 31d8634e8aa1..32ce64c6b2dc 100644 --- a/sound/soc/intel/skylake/skl.c +++ b/sound/soc/intel/skylake/skl.c | |||
@@ -355,6 +355,7 @@ static int skl_resume(struct device *dev) | |||
355 | 355 | ||
356 | if (ebus->cmd_dma_state) | 356 | if (ebus->cmd_dma_state) |
357 | snd_hdac_bus_init_cmd_io(&ebus->bus); | 357 | snd_hdac_bus_init_cmd_io(&ebus->bus); |
358 | ret = 0; | ||
358 | } else { | 359 | } else { |
359 | ret = _skl_resume(ebus); | 360 | ret = _skl_resume(ebus); |
360 | 361 | ||
@@ -435,19 +436,51 @@ static int skl_free(struct hdac_ext_bus *ebus) | |||
435 | return 0; | 436 | return 0; |
436 | } | 437 | } |
437 | 438 | ||
438 | static int skl_machine_device_register(struct skl *skl, void *driver_data) | 439 | /* |
440 | * For each ssp there are 3 clocks (mclk/sclk/sclkfs). | ||
441 | * e.g. for ssp0, clocks will be named as | ||
442 | * "ssp0_mclk", "ssp0_sclk", "ssp0_sclkfs" | ||
443 | * So for skl+, there are 6 ssps, so 18 clocks will be created. | ||
444 | */ | ||
445 | static struct skl_ssp_clk skl_ssp_clks[] = { | ||
446 | {.name = "ssp0_mclk"}, {.name = "ssp1_mclk"}, {.name = "ssp2_mclk"}, | ||
447 | {.name = "ssp3_mclk"}, {.name = "ssp4_mclk"}, {.name = "ssp5_mclk"}, | ||
448 | {.name = "ssp0_sclk"}, {.name = "ssp1_sclk"}, {.name = "ssp2_sclk"}, | ||
449 | {.name = "ssp3_sclk"}, {.name = "ssp4_sclk"}, {.name = "ssp5_sclk"}, | ||
450 | {.name = "ssp0_sclkfs"}, {.name = "ssp1_sclkfs"}, | ||
451 | {.name = "ssp2_sclkfs"}, | ||
452 | {.name = "ssp3_sclkfs"}, {.name = "ssp4_sclkfs"}, | ||
453 | {.name = "ssp5_sclkfs"}, | ||
454 | }; | ||
455 | |||
456 | static int skl_find_machine(struct skl *skl, void *driver_data) | ||
439 | { | 457 | { |
440 | struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); | ||
441 | struct platform_device *pdev; | ||
442 | struct snd_soc_acpi_mach *mach = driver_data; | 458 | struct snd_soc_acpi_mach *mach = driver_data; |
443 | int ret; | 459 | struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); |
460 | struct skl_machine_pdata *pdata; | ||
444 | 461 | ||
445 | mach = snd_soc_acpi_find_machine(mach); | 462 | mach = snd_soc_acpi_find_machine(mach); |
446 | if (mach == NULL) { | 463 | if (mach == NULL) { |
447 | dev_err(bus->dev, "No matching machine driver found\n"); | 464 | dev_err(bus->dev, "No matching machine driver found\n"); |
448 | return -ENODEV; | 465 | return -ENODEV; |
449 | } | 466 | } |
467 | |||
468 | skl->mach = mach; | ||
450 | skl->fw_name = mach->fw_filename; | 469 | skl->fw_name = mach->fw_filename; |
470 | pdata = skl->mach->pdata; | ||
471 | |||
472 | if (mach->pdata) | ||
473 | skl->use_tplg_pcm = pdata->use_tplg_pcm; | ||
474 | |||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static int skl_machine_device_register(struct skl *skl) | ||
479 | { | ||
480 | struct hdac_bus *bus = ebus_to_hbus(&skl->ebus); | ||
481 | struct snd_soc_acpi_mach *mach = skl->mach; | ||
482 | struct platform_device *pdev; | ||
483 | int ret; | ||
451 | 484 | ||
452 | pdev = platform_device_alloc(mach->drv_name, -1); | 485 | pdev = platform_device_alloc(mach->drv_name, -1); |
453 | if (pdev == NULL) { | 486 | if (pdev == NULL) { |
@@ -462,11 +495,8 @@ static int skl_machine_device_register(struct skl *skl, void *driver_data) | |||
462 | return -EIO; | 495 | return -EIO; |
463 | } | 496 | } |
464 | 497 | ||
465 | if (mach->pdata) { | 498 | if (mach->pdata) |
466 | skl->use_tplg_pcm = | ||
467 | ((struct skl_machine_pdata *)mach->pdata)->use_tplg_pcm; | ||
468 | dev_set_drvdata(&pdev->dev, mach->pdata); | 499 | dev_set_drvdata(&pdev->dev, mach->pdata); |
469 | } | ||
470 | 500 | ||
471 | skl->i2s_dev = pdev; | 501 | skl->i2s_dev = pdev; |
472 | 502 | ||
@@ -509,6 +539,74 @@ static void skl_dmic_device_unregister(struct skl *skl) | |||
509 | platform_device_unregister(skl->dmic_dev); | 539 | platform_device_unregister(skl->dmic_dev); |
510 | } | 540 | } |
511 | 541 | ||
542 | static struct skl_clk_parent_src skl_clk_src[] = { | ||
543 | { .clk_id = SKL_XTAL, .name = "xtal" }, | ||
544 | { .clk_id = SKL_CARDINAL, .name = "cardinal", .rate = 24576000 }, | ||
545 | { .clk_id = SKL_PLL, .name = "pll", .rate = 96000000 }, | ||
546 | }; | ||
547 | |||
548 | struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id) | ||
549 | { | ||
550 | unsigned int i; | ||
551 | |||
552 | for (i = 0; i < ARRAY_SIZE(skl_clk_src); i++) { | ||
553 | if (skl_clk_src[i].clk_id == clk_id) | ||
554 | return &skl_clk_src[i]; | ||
555 | } | ||
556 | |||
557 | return NULL; | ||
558 | } | ||
559 | |||
560 | static void init_skl_xtal_rate(int pci_id) | ||
561 | { | ||
562 | switch (pci_id) { | ||
563 | case 0x9d70: | ||
564 | case 0x9d71: | ||
565 | skl_clk_src[0].rate = 24000000; | ||
566 | return; | ||
567 | |||
568 | default: | ||
569 | skl_clk_src[0].rate = 19200000; | ||
570 | return; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | static int skl_clock_device_register(struct skl *skl) | ||
575 | { | ||
576 | struct platform_device_info pdevinfo = {NULL}; | ||
577 | struct skl_clk_pdata *clk_pdata; | ||
578 | |||
579 | clk_pdata = devm_kzalloc(&skl->pci->dev, sizeof(*clk_pdata), | ||
580 | GFP_KERNEL); | ||
581 | if (!clk_pdata) | ||
582 | return -ENOMEM; | ||
583 | |||
584 | init_skl_xtal_rate(skl->pci->device); | ||
585 | |||
586 | clk_pdata->parent_clks = skl_clk_src; | ||
587 | clk_pdata->ssp_clks = skl_ssp_clks; | ||
588 | clk_pdata->num_clks = ARRAY_SIZE(skl_ssp_clks); | ||
589 | |||
590 | /* Query NHLT to fill the rates and parent */ | ||
591 | skl_get_clks(skl, clk_pdata->ssp_clks); | ||
592 | clk_pdata->pvt_data = skl; | ||
593 | |||
594 | /* Register Platform device */ | ||
595 | pdevinfo.parent = &skl->pci->dev; | ||
596 | pdevinfo.id = -1; | ||
597 | pdevinfo.name = "skl-ssp-clk"; | ||
598 | pdevinfo.data = clk_pdata; | ||
599 | pdevinfo.size_data = sizeof(*clk_pdata); | ||
600 | skl->clk_dev = platform_device_register_full(&pdevinfo); | ||
601 | return PTR_ERR_OR_ZERO(skl->clk_dev); | ||
602 | } | ||
603 | |||
604 | static void skl_clock_device_unregister(struct skl *skl) | ||
605 | { | ||
606 | if (skl->clk_dev) | ||
607 | platform_device_unregister(skl->clk_dev); | ||
608 | } | ||
609 | |||
512 | /* | 610 | /* |
513 | * Probe the given codec address | 611 | * Probe the given codec address |
514 | */ | 612 | */ |
@@ -615,18 +713,30 @@ static void skl_probe_work(struct work_struct *work) | |||
615 | /* create codec instances */ | 713 | /* create codec instances */ |
616 | skl_codec_create(ebus); | 714 | skl_codec_create(ebus); |
617 | 715 | ||
716 | /* register platform dai and controls */ | ||
717 | err = skl_platform_register(bus->dev); | ||
718 | if (err < 0) { | ||
719 | dev_err(bus->dev, "platform register failed: %d\n", err); | ||
720 | return; | ||
721 | } | ||
722 | |||
723 | if (bus->ppcap) { | ||
724 | err = skl_machine_device_register(skl); | ||
725 | if (err < 0) { | ||
726 | dev_err(bus->dev, "machine register failed: %d\n", err); | ||
727 | goto out_err; | ||
728 | } | ||
729 | } | ||
730 | |||
618 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { | 731 | if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { |
619 | err = snd_hdac_display_power(bus, false); | 732 | err = snd_hdac_display_power(bus, false); |
620 | if (err < 0) { | 733 | if (err < 0) { |
621 | dev_err(bus->dev, "Cannot turn off display power on i915\n"); | 734 | dev_err(bus->dev, "Cannot turn off display power on i915\n"); |
735 | skl_machine_device_unregister(skl); | ||
622 | return; | 736 | return; |
623 | } | 737 | } |
624 | } | 738 | } |
625 | 739 | ||
626 | /* register platform dai and controls */ | ||
627 | err = skl_platform_register(bus->dev); | ||
628 | if (err < 0) | ||
629 | return; | ||
630 | /* | 740 | /* |
631 | * we are done probing so decrement link counts | 741 | * we are done probing so decrement link counts |
632 | */ | 742 | */ |
@@ -791,18 +901,21 @@ static int skl_probe(struct pci_dev *pci, | |||
791 | 901 | ||
792 | /* check if dsp is there */ | 902 | /* check if dsp is there */ |
793 | if (bus->ppcap) { | 903 | if (bus->ppcap) { |
794 | err = skl_machine_device_register(skl, | 904 | /* create device for dsp clk */ |
795 | (void *)pci_id->driver_data); | 905 | err = skl_clock_device_register(skl); |
906 | if (err < 0) | ||
907 | goto out_clk_free; | ||
908 | |||
909 | err = skl_find_machine(skl, (void *)pci_id->driver_data); | ||
796 | if (err < 0) | 910 | if (err < 0) |
797 | goto out_nhlt_free; | 911 | goto out_nhlt_free; |
798 | 912 | ||
799 | err = skl_init_dsp(skl); | 913 | err = skl_init_dsp(skl); |
800 | if (err < 0) { | 914 | if (err < 0) { |
801 | dev_dbg(bus->dev, "error failed to register dsp\n"); | 915 | dev_dbg(bus->dev, "error failed to register dsp\n"); |
802 | goto out_mach_free; | 916 | goto out_nhlt_free; |
803 | } | 917 | } |
804 | skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; | 918 | skl->skl_sst->enable_miscbdcge = skl_enable_miscbdcge; |
805 | |||
806 | } | 919 | } |
807 | if (bus->mlcap) | 920 | if (bus->mlcap) |
808 | snd_hdac_ext_bus_get_ml_capabilities(ebus); | 921 | snd_hdac_ext_bus_get_ml_capabilities(ebus); |
@@ -820,8 +933,8 @@ static int skl_probe(struct pci_dev *pci, | |||
820 | 933 | ||
821 | out_dsp_free: | 934 | out_dsp_free: |
822 | skl_free_dsp(skl); | 935 | skl_free_dsp(skl); |
823 | out_mach_free: | 936 | out_clk_free: |
824 | skl_machine_device_unregister(skl); | 937 | skl_clock_device_unregister(skl); |
825 | out_nhlt_free: | 938 | out_nhlt_free: |
826 | skl_nhlt_free(skl->nhlt); | 939 | skl_nhlt_free(skl->nhlt); |
827 | out_free: | 940 | out_free: |
@@ -872,6 +985,7 @@ static void skl_remove(struct pci_dev *pci) | |||
872 | skl_free_dsp(skl); | 985 | skl_free_dsp(skl); |
873 | skl_machine_device_unregister(skl); | 986 | skl_machine_device_unregister(skl); |
874 | skl_dmic_device_unregister(skl); | 987 | skl_dmic_device_unregister(skl); |
988 | skl_clock_device_unregister(skl); | ||
875 | skl_nhlt_remove_sysfs(skl); | 989 | skl_nhlt_remove_sysfs(skl); |
876 | skl_nhlt_free(skl->nhlt); | 990 | skl_nhlt_free(skl->nhlt); |
877 | skl_free(ebus); | 991 | skl_free(ebus); |
diff --git a/sound/soc/intel/skylake/skl.h b/sound/soc/intel/skylake/skl.h index e00cde8200dd..f411579bc713 100644 --- a/sound/soc/intel/skylake/skl.h +++ b/sound/soc/intel/skylake/skl.h | |||
@@ -25,9 +25,12 @@ | |||
25 | #include <sound/hdaudio_ext.h> | 25 | #include <sound/hdaudio_ext.h> |
26 | #include <sound/soc.h> | 26 | #include <sound/soc.h> |
27 | #include "skl-nhlt.h" | 27 | #include "skl-nhlt.h" |
28 | #include "skl-ssp-clk.h" | ||
28 | 29 | ||
29 | #define SKL_SUSPEND_DELAY 2000 | 30 | #define SKL_SUSPEND_DELAY 2000 |
30 | 31 | ||
32 | #define SKL_MAX_ASTATE_CFG 3 | ||
33 | |||
31 | #define AZX_PCIREG_PGCTL 0x44 | 34 | #define AZX_PCIREG_PGCTL 0x44 |
32 | #define AZX_PGCTL_LSRMD_MASK (1 << 4) | 35 | #define AZX_PGCTL_LSRMD_MASK (1 << 4) |
33 | #define AZX_PCIREG_CGCTL 0x48 | 36 | #define AZX_PCIREG_CGCTL 0x48 |
@@ -45,6 +48,20 @@ struct skl_dsp_resource { | |||
45 | 48 | ||
46 | struct skl_debug; | 49 | struct skl_debug; |
47 | 50 | ||
51 | struct skl_astate_param { | ||
52 | u32 kcps; | ||
53 | u32 clk_src; | ||
54 | }; | ||
55 | |||
56 | struct skl_astate_config { | ||
57 | u32 count; | ||
58 | struct skl_astate_param astate_table[0]; | ||
59 | }; | ||
60 | |||
61 | struct skl_fw_config { | ||
62 | struct skl_astate_config *astate_cfg; | ||
63 | }; | ||
64 | |||
48 | struct skl { | 65 | struct skl { |
49 | struct hdac_ext_bus ebus; | 66 | struct hdac_ext_bus ebus; |
50 | struct pci_dev *pci; | 67 | struct pci_dev *pci; |
@@ -52,6 +69,7 @@ struct skl { | |||
52 | unsigned int init_done:1; /* delayed init status */ | 69 | unsigned int init_done:1; /* delayed init status */ |
53 | struct platform_device *dmic_dev; | 70 | struct platform_device *dmic_dev; |
54 | struct platform_device *i2s_dev; | 71 | struct platform_device *i2s_dev; |
72 | struct platform_device *clk_dev; | ||
55 | struct snd_soc_platform *platform; | 73 | struct snd_soc_platform *platform; |
56 | struct snd_soc_dai_driver *dais; | 74 | struct snd_soc_dai_driver *dais; |
57 | 75 | ||
@@ -75,6 +93,8 @@ struct skl { | |||
75 | u8 nr_modules; | 93 | u8 nr_modules; |
76 | struct skl_module **modules; | 94 | struct skl_module **modules; |
77 | bool use_tplg_pcm; | 95 | bool use_tplg_pcm; |
96 | struct skl_fw_config cfg; | ||
97 | struct snd_soc_acpi_mach *mach; | ||
78 | }; | 98 | }; |
79 | 99 | ||
80 | #define skl_to_ebus(s) (&(s)->ebus) | 100 | #define skl_to_ebus(s) (&(s)->ebus) |
@@ -125,6 +145,8 @@ const struct skl_dsp_ops *skl_get_dsp_ops(int pci_id); | |||
125 | void skl_update_d0i3c(struct device *dev, bool enable); | 145 | void skl_update_d0i3c(struct device *dev, bool enable); |
126 | int skl_nhlt_create_sysfs(struct skl *skl); | 146 | int skl_nhlt_create_sysfs(struct skl *skl); |
127 | void skl_nhlt_remove_sysfs(struct skl *skl); | 147 | void skl_nhlt_remove_sysfs(struct skl *skl); |
148 | void skl_get_clks(struct skl *skl, struct skl_ssp_clk *ssp_clks); | ||
149 | struct skl_clk_parent_src *skl_get_parent_clk(u8 clk_id); | ||
128 | 150 | ||
129 | struct skl_module_cfg; | 151 | struct skl_module_cfg; |
130 | 152 | ||
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c index affa7fb25dd9..949fc3a1d025 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.c | |||
@@ -14,451 +14,285 @@ | |||
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <sound/soc.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/pm_runtime.h> | ||
20 | |||
21 | #include "mt2701-afe-common.h" | 17 | #include "mt2701-afe-common.h" |
22 | #include "mt2701-afe-clock-ctrl.h" | 18 | #include "mt2701-afe-clock-ctrl.h" |
23 | 19 | ||
24 | static const char *aud_clks[MT2701_CLOCK_NUM] = { | 20 | static const char *const base_clks[] = { |
25 | [MT2701_AUD_INFRA_SYS_AUDIO] = "infra_sys_audio_clk", | 21 | [MT2701_INFRA_SYS_AUDIO] = "infra_sys_audio_clk", |
26 | [MT2701_AUD_AUD_MUX1_SEL] = "top_audio_mux1_sel", | 22 | [MT2701_TOP_AUD_MCLK_SRC0] = "top_audio_mux1_sel", |
27 | [MT2701_AUD_AUD_MUX2_SEL] = "top_audio_mux2_sel", | 23 | [MT2701_TOP_AUD_MCLK_SRC1] = "top_audio_mux2_sel", |
28 | [MT2701_AUD_AUD_MUX1_DIV] = "top_audio_mux1_div", | 24 | [MT2701_TOP_AUD_A1SYS] = "top_audio_a1sys_hp", |
29 | [MT2701_AUD_AUD_MUX2_DIV] = "top_audio_mux2_div", | 25 | [MT2701_TOP_AUD_A2SYS] = "top_audio_a2sys_hp", |
30 | [MT2701_AUD_AUD_48K_TIMING] = "top_audio_48k_timing", | 26 | [MT2701_AUDSYS_AFE] = "audio_afe_pd", |
31 | [MT2701_AUD_AUD_44K_TIMING] = "top_audio_44k_timing", | 27 | [MT2701_AUDSYS_AFE_CONN] = "audio_afe_conn_pd", |
32 | [MT2701_AUD_AUDPLL_MUX_SEL] = "top_audpll_mux_sel", | 28 | [MT2701_AUDSYS_A1SYS] = "audio_a1sys_pd", |
33 | [MT2701_AUD_APLL_SEL] = "top_apll_sel", | 29 | [MT2701_AUDSYS_A2SYS] = "audio_a2sys_pd", |
34 | [MT2701_AUD_AUD1PLL_98M] = "top_aud1_pll_98M", | ||
35 | [MT2701_AUD_AUD2PLL_90M] = "top_aud2_pll_90M", | ||
36 | [MT2701_AUD_HADDS2PLL_98M] = "top_hadds2_pll_98M", | ||
37 | [MT2701_AUD_HADDS2PLL_294M] = "top_hadds2_pll_294M", | ||
38 | [MT2701_AUD_AUDPLL] = "top_audpll", | ||
39 | [MT2701_AUD_AUDPLL_D4] = "top_audpll_d4", | ||
40 | [MT2701_AUD_AUDPLL_D8] = "top_audpll_d8", | ||
41 | [MT2701_AUD_AUDPLL_D16] = "top_audpll_d16", | ||
42 | [MT2701_AUD_AUDPLL_D24] = "top_audpll_d24", | ||
43 | [MT2701_AUD_AUDINTBUS] = "top_audintbus_sel", | ||
44 | [MT2701_AUD_CLK_26M] = "clk_26m", | ||
45 | [MT2701_AUD_SYSPLL1_D4] = "top_syspll1_d4", | ||
46 | [MT2701_AUD_AUD_K1_SRC_SEL] = "top_aud_k1_src_sel", | ||
47 | [MT2701_AUD_AUD_K2_SRC_SEL] = "top_aud_k2_src_sel", | ||
48 | [MT2701_AUD_AUD_K3_SRC_SEL] = "top_aud_k3_src_sel", | ||
49 | [MT2701_AUD_AUD_K4_SRC_SEL] = "top_aud_k4_src_sel", | ||
50 | [MT2701_AUD_AUD_K5_SRC_SEL] = "top_aud_k5_src_sel", | ||
51 | [MT2701_AUD_AUD_K6_SRC_SEL] = "top_aud_k6_src_sel", | ||
52 | [MT2701_AUD_AUD_K1_SRC_DIV] = "top_aud_k1_src_div", | ||
53 | [MT2701_AUD_AUD_K2_SRC_DIV] = "top_aud_k2_src_div", | ||
54 | [MT2701_AUD_AUD_K3_SRC_DIV] = "top_aud_k3_src_div", | ||
55 | [MT2701_AUD_AUD_K4_SRC_DIV] = "top_aud_k4_src_div", | ||
56 | [MT2701_AUD_AUD_K5_SRC_DIV] = "top_aud_k5_src_div", | ||
57 | [MT2701_AUD_AUD_K6_SRC_DIV] = "top_aud_k6_src_div", | ||
58 | [MT2701_AUD_AUD_I2S1_MCLK] = "top_aud_i2s1_mclk", | ||
59 | [MT2701_AUD_AUD_I2S2_MCLK] = "top_aud_i2s2_mclk", | ||
60 | [MT2701_AUD_AUD_I2S3_MCLK] = "top_aud_i2s3_mclk", | ||
61 | [MT2701_AUD_AUD_I2S4_MCLK] = "top_aud_i2s4_mclk", | ||
62 | [MT2701_AUD_AUD_I2S5_MCLK] = "top_aud_i2s5_mclk", | ||
63 | [MT2701_AUD_AUD_I2S6_MCLK] = "top_aud_i2s6_mclk", | ||
64 | [MT2701_AUD_ASM_M_SEL] = "top_asm_m_sel", | ||
65 | [MT2701_AUD_ASM_H_SEL] = "top_asm_h_sel", | ||
66 | [MT2701_AUD_UNIVPLL2_D4] = "top_univpll2_d4", | ||
67 | [MT2701_AUD_UNIVPLL2_D2] = "top_univpll2_d2", | ||
68 | [MT2701_AUD_SYSPLL_D5] = "top_syspll_d5", | ||
69 | }; | 30 | }; |
70 | 31 | ||
71 | int mt2701_init_clock(struct mtk_base_afe *afe) | 32 | int mt2701_init_clock(struct mtk_base_afe *afe) |
72 | { | 33 | { |
73 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 34 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
74 | int i = 0; | 35 | int i; |
75 | 36 | ||
76 | for (i = 0; i < MT2701_CLOCK_NUM; i++) { | 37 | for (i = 0; i < MT2701_BASE_CLK_NUM; i++) { |
77 | afe_priv->clocks[i] = devm_clk_get(afe->dev, aud_clks[i]); | 38 | afe_priv->base_ck[i] = devm_clk_get(afe->dev, base_clks[i]); |
78 | if (IS_ERR(afe_priv->clocks[i])) { | 39 | if (IS_ERR(afe_priv->base_ck[i])) { |
79 | dev_warn(afe->dev, "%s devm_clk_get %s fail\n", | 40 | dev_err(afe->dev, "failed to get %s\n", base_clks[i]); |
80 | __func__, aud_clks[i]); | 41 | return PTR_ERR(afe_priv->base_ck[i]); |
81 | return PTR_ERR(aud_clks[i]); | 42 | } |
43 | } | ||
44 | |||
45 | /* Get I2S related clocks */ | ||
46 | for (i = 0; i < MT2701_I2S_NUM; i++) { | ||
47 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i]; | ||
48 | char name[13]; | ||
49 | |||
50 | snprintf(name, sizeof(name), "i2s%d_src_sel", i); | ||
51 | i2s_path->sel_ck = devm_clk_get(afe->dev, name); | ||
52 | if (IS_ERR(i2s_path->sel_ck)) { | ||
53 | dev_err(afe->dev, "failed to get %s\n", name); | ||
54 | return PTR_ERR(i2s_path->sel_ck); | ||
55 | } | ||
56 | |||
57 | snprintf(name, sizeof(name), "i2s%d_src_div", i); | ||
58 | i2s_path->div_ck = devm_clk_get(afe->dev, name); | ||
59 | if (IS_ERR(i2s_path->div_ck)) { | ||
60 | dev_err(afe->dev, "failed to get %s\n", name); | ||
61 | return PTR_ERR(i2s_path->div_ck); | ||
62 | } | ||
63 | |||
64 | snprintf(name, sizeof(name), "i2s%d_mclk_en", i); | ||
65 | i2s_path->mclk_ck = devm_clk_get(afe->dev, name); | ||
66 | if (IS_ERR(i2s_path->mclk_ck)) { | ||
67 | dev_err(afe->dev, "failed to get %s\n", name); | ||
68 | return PTR_ERR(i2s_path->mclk_ck); | ||
69 | } | ||
70 | |||
71 | snprintf(name, sizeof(name), "i2so%d_hop_ck", i); | ||
72 | i2s_path->hop_ck[I2S_OUT] = devm_clk_get(afe->dev, name); | ||
73 | if (IS_ERR(i2s_path->hop_ck[I2S_OUT])) { | ||
74 | dev_err(afe->dev, "failed to get %s\n", name); | ||
75 | return PTR_ERR(i2s_path->hop_ck[I2S_OUT]); | ||
76 | } | ||
77 | |||
78 | snprintf(name, sizeof(name), "i2si%d_hop_ck", i); | ||
79 | i2s_path->hop_ck[I2S_IN] = devm_clk_get(afe->dev, name); | ||
80 | if (IS_ERR(i2s_path->hop_ck[I2S_IN])) { | ||
81 | dev_err(afe->dev, "failed to get %s\n", name); | ||
82 | return PTR_ERR(i2s_path->hop_ck[I2S_IN]); | ||
83 | } | ||
84 | |||
85 | snprintf(name, sizeof(name), "asrc%d_out_ck", i); | ||
86 | i2s_path->asrco_ck = devm_clk_get(afe->dev, name); | ||
87 | if (IS_ERR(i2s_path->asrco_ck)) { | ||
88 | dev_err(afe->dev, "failed to get %s\n", name); | ||
89 | return PTR_ERR(i2s_path->asrco_ck); | ||
82 | } | 90 | } |
83 | } | 91 | } |
84 | 92 | ||
93 | /* Some platforms may support BT path */ | ||
94 | afe_priv->mrgif_ck = devm_clk_get(afe->dev, "audio_mrgif_pd"); | ||
95 | if (IS_ERR(afe_priv->mrgif_ck)) { | ||
96 | if (PTR_ERR(afe_priv->mrgif_ck) == -EPROBE_DEFER) | ||
97 | return -EPROBE_DEFER; | ||
98 | |||
99 | afe_priv->mrgif_ck = NULL; | ||
100 | } | ||
101 | |||
85 | return 0; | 102 | return 0; |
86 | } | 103 | } |
87 | 104 | ||
88 | int mt2701_afe_enable_clock(struct mtk_base_afe *afe) | 105 | int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir) |
89 | { | 106 | { |
90 | int ret = 0; | 107 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
108 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; | ||
109 | int ret; | ||
91 | 110 | ||
92 | ret = mt2701_turn_on_a1sys_clock(afe); | 111 | ret = clk_prepare_enable(i2s_path->asrco_ck); |
93 | if (ret) { | 112 | if (ret) { |
94 | dev_err(afe->dev, "%s turn_on_a1sys_clock fail %d\n", | 113 | dev_err(afe->dev, "failed to enable ASRC clock %d\n", ret); |
95 | __func__, ret); | ||
96 | return ret; | 114 | return ret; |
97 | } | 115 | } |
98 | 116 | ||
99 | ret = mt2701_turn_on_a2sys_clock(afe); | 117 | ret = clk_prepare_enable(i2s_path->hop_ck[dir]); |
100 | if (ret) { | 118 | if (ret) { |
101 | dev_err(afe->dev, "%s turn_on_a2sys_clock fail %d\n", | 119 | dev_err(afe->dev, "failed to enable I2S clock %d\n", ret); |
102 | __func__, ret); | 120 | goto err_hop_ck; |
103 | mt2701_turn_off_a1sys_clock(afe); | ||
104 | return ret; | ||
105 | } | 121 | } |
106 | 122 | ||
107 | ret = mt2701_turn_on_afe_clock(afe); | 123 | return 0; |
108 | if (ret) { | ||
109 | dev_err(afe->dev, "%s turn_on_afe_clock fail %d\n", | ||
110 | __func__, ret); | ||
111 | mt2701_turn_off_a1sys_clock(afe); | ||
112 | mt2701_turn_off_a2sys_clock(afe); | ||
113 | return ret; | ||
114 | } | ||
115 | 124 | ||
116 | regmap_update_bits(afe->regmap, ASYS_TOP_CON, | 125 | err_hop_ck: |
117 | AUDIO_TOP_CON0_A1SYS_A2SYS_ON, | 126 | clk_disable_unprepare(i2s_path->asrco_ck); |
118 | AUDIO_TOP_CON0_A1SYS_A2SYS_ON); | ||
119 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, | ||
120 | AFE_DAC_CON0_AFE_ON, | ||
121 | AFE_DAC_CON0_AFE_ON); | ||
122 | regmap_write(afe->regmap, PWR2_TOP_CON, | ||
123 | PWR2_TOP_CON_INIT_VAL); | ||
124 | regmap_write(afe->regmap, PWR1_ASM_CON1, | ||
125 | PWR1_ASM_CON1_INIT_VAL); | ||
126 | regmap_write(afe->regmap, PWR2_ASM_CON1, | ||
127 | PWR2_ASM_CON1_INIT_VAL); | ||
128 | 127 | ||
129 | return 0; | 128 | return ret; |
130 | } | 129 | } |
131 | 130 | ||
132 | void mt2701_afe_disable_clock(struct mtk_base_afe *afe) | 131 | void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir) |
133 | { | 132 | { |
134 | mt2701_turn_off_afe_clock(afe); | 133 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
135 | mt2701_turn_off_a1sys_clock(afe); | 134 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; |
136 | mt2701_turn_off_a2sys_clock(afe); | 135 | |
137 | regmap_update_bits(afe->regmap, ASYS_TOP_CON, | 136 | clk_disable_unprepare(i2s_path->hop_ck[dir]); |
138 | AUDIO_TOP_CON0_A1SYS_A2SYS_ON, 0); | 137 | clk_disable_unprepare(i2s_path->asrco_ck); |
139 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, | ||
140 | AFE_DAC_CON0_AFE_ON, 0); | ||
141 | } | 138 | } |
142 | 139 | ||
143 | int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe) | 140 | int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id) |
144 | { | 141 | { |
145 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 142 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
146 | int ret = 0; | 143 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; |
147 | |||
148 | /* Set Mux */ | ||
149 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); | ||
150 | if (ret) { | ||
151 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
152 | __func__, aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret); | ||
153 | goto A1SYS_CLK_AUD_MUX1_SEL_ERR; | ||
154 | } | ||
155 | |||
156 | ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL], | ||
157 | afe_priv->clocks[MT2701_AUD_AUD1PLL_98M]); | ||
158 | if (ret) { | ||
159 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, | ||
160 | aud_clks[MT2701_AUD_AUD_MUX1_SEL], | ||
161 | aud_clks[MT2701_AUD_AUD1PLL_98M], ret); | ||
162 | goto A1SYS_CLK_AUD_MUX1_SEL_ERR; | ||
163 | } | ||
164 | |||
165 | /* Set Divider */ | ||
166 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); | ||
167 | if (ret) { | ||
168 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
169 | __func__, | ||
170 | aud_clks[MT2701_AUD_AUD_MUX1_DIV], | ||
171 | ret); | ||
172 | goto A1SYS_CLK_AUD_MUX1_DIV_ERR; | ||
173 | } | ||
174 | |||
175 | ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV], | ||
176 | MT2701_AUD_AUD_MUX1_DIV_RATE); | ||
177 | if (ret) { | ||
178 | dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__, | ||
179 | aud_clks[MT2701_AUD_AUD_MUX1_DIV], | ||
180 | MT2701_AUD_AUD_MUX1_DIV_RATE, ret); | ||
181 | goto A1SYS_CLK_AUD_MUX1_DIV_ERR; | ||
182 | } | ||
183 | 144 | ||
184 | /* Enable clock gate */ | 145 | return clk_prepare_enable(i2s_path->mclk_ck); |
185 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); | 146 | } |
186 | if (ret) { | ||
187 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
188 | __func__, aud_clks[MT2701_AUD_AUD_48K_TIMING], ret); | ||
189 | goto A1SYS_CLK_AUD_48K_ERR; | ||
190 | } | ||
191 | 147 | ||
192 | /* Enable infra audio */ | 148 | void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id) |
193 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 149 | { |
194 | if (ret) { | 150 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
195 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 151 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[id]; |
196 | __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); | ||
197 | goto A1SYS_CLK_INFRA_ERR; | ||
198 | } | ||
199 | 152 | ||
200 | return 0; | 153 | clk_disable_unprepare(i2s_path->mclk_ck); |
154 | } | ||
201 | 155 | ||
202 | A1SYS_CLK_INFRA_ERR: | 156 | int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe) |
203 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 157 | { |
204 | A1SYS_CLK_AUD_48K_ERR: | 158 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
205 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); | ||
206 | A1SYS_CLK_AUD_MUX1_DIV_ERR: | ||
207 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); | ||
208 | A1SYS_CLK_AUD_MUX1_SEL_ERR: | ||
209 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); | ||
210 | 159 | ||
211 | return ret; | 160 | return clk_prepare_enable(afe_priv->mrgif_ck); |
212 | } | 161 | } |
213 | 162 | ||
214 | void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe) | 163 | void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe) |
215 | { | 164 | { |
216 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 165 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
217 | 166 | ||
218 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 167 | clk_disable_unprepare(afe_priv->mrgif_ck); |
219 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_48K_TIMING]); | ||
220 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_DIV]); | ||
221 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); | ||
222 | } | 168 | } |
223 | 169 | ||
224 | int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe) | 170 | static int mt2701_afe_enable_audsys(struct mtk_base_afe *afe) |
225 | { | 171 | { |
226 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 172 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
227 | int ret = 0; | 173 | int ret; |
228 | 174 | ||
229 | /* Set Mux */ | 175 | /* Enable infra clock gate */ |
230 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); | 176 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]); |
231 | if (ret) { | 177 | if (ret) |
232 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 178 | return ret; |
233 | __func__, aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret); | ||
234 | goto A2SYS_CLK_AUD_MUX2_SEL_ERR; | ||
235 | } | ||
236 | 179 | ||
237 | ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL], | 180 | /* Enable top a1sys clock gate */ |
238 | afe_priv->clocks[MT2701_AUD_AUD2PLL_90M]); | 181 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]); |
239 | if (ret) { | 182 | if (ret) |
240 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, | 183 | goto err_a1sys; |
241 | aud_clks[MT2701_AUD_AUD_MUX2_SEL], | ||
242 | aud_clks[MT2701_AUD_AUD2PLL_90M], ret); | ||
243 | goto A2SYS_CLK_AUD_MUX2_SEL_ERR; | ||
244 | } | ||
245 | 184 | ||
246 | /* Set Divider */ | 185 | /* Enable top a2sys clock gate */ |
247 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); | 186 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]); |
248 | if (ret) { | 187 | if (ret) |
249 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 188 | goto err_a2sys; |
250 | __func__, aud_clks[MT2701_AUD_AUD_MUX2_DIV], ret); | ||
251 | goto A2SYS_CLK_AUD_MUX2_DIV_ERR; | ||
252 | } | ||
253 | 189 | ||
254 | ret = clk_set_rate(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV], | 190 | /* Internal clock gates */ |
255 | MT2701_AUD_AUD_MUX2_DIV_RATE); | 191 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE]); |
256 | if (ret) { | 192 | if (ret) |
257 | dev_err(afe->dev, "%s clk_set_parent %s-%d fail %d\n", __func__, | 193 | goto err_afe; |
258 | aud_clks[MT2701_AUD_AUD_MUX2_DIV], | ||
259 | MT2701_AUD_AUD_MUX2_DIV_RATE, ret); | ||
260 | goto A2SYS_CLK_AUD_MUX2_DIV_ERR; | ||
261 | } | ||
262 | 194 | ||
263 | /* Enable clock gate */ | 195 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]); |
264 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); | 196 | if (ret) |
265 | if (ret) { | 197 | goto err_audio_a1sys; |
266 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
267 | __func__, aud_clks[MT2701_AUD_AUD_44K_TIMING], ret); | ||
268 | goto A2SYS_CLK_AUD_44K_ERR; | ||
269 | } | ||
270 | 198 | ||
271 | /* Enable infra audio */ | 199 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]); |
272 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 200 | if (ret) |
273 | if (ret) { | 201 | goto err_audio_a2sys; |
274 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 202 | |
275 | __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); | 203 | ret = clk_prepare_enable(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]); |
276 | goto A2SYS_CLK_INFRA_ERR; | 204 | if (ret) |
277 | } | 205 | goto err_afe_conn; |
278 | 206 | ||
279 | return 0; | 207 | return 0; |
280 | 208 | ||
281 | A2SYS_CLK_INFRA_ERR: | 209 | err_afe_conn: |
282 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 210 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]); |
283 | A2SYS_CLK_AUD_44K_ERR: | 211 | err_audio_a2sys: |
284 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); | 212 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]); |
285 | A2SYS_CLK_AUD_MUX2_DIV_ERR: | 213 | err_audio_a1sys: |
286 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); | 214 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]); |
287 | A2SYS_CLK_AUD_MUX2_SEL_ERR: | 215 | err_afe: |
288 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); | 216 | clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]); |
217 | err_a2sys: | ||
218 | clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]); | ||
219 | err_a1sys: | ||
220 | clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]); | ||
289 | 221 | ||
290 | return ret; | 222 | return ret; |
291 | } | 223 | } |
292 | 224 | ||
293 | void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe) | 225 | static void mt2701_afe_disable_audsys(struct mtk_base_afe *afe) |
294 | { | 226 | { |
295 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 227 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
296 | 228 | ||
297 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 229 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE_CONN]); |
298 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_44K_TIMING]); | 230 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A2SYS]); |
299 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_DIV]); | 231 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_A1SYS]); |
300 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); | 232 | clk_disable_unprepare(afe_priv->base_ck[MT2701_AUDSYS_AFE]); |
233 | clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A1SYS]); | ||
234 | clk_disable_unprepare(afe_priv->base_ck[MT2701_TOP_AUD_A2SYS]); | ||
235 | clk_disable_unprepare(afe_priv->base_ck[MT2701_INFRA_SYS_AUDIO]); | ||
301 | } | 236 | } |
302 | 237 | ||
303 | int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe) | 238 | int mt2701_afe_enable_clock(struct mtk_base_afe *afe) |
304 | { | 239 | { |
305 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | ||
306 | int ret; | 240 | int ret; |
307 | 241 | ||
308 | /* enable INFRA_SYS */ | 242 | /* Enable audio system */ |
309 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 243 | ret = mt2701_afe_enable_audsys(afe); |
310 | if (ret) { | ||
311 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
312 | __func__, aud_clks[MT2701_AUD_INFRA_SYS_AUDIO], ret); | ||
313 | goto AFE_AUD_INFRA_ERR; | ||
314 | } | ||
315 | |||
316 | /* Set MT2701_AUD_AUDINTBUS to MT2701_AUD_SYSPLL1_D4 */ | ||
317 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); | ||
318 | if (ret) { | ||
319 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
320 | __func__, aud_clks[MT2701_AUD_AUDINTBUS], ret); | ||
321 | goto AFE_AUD_AUDINTBUS_ERR; | ||
322 | } | ||
323 | |||
324 | ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_AUDINTBUS], | ||
325 | afe_priv->clocks[MT2701_AUD_SYSPLL1_D4]); | ||
326 | if (ret) { | ||
327 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, | ||
328 | aud_clks[MT2701_AUD_AUDINTBUS], | ||
329 | aud_clks[MT2701_AUD_SYSPLL1_D4], ret); | ||
330 | goto AFE_AUD_AUDINTBUS_ERR; | ||
331 | } | ||
332 | |||
333 | /* Set MT2701_AUD_ASM_H_SEL to MT2701_AUD_UNIVPLL2_D2 */ | ||
334 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); | ||
335 | if (ret) { | 244 | if (ret) { |
336 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 245 | dev_err(afe->dev, "failed to enable audio system %d\n", ret); |
337 | __func__, aud_clks[MT2701_AUD_ASM_H_SEL], ret); | 246 | return ret; |
338 | goto AFE_AUD_ASM_H_ERR; | ||
339 | } | ||
340 | |||
341 | ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_H_SEL], | ||
342 | afe_priv->clocks[MT2701_AUD_UNIVPLL2_D2]); | ||
343 | if (ret) { | ||
344 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, | ||
345 | aud_clks[MT2701_AUD_ASM_H_SEL], | ||
346 | aud_clks[MT2701_AUD_UNIVPLL2_D2], ret); | ||
347 | goto AFE_AUD_ASM_H_ERR; | ||
348 | } | ||
349 | |||
350 | /* Set MT2701_AUD_ASM_M_SEL to MT2701_AUD_UNIVPLL2_D4 */ | ||
351 | ret = clk_prepare_enable(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); | ||
352 | if (ret) { | ||
353 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | ||
354 | __func__, aud_clks[MT2701_AUD_ASM_M_SEL], ret); | ||
355 | goto AFE_AUD_ASM_M_ERR; | ||
356 | } | 247 | } |
357 | 248 | ||
358 | ret = clk_set_parent(afe_priv->clocks[MT2701_AUD_ASM_M_SEL], | 249 | regmap_update_bits(afe->regmap, ASYS_TOP_CON, |
359 | afe_priv->clocks[MT2701_AUD_UNIVPLL2_D4]); | 250 | ASYS_TOP_CON_ASYS_TIMING_ON, |
360 | if (ret) { | 251 | ASYS_TOP_CON_ASYS_TIMING_ON); |
361 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", __func__, | 252 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, |
362 | aud_clks[MT2701_AUD_ASM_M_SEL], | 253 | AFE_DAC_CON0_AFE_ON, |
363 | aud_clks[MT2701_AUD_UNIVPLL2_D4], ret); | 254 | AFE_DAC_CON0_AFE_ON); |
364 | goto AFE_AUD_ASM_M_ERR; | ||
365 | } | ||
366 | 255 | ||
367 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | 256 | /* Configure ASRC */ |
368 | AUDIO_TOP_CON0_PDN_AFE, 0); | 257 | regmap_write(afe->regmap, PWR1_ASM_CON1, PWR1_ASM_CON1_INIT_VAL); |
369 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | 258 | regmap_write(afe->regmap, PWR2_ASM_CON1, PWR2_ASM_CON1_INIT_VAL); |
370 | AUDIO_TOP_CON0_PDN_APLL_CK, 0); | ||
371 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | ||
372 | AUDIO_TOP_CON4_PDN_A1SYS, 0); | ||
373 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | ||
374 | AUDIO_TOP_CON4_PDN_A2SYS, 0); | ||
375 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | ||
376 | AUDIO_TOP_CON4_PDN_AFE_CONN, 0); | ||
377 | 259 | ||
378 | return 0; | 260 | return 0; |
379 | |||
380 | AFE_AUD_ASM_M_ERR: | ||
381 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); | ||
382 | AFE_AUD_ASM_H_ERR: | ||
383 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); | ||
384 | AFE_AUD_AUDINTBUS_ERR: | ||
385 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); | ||
386 | AFE_AUD_INFRA_ERR: | ||
387 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | ||
388 | |||
389 | return ret; | ||
390 | } | 261 | } |
391 | 262 | ||
392 | void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe) | 263 | int mt2701_afe_disable_clock(struct mtk_base_afe *afe) |
393 | { | 264 | { |
394 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 265 | regmap_update_bits(afe->regmap, ASYS_TOP_CON, |
266 | ASYS_TOP_CON_ASYS_TIMING_ON, 0); | ||
267 | regmap_update_bits(afe->regmap, AFE_DAC_CON0, | ||
268 | AFE_DAC_CON0_AFE_ON, 0); | ||
269 | |||
270 | mt2701_afe_disable_audsys(afe); | ||
395 | 271 | ||
396 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_INFRA_SYS_AUDIO]); | 272 | return 0; |
397 | |||
398 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_AUDINTBUS]); | ||
399 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_H_SEL]); | ||
400 | clk_disable_unprepare(afe_priv->clocks[MT2701_AUD_ASM_M_SEL]); | ||
401 | |||
402 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
403 | AUDIO_TOP_CON0_PDN_AFE, AUDIO_TOP_CON0_PDN_AFE); | ||
404 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON0, | ||
405 | AUDIO_TOP_CON0_PDN_APLL_CK, | ||
406 | AUDIO_TOP_CON0_PDN_APLL_CK); | ||
407 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | ||
408 | AUDIO_TOP_CON4_PDN_A1SYS, | ||
409 | AUDIO_TOP_CON4_PDN_A1SYS); | ||
410 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | ||
411 | AUDIO_TOP_CON4_PDN_A2SYS, | ||
412 | AUDIO_TOP_CON4_PDN_A2SYS); | ||
413 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | ||
414 | AUDIO_TOP_CON4_PDN_AFE_CONN, | ||
415 | AUDIO_TOP_CON4_PDN_AFE_CONN); | ||
416 | } | 273 | } |
417 | 274 | ||
418 | void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, | 275 | void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, |
419 | int mclk) | 276 | int mclk) |
420 | { | 277 | { |
421 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 278 | struct mt2701_afe_private *priv = afe->platform_priv; |
279 | struct mt2701_i2s_path *i2s_path = &priv->i2s_path[id]; | ||
422 | int ret; | 280 | int ret; |
423 | int aud_src_div_id = MT2701_AUD_AUD_K1_SRC_DIV + id; | ||
424 | int aud_src_clk_id = MT2701_AUD_AUD_K1_SRC_SEL + id; | ||
425 | 281 | ||
426 | /* Set MCLK Kx_SRC_SEL(domain) */ | 282 | /* Set mclk source */ |
427 | ret = clk_prepare_enable(afe_priv->clocks[aud_src_clk_id]); | 283 | if (domain == 0) |
428 | if (ret) | 284 | ret = clk_set_parent(i2s_path->sel_ck, |
429 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 285 | priv->base_ck[MT2701_TOP_AUD_MCLK_SRC0]); |
430 | __func__, aud_clks[aud_src_clk_id], ret); | 286 | else |
431 | 287 | ret = clk_set_parent(i2s_path->sel_ck, | |
432 | if (domain == 0) { | 288 | priv->base_ck[MT2701_TOP_AUD_MCLK_SRC1]); |
433 | ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id], | ||
434 | afe_priv->clocks[MT2701_AUD_AUD_MUX1_SEL]); | ||
435 | if (ret) | ||
436 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", | ||
437 | __func__, aud_clks[aud_src_clk_id], | ||
438 | aud_clks[MT2701_AUD_AUD_MUX1_SEL], ret); | ||
439 | } else { | ||
440 | ret = clk_set_parent(afe_priv->clocks[aud_src_clk_id], | ||
441 | afe_priv->clocks[MT2701_AUD_AUD_MUX2_SEL]); | ||
442 | if (ret) | ||
443 | dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n", | ||
444 | __func__, aud_clks[aud_src_clk_id], | ||
445 | aud_clks[MT2701_AUD_AUD_MUX2_SEL], ret); | ||
446 | } | ||
447 | clk_disable_unprepare(afe_priv->clocks[aud_src_clk_id]); | ||
448 | 289 | ||
449 | /* Set MCLK Kx_SRC_DIV(divider) */ | ||
450 | ret = clk_prepare_enable(afe_priv->clocks[aud_src_div_id]); | ||
451 | if (ret) | 290 | if (ret) |
452 | dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", | 291 | dev_err(afe->dev, "failed to set domain%d mclk source %d\n", |
453 | __func__, aud_clks[aud_src_div_id], ret); | 292 | domain, ret); |
454 | 293 | ||
455 | ret = clk_set_rate(afe_priv->clocks[aud_src_div_id], mclk); | 294 | /* Set mclk divider */ |
295 | ret = clk_set_rate(i2s_path->div_ck, mclk); | ||
456 | if (ret) | 296 | if (ret) |
457 | dev_err(afe->dev, "%s clk_set_rate %s-%d fail %d\n", __func__, | 297 | dev_err(afe->dev, "failed to set mclk divider %d\n", ret); |
458 | aud_clks[aud_src_div_id], mclk, ret); | ||
459 | clk_disable_unprepare(afe_priv->clocks[aud_src_div_id]); | ||
460 | } | 298 | } |
461 | |||
462 | MODULE_DESCRIPTION("MT2701 afe clock control"); | ||
463 | MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); | ||
464 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h index 6497d570cf09..15417d9d6597 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h +++ b/sound/soc/mediatek/mt2701/mt2701-afe-clock-ctrl.h | |||
@@ -21,16 +21,15 @@ struct mtk_base_afe; | |||
21 | 21 | ||
22 | int mt2701_init_clock(struct mtk_base_afe *afe); | 22 | int mt2701_init_clock(struct mtk_base_afe *afe); |
23 | int mt2701_afe_enable_clock(struct mtk_base_afe *afe); | 23 | int mt2701_afe_enable_clock(struct mtk_base_afe *afe); |
24 | void mt2701_afe_disable_clock(struct mtk_base_afe *afe); | 24 | int mt2701_afe_disable_clock(struct mtk_base_afe *afe); |
25 | 25 | ||
26 | int mt2701_turn_on_a1sys_clock(struct mtk_base_afe *afe); | 26 | int mt2701_afe_enable_i2s(struct mtk_base_afe *afe, int id, int dir); |
27 | void mt2701_turn_off_a1sys_clock(struct mtk_base_afe *afe); | 27 | void mt2701_afe_disable_i2s(struct mtk_base_afe *afe, int id, int dir); |
28 | int mt2701_afe_enable_mclk(struct mtk_base_afe *afe, int id); | ||
29 | void mt2701_afe_disable_mclk(struct mtk_base_afe *afe, int id); | ||
28 | 30 | ||
29 | int mt2701_turn_on_a2sys_clock(struct mtk_base_afe *afe); | 31 | int mt2701_enable_btmrg_clk(struct mtk_base_afe *afe); |
30 | void mt2701_turn_off_a2sys_clock(struct mtk_base_afe *afe); | 32 | void mt2701_disable_btmrg_clk(struct mtk_base_afe *afe); |
31 | |||
32 | int mt2701_turn_on_afe_clock(struct mtk_base_afe *afe); | ||
33 | void mt2701_turn_off_afe_clock(struct mtk_base_afe *afe); | ||
34 | 33 | ||
35 | void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, | 34 | void mt2701_mclk_configuration(struct mtk_base_afe *afe, int id, int domain, |
36 | int mclk); | 35 | int mclk); |
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-common.h b/sound/soc/mediatek/mt2701/mt2701-afe-common.h index c19430e98adf..ae8ddeacfbfe 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-common.h +++ b/sound/soc/mediatek/mt2701/mt2701-afe-common.h | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #ifndef _MT_2701_AFE_COMMON_H_ | 17 | #ifndef _MT_2701_AFE_COMMON_H_ |
18 | #define _MT_2701_AFE_COMMON_H_ | 18 | #define _MT_2701_AFE_COMMON_H_ |
19 | |||
19 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
20 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
21 | #include <linux/regmap.h> | 22 | #include <linux/regmap.h> |
@@ -25,16 +26,7 @@ | |||
25 | #define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1) | 26 | #define MT2701_STREAM_DIR_NUM (SNDRV_PCM_STREAM_LAST + 1) |
26 | #define MT2701_PLL_DOMAIN_0_RATE 98304000 | 27 | #define MT2701_PLL_DOMAIN_0_RATE 98304000 |
27 | #define MT2701_PLL_DOMAIN_1_RATE 90316800 | 28 | #define MT2701_PLL_DOMAIN_1_RATE 90316800 |
28 | #define MT2701_AUD_AUD_MUX1_DIV_RATE (MT2701_PLL_DOMAIN_0_RATE / 2) | 29 | #define MT2701_I2S_NUM 4 |
29 | #define MT2701_AUD_AUD_MUX2_DIV_RATE (MT2701_PLL_DOMAIN_1_RATE / 2) | ||
30 | |||
31 | enum { | ||
32 | MT2701_I2S_1, | ||
33 | MT2701_I2S_2, | ||
34 | MT2701_I2S_3, | ||
35 | MT2701_I2S_4, | ||
36 | MT2701_I2S_NUM, | ||
37 | }; | ||
38 | 30 | ||
39 | enum { | 31 | enum { |
40 | MT2701_MEMIF_DL1, | 32 | MT2701_MEMIF_DL1, |
@@ -62,60 +54,23 @@ enum { | |||
62 | }; | 54 | }; |
63 | 55 | ||
64 | enum { | 56 | enum { |
65 | MT2701_IRQ_ASYS_START, | 57 | MT2701_IRQ_ASYS_IRQ1, |
66 | MT2701_IRQ_ASYS_IRQ1 = MT2701_IRQ_ASYS_START, | ||
67 | MT2701_IRQ_ASYS_IRQ2, | 58 | MT2701_IRQ_ASYS_IRQ2, |
68 | MT2701_IRQ_ASYS_IRQ3, | 59 | MT2701_IRQ_ASYS_IRQ3, |
69 | MT2701_IRQ_ASYS_END, | 60 | MT2701_IRQ_ASYS_END, |
70 | }; | 61 | }; |
71 | 62 | ||
72 | /* 2701 clock def */ | 63 | enum audio_base_clock { |
73 | enum audio_system_clock_type { | 64 | MT2701_INFRA_SYS_AUDIO, |
74 | MT2701_AUD_INFRA_SYS_AUDIO, | 65 | MT2701_TOP_AUD_MCLK_SRC0, |
75 | MT2701_AUD_AUD_MUX1_SEL, | 66 | MT2701_TOP_AUD_MCLK_SRC1, |
76 | MT2701_AUD_AUD_MUX2_SEL, | 67 | MT2701_TOP_AUD_A1SYS, |
77 | MT2701_AUD_AUD_MUX1_DIV, | 68 | MT2701_TOP_AUD_A2SYS, |
78 | MT2701_AUD_AUD_MUX2_DIV, | 69 | MT2701_AUDSYS_AFE, |
79 | MT2701_AUD_AUD_48K_TIMING, | 70 | MT2701_AUDSYS_AFE_CONN, |
80 | MT2701_AUD_AUD_44K_TIMING, | 71 | MT2701_AUDSYS_A1SYS, |
81 | MT2701_AUD_AUDPLL_MUX_SEL, | 72 | MT2701_AUDSYS_A2SYS, |
82 | MT2701_AUD_APLL_SEL, | 73 | MT2701_BASE_CLK_NUM, |
83 | MT2701_AUD_AUD1PLL_98M, | ||
84 | MT2701_AUD_AUD2PLL_90M, | ||
85 | MT2701_AUD_HADDS2PLL_98M, | ||
86 | MT2701_AUD_HADDS2PLL_294M, | ||
87 | MT2701_AUD_AUDPLL, | ||
88 | MT2701_AUD_AUDPLL_D4, | ||
89 | MT2701_AUD_AUDPLL_D8, | ||
90 | MT2701_AUD_AUDPLL_D16, | ||
91 | MT2701_AUD_AUDPLL_D24, | ||
92 | MT2701_AUD_AUDINTBUS, | ||
93 | MT2701_AUD_CLK_26M, | ||
94 | MT2701_AUD_SYSPLL1_D4, | ||
95 | MT2701_AUD_AUD_K1_SRC_SEL, | ||
96 | MT2701_AUD_AUD_K2_SRC_SEL, | ||
97 | MT2701_AUD_AUD_K3_SRC_SEL, | ||
98 | MT2701_AUD_AUD_K4_SRC_SEL, | ||
99 | MT2701_AUD_AUD_K5_SRC_SEL, | ||
100 | MT2701_AUD_AUD_K6_SRC_SEL, | ||
101 | MT2701_AUD_AUD_K1_SRC_DIV, | ||
102 | MT2701_AUD_AUD_K2_SRC_DIV, | ||
103 | MT2701_AUD_AUD_K3_SRC_DIV, | ||
104 | MT2701_AUD_AUD_K4_SRC_DIV, | ||
105 | MT2701_AUD_AUD_K5_SRC_DIV, | ||
106 | MT2701_AUD_AUD_K6_SRC_DIV, | ||
107 | MT2701_AUD_AUD_I2S1_MCLK, | ||
108 | MT2701_AUD_AUD_I2S2_MCLK, | ||
109 | MT2701_AUD_AUD_I2S3_MCLK, | ||
110 | MT2701_AUD_AUD_I2S4_MCLK, | ||
111 | MT2701_AUD_AUD_I2S5_MCLK, | ||
112 | MT2701_AUD_AUD_I2S6_MCLK, | ||
113 | MT2701_AUD_ASM_M_SEL, | ||
114 | MT2701_AUD_ASM_H_SEL, | ||
115 | MT2701_AUD_UNIVPLL2_D4, | ||
116 | MT2701_AUD_UNIVPLL2_D2, | ||
117 | MT2701_AUD_SYSPLL_D5, | ||
118 | MT2701_CLOCK_NUM | ||
119 | }; | 74 | }; |
120 | 75 | ||
121 | static const unsigned int mt2701_afe_backup_list[] = { | 76 | static const unsigned int mt2701_afe_backup_list[] = { |
@@ -139,12 +94,8 @@ static const unsigned int mt2701_afe_backup_list[] = { | |||
139 | AFE_MEMIF_PBUF_SIZE, | 94 | AFE_MEMIF_PBUF_SIZE, |
140 | }; | 95 | }; |
141 | 96 | ||
142 | struct snd_pcm_substream; | ||
143 | struct mtk_base_irq_data; | ||
144 | |||
145 | struct mt2701_i2s_data { | 97 | struct mt2701_i2s_data { |
146 | int i2s_ctrl_reg; | 98 | int i2s_ctrl_reg; |
147 | int i2s_pwn_shift; | ||
148 | int i2s_asrc_fs_shift; | 99 | int i2s_asrc_fs_shift; |
149 | int i2s_asrc_fs_mask; | 100 | int i2s_asrc_fs_mask; |
150 | }; | 101 | }; |
@@ -160,12 +111,18 @@ struct mt2701_i2s_path { | |||
160 | int mclk_rate; | 111 | int mclk_rate; |
161 | int on[I2S_DIR_NUM]; | 112 | int on[I2S_DIR_NUM]; |
162 | int occupied[I2S_DIR_NUM]; | 113 | int occupied[I2S_DIR_NUM]; |
163 | const struct mt2701_i2s_data *i2s_data[2]; | 114 | const struct mt2701_i2s_data *i2s_data[I2S_DIR_NUM]; |
115 | struct clk *hop_ck[I2S_DIR_NUM]; | ||
116 | struct clk *sel_ck; | ||
117 | struct clk *div_ck; | ||
118 | struct clk *mclk_ck; | ||
119 | struct clk *asrco_ck; | ||
164 | }; | 120 | }; |
165 | 121 | ||
166 | struct mt2701_afe_private { | 122 | struct mt2701_afe_private { |
167 | struct clk *clocks[MT2701_CLOCK_NUM]; | ||
168 | struct mt2701_i2s_path i2s_path[MT2701_I2S_NUM]; | 123 | struct mt2701_i2s_path i2s_path[MT2701_I2S_NUM]; |
124 | struct clk *base_ck[MT2701_BASE_CLK_NUM]; | ||
125 | struct clk *mrgif_ck; | ||
169 | bool mrg_enable[MT2701_STREAM_DIR_NUM]; | 126 | bool mrg_enable[MT2701_STREAM_DIR_NUM]; |
170 | }; | 127 | }; |
171 | 128 | ||
diff --git a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c index 8fda182f849b..5bc4e00a4a29 100644 --- a/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c +++ b/sound/soc/mediatek/mt2701/mt2701-afe-pcm.c | |||
@@ -17,19 +17,16 @@ | |||
17 | 17 | ||
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/mfd/syscon.h> | ||
20 | #include <linux/of.h> | 21 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 22 | #include <linux/of_address.h> |
22 | #include <linux/pm_runtime.h> | 23 | #include <linux/pm_runtime.h> |
23 | #include <sound/soc.h> | ||
24 | 24 | ||
25 | #include "mt2701-afe-common.h" | 25 | #include "mt2701-afe-common.h" |
26 | |||
27 | #include "mt2701-afe-clock-ctrl.h" | 26 | #include "mt2701-afe-clock-ctrl.h" |
28 | #include "../common/mtk-afe-platform-driver.h" | 27 | #include "../common/mtk-afe-platform-driver.h" |
29 | #include "../common/mtk-afe-fe-dai.h" | 28 | #include "../common/mtk-afe-fe-dai.h" |
30 | 29 | ||
31 | #define AFE_IRQ_STATUS_BITS 0xff | ||
32 | |||
33 | static const struct snd_pcm_hardware mt2701_afe_hardware = { | 30 | static const struct snd_pcm_hardware mt2701_afe_hardware = { |
34 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 31 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
35 | | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID, | 32 | | SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID, |
@@ -97,40 +94,26 @@ static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream, | |||
97 | { | 94 | { |
98 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
99 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | 96 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); |
100 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | ||
101 | int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); | 97 | int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); |
102 | int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num; | ||
103 | int ret = 0; | ||
104 | 98 | ||
105 | if (i2s_num < 0) | 99 | if (i2s_num < 0) |
106 | return i2s_num; | 100 | return i2s_num; |
107 | 101 | ||
108 | /* enable mclk */ | 102 | return mt2701_afe_enable_mclk(afe, i2s_num); |
109 | ret = clk_prepare_enable(afe_priv->clocks[clk_num]); | ||
110 | if (ret) | ||
111 | dev_err(afe->dev, "Failed to enable mclk for I2S: %d\n", | ||
112 | i2s_num); | ||
113 | |||
114 | return ret; | ||
115 | } | 103 | } |
116 | 104 | ||
117 | static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream, | 105 | static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream, |
118 | struct snd_soc_dai *dai, | 106 | struct snd_soc_dai *dai, |
107 | int i2s_num, | ||
119 | int dir_invert) | 108 | int dir_invert) |
120 | { | 109 | { |
121 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 110 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
122 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | 111 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); |
123 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 112 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
124 | int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); | 113 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num]; |
125 | struct mt2701_i2s_path *i2s_path; | ||
126 | const struct mt2701_i2s_data *i2s_data; | 114 | const struct mt2701_i2s_data *i2s_data; |
127 | int stream_dir = substream->stream; | 115 | int stream_dir = substream->stream; |
128 | 116 | ||
129 | if (i2s_num < 0) | ||
130 | return i2s_num; | ||
131 | |||
132 | i2s_path = &afe_priv->i2s_path[i2s_num]; | ||
133 | |||
134 | if (dir_invert) { | 117 | if (dir_invert) { |
135 | if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) | 118 | if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) |
136 | stream_dir = SNDRV_PCM_STREAM_CAPTURE; | 119 | stream_dir = SNDRV_PCM_STREAM_CAPTURE; |
@@ -151,9 +134,9 @@ static int mt2701_afe_i2s_path_shutdown(struct snd_pcm_substream *substream, | |||
151 | /* disable i2s */ | 134 | /* disable i2s */ |
152 | regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, | 135 | regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, |
153 | ASYS_I2S_CON_I2S_EN, 0); | 136 | ASYS_I2S_CON_I2S_EN, 0); |
154 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | 137 | |
155 | 1 << i2s_data->i2s_pwn_shift, | 138 | mt2701_afe_disable_i2s(afe, i2s_num, stream_dir); |
156 | 1 << i2s_data->i2s_pwn_shift); | 139 | |
157 | return 0; | 140 | return 0; |
158 | } | 141 | } |
159 | 142 | ||
@@ -165,7 +148,6 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream, | |||
165 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 148 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
166 | int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); | 149 | int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); |
167 | struct mt2701_i2s_path *i2s_path; | 150 | struct mt2701_i2s_path *i2s_path; |
168 | int clk_num = MT2701_AUD_AUD_I2S1_MCLK + i2s_num; | ||
169 | 151 | ||
170 | if (i2s_num < 0) | 152 | if (i2s_num < 0) |
171 | return; | 153 | return; |
@@ -177,37 +159,32 @@ static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream, | |||
177 | else | 159 | else |
178 | goto I2S_UNSTART; | 160 | goto I2S_UNSTART; |
179 | 161 | ||
180 | mt2701_afe_i2s_path_shutdown(substream, dai, 0); | 162 | mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 0); |
181 | 163 | ||
182 | /* need to disable i2s-out path when disable i2s-in */ | 164 | /* need to disable i2s-out path when disable i2s-in */ |
183 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 165 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
184 | mt2701_afe_i2s_path_shutdown(substream, dai, 1); | 166 | mt2701_afe_i2s_path_shutdown(substream, dai, i2s_num, 1); |
185 | 167 | ||
186 | I2S_UNSTART: | 168 | I2S_UNSTART: |
187 | /* disable mclk */ | 169 | /* disable mclk */ |
188 | clk_disable_unprepare(afe_priv->clocks[clk_num]); | 170 | mt2701_afe_disable_mclk(afe, i2s_num); |
189 | } | 171 | } |
190 | 172 | ||
191 | static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream, | 173 | static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream, |
192 | struct snd_soc_dai *dai, | 174 | struct snd_soc_dai *dai, |
175 | int i2s_num, | ||
193 | int dir_invert) | 176 | int dir_invert) |
194 | { | 177 | { |
195 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 178 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
196 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | 179 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); |
197 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 180 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
198 | int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id); | 181 | struct mt2701_i2s_path *i2s_path = &afe_priv->i2s_path[i2s_num]; |
199 | struct mt2701_i2s_path *i2s_path; | ||
200 | const struct mt2701_i2s_data *i2s_data; | 182 | const struct mt2701_i2s_data *i2s_data; |
201 | struct snd_pcm_runtime * const runtime = substream->runtime; | 183 | struct snd_pcm_runtime * const runtime = substream->runtime; |
202 | int reg, fs, w_len = 1; /* now we support bck 64bits only */ | 184 | int reg, fs, w_len = 1; /* now we support bck 64bits only */ |
203 | int stream_dir = substream->stream; | 185 | int stream_dir = substream->stream; |
204 | unsigned int mask = 0, val = 0; | 186 | unsigned int mask = 0, val = 0; |
205 | 187 | ||
206 | if (i2s_num < 0) | ||
207 | return i2s_num; | ||
208 | |||
209 | i2s_path = &afe_priv->i2s_path[i2s_num]; | ||
210 | |||
211 | if (dir_invert) { | 188 | if (dir_invert) { |
212 | if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) | 189 | if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) |
213 | stream_dir = SNDRV_PCM_STREAM_CAPTURE; | 190 | stream_dir = SNDRV_PCM_STREAM_CAPTURE; |
@@ -251,9 +228,7 @@ static int mt2701_i2s_path_prepare_enable(struct snd_pcm_substream *substream, | |||
251 | fs << i2s_data->i2s_asrc_fs_shift); | 228 | fs << i2s_data->i2s_asrc_fs_shift); |
252 | 229 | ||
253 | /* enable i2s */ | 230 | /* enable i2s */ |
254 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | 231 | mt2701_afe_enable_i2s(afe, i2s_num, stream_dir); |
255 | 1 << i2s_data->i2s_pwn_shift, | ||
256 | 0 << i2s_data->i2s_pwn_shift); | ||
257 | 232 | ||
258 | /* reset i2s hw status before enable */ | 233 | /* reset i2s hw status before enable */ |
259 | regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, | 234 | regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, |
@@ -300,13 +275,13 @@ static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream, | |||
300 | mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate); | 275 | mt2701_mclk_configuration(afe, i2s_num, clk_domain, mclk_rate); |
301 | 276 | ||
302 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 277 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
303 | mt2701_i2s_path_prepare_enable(substream, dai, 0); | 278 | mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0); |
304 | } else { | 279 | } else { |
305 | /* need to enable i2s-out path when enable i2s-in */ | 280 | /* need to enable i2s-out path when enable i2s-in */ |
306 | /* prepare for another direction "out" */ | 281 | /* prepare for another direction "out" */ |
307 | mt2701_i2s_path_prepare_enable(substream, dai, 1); | 282 | mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 1); |
308 | /* prepare for "in" */ | 283 | /* prepare for "in" */ |
309 | mt2701_i2s_path_prepare_enable(substream, dai, 0); | 284 | mt2701_i2s_path_prepare_enable(substream, dai, i2s_num, 0); |
310 | } | 285 | } |
311 | 286 | ||
312 | return 0; | 287 | return 0; |
@@ -339,9 +314,11 @@ static int mt2701_btmrg_startup(struct snd_pcm_substream *substream, | |||
339 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 314 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
340 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); | 315 | struct mtk_base_afe *afe = snd_soc_platform_get_drvdata(rtd->platform); |
341 | struct mt2701_afe_private *afe_priv = afe->platform_priv; | 316 | struct mt2701_afe_private *afe_priv = afe->platform_priv; |
317 | int ret; | ||
342 | 318 | ||
343 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | 319 | ret = mt2701_enable_btmrg_clk(afe); |
344 | AUDIO_TOP_CON4_PDN_MRGIF, 0); | 320 | if (ret) |
321 | return ret; | ||
345 | 322 | ||
346 | afe_priv->mrg_enable[substream->stream] = 1; | 323 | afe_priv->mrg_enable[substream->stream] = 1; |
347 | return 0; | 324 | return 0; |
@@ -406,9 +383,7 @@ static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream, | |||
406 | AFE_MRGIF_CON_MRG_EN, 0); | 383 | AFE_MRGIF_CON_MRG_EN, 0); |
407 | regmap_update_bits(afe->regmap, AFE_MRGIF_CON, | 384 | regmap_update_bits(afe->regmap, AFE_MRGIF_CON, |
408 | AFE_MRGIF_CON_MRG_I2S_EN, 0); | 385 | AFE_MRGIF_CON_MRG_I2S_EN, 0); |
409 | regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, | 386 | mt2701_disable_btmrg_clk(afe); |
410 | AUDIO_TOP_CON4_PDN_MRGIF, | ||
411 | AUDIO_TOP_CON4_PDN_MRGIF); | ||
412 | } | 387 | } |
413 | afe_priv->mrg_enable[substream->stream] = 0; | 388 | afe_priv->mrg_enable[substream->stream] = 0; |
414 | } | 389 | } |
@@ -574,7 +549,6 @@ static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = { | |||
574 | .hw_free = mtk_afe_fe_hw_free, | 549 | .hw_free = mtk_afe_fe_hw_free, |
575 | .prepare = mtk_afe_fe_prepare, | 550 | .prepare = mtk_afe_fe_prepare, |
576 | .trigger = mtk_afe_fe_trigger, | 551 | .trigger = mtk_afe_fe_trigger, |
577 | |||
578 | }; | 552 | }; |
579 | 553 | ||
580 | static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = { | 554 | static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = { |
@@ -915,31 +889,6 @@ static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s4[] = { | |||
915 | PWR2_TOP_CON, 19, 1, 0), | 889 | PWR2_TOP_CON, 19, 1, 0), |
916 | }; | 890 | }; |
917 | 891 | ||
918 | static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc0[] = { | ||
919 | SOC_DAPM_SINGLE_AUTODISABLE("Asrc0 out Switch", AUDIO_TOP_CON4, 14, 1, | ||
920 | 1), | ||
921 | }; | ||
922 | |||
923 | static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc1[] = { | ||
924 | SOC_DAPM_SINGLE_AUTODISABLE("Asrc1 out Switch", AUDIO_TOP_CON4, 15, 1, | ||
925 | 1), | ||
926 | }; | ||
927 | |||
928 | static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc2[] = { | ||
929 | SOC_DAPM_SINGLE_AUTODISABLE("Asrc2 out Switch", PWR2_TOP_CON, 6, 1, | ||
930 | 1), | ||
931 | }; | ||
932 | |||
933 | static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc3[] = { | ||
934 | SOC_DAPM_SINGLE_AUTODISABLE("Asrc3 out Switch", PWR2_TOP_CON, 7, 1, | ||
935 | 1), | ||
936 | }; | ||
937 | |||
938 | static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_asrc4[] = { | ||
939 | SOC_DAPM_SINGLE_AUTODISABLE("Asrc4 out Switch", PWR2_TOP_CON, 8, 1, | ||
940 | 1), | ||
941 | }; | ||
942 | |||
943 | static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { | 892 | static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { |
944 | /* inter-connections */ | 893 | /* inter-connections */ |
945 | SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), | 894 | SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0), |
@@ -999,19 +948,6 @@ static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = { | |||
999 | SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0, | 948 | SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0, |
1000 | mt2701_afe_multi_ch_out_i2s3, | 949 | mt2701_afe_multi_ch_out_i2s3, |
1001 | ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)), | 950 | ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)), |
1002 | |||
1003 | SND_SOC_DAPM_MIXER("ASRC_O0", SND_SOC_NOPM, 0, 0, | ||
1004 | mt2701_afe_multi_ch_out_asrc0, | ||
1005 | ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc0)), | ||
1006 | SND_SOC_DAPM_MIXER("ASRC_O1", SND_SOC_NOPM, 0, 0, | ||
1007 | mt2701_afe_multi_ch_out_asrc1, | ||
1008 | ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc1)), | ||
1009 | SND_SOC_DAPM_MIXER("ASRC_O2", SND_SOC_NOPM, 0, 0, | ||
1010 | mt2701_afe_multi_ch_out_asrc2, | ||
1011 | ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc2)), | ||
1012 | SND_SOC_DAPM_MIXER("ASRC_O3", SND_SOC_NOPM, 0, 0, | ||
1013 | mt2701_afe_multi_ch_out_asrc3, | ||
1014 | ARRAY_SIZE(mt2701_afe_multi_ch_out_asrc3)), | ||
1015 | }; | 951 | }; |
1016 | 952 | ||
1017 | static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { | 953 | static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { |
@@ -1021,7 +957,6 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { | |||
1021 | 957 | ||
1022 | {"I2S0 Playback", NULL, "O15"}, | 958 | {"I2S0 Playback", NULL, "O15"}, |
1023 | {"I2S0 Playback", NULL, "O16"}, | 959 | {"I2S0 Playback", NULL, "O16"}, |
1024 | |||
1025 | {"I2S1 Playback", NULL, "O17"}, | 960 | {"I2S1 Playback", NULL, "O17"}, |
1026 | {"I2S1 Playback", NULL, "O18"}, | 961 | {"I2S1 Playback", NULL, "O18"}, |
1027 | {"I2S2 Playback", NULL, "O19"}, | 962 | {"I2S2 Playback", NULL, "O19"}, |
@@ -1038,7 +973,6 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { | |||
1038 | 973 | ||
1039 | {"I00", NULL, "I2S0 Capture"}, | 974 | {"I00", NULL, "I2S0 Capture"}, |
1040 | {"I01", NULL, "I2S0 Capture"}, | 975 | {"I01", NULL, "I2S0 Capture"}, |
1041 | |||
1042 | {"I02", NULL, "I2S1 Capture"}, | 976 | {"I02", NULL, "I2S1 Capture"}, |
1043 | {"I03", NULL, "I2S1 Capture"}, | 977 | {"I03", NULL, "I2S1 Capture"}, |
1044 | /* I02,03 link to UL2, also need to open I2S0 */ | 978 | /* I02,03 link to UL2, also need to open I2S0 */ |
@@ -1046,15 +980,10 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { | |||
1046 | 980 | ||
1047 | {"I26", NULL, "BT Capture"}, | 981 | {"I26", NULL, "BT Capture"}, |
1048 | 982 | ||
1049 | {"ASRC_O0", "Asrc0 out Switch", "DLM"}, | 983 | {"I12I13", "Multich I2S0 Out Switch", "DLM"}, |
1050 | {"ASRC_O1", "Asrc1 out Switch", "DLM"}, | 984 | {"I14I15", "Multich I2S1 Out Switch", "DLM"}, |
1051 | {"ASRC_O2", "Asrc2 out Switch", "DLM"}, | 985 | {"I16I17", "Multich I2S2 Out Switch", "DLM"}, |
1052 | {"ASRC_O3", "Asrc3 out Switch", "DLM"}, | 986 | {"I18I19", "Multich I2S3 Out Switch", "DLM"}, |
1053 | |||
1054 | {"I12I13", "Multich I2S0 Out Switch", "ASRC_O0"}, | ||
1055 | {"I14I15", "Multich I2S1 Out Switch", "ASRC_O1"}, | ||
1056 | {"I16I17", "Multich I2S2 Out Switch", "ASRC_O2"}, | ||
1057 | {"I18I19", "Multich I2S3 Out Switch", "ASRC_O3"}, | ||
1058 | 987 | ||
1059 | { "I12", NULL, "I12I13" }, | 988 | { "I12", NULL, "I12I13" }, |
1060 | { "I13", NULL, "I12I13" }, | 989 | { "I13", NULL, "I12I13" }, |
@@ -1079,7 +1008,6 @@ static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = { | |||
1079 | { "O21", "I18 Switch", "I18" }, | 1008 | { "O21", "I18 Switch", "I18" }, |
1080 | { "O22", "I19 Switch", "I19" }, | 1009 | { "O22", "I19 Switch", "I19" }, |
1081 | { "O31", "I35 Switch", "I35" }, | 1010 | { "O31", "I35 Switch", "I35" }, |
1082 | |||
1083 | }; | 1011 | }; |
1084 | 1012 | ||
1085 | static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = { | 1013 | static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = { |
@@ -1386,14 +1314,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { | |||
1386 | { | 1314 | { |
1387 | { | 1315 | { |
1388 | .i2s_ctrl_reg = ASYS_I2SO1_CON, | 1316 | .i2s_ctrl_reg = ASYS_I2SO1_CON, |
1389 | .i2s_pwn_shift = 6, | ||
1390 | .i2s_asrc_fs_shift = 0, | 1317 | .i2s_asrc_fs_shift = 0, |
1391 | .i2s_asrc_fs_mask = 0x1f, | 1318 | .i2s_asrc_fs_mask = 0x1f, |
1392 | 1319 | ||
1393 | }, | 1320 | }, |
1394 | { | 1321 | { |
1395 | .i2s_ctrl_reg = ASYS_I2SIN1_CON, | 1322 | .i2s_ctrl_reg = ASYS_I2SIN1_CON, |
1396 | .i2s_pwn_shift = 0, | ||
1397 | .i2s_asrc_fs_shift = 0, | 1323 | .i2s_asrc_fs_shift = 0, |
1398 | .i2s_asrc_fs_mask = 0x1f, | 1324 | .i2s_asrc_fs_mask = 0x1f, |
1399 | 1325 | ||
@@ -1402,14 +1328,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { | |||
1402 | { | 1328 | { |
1403 | { | 1329 | { |
1404 | .i2s_ctrl_reg = ASYS_I2SO2_CON, | 1330 | .i2s_ctrl_reg = ASYS_I2SO2_CON, |
1405 | .i2s_pwn_shift = 7, | ||
1406 | .i2s_asrc_fs_shift = 5, | 1331 | .i2s_asrc_fs_shift = 5, |
1407 | .i2s_asrc_fs_mask = 0x1f, | 1332 | .i2s_asrc_fs_mask = 0x1f, |
1408 | 1333 | ||
1409 | }, | 1334 | }, |
1410 | { | 1335 | { |
1411 | .i2s_ctrl_reg = ASYS_I2SIN2_CON, | 1336 | .i2s_ctrl_reg = ASYS_I2SIN2_CON, |
1412 | .i2s_pwn_shift = 1, | ||
1413 | .i2s_asrc_fs_shift = 5, | 1337 | .i2s_asrc_fs_shift = 5, |
1414 | .i2s_asrc_fs_mask = 0x1f, | 1338 | .i2s_asrc_fs_mask = 0x1f, |
1415 | 1339 | ||
@@ -1418,14 +1342,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { | |||
1418 | { | 1342 | { |
1419 | { | 1343 | { |
1420 | .i2s_ctrl_reg = ASYS_I2SO3_CON, | 1344 | .i2s_ctrl_reg = ASYS_I2SO3_CON, |
1421 | .i2s_pwn_shift = 8, | ||
1422 | .i2s_asrc_fs_shift = 10, | 1345 | .i2s_asrc_fs_shift = 10, |
1423 | .i2s_asrc_fs_mask = 0x1f, | 1346 | .i2s_asrc_fs_mask = 0x1f, |
1424 | 1347 | ||
1425 | }, | 1348 | }, |
1426 | { | 1349 | { |
1427 | .i2s_ctrl_reg = ASYS_I2SIN3_CON, | 1350 | .i2s_ctrl_reg = ASYS_I2SIN3_CON, |
1428 | .i2s_pwn_shift = 2, | ||
1429 | .i2s_asrc_fs_shift = 10, | 1351 | .i2s_asrc_fs_shift = 10, |
1430 | .i2s_asrc_fs_mask = 0x1f, | 1352 | .i2s_asrc_fs_mask = 0x1f, |
1431 | 1353 | ||
@@ -1434,14 +1356,12 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { | |||
1434 | { | 1356 | { |
1435 | { | 1357 | { |
1436 | .i2s_ctrl_reg = ASYS_I2SO4_CON, | 1358 | .i2s_ctrl_reg = ASYS_I2SO4_CON, |
1437 | .i2s_pwn_shift = 9, | ||
1438 | .i2s_asrc_fs_shift = 15, | 1359 | .i2s_asrc_fs_shift = 15, |
1439 | .i2s_asrc_fs_mask = 0x1f, | 1360 | .i2s_asrc_fs_mask = 0x1f, |
1440 | 1361 | ||
1441 | }, | 1362 | }, |
1442 | { | 1363 | { |
1443 | .i2s_ctrl_reg = ASYS_I2SIN4_CON, | 1364 | .i2s_ctrl_reg = ASYS_I2SIN4_CON, |
1444 | .i2s_pwn_shift = 3, | ||
1445 | .i2s_asrc_fs_shift = 15, | 1365 | .i2s_asrc_fs_shift = 15, |
1446 | .i2s_asrc_fs_mask = 0x1f, | 1366 | .i2s_asrc_fs_mask = 0x1f, |
1447 | 1367 | ||
@@ -1449,14 +1369,6 @@ static const struct mt2701_i2s_data mt2701_i2s_data[MT2701_I2S_NUM][2] = { | |||
1449 | }, | 1369 | }, |
1450 | }; | 1370 | }; |
1451 | 1371 | ||
1452 | static const struct regmap_config mt2701_afe_regmap_config = { | ||
1453 | .reg_bits = 32, | ||
1454 | .reg_stride = 4, | ||
1455 | .val_bits = 32, | ||
1456 | .max_register = AFE_END_ADDR, | ||
1457 | .cache_type = REGCACHE_NONE, | ||
1458 | }; | ||
1459 | |||
1460 | static irqreturn_t mt2701_asys_isr(int irq_id, void *dev) | 1372 | static irqreturn_t mt2701_asys_isr(int irq_id, void *dev) |
1461 | { | 1373 | { |
1462 | int id; | 1374 | int id; |
@@ -1483,8 +1395,7 @@ static int mt2701_afe_runtime_suspend(struct device *dev) | |||
1483 | { | 1395 | { |
1484 | struct mtk_base_afe *afe = dev_get_drvdata(dev); | 1396 | struct mtk_base_afe *afe = dev_get_drvdata(dev); |
1485 | 1397 | ||
1486 | mt2701_afe_disable_clock(afe); | 1398 | return mt2701_afe_disable_clock(afe); |
1487 | return 0; | ||
1488 | } | 1399 | } |
1489 | 1400 | ||
1490 | static int mt2701_afe_runtime_resume(struct device *dev) | 1401 | static int mt2701_afe_runtime_resume(struct device *dev) |
@@ -1496,21 +1407,22 @@ static int mt2701_afe_runtime_resume(struct device *dev) | |||
1496 | 1407 | ||
1497 | static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) | 1408 | static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) |
1498 | { | 1409 | { |
1410 | struct snd_soc_component *component; | ||
1499 | struct mtk_base_afe *afe; | 1411 | struct mtk_base_afe *afe; |
1500 | struct mt2701_afe_private *afe_priv; | 1412 | struct mt2701_afe_private *afe_priv; |
1501 | struct resource *res; | ||
1502 | struct device *dev; | 1413 | struct device *dev; |
1503 | int i, irq_id, ret; | 1414 | int i, irq_id, ret; |
1504 | 1415 | ||
1505 | afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); | 1416 | afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); |
1506 | if (!afe) | 1417 | if (!afe) |
1507 | return -ENOMEM; | 1418 | return -ENOMEM; |
1419 | |||
1508 | afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), | 1420 | afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), |
1509 | GFP_KERNEL); | 1421 | GFP_KERNEL); |
1510 | if (!afe->platform_priv) | 1422 | if (!afe->platform_priv) |
1511 | return -ENOMEM; | 1423 | return -ENOMEM; |
1512 | afe_priv = afe->platform_priv; | ||
1513 | 1424 | ||
1425 | afe_priv = afe->platform_priv; | ||
1514 | afe->dev = &pdev->dev; | 1426 | afe->dev = &pdev->dev; |
1515 | dev = afe->dev; | 1427 | dev = afe->dev; |
1516 | 1428 | ||
@@ -1527,17 +1439,11 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) | |||
1527 | return ret; | 1439 | return ret; |
1528 | } | 1440 | } |
1529 | 1441 | ||
1530 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1442 | afe->regmap = syscon_node_to_regmap(dev->parent->of_node); |
1531 | 1443 | if (IS_ERR(afe->regmap)) { | |
1532 | afe->base_addr = devm_ioremap_resource(&pdev->dev, res); | 1444 | dev_err(dev, "could not get regmap from parent\n"); |
1533 | |||
1534 | if (IS_ERR(afe->base_addr)) | ||
1535 | return PTR_ERR(afe->base_addr); | ||
1536 | |||
1537 | afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, | ||
1538 | &mt2701_afe_regmap_config); | ||
1539 | if (IS_ERR(afe->regmap)) | ||
1540 | return PTR_ERR(afe->regmap); | 1445 | return PTR_ERR(afe->regmap); |
1446 | } | ||
1541 | 1447 | ||
1542 | mutex_init(&afe->irq_alloc_lock); | 1448 | mutex_init(&afe->irq_alloc_lock); |
1543 | 1449 | ||
@@ -1545,7 +1451,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) | |||
1545 | afe->memif_size = MT2701_MEMIF_NUM; | 1451 | afe->memif_size = MT2701_MEMIF_NUM; |
1546 | afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), | 1452 | afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), |
1547 | GFP_KERNEL); | 1453 | GFP_KERNEL); |
1548 | |||
1549 | if (!afe->memif) | 1454 | if (!afe->memif) |
1550 | return -ENOMEM; | 1455 | return -ENOMEM; |
1551 | 1456 | ||
@@ -1558,7 +1463,6 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) | |||
1558 | afe->irqs_size = MT2701_IRQ_ASYS_END; | 1463 | afe->irqs_size = MT2701_IRQ_ASYS_END; |
1559 | afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), | 1464 | afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), |
1560 | GFP_KERNEL); | 1465 | GFP_KERNEL); |
1561 | |||
1562 | if (!afe->irqs) | 1466 | if (!afe->irqs) |
1563 | return -ENOMEM; | 1467 | return -ENOMEM; |
1564 | 1468 | ||
@@ -1573,10 +1477,15 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) | |||
1573 | = &mt2701_i2s_data[i][I2S_IN]; | 1477 | = &mt2701_i2s_data[i][I2S_IN]; |
1574 | } | 1478 | } |
1575 | 1479 | ||
1480 | component = kzalloc(sizeof(*component), GFP_KERNEL); | ||
1481 | if (!component) | ||
1482 | return -ENOMEM; | ||
1483 | |||
1484 | component->regmap = afe->regmap; | ||
1485 | |||
1576 | afe->mtk_afe_hardware = &mt2701_afe_hardware; | 1486 | afe->mtk_afe_hardware = &mt2701_afe_hardware; |
1577 | afe->memif_fs = mt2701_memif_fs; | 1487 | afe->memif_fs = mt2701_memif_fs; |
1578 | afe->irq_fs = mt2701_irq_fs; | 1488 | afe->irq_fs = mt2701_irq_fs; |
1579 | |||
1580 | afe->reg_back_up_list = mt2701_afe_backup_list; | 1489 | afe->reg_back_up_list = mt2701_afe_backup_list; |
1581 | afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list); | 1490 | afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list); |
1582 | afe->runtime_resume = mt2701_afe_runtime_resume; | 1491 | afe->runtime_resume = mt2701_afe_runtime_resume; |
@@ -1586,59 +1495,58 @@ static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev) | |||
1586 | ret = mt2701_init_clock(afe); | 1495 | ret = mt2701_init_clock(afe); |
1587 | if (ret) { | 1496 | if (ret) { |
1588 | dev_err(dev, "init clock error\n"); | 1497 | dev_err(dev, "init clock error\n"); |
1589 | return ret; | 1498 | goto err_init_clock; |
1590 | } | 1499 | } |
1591 | 1500 | ||
1592 | platform_set_drvdata(pdev, afe); | 1501 | platform_set_drvdata(pdev, afe); |
1593 | pm_runtime_enable(&pdev->dev); | ||
1594 | if (!pm_runtime_enabled(&pdev->dev)) | ||
1595 | goto err_pm_disable; | ||
1596 | pm_runtime_get_sync(&pdev->dev); | ||
1597 | 1502 | ||
1598 | ret = snd_soc_register_platform(&pdev->dev, &mtk_afe_pcm_platform); | 1503 | pm_runtime_enable(dev); |
1504 | if (!pm_runtime_enabled(dev)) { | ||
1505 | ret = mt2701_afe_runtime_resume(dev); | ||
1506 | if (ret) | ||
1507 | goto err_pm_disable; | ||
1508 | } | ||
1509 | pm_runtime_get_sync(dev); | ||
1510 | |||
1511 | ret = snd_soc_register_platform(dev, &mtk_afe_pcm_platform); | ||
1599 | if (ret) { | 1512 | if (ret) { |
1600 | dev_warn(dev, "err_platform\n"); | 1513 | dev_warn(dev, "err_platform\n"); |
1601 | goto err_platform; | 1514 | goto err_platform; |
1602 | } | 1515 | } |
1603 | 1516 | ||
1604 | ret = snd_soc_register_component(&pdev->dev, | 1517 | ret = snd_soc_add_component(dev, component, |
1605 | &mt2701_afe_pcm_dai_component, | 1518 | &mt2701_afe_pcm_dai_component, |
1606 | mt2701_afe_pcm_dais, | 1519 | mt2701_afe_pcm_dais, |
1607 | ARRAY_SIZE(mt2701_afe_pcm_dais)); | 1520 | ARRAY_SIZE(mt2701_afe_pcm_dais)); |
1608 | if (ret) { | 1521 | if (ret) { |
1609 | dev_warn(dev, "err_dai_component\n"); | 1522 | dev_warn(dev, "err_dai_component\n"); |
1610 | goto err_dai_component; | 1523 | goto err_dai_component; |
1611 | } | 1524 | } |
1612 | 1525 | ||
1613 | mt2701_afe_runtime_resume(&pdev->dev); | ||
1614 | |||
1615 | return 0; | 1526 | return 0; |
1616 | 1527 | ||
1617 | err_dai_component: | 1528 | err_dai_component: |
1618 | snd_soc_unregister_component(&pdev->dev); | 1529 | snd_soc_unregister_platform(dev); |
1619 | |||
1620 | err_platform: | 1530 | err_platform: |
1621 | snd_soc_unregister_platform(&pdev->dev); | 1531 | pm_runtime_put_sync(dev); |
1622 | |||
1623 | err_pm_disable: | 1532 | err_pm_disable: |
1624 | pm_runtime_disable(&pdev->dev); | 1533 | pm_runtime_disable(dev); |
1534 | err_init_clock: | ||
1535 | kfree(component); | ||
1625 | 1536 | ||
1626 | return ret; | 1537 | return ret; |
1627 | } | 1538 | } |
1628 | 1539 | ||
1629 | static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev) | 1540 | static int mt2701_afe_pcm_dev_remove(struct platform_device *pdev) |
1630 | { | 1541 | { |
1631 | struct mtk_base_afe *afe = platform_get_drvdata(pdev); | 1542 | pm_runtime_put_sync(&pdev->dev); |
1632 | |||
1633 | pm_runtime_disable(&pdev->dev); | 1543 | pm_runtime_disable(&pdev->dev); |
1634 | if (!pm_runtime_status_suspended(&pdev->dev)) | 1544 | if (!pm_runtime_status_suspended(&pdev->dev)) |
1635 | mt2701_afe_runtime_suspend(&pdev->dev); | 1545 | mt2701_afe_runtime_suspend(&pdev->dev); |
1636 | pm_runtime_put_sync(&pdev->dev); | ||
1637 | 1546 | ||
1638 | snd_soc_unregister_component(&pdev->dev); | 1547 | snd_soc_unregister_component(&pdev->dev); |
1639 | snd_soc_unregister_platform(&pdev->dev); | 1548 | snd_soc_unregister_platform(&pdev->dev); |
1640 | /* disable afe clock */ | 1549 | |
1641 | mt2701_afe_disable_clock(afe); | ||
1642 | return 0; | 1550 | return 0; |
1643 | } | 1551 | } |
1644 | 1552 | ||
@@ -1670,4 +1578,3 @@ module_platform_driver(mt2701_afe_pcm_driver); | |||
1670 | MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701"); | 1578 | MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701"); |
1671 | MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); | 1579 | MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>"); |
1672 | MODULE_LICENSE("GPL v2"); | 1580 | MODULE_LICENSE("GPL v2"); |
1673 | |||
diff --git a/sound/soc/mediatek/mt2701/mt2701-reg.h b/sound/soc/mediatek/mt2701/mt2701-reg.h index bb62b1c55957..18e676974f22 100644 --- a/sound/soc/mediatek/mt2701/mt2701-reg.h +++ b/sound/soc/mediatek/mt2701/mt2701-reg.h | |||
@@ -17,17 +17,6 @@ | |||
17 | #ifndef _MT2701_REG_H_ | 17 | #ifndef _MT2701_REG_H_ |
18 | #define _MT2701_REG_H_ | 18 | #define _MT2701_REG_H_ |
19 | 19 | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/of.h> | ||
23 | #include <linux/of_address.h> | ||
24 | #include <linux/pm_runtime.h> | ||
25 | #include <sound/soc.h> | ||
26 | #include "mt2701-afe-common.h" | ||
27 | |||
28 | /***************************************************************************** | ||
29 | * R E G I S T E R D E F I N I T I O N | ||
30 | *****************************************************************************/ | ||
31 | #define AUDIO_TOP_CON0 0x0000 | 20 | #define AUDIO_TOP_CON0 0x0000 |
32 | #define AUDIO_TOP_CON4 0x0010 | 21 | #define AUDIO_TOP_CON4 0x0010 |
33 | #define AUDIO_TOP_CON5 0x0014 | 22 | #define AUDIO_TOP_CON5 0x0014 |
@@ -109,18 +98,6 @@ | |||
109 | #define AFE_DAI_BASE 0x1370 | 98 | #define AFE_DAI_BASE 0x1370 |
110 | #define AFE_DAI_CUR 0x137c | 99 | #define AFE_DAI_CUR 0x137c |
111 | 100 | ||
112 | /* AUDIO_TOP_CON0 (0x0000) */ | ||
113 | #define AUDIO_TOP_CON0_A1SYS_A2SYS_ON (0x3 << 0) | ||
114 | #define AUDIO_TOP_CON0_PDN_AFE (0x1 << 2) | ||
115 | #define AUDIO_TOP_CON0_PDN_APLL_CK (0x1 << 23) | ||
116 | |||
117 | /* AUDIO_TOP_CON4 (0x0010) */ | ||
118 | #define AUDIO_TOP_CON4_I2SO1_PWN (0x1 << 6) | ||
119 | #define AUDIO_TOP_CON4_PDN_A1SYS (0x1 << 21) | ||
120 | #define AUDIO_TOP_CON4_PDN_A2SYS (0x1 << 22) | ||
121 | #define AUDIO_TOP_CON4_PDN_AFE_CONN (0x1 << 23) | ||
122 | #define AUDIO_TOP_CON4_PDN_MRGIF (0x1 << 25) | ||
123 | |||
124 | /* AFE_DAIBT_CON0 (0x001c) */ | 101 | /* AFE_DAIBT_CON0 (0x001c) */ |
125 | #define AFE_DAIBT_CON0_DAIBT_EN (0x1 << 0) | 102 | #define AFE_DAIBT_CON0_DAIBT_EN (0x1 << 0) |
126 | #define AFE_DAIBT_CON0_BT_FUNC_EN (0x1 << 1) | 103 | #define AFE_DAIBT_CON0_BT_FUNC_EN (0x1 << 1) |
@@ -137,22 +114,8 @@ | |||
137 | #define AFE_MRGIF_CON_I2S_MODE_MASK (0xf << 20) | 114 | #define AFE_MRGIF_CON_I2S_MODE_MASK (0xf << 20) |
138 | #define AFE_MRGIF_CON_I2S_MODE_32K (0x4 << 20) | 115 | #define AFE_MRGIF_CON_I2S_MODE_32K (0x4 << 20) |
139 | 116 | ||
140 | /* ASYS_I2SO1_CON (0x061c) */ | 117 | /* ASYS_TOP_CON (0x0600) */ |
141 | #define ASYS_I2SO1_CON_FS (0x1f << 8) | 118 | #define ASYS_TOP_CON_ASYS_TIMING_ON (0x3 << 0) |
142 | #define ASYS_I2SO1_CON_FS_SET(x) ((x) << 8) | ||
143 | #define ASYS_I2SO1_CON_MULTI_CH (0x1 << 16) | ||
144 | #define ASYS_I2SO1_CON_SIDEGEN (0x1 << 30) | ||
145 | #define ASYS_I2SO1_CON_I2S_EN (0x1 << 0) | ||
146 | /* 0:EIAJ 1:I2S */ | ||
147 | #define ASYS_I2SO1_CON_I2S_MODE (0x1 << 3) | ||
148 | #define ASYS_I2SO1_CON_WIDE_MODE (0x1 << 1) | ||
149 | #define ASYS_I2SO1_CON_WIDE_MODE_SET(x) ((x) << 1) | ||
150 | |||
151 | /* PWR2_TOP_CON (0x0634) */ | ||
152 | #define PWR2_TOP_CON_INIT_VAL (0xffe1ffff) | ||
153 | |||
154 | /* ASYS_IRQ_CLR (0x07c0) */ | ||
155 | #define ASYS_IRQ_CLR_ALL (0xffffffff) | ||
156 | 119 | ||
157 | /* PWR2_ASM_CON1 (0x1070) */ | 120 | /* PWR2_ASM_CON1 (0x1070) */ |
158 | #define PWR2_ASM_CON1_INIT_VAL (0x492492) | 121 | #define PWR2_ASM_CON1_INIT_VAL (0x492492) |
@@ -182,5 +145,4 @@ | |||
182 | #define ASYS_I2S_CON_WIDE_MODE_SET(x) ((x) << 1) | 145 | #define ASYS_I2S_CON_WIDE_MODE_SET(x) ((x) << 1) |
183 | #define ASYS_I2S_IN_PHASE_FIX (0x1 << 31) | 146 | #define ASYS_I2S_IN_PHASE_FIX (0x1 << 31) |
184 | 147 | ||
185 | #define AFE_END_ADDR 0x15e0 | ||
186 | #endif | 148 | #endif |
diff --git a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c index 8a643a35d3d4..c7f7f8add5d9 100644 --- a/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c +++ b/sound/soc/mediatek/mt8173/mt8173-afe-pcm.c | |||
@@ -1083,7 +1083,7 @@ static int mt8173_afe_init_audio_clk(struct mtk_base_afe *afe) | |||
1083 | static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) | 1083 | static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) |
1084 | { | 1084 | { |
1085 | int ret, i; | 1085 | int ret, i; |
1086 | unsigned int irq_id; | 1086 | int irq_id; |
1087 | struct mtk_base_afe *afe; | 1087 | struct mtk_base_afe *afe; |
1088 | struct mt8173_afe_private *afe_priv; | 1088 | struct mt8173_afe_private *afe_priv; |
1089 | struct resource *res; | 1089 | struct resource *res; |
@@ -1105,9 +1105,9 @@ static int mt8173_afe_pcm_dev_probe(struct platform_device *pdev) | |||
1105 | afe->dev = &pdev->dev; | 1105 | afe->dev = &pdev->dev; |
1106 | 1106 | ||
1107 | irq_id = platform_get_irq(pdev, 0); | 1107 | irq_id = platform_get_irq(pdev, 0); |
1108 | if (!irq_id) { | 1108 | if (irq_id <= 0) { |
1109 | dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name); | 1109 | dev_err(afe->dev, "np %s no irq\n", afe->dev->of_node->name); |
1110 | return -ENXIO; | 1110 | return irq_id < 0 ? irq_id : -ENXIO; |
1111 | } | 1111 | } |
1112 | ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, | 1112 | ret = devm_request_irq(afe->dev, irq_id, mt8173_afe_irq_handler, |
1113 | 0, "Afe_ISR_Handle", (void *)afe); | 1113 | 0, "Afe_ISR_Handle", (void *)afe); |
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c index 99c15219dbc8..5a9a5482976e 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c | |||
@@ -37,8 +37,6 @@ static const struct snd_soc_dapm_route mt8173_rt5650_rt5514_routes[] = { | |||
37 | {"Sub DMIC1R", NULL, "Int Mic"}, | 37 | {"Sub DMIC1R", NULL, "Int Mic"}, |
38 | {"Headphone", NULL, "HPOL"}, | 38 | {"Headphone", NULL, "HPOL"}, |
39 | {"Headphone", NULL, "HPOR"}, | 39 | {"Headphone", NULL, "HPOR"}, |
40 | {"Headset Mic", NULL, "micbias1"}, | ||
41 | {"Headset Mic", NULL, "micbias2"}, | ||
42 | {"IN1P", NULL, "Headset Mic"}, | 40 | {"IN1P", NULL, "Headset Mic"}, |
43 | {"IN1N", NULL, "Headset Mic"}, | 41 | {"IN1N", NULL, "Headset Mic"}, |
44 | }; | 42 | }; |
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c index 42de84ca8c84..b7248085ca04 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c | |||
@@ -40,8 +40,6 @@ static const struct snd_soc_dapm_route mt8173_rt5650_rt5676_routes[] = { | |||
40 | {"Headphone", NULL, "HPOL"}, | 40 | {"Headphone", NULL, "HPOL"}, |
41 | {"Headphone", NULL, "HPOR"}, | 41 | {"Headphone", NULL, "HPOR"}, |
42 | {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ | 42 | {"Headphone", NULL, "Sub AIF2TX"}, /* IF2 ADC to 5650 */ |
43 | {"Headset Mic", NULL, "micbias1"}, | ||
44 | {"Headset Mic", NULL, "micbias2"}, | ||
45 | {"IN1P", NULL, "Headset Mic"}, | 43 | {"IN1P", NULL, "Headset Mic"}, |
46 | {"IN1N", NULL, "Headset Mic"}, | 44 | {"IN1N", NULL, "Headset Mic"}, |
47 | {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */ | 45 | {"Sub AIF2RX", NULL, "Headset Mic"}, /* IF2 DAC from 5650 */ |
diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c index e69c141d8ed4..40ebefd625c1 100644 --- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c +++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c | |||
@@ -51,8 +51,6 @@ static const struct snd_soc_dapm_route mt8173_rt5650_routes[] = { | |||
51 | {"DMIC R1", NULL, "Int Mic"}, | 51 | {"DMIC R1", NULL, "Int Mic"}, |
52 | {"Headphone", NULL, "HPOL"}, | 52 | {"Headphone", NULL, "HPOL"}, |
53 | {"Headphone", NULL, "HPOR"}, | 53 | {"Headphone", NULL, "HPOR"}, |
54 | {"Headset Mic", NULL, "micbias1"}, | ||
55 | {"Headset Mic", NULL, "micbias2"}, | ||
56 | {"IN1P", NULL, "Headset Mic"}, | 54 | {"IN1P", NULL, "Headset Mic"}, |
57 | {"IN1N", NULL, "Headset Mic"}, | 55 | {"IN1N", NULL, "Headset Mic"}, |
58 | }; | 56 | }; |
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c index 2ed3240cc682..2b3f2408301a 100644 --- a/sound/soc/mxs/mxs-sgtl5000.c +++ b/sound/soc/mxs/mxs-sgtl5000.c | |||
@@ -93,6 +93,14 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { | |||
93 | }, | 93 | }, |
94 | }; | 94 | }; |
95 | 95 | ||
96 | static const struct snd_soc_dapm_widget mxs_sgtl5000_dapm_widgets[] = { | ||
97 | SND_SOC_DAPM_MIC("Mic Jack", NULL), | ||
98 | SND_SOC_DAPM_LINE("Line In Jack", NULL), | ||
99 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | ||
100 | SND_SOC_DAPM_SPK("Line Out Jack", NULL), | ||
101 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
102 | }; | ||
103 | |||
96 | static struct snd_soc_card mxs_sgtl5000 = { | 104 | static struct snd_soc_card mxs_sgtl5000 = { |
97 | .name = "mxs_sgtl5000", | 105 | .name = "mxs_sgtl5000", |
98 | .owner = THIS_MODULE, | 106 | .owner = THIS_MODULE, |
@@ -141,10 +149,23 @@ static int mxs_sgtl5000_probe(struct platform_device *pdev) | |||
141 | 149 | ||
142 | card->dev = &pdev->dev; | 150 | card->dev = &pdev->dev; |
143 | 151 | ||
152 | if (of_find_property(np, "audio-routing", NULL)) { | ||
153 | card->dapm_widgets = mxs_sgtl5000_dapm_widgets; | ||
154 | card->num_dapm_widgets = ARRAY_SIZE(mxs_sgtl5000_dapm_widgets); | ||
155 | |||
156 | ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); | ||
157 | if (ret) { | ||
158 | dev_err(&pdev->dev, "failed to parse audio-routing (%d)\n", | ||
159 | ret); | ||
160 | return ret; | ||
161 | } | ||
162 | } | ||
163 | |||
144 | ret = devm_snd_soc_register_card(&pdev->dev, card); | 164 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
145 | if (ret) { | 165 | if (ret) { |
146 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | 166 | if (ret != -EPROBE_DEFER) |
147 | ret); | 167 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", |
168 | ret); | ||
148 | return ret; | 169 | return ret; |
149 | } | 170 | } |
150 | 171 | ||
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index b6615affe571..81b09d740ed9 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c | |||
@@ -67,7 +67,7 @@ static unsigned short nuc900_ac97_read(struct snd_ac97 *ac97, | |||
67 | 67 | ||
68 | /* polling the AC_R_FINISH */ | 68 | /* polling the AC_R_FINISH */ |
69 | while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH) | 69 | while (!(AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_R_FINISH) |
70 | && timeout--) | 70 | && --timeout) |
71 | mdelay(1); | 71 | mdelay(1); |
72 | 72 | ||
73 | if (!timeout) { | 73 | if (!timeout) { |
@@ -121,7 +121,7 @@ static void nuc900_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | |||
121 | 121 | ||
122 | /* polling the AC_W_FINISH */ | 122 | /* polling the AC_W_FINISH */ |
123 | while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH) | 123 | while ((AUDIO_READ(nuc900_audio->mmio + ACTL_ACCON) & AC_W_FINISH) |
124 | && timeout--) | 124 | && --timeout) |
125 | mdelay(1); | 125 | mdelay(1); |
126 | 126 | ||
127 | if (!timeout) | 127 | if (!timeout) |
@@ -345,11 +345,10 @@ static int nuc900_ac97_drvprobe(struct platform_device *pdev) | |||
345 | goto out; | 345 | goto out; |
346 | } | 346 | } |
347 | 347 | ||
348 | nuc900_audio->irq_num = platform_get_irq(pdev, 0); | 348 | ret = platform_get_irq(pdev, 0); |
349 | if (!nuc900_audio->irq_num) { | 349 | if (ret < 0) |
350 | ret = -EBUSY; | ||
351 | goto out; | 350 | goto out; |
352 | } | 351 | nuc900_audio->irq_num = ret; |
353 | 352 | ||
354 | nuc900_ac97_data = nuc900_audio; | 353 | nuc900_ac97_data = nuc900_audio; |
355 | 354 | ||
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index d40219678700..cb72c1e57da0 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -105,7 +105,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, | |||
105 | int pin, changed = 0; | 105 | int pin, changed = 0; |
106 | 106 | ||
107 | /* Refuse any mode changes if we are not able to control the codec. */ | 107 | /* Refuse any mode changes if we are not able to control the codec. */ |
108 | if (!cx20442_codec->hw_write) | 108 | if (!cx20442_codec->component.card->pop_time) |
109 | return -EUNATCH; | 109 | return -EUNATCH; |
110 | 110 | ||
111 | if (ucontrol->value.enumerated.item[0] >= control->items) | 111 | if (ucontrol->value.enumerated.item[0] >= control->items) |
@@ -345,7 +345,7 @@ static void cx81801_receive(struct tty_struct *tty, | |||
345 | if (!codec) | 345 | if (!codec) |
346 | return; | 346 | return; |
347 | 347 | ||
348 | if (!codec->hw_write) { | 348 | if (!codec->component.card->pop_time) { |
349 | /* First modem response, complete setup procedure */ | 349 | /* First modem response, complete setup procedure */ |
350 | 350 | ||
351 | /* Initialize timer used for config pulse generation */ | 351 | /* Initialize timer used for config pulse generation */ |
diff --git a/sound/soc/qcom/apq8016_sbc.c b/sound/soc/qcom/apq8016_sbc.c index d49adc822a11..704428735e3c 100644 --- a/sound/soc/qcom/apq8016_sbc.c +++ b/sound/soc/qcom/apq8016_sbc.c | |||
@@ -43,7 +43,7 @@ struct apq8016_sbc_data { | |||
43 | static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) | 43 | static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) |
44 | { | 44 | { |
45 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 45 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
46 | struct snd_soc_codec *codec; | 46 | struct snd_soc_component *component; |
47 | struct snd_soc_dai_link *dai_link = rtd->dai_link; | 47 | struct snd_soc_dai_link *dai_link = rtd->dai_link; |
48 | struct snd_soc_card *card = rtd->card; | 48 | struct snd_soc_card *card = rtd->card; |
49 | struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); | 49 | struct apq8016_sbc_data *pdata = snd_soc_card_get_drvdata(card); |
@@ -92,7 +92,7 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
92 | 92 | ||
93 | jack = pdata->jack.jack; | 93 | jack = pdata->jack.jack; |
94 | 94 | ||
95 | snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_MEDIA); | 95 | snd_jack_set_key(jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
96 | snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); | 96 | snd_jack_set_key(jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); |
97 | snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); | 97 | snd_jack_set_key(jack, SND_JACK_BTN_2, KEY_VOLUMEUP); |
98 | snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); | 98 | snd_jack_set_key(jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); |
@@ -102,15 +102,15 @@ static int apq8016_sbc_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
102 | for (i = 0 ; i < dai_link->num_codecs; i++) { | 102 | for (i = 0 ; i < dai_link->num_codecs; i++) { |
103 | struct snd_soc_dai *dai = rtd->codec_dais[i]; | 103 | struct snd_soc_dai *dai = rtd->codec_dais[i]; |
104 | 104 | ||
105 | codec = dai->codec; | 105 | component = dai->component; |
106 | /* Set default mclk for internal codec */ | 106 | /* Set default mclk for internal codec */ |
107 | rval = snd_soc_codec_set_sysclk(codec, 0, 0, DEFAULT_MCLK_RATE, | 107 | rval = snd_soc_component_set_sysclk(component, 0, 0, DEFAULT_MCLK_RATE, |
108 | SND_SOC_CLOCK_IN); | 108 | SND_SOC_CLOCK_IN); |
109 | if (rval != 0 && rval != -ENOTSUPP) { | 109 | if (rval != 0 && rval != -ENOTSUPP) { |
110 | dev_warn(card->dev, "Failed to set mclk: %d\n", rval); | 110 | dev_warn(card->dev, "Failed to set mclk: %d\n", rval); |
111 | return rval; | 111 | return rval; |
112 | } | 112 | } |
113 | rval = snd_soc_codec_set_jack(codec, &pdata->jack, NULL); | 113 | rval = snd_soc_component_set_jack(component, &pdata->jack, NULL); |
114 | if (rval != 0 && rval != -ENOTSUPP) { | 114 | if (rval != 0 && rval != -ENOTSUPP) { |
115 | dev_warn(card->dev, "Failed to set jack: %d\n", rval); | 115 | dev_warn(card->dev, "Failed to set jack: %d\n", rval); |
116 | return rval; | 116 | return rval; |
diff --git a/sound/soc/rockchip/rk3399_gru_sound.c b/sound/soc/rockchip/rk3399_gru_sound.c index d64fbbd50544..fa6cd1de828b 100644 --- a/sound/soc/rockchip/rk3399_gru_sound.c +++ b/sound/soc/rockchip/rk3399_gru_sound.c | |||
@@ -206,7 +206,8 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd) | |||
206 | return ret; | 206 | return ret; |
207 | } | 207 | } |
208 | 208 | ||
209 | snd_jack_set_key(rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_MEDIA); | 209 | snd_jack_set_key( |
210 | rockchip_sound_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); | ||
210 | snd_jack_set_key( | 211 | snd_jack_set_key( |
211 | rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); | 212 | rockchip_sound_jack.jack, SND_JACK_BTN_1, KEY_VOLUMEUP); |
212 | snd_jack_set_key( | 213 | snd_jack_set_key( |
diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 908211e1d6fc..950823d69e9c 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c | |||
@@ -328,6 +328,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, | |||
328 | val |= I2S_CHN_4; | 328 | val |= I2S_CHN_4; |
329 | break; | 329 | break; |
330 | case 2: | 330 | case 2: |
331 | case 1: | ||
331 | val |= I2S_CHN_2; | 332 | val |= I2S_CHN_2; |
332 | break; | 333 | break; |
333 | default: | 334 | default: |
@@ -460,7 +461,7 @@ static struct snd_soc_dai_driver rockchip_i2s_dai = { | |||
460 | }, | 461 | }, |
461 | .capture = { | 462 | .capture = { |
462 | .stream_name = "Capture", | 463 | .stream_name = "Capture", |
463 | .channels_min = 2, | 464 | .channels_min = 1, |
464 | .channels_max = 2, | 465 | .channels_max = 2, |
465 | .rates = SNDRV_PCM_RATE_8000_192000, | 466 | .rates = SNDRV_PCM_RATE_8000_192000, |
466 | .formats = (SNDRV_PCM_FMTBIT_S8 | | 467 | .formats = (SNDRV_PCM_FMTBIT_S8 | |
@@ -504,6 +505,7 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg) | |||
504 | case I2S_INTCR: | 505 | case I2S_INTCR: |
505 | case I2S_XFER: | 506 | case I2S_XFER: |
506 | case I2S_CLR: | 507 | case I2S_CLR: |
508 | case I2S_TXDR: | ||
507 | case I2S_RXDR: | 509 | case I2S_RXDR: |
508 | case I2S_FIFOLR: | 510 | case I2S_FIFOLR: |
509 | case I2S_INTSR: | 511 | case I2S_INTSR: |
@@ -518,6 +520,9 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) | |||
518 | switch (reg) { | 520 | switch (reg) { |
519 | case I2S_INTSR: | 521 | case I2S_INTSR: |
520 | case I2S_CLR: | 522 | case I2S_CLR: |
523 | case I2S_FIFOLR: | ||
524 | case I2S_TXDR: | ||
525 | case I2S_RXDR: | ||
521 | return true; | 526 | return true; |
522 | default: | 527 | default: |
523 | return false; | 528 | return false; |
@@ -527,6 +532,8 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg) | |||
527 | static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg) | 532 | static bool rockchip_i2s_precious_reg(struct device *dev, unsigned int reg) |
528 | { | 533 | { |
529 | switch (reg) { | 534 | switch (reg) { |
535 | case I2S_RXDR: | ||
536 | return true; | ||
530 | default: | 537 | default: |
531 | return false; | 538 | return false; |
532 | } | 539 | } |
@@ -654,7 +661,7 @@ static int rockchip_i2s_probe(struct platform_device *pdev) | |||
654 | } | 661 | } |
655 | 662 | ||
656 | if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { | 663 | if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { |
657 | if (val >= 2 && val <= 8) | 664 | if (val >= 1 && val <= 8) |
658 | soc_dai->capture.channels_max = val; | 665 | soc_dai->capture.channels_max = val; |
659 | } | 666 | } |
660 | 667 | ||
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 34deba461ae1..0e66cd8ef2f9 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c | |||
@@ -60,13 +60,13 @@ static int bells_set_bias_level(struct snd_soc_card *card, | |||
60 | { | 60 | { |
61 | struct snd_soc_pcm_runtime *rtd; | 61 | struct snd_soc_pcm_runtime *rtd; |
62 | struct snd_soc_dai *codec_dai; | 62 | struct snd_soc_dai *codec_dai; |
63 | struct snd_soc_codec *codec; | 63 | struct snd_soc_component *component; |
64 | struct bells_drvdata *bells = card->drvdata; | 64 | struct bells_drvdata *bells = card->drvdata; |
65 | int ret; | 65 | int ret; |
66 | 66 | ||
67 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); | 67 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); |
68 | codec_dai = rtd->codec_dai; | 68 | codec_dai = rtd->codec_dai; |
69 | codec = codec_dai->codec; | 69 | component = codec_dai->component; |
70 | 70 | ||
71 | if (dapm->dev != codec_dai->dev) | 71 | if (dapm->dev != codec_dai->dev) |
72 | return 0; | 72 | return 0; |
@@ -76,7 +76,7 @@ static int bells_set_bias_level(struct snd_soc_card *card, | |||
76 | if (dapm->bias_level != SND_SOC_BIAS_STANDBY) | 76 | if (dapm->bias_level != SND_SOC_BIAS_STANDBY) |
77 | break; | 77 | break; |
78 | 78 | ||
79 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, | 79 | ret = snd_soc_component_set_pll(component, WM5102_FLL1, |
80 | ARIZONA_FLL_SRC_MCLK1, | 80 | ARIZONA_FLL_SRC_MCLK1, |
81 | MCLK_RATE, | 81 | MCLK_RATE, |
82 | bells->sysclk_rate); | 82 | bells->sysclk_rate); |
@@ -84,7 +84,7 @@ static int bells_set_bias_level(struct snd_soc_card *card, | |||
84 | pr_err("Failed to start FLL: %d\n", ret); | 84 | pr_err("Failed to start FLL: %d\n", ret); |
85 | 85 | ||
86 | if (bells->asyncclk_rate) { | 86 | if (bells->asyncclk_rate) { |
87 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, | 87 | ret = snd_soc_component_set_pll(component, WM5102_FLL2, |
88 | ARIZONA_FLL_SRC_AIF2BCLK, | 88 | ARIZONA_FLL_SRC_AIF2BCLK, |
89 | BCLK2_RATE, | 89 | BCLK2_RATE, |
90 | bells->asyncclk_rate); | 90 | bells->asyncclk_rate); |
@@ -106,27 +106,27 @@ static int bells_set_bias_level_post(struct snd_soc_card *card, | |||
106 | { | 106 | { |
107 | struct snd_soc_pcm_runtime *rtd; | 107 | struct snd_soc_pcm_runtime *rtd; |
108 | struct snd_soc_dai *codec_dai; | 108 | struct snd_soc_dai *codec_dai; |
109 | struct snd_soc_codec *codec; | 109 | struct snd_soc_component *component; |
110 | struct bells_drvdata *bells = card->drvdata; | 110 | struct bells_drvdata *bells = card->drvdata; |
111 | int ret; | 111 | int ret; |
112 | 112 | ||
113 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); | 113 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); |
114 | codec_dai = rtd->codec_dai; | 114 | codec_dai = rtd->codec_dai; |
115 | codec = codec_dai->codec; | 115 | component = codec_dai->component; |
116 | 116 | ||
117 | if (dapm->dev != codec_dai->dev) | 117 | if (dapm->dev != codec_dai->dev) |
118 | return 0; | 118 | return 0; |
119 | 119 | ||
120 | switch (level) { | 120 | switch (level) { |
121 | case SND_SOC_BIAS_STANDBY: | 121 | case SND_SOC_BIAS_STANDBY: |
122 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL1, 0, 0, 0); | 122 | ret = snd_soc_component_set_pll(component, WM5102_FLL1, 0, 0, 0); |
123 | if (ret < 0) { | 123 | if (ret < 0) { |
124 | pr_err("Failed to stop FLL: %d\n", ret); | 124 | pr_err("Failed to stop FLL: %d\n", ret); |
125 | return ret; | 125 | return ret; |
126 | } | 126 | } |
127 | 127 | ||
128 | if (bells->asyncclk_rate) { | 128 | if (bells->asyncclk_rate) { |
129 | ret = snd_soc_codec_set_pll(codec, WM5102_FLL2, | 129 | ret = snd_soc_component_set_pll(component, WM5102_FLL2, |
130 | 0, 0, 0); | 130 | 0, 0, 0); |
131 | if (ret < 0) { | 131 | if (ret < 0) { |
132 | pr_err("Failed to stop FLL: %d\n", ret); | 132 | pr_err("Failed to stop FLL: %d\n", ret); |
@@ -148,8 +148,8 @@ static int bells_late_probe(struct snd_soc_card *card) | |||
148 | { | 148 | { |
149 | struct bells_drvdata *bells = card->drvdata; | 149 | struct bells_drvdata *bells = card->drvdata; |
150 | struct snd_soc_pcm_runtime *rtd; | 150 | struct snd_soc_pcm_runtime *rtd; |
151 | struct snd_soc_codec *wm0010; | 151 | struct snd_soc_component *wm0010; |
152 | struct snd_soc_codec *codec; | 152 | struct snd_soc_component *component; |
153 | struct snd_soc_dai *aif1_dai; | 153 | struct snd_soc_dai *aif1_dai; |
154 | struct snd_soc_dai *aif2_dai; | 154 | struct snd_soc_dai *aif2_dai; |
155 | struct snd_soc_dai *aif3_dai; | 155 | struct snd_soc_dai *aif3_dai; |
@@ -157,22 +157,22 @@ static int bells_late_probe(struct snd_soc_card *card) | |||
157 | int ret; | 157 | int ret; |
158 | 158 | ||
159 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name); | 159 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name); |
160 | wm0010 = rtd->codec; | 160 | wm0010 = rtd->codec_dai->component; |
161 | 161 | ||
162 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); | 162 | rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name); |
163 | codec = rtd->codec; | 163 | component = rtd->codec_dai->component; |
164 | aif1_dai = rtd->codec_dai; | 164 | aif1_dai = rtd->codec_dai; |
165 | 165 | ||
166 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK, | 166 | ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_SYSCLK, |
167 | ARIZONA_CLK_SRC_FLL1, | 167 | ARIZONA_CLK_SRC_FLL1, |
168 | bells->sysclk_rate, | 168 | bells->sysclk_rate, |
169 | SND_SOC_CLOCK_IN); | 169 | SND_SOC_CLOCK_IN); |
170 | if (ret != 0) { | 170 | if (ret != 0) { |
171 | dev_err(codec->dev, "Failed to set SYSCLK: %d\n", ret); | 171 | dev_err(component->dev, "Failed to set SYSCLK: %d\n", ret); |
172 | return ret; | 172 | return ret; |
173 | } | 173 | } |
174 | 174 | ||
175 | ret = snd_soc_codec_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0); | 175 | ret = snd_soc_component_set_sysclk(wm0010, 0, 0, SYS_MCLK_RATE, 0); |
176 | if (ret != 0) { | 176 | if (ret != 0) { |
177 | dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret); | 177 | dev_err(wm0010->dev, "Failed to set WM0010 clock: %d\n", ret); |
178 | return ret; | 178 | return ret; |
@@ -182,20 +182,20 @@ static int bells_late_probe(struct snd_soc_card *card) | |||
182 | if (ret != 0) | 182 | if (ret != 0) |
183 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); | 183 | dev_err(aif1_dai->dev, "Failed to set AIF1 clock: %d\n", ret); |
184 | 184 | ||
185 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_OPCLK, 0, | 185 | ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_OPCLK, 0, |
186 | SYS_MCLK_RATE, SND_SOC_CLOCK_OUT); | 186 | SYS_MCLK_RATE, SND_SOC_CLOCK_OUT); |
187 | if (ret != 0) | 187 | if (ret != 0) |
188 | dev_err(codec->dev, "Failed to set OPCLK: %d\n", ret); | 188 | dev_err(component->dev, "Failed to set OPCLK: %d\n", ret); |
189 | 189 | ||
190 | if (card->num_rtd == DAI_CODEC_CP) | 190 | if (card->num_rtd == DAI_CODEC_CP) |
191 | return 0; | 191 | return 0; |
192 | 192 | ||
193 | ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_ASYNCCLK, | 193 | ret = snd_soc_component_set_sysclk(component, ARIZONA_CLK_ASYNCCLK, |
194 | ARIZONA_CLK_SRC_FLL2, | 194 | ARIZONA_CLK_SRC_FLL2, |
195 | bells->asyncclk_rate, | 195 | bells->asyncclk_rate, |
196 | SND_SOC_CLOCK_IN); | 196 | SND_SOC_CLOCK_IN); |
197 | if (ret != 0) { | 197 | if (ret != 0) { |
198 | dev_err(codec->dev, "Failed to set ASYNCCLK: %d\n", ret); | 198 | dev_err(component->dev, "Failed to set ASYNCCLK: %d\n", ret); |
199 | return ret; | 199 | return ret; |
200 | } | 200 | } |
201 | 201 | ||
@@ -221,7 +221,7 @@ static int bells_late_probe(struct snd_soc_card *card) | |||
221 | return ret; | 221 | return ret; |
222 | } | 222 | } |
223 | 223 | ||
224 | ret = snd_soc_codec_set_sysclk(wm9081_dai->codec, WM9081_SYSCLK_MCLK, | 224 | ret = snd_soc_component_set_sysclk(wm9081_dai->component, WM9081_SYSCLK_MCLK, |
225 | 0, SYS_MCLK_RATE, 0); | 225 | 0, SYS_MCLK_RATE, 0); |
226 | if (ret != 0) { | 226 | if (ret != 0) { |
227 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); | 227 | dev_err(wm9081_dai->dev, "Failed to set MCLK: %d\n", ret); |
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index f12a88a21dfa..64d5ecb86528 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -197,16 +197,27 @@ int rsnd_io_is_working(struct rsnd_dai_stream *io) | |||
197 | return 0; | 197 | return 0; |
198 | } | 198 | } |
199 | 199 | ||
200 | int rsnd_runtime_channel_original(struct rsnd_dai_stream *io) | 200 | int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io, |
201 | struct snd_pcm_hw_params *params) | ||
201 | { | 202 | { |
202 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 203 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
203 | 204 | ||
204 | return runtime->channels; | 205 | /* |
206 | * params will be added when refine | ||
207 | * see | ||
208 | * __rsnd_soc_hw_rule_rate() | ||
209 | * __rsnd_soc_hw_rule_channels() | ||
210 | */ | ||
211 | if (params) | ||
212 | return params_channels(params); | ||
213 | else | ||
214 | return runtime->channels; | ||
205 | } | 215 | } |
206 | 216 | ||
207 | int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io) | 217 | int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io, |
218 | struct snd_pcm_hw_params *params) | ||
208 | { | 219 | { |
209 | int chan = rsnd_runtime_channel_original(io); | 220 | int chan = rsnd_runtime_channel_original_with_params(io, params); |
210 | struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io); | 221 | struct rsnd_mod *ctu_mod = rsnd_io_to_mod_ctu(io); |
211 | 222 | ||
212 | if (ctu_mod) { | 223 | if (ctu_mod) { |
@@ -219,12 +230,13 @@ int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io) | |||
219 | return chan; | 230 | return chan; |
220 | } | 231 | } |
221 | 232 | ||
222 | int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io) | 233 | int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io, |
234 | struct snd_pcm_hw_params *params) | ||
223 | { | 235 | { |
224 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); | 236 | struct rsnd_dai *rdai = rsnd_io_to_rdai(io); |
225 | int chan = rsnd_io_is_play(io) ? | 237 | int chan = rsnd_io_is_play(io) ? |
226 | rsnd_runtime_channel_after_ctu(io) : | 238 | rsnd_runtime_channel_after_ctu_with_params(io, params) : |
227 | rsnd_runtime_channel_original(io); | 239 | rsnd_runtime_channel_original_with_params(io, params); |
228 | 240 | ||
229 | /* Use Multi SSI */ | 241 | /* Use Multi SSI */ |
230 | if (rsnd_runtime_is_ssi_multi(io)) | 242 | if (rsnd_runtime_is_ssi_multi(io)) |
@@ -262,10 +274,10 @@ u32 rsnd_get_adinr_bit(struct rsnd_mod *mod, struct rsnd_dai_stream *io) | |||
262 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 274 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
263 | struct device *dev = rsnd_priv_to_dev(priv); | 275 | struct device *dev = rsnd_priv_to_dev(priv); |
264 | 276 | ||
265 | switch (runtime->sample_bits) { | 277 | switch (snd_pcm_format_width(runtime->format)) { |
266 | case 16: | 278 | case 16: |
267 | return 8 << 16; | 279 | return 8 << 16; |
268 | case 32: | 280 | case 24: |
269 | return 0 << 16; | 281 | return 0 << 16; |
270 | } | 282 | } |
271 | 283 | ||
@@ -282,11 +294,12 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) | |||
282 | struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io); | 294 | struct rsnd_mod *ssiu = rsnd_io_to_mod_ssiu(io); |
283 | struct rsnd_mod *target; | 295 | struct rsnd_mod *target; |
284 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 296 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
285 | u32 val = 0x76543210; | ||
286 | u32 mask = ~0; | ||
287 | 297 | ||
288 | /* | 298 | /* |
289 | * *Hardware* L/R and *Software* L/R are inverted. | 299 | * *Hardware* L/R and *Software* L/R are inverted for 16bit data. |
300 | * 31..16 15...0 | ||
301 | * HW: [L ch] [R ch] | ||
302 | * SW: [R ch] [L ch] | ||
290 | * We need to care about inversion timing to control | 303 | * We need to care about inversion timing to control |
291 | * Playback/Capture correctly. | 304 | * Playback/Capture correctly. |
292 | * The point is [DVC] needs *Hardware* L/R, [MEM] needs *Software* L/R | 305 | * The point is [DVC] needs *Hardware* L/R, [MEM] needs *Software* L/R |
@@ -313,27 +326,13 @@ u32 rsnd_get_dalign(struct rsnd_mod *mod, struct rsnd_dai_stream *io) | |||
313 | target = cmd ? cmd : ssiu; | 326 | target = cmd ? cmd : ssiu; |
314 | } | 327 | } |
315 | 328 | ||
316 | mask <<= runtime->channels * 4; | 329 | /* Non target mod or 24bit data needs normal DALIGN */ |
317 | val = val & mask; | 330 | if ((snd_pcm_format_width(runtime->format) != 16) || |
318 | 331 | (mod != target)) | |
319 | switch (runtime->sample_bits) { | ||
320 | case 16: | ||
321 | val |= 0x67452301 & ~mask; | ||
322 | break; | ||
323 | case 32: | ||
324 | val |= 0x76543210 & ~mask; | ||
325 | break; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * exchange channeles on SRC if possible, | ||
330 | * otherwise, R/L volume settings on DVC | ||
331 | * changes inverted channels | ||
332 | */ | ||
333 | if (mod == target) | ||
334 | return val; | ||
335 | else | ||
336 | return 0x76543210; | 332 | return 0x76543210; |
333 | /* Target mod needs inverted DALIGN when 16bit */ | ||
334 | else | ||
335 | return 0x67452301; | ||
337 | } | 336 | } |
338 | 337 | ||
339 | u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod) | 338 | u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod) |
@@ -363,12 +362,8 @@ u32 rsnd_get_busif_shift(struct rsnd_dai_stream *io, struct rsnd_mod *mod) | |||
363 | * HW 24bit data is located as 0x******00 | 362 | * HW 24bit data is located as 0x******00 |
364 | * | 363 | * |
365 | */ | 364 | */ |
366 | switch (runtime->sample_bits) { | 365 | if (snd_pcm_format_width(runtime->format) == 16) |
367 | case 16: | ||
368 | return 0; | 366 | return 0; |
369 | case 32: | ||
370 | break; | ||
371 | } | ||
372 | 367 | ||
373 | for (i = 0; i < ARRAY_SIZE(playback_mods); i++) { | 368 | for (i = 0; i < ARRAY_SIZE(playback_mods); i++) { |
374 | tmod = rsnd_io_to_mod(io, mods[i]); | 369 | tmod = rsnd_io_to_mod(io, mods[i]); |
@@ -616,8 +611,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
616 | switch (cmd) { | 611 | switch (cmd) { |
617 | case SNDRV_PCM_TRIGGER_START: | 612 | case SNDRV_PCM_TRIGGER_START: |
618 | case SNDRV_PCM_TRIGGER_RESUME: | 613 | case SNDRV_PCM_TRIGGER_RESUME: |
619 | rsnd_dai_stream_init(io, substream); | ||
620 | |||
621 | ret = rsnd_dai_call(init, io, priv); | 614 | ret = rsnd_dai_call(init, io, priv); |
622 | if (ret < 0) | 615 | if (ret < 0) |
623 | goto dai_trigger_end; | 616 | goto dai_trigger_end; |
@@ -639,7 +632,6 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
639 | 632 | ||
640 | ret |= rsnd_dai_call(quit, io, priv); | 633 | ret |= rsnd_dai_call(quit, io, priv); |
641 | 634 | ||
642 | rsnd_dai_stream_quit(io); | ||
643 | break; | 635 | break; |
644 | default: | 636 | default: |
645 | ret = -EINVAL; | 637 | ret = -EINVAL; |
@@ -784,8 +776,9 @@ static int rsnd_soc_hw_rule(struct rsnd_priv *priv, | |||
784 | return snd_interval_refine(iv, &p); | 776 | return snd_interval_refine(iv, &p); |
785 | } | 777 | } |
786 | 778 | ||
787 | static int rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params, | 779 | static int __rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params, |
788 | struct snd_pcm_hw_rule *rule) | 780 | struct snd_pcm_hw_rule *rule, |
781 | int is_play) | ||
789 | { | 782 | { |
790 | struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 783 | struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
791 | struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 784 | struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
@@ -793,25 +786,37 @@ static int rsnd_soc_hw_rule_rate(struct snd_pcm_hw_params *params, | |||
793 | struct snd_soc_dai *dai = rule->private; | 786 | struct snd_soc_dai *dai = rule->private; |
794 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | 787 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
795 | struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); | 788 | struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); |
789 | struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; | ||
796 | 790 | ||
797 | /* | 791 | /* |
798 | * possible sampling rate limitation is same as | 792 | * possible sampling rate limitation is same as |
799 | * 2ch if it supports multi ssi | 793 | * 2ch if it supports multi ssi |
794 | * and same as 8ch if TDM 6ch (see rsnd_ssi_config_init()) | ||
800 | */ | 795 | */ |
801 | ic = *ic_; | 796 | ic = *ic_; |
802 | if (1 < rsnd_rdai_ssi_lane_get(rdai)) { | 797 | ic.min = |
803 | ic.min = 2; | 798 | ic.max = rsnd_runtime_channel_for_ssi_with_params(io, params); |
804 | ic.max = 2; | ||
805 | } | ||
806 | 799 | ||
807 | return rsnd_soc_hw_rule(priv, rsnd_soc_hw_rate_list, | 800 | return rsnd_soc_hw_rule(priv, rsnd_soc_hw_rate_list, |
808 | ARRAY_SIZE(rsnd_soc_hw_rate_list), | 801 | ARRAY_SIZE(rsnd_soc_hw_rate_list), |
809 | &ic, ir); | 802 | &ic, ir); |
810 | } | 803 | } |
811 | 804 | ||
805 | static int rsnd_soc_hw_rule_rate_playback(struct snd_pcm_hw_params *params, | ||
806 | struct snd_pcm_hw_rule *rule) | ||
807 | { | ||
808 | return __rsnd_soc_hw_rule_rate(params, rule, 1); | ||
809 | } | ||
810 | |||
811 | static int rsnd_soc_hw_rule_rate_capture(struct snd_pcm_hw_params *params, | ||
812 | struct snd_pcm_hw_rule *rule) | ||
813 | { | ||
814 | return __rsnd_soc_hw_rule_rate(params, rule, 0); | ||
815 | } | ||
812 | 816 | ||
813 | static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, | 817 | static int __rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, |
814 | struct snd_pcm_hw_rule *rule) | 818 | struct snd_pcm_hw_rule *rule, |
819 | int is_play) | ||
815 | { | 820 | { |
816 | struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); | 821 | struct snd_interval *ic_ = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); |
817 | struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | 822 | struct snd_interval *ir = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); |
@@ -819,22 +824,34 @@ static int rsnd_soc_hw_rule_channels(struct snd_pcm_hw_params *params, | |||
819 | struct snd_soc_dai *dai = rule->private; | 824 | struct snd_soc_dai *dai = rule->private; |
820 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | 825 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
821 | struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); | 826 | struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); |
827 | struct rsnd_dai_stream *io = is_play ? &rdai->playback : &rdai->capture; | ||
822 | 828 | ||
823 | /* | 829 | /* |
824 | * possible sampling rate limitation is same as | 830 | * possible sampling rate limitation is same as |
825 | * 2ch if it supports multi ssi | 831 | * 2ch if it supports multi ssi |
832 | * and same as 8ch if TDM 6ch (see rsnd_ssi_config_init()) | ||
826 | */ | 833 | */ |
827 | ic = *ic_; | 834 | ic = *ic_; |
828 | if (1 < rsnd_rdai_ssi_lane_get(rdai)) { | 835 | ic.min = |
829 | ic.min = 2; | 836 | ic.max = rsnd_runtime_channel_for_ssi_with_params(io, params); |
830 | ic.max = 2; | ||
831 | } | ||
832 | 837 | ||
833 | return rsnd_soc_hw_rule(priv, rsnd_soc_hw_channels_list, | 838 | return rsnd_soc_hw_rule(priv, rsnd_soc_hw_channels_list, |
834 | ARRAY_SIZE(rsnd_soc_hw_channels_list), | 839 | ARRAY_SIZE(rsnd_soc_hw_channels_list), |
835 | ir, &ic); | 840 | ir, &ic); |
836 | } | 841 | } |
837 | 842 | ||
843 | static int rsnd_soc_hw_rule_channels_playback(struct snd_pcm_hw_params *params, | ||
844 | struct snd_pcm_hw_rule *rule) | ||
845 | { | ||
846 | return __rsnd_soc_hw_rule_channels(params, rule, 1); | ||
847 | } | ||
848 | |||
849 | static int rsnd_soc_hw_rule_channels_capture(struct snd_pcm_hw_params *params, | ||
850 | struct snd_pcm_hw_rule *rule) | ||
851 | { | ||
852 | return __rsnd_soc_hw_rule_channels(params, rule, 0); | ||
853 | } | ||
854 | |||
838 | static const struct snd_pcm_hardware rsnd_pcm_hardware = { | 855 | static const struct snd_pcm_hardware rsnd_pcm_hardware = { |
839 | .info = SNDRV_PCM_INFO_INTERLEAVED | | 856 | .info = SNDRV_PCM_INFO_INTERLEAVED | |
840 | SNDRV_PCM_INFO_MMAP | | 857 | SNDRV_PCM_INFO_MMAP | |
@@ -859,6 +876,8 @@ static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, | |||
859 | int ret; | 876 | int ret; |
860 | int i; | 877 | int i; |
861 | 878 | ||
879 | rsnd_dai_stream_init(io, substream); | ||
880 | |||
862 | /* | 881 | /* |
863 | * Channel Limitation | 882 | * Channel Limitation |
864 | * It depends on Platform design | 883 | * It depends on Platform design |
@@ -886,11 +905,17 @@ static int rsnd_soc_dai_startup(struct snd_pcm_substream *substream, | |||
886 | * It depends on Clock Master Mode | 905 | * It depends on Clock Master Mode |
887 | */ | 906 | */ |
888 | if (rsnd_rdai_is_clk_master(rdai)) { | 907 | if (rsnd_rdai_is_clk_master(rdai)) { |
908 | int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
909 | |||
889 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 910 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
890 | rsnd_soc_hw_rule_rate, dai, | 911 | is_play ? rsnd_soc_hw_rule_rate_playback : |
912 | rsnd_soc_hw_rule_rate_capture, | ||
913 | dai, | ||
891 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); | 914 | SNDRV_PCM_HW_PARAM_CHANNELS, -1); |
892 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 915 | snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
893 | rsnd_soc_hw_rule_channels, dai, | 916 | is_play ? rsnd_soc_hw_rule_channels_playback : |
917 | rsnd_soc_hw_rule_channels_capture, | ||
918 | dai, | ||
894 | SNDRV_PCM_HW_PARAM_RATE, -1); | 919 | SNDRV_PCM_HW_PARAM_RATE, -1); |
895 | } | 920 | } |
896 | 921 | ||
@@ -915,6 +940,8 @@ static void rsnd_soc_dai_shutdown(struct snd_pcm_substream *substream, | |||
915 | * call rsnd_dai_call without spinlock | 940 | * call rsnd_dai_call without spinlock |
916 | */ | 941 | */ |
917 | rsnd_dai_call(nolock_stop, io, priv); | 942 | rsnd_dai_call(nolock_stop, io, priv); |
943 | |||
944 | rsnd_dai_stream_quit(io); | ||
918 | } | 945 | } |
919 | 946 | ||
920 | static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { | 947 | static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { |
@@ -990,7 +1017,7 @@ of_node_compatible: | |||
990 | 1017 | ||
991 | static void __rsnd_dai_probe(struct rsnd_priv *priv, | 1018 | static void __rsnd_dai_probe(struct rsnd_priv *priv, |
992 | struct device_node *dai_np, | 1019 | struct device_node *dai_np, |
993 | int dai_i, int is_graph) | 1020 | int dai_i) |
994 | { | 1021 | { |
995 | struct device_node *playback, *capture; | 1022 | struct device_node *playback, *capture; |
996 | struct rsnd_dai_stream *io_playback; | 1023 | struct rsnd_dai_stream *io_playback; |
@@ -1089,13 +1116,13 @@ static int rsnd_dai_probe(struct rsnd_priv *priv) | |||
1089 | dai_i = 0; | 1116 | dai_i = 0; |
1090 | if (is_graph) { | 1117 | if (is_graph) { |
1091 | for_each_endpoint_of_node(dai_node, dai_np) { | 1118 | for_each_endpoint_of_node(dai_node, dai_np) { |
1092 | __rsnd_dai_probe(priv, dai_np, dai_i, is_graph); | 1119 | __rsnd_dai_probe(priv, dai_np, dai_i); |
1093 | rsnd_ssi_parse_hdmi_connection(priv, dai_np, dai_i); | 1120 | rsnd_ssi_parse_hdmi_connection(priv, dai_np, dai_i); |
1094 | dai_i++; | 1121 | dai_i++; |
1095 | } | 1122 | } |
1096 | } else { | 1123 | } else { |
1097 | for_each_child_of_node(dai_node, dai_np) | 1124 | for_each_child_of_node(dai_node, dai_np) |
1098 | __rsnd_dai_probe(priv, dai_np, dai_i++, is_graph); | 1125 | __rsnd_dai_probe(priv, dai_np, dai_i++); |
1099 | } | 1126 | } |
1100 | 1127 | ||
1101 | return 0; | 1128 | return 0; |
@@ -1496,6 +1523,8 @@ static int rsnd_remove(struct platform_device *pdev) | |||
1496 | }; | 1523 | }; |
1497 | int ret = 0, i; | 1524 | int ret = 0, i; |
1498 | 1525 | ||
1526 | snd_soc_disconnect_sync(&pdev->dev); | ||
1527 | |||
1499 | pm_runtime_disable(&pdev->dev); | 1528 | pm_runtime_disable(&pdev->dev); |
1500 | 1529 | ||
1501 | for_each_rsnd_dai(rdai, priv, i) { | 1530 | for_each_rsnd_dai(rdai, priv, i) { |
diff --git a/sound/soc/sh/rcar/dma.c b/sound/soc/sh/rcar/dma.c index 4d750bdf8e24..41de23417c4a 100644 --- a/sound/soc/sh/rcar/dma.c +++ b/sound/soc/sh/rcar/dma.c | |||
@@ -71,25 +71,7 @@ static struct rsnd_mod mem = { | |||
71 | static void __rsnd_dmaen_complete(struct rsnd_mod *mod, | 71 | static void __rsnd_dmaen_complete(struct rsnd_mod *mod, |
72 | struct rsnd_dai_stream *io) | 72 | struct rsnd_dai_stream *io) |
73 | { | 73 | { |
74 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
75 | bool elapsed = false; | ||
76 | unsigned long flags; | ||
77 | |||
78 | /* | ||
79 | * Renesas sound Gen1 needs 1 DMAC, | ||
80 | * Gen2 needs 2 DMAC. | ||
81 | * In Gen2 case, it are Audio-DMAC, and Audio-DMAC-peri-peri. | ||
82 | * But, Audio-DMAC-peri-peri doesn't have interrupt, | ||
83 | * and this driver is assuming that here. | ||
84 | */ | ||
85 | spin_lock_irqsave(&priv->lock, flags); | ||
86 | |||
87 | if (rsnd_io_is_working(io)) | 74 | if (rsnd_io_is_working(io)) |
88 | elapsed = true; | ||
89 | |||
90 | spin_unlock_irqrestore(&priv->lock, flags); | ||
91 | |||
92 | if (elapsed) | ||
93 | rsnd_dai_period_elapsed(io); | 75 | rsnd_dai_period_elapsed(io); |
94 | } | 76 | } |
95 | 77 | ||
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 57cd2bc773c2..ad6523595b0a 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -399,9 +399,18 @@ void rsnd_parse_connect_common(struct rsnd_dai *rdai, | |||
399 | struct device_node *playback, | 399 | struct device_node *playback, |
400 | struct device_node *capture); | 400 | struct device_node *capture); |
401 | 401 | ||
402 | int rsnd_runtime_channel_original(struct rsnd_dai_stream *io); | 402 | #define rsnd_runtime_channel_original(io) \ |
403 | int rsnd_runtime_channel_after_ctu(struct rsnd_dai_stream *io); | 403 | rsnd_runtime_channel_original_with_params(io, NULL) |
404 | int rsnd_runtime_channel_for_ssi(struct rsnd_dai_stream *io); | 404 | int rsnd_runtime_channel_original_with_params(struct rsnd_dai_stream *io, |
405 | struct snd_pcm_hw_params *params); | ||
406 | #define rsnd_runtime_channel_after_ctu(io) \ | ||
407 | rsnd_runtime_channel_after_ctu_with_params(io, NULL) | ||
408 | int rsnd_runtime_channel_after_ctu_with_params(struct rsnd_dai_stream *io, | ||
409 | struct snd_pcm_hw_params *params); | ||
410 | #define rsnd_runtime_channel_for_ssi(io) \ | ||
411 | rsnd_runtime_channel_for_ssi_with_params(io, NULL) | ||
412 | int rsnd_runtime_channel_for_ssi_with_params(struct rsnd_dai_stream *io, | ||
413 | struct snd_pcm_hw_params *params); | ||
405 | int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io); | 414 | int rsnd_runtime_is_ssi_multi(struct rsnd_dai_stream *io); |
406 | int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io); | 415 | int rsnd_runtime_is_ssi_tdm(struct rsnd_dai_stream *io); |
407 | 416 | ||
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index cbf3bf312d23..97a9db892a8f 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -79,8 +79,8 @@ struct rsnd_ssi { | |||
79 | int irq; | 79 | int irq; |
80 | unsigned int usrcnt; | 80 | unsigned int usrcnt; |
81 | 81 | ||
82 | /* for PIO */ | ||
82 | int byte_pos; | 83 | int byte_pos; |
83 | int period_pos; | ||
84 | int byte_per_period; | 84 | int byte_per_period; |
85 | int next_period_byte; | 85 | int next_period_byte; |
86 | }; | 86 | }; |
@@ -371,11 +371,11 @@ static void rsnd_ssi_config_init(struct rsnd_mod *mod, | |||
371 | if (rsnd_io_is_play(io)) | 371 | if (rsnd_io_is_play(io)) |
372 | cr_own |= TRMD; | 372 | cr_own |= TRMD; |
373 | 373 | ||
374 | switch (runtime->sample_bits) { | 374 | switch (snd_pcm_format_width(runtime->format)) { |
375 | case 16: | 375 | case 16: |
376 | cr_own |= DWL_16; | 376 | cr_own |= DWL_16; |
377 | break; | 377 | break; |
378 | case 32: | 378 | case 24: |
379 | cr_own |= DWL_24; | 379 | cr_own |= DWL_24; |
380 | break; | 380 | break; |
381 | } | 381 | } |
@@ -414,63 +414,6 @@ static void rsnd_ssi_register_setup(struct rsnd_mod *mod) | |||
414 | ssi->cr_en); | 414 | ssi->cr_en); |
415 | } | 415 | } |
416 | 416 | ||
417 | static void rsnd_ssi_pointer_init(struct rsnd_mod *mod, | ||
418 | struct rsnd_dai_stream *io) | ||
419 | { | ||
420 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
421 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
422 | |||
423 | ssi->byte_pos = 0; | ||
424 | ssi->period_pos = 0; | ||
425 | ssi->byte_per_period = runtime->period_size * | ||
426 | runtime->channels * | ||
427 | samples_to_bytes(runtime, 1); | ||
428 | ssi->next_period_byte = ssi->byte_per_period; | ||
429 | } | ||
430 | |||
431 | static int rsnd_ssi_pointer_offset(struct rsnd_mod *mod, | ||
432 | struct rsnd_dai_stream *io, | ||
433 | int additional) | ||
434 | { | ||
435 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
436 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
437 | int pos = ssi->byte_pos + additional; | ||
438 | |||
439 | pos %= (runtime->periods * ssi->byte_per_period); | ||
440 | |||
441 | return pos; | ||
442 | } | ||
443 | |||
444 | static bool rsnd_ssi_pointer_update(struct rsnd_mod *mod, | ||
445 | struct rsnd_dai_stream *io, | ||
446 | int byte) | ||
447 | { | ||
448 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
449 | bool ret = false; | ||
450 | int byte_pos; | ||
451 | |||
452 | byte_pos = ssi->byte_pos + byte; | ||
453 | |||
454 | if (byte_pos >= ssi->next_period_byte) { | ||
455 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
456 | |||
457 | ssi->period_pos++; | ||
458 | ssi->next_period_byte += ssi->byte_per_period; | ||
459 | |||
460 | if (ssi->period_pos >= runtime->periods) { | ||
461 | byte_pos = 0; | ||
462 | ssi->period_pos = 0; | ||
463 | ssi->next_period_byte = ssi->byte_per_period; | ||
464 | } | ||
465 | |||
466 | ret = true; | ||
467 | } | ||
468 | |||
469 | WRITE_ONCE(ssi->byte_pos, byte_pos); | ||
470 | |||
471 | return ret; | ||
472 | } | ||
473 | |||
474 | /* | 417 | /* |
475 | * SSI mod common functions | 418 | * SSI mod common functions |
476 | */ | 419 | */ |
@@ -484,8 +427,6 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
484 | if (!rsnd_ssi_is_run_mods(mod, io)) | 427 | if (!rsnd_ssi_is_run_mods(mod, io)) |
485 | return 0; | 428 | return 0; |
486 | 429 | ||
487 | rsnd_ssi_pointer_init(mod, io); | ||
488 | |||
489 | ssi->usrcnt++; | 430 | ssi->usrcnt++; |
490 | 431 | ||
491 | rsnd_mod_power_on(mod); | 432 | rsnd_mod_power_on(mod); |
@@ -656,6 +597,8 @@ static int rsnd_ssi_irq(struct rsnd_mod *mod, | |||
656 | return 0; | 597 | return 0; |
657 | } | 598 | } |
658 | 599 | ||
600 | static bool rsnd_ssi_pio_interrupt(struct rsnd_mod *mod, | ||
601 | struct rsnd_dai_stream *io); | ||
659 | static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, | 602 | static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, |
660 | struct rsnd_dai_stream *io) | 603 | struct rsnd_dai_stream *io) |
661 | { | 604 | { |
@@ -674,30 +617,8 @@ static void __rsnd_ssi_interrupt(struct rsnd_mod *mod, | |||
674 | status = rsnd_ssi_status_get(mod); | 617 | status = rsnd_ssi_status_get(mod); |
675 | 618 | ||
676 | /* PIO only */ | 619 | /* PIO only */ |
677 | if (!is_dma && (status & DIRQ)) { | 620 | if (!is_dma && (status & DIRQ)) |
678 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 621 | elapsed = rsnd_ssi_pio_interrupt(mod, io); |
679 | u32 *buf = (u32 *)(runtime->dma_area + | ||
680 | rsnd_ssi_pointer_offset(mod, io, 0)); | ||
681 | int shift = 0; | ||
682 | |||
683 | switch (runtime->sample_bits) { | ||
684 | case 32: | ||
685 | shift = 8; | ||
686 | break; | ||
687 | } | ||
688 | |||
689 | /* | ||
690 | * 8/16/32 data can be assesse to TDR/RDR register | ||
691 | * directly as 32bit data | ||
692 | * see rsnd_ssi_init() | ||
693 | */ | ||
694 | if (rsnd_io_is_play(io)) | ||
695 | rsnd_mod_write(mod, SSITDR, (*buf) << shift); | ||
696 | else | ||
697 | *buf = (rsnd_mod_read(mod, SSIRDR) >> shift); | ||
698 | |||
699 | elapsed = rsnd_ssi_pointer_update(mod, io, sizeof(*buf)); | ||
700 | } | ||
701 | 622 | ||
702 | /* DMA only */ | 623 | /* DMA only */ |
703 | if (is_dma && (status & (UIRQ | OIRQ))) | 624 | if (is_dma && (status & (UIRQ | OIRQ))) |
@@ -835,7 +756,71 @@ static int rsnd_ssi_common_remove(struct rsnd_mod *mod, | |||
835 | return 0; | 756 | return 0; |
836 | } | 757 | } |
837 | 758 | ||
838 | static int rsnd_ssi_pointer(struct rsnd_mod *mod, | 759 | /* |
760 | * SSI PIO functions | ||
761 | */ | ||
762 | static bool rsnd_ssi_pio_interrupt(struct rsnd_mod *mod, | ||
763 | struct rsnd_dai_stream *io) | ||
764 | { | ||
765 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
766 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
767 | u32 *buf = (u32 *)(runtime->dma_area + ssi->byte_pos); | ||
768 | int shift = 0; | ||
769 | int byte_pos; | ||
770 | bool elapsed = false; | ||
771 | |||
772 | if (snd_pcm_format_width(runtime->format) == 24) | ||
773 | shift = 8; | ||
774 | |||
775 | /* | ||
776 | * 8/16/32 data can be assesse to TDR/RDR register | ||
777 | * directly as 32bit data | ||
778 | * see rsnd_ssi_init() | ||
779 | */ | ||
780 | if (rsnd_io_is_play(io)) | ||
781 | rsnd_mod_write(mod, SSITDR, (*buf) << shift); | ||
782 | else | ||
783 | *buf = (rsnd_mod_read(mod, SSIRDR) >> shift); | ||
784 | |||
785 | byte_pos = ssi->byte_pos + sizeof(*buf); | ||
786 | |||
787 | if (byte_pos >= ssi->next_period_byte) { | ||
788 | int period_pos = byte_pos / ssi->byte_per_period; | ||
789 | |||
790 | if (period_pos >= runtime->periods) { | ||
791 | byte_pos = 0; | ||
792 | period_pos = 0; | ||
793 | } | ||
794 | |||
795 | ssi->next_period_byte = (period_pos + 1) * ssi->byte_per_period; | ||
796 | |||
797 | elapsed = true; | ||
798 | } | ||
799 | |||
800 | WRITE_ONCE(ssi->byte_pos, byte_pos); | ||
801 | |||
802 | return elapsed; | ||
803 | } | ||
804 | |||
805 | static int rsnd_ssi_pio_init(struct rsnd_mod *mod, | ||
806 | struct rsnd_dai_stream *io, | ||
807 | struct rsnd_priv *priv) | ||
808 | { | ||
809 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
810 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
811 | |||
812 | if (!rsnd_ssi_is_parent(mod, io)) { | ||
813 | ssi->byte_pos = 0; | ||
814 | ssi->byte_per_period = runtime->period_size * | ||
815 | runtime->channels * | ||
816 | samples_to_bytes(runtime, 1); | ||
817 | ssi->next_period_byte = ssi->byte_per_period; | ||
818 | } | ||
819 | |||
820 | return rsnd_ssi_init(mod, io, priv); | ||
821 | } | ||
822 | |||
823 | static int rsnd_ssi_pio_pointer(struct rsnd_mod *mod, | ||
839 | struct rsnd_dai_stream *io, | 824 | struct rsnd_dai_stream *io, |
840 | snd_pcm_uframes_t *pointer) | 825 | snd_pcm_uframes_t *pointer) |
841 | { | 826 | { |
@@ -851,12 +836,12 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
851 | .name = SSI_NAME, | 836 | .name = SSI_NAME, |
852 | .probe = rsnd_ssi_common_probe, | 837 | .probe = rsnd_ssi_common_probe, |
853 | .remove = rsnd_ssi_common_remove, | 838 | .remove = rsnd_ssi_common_remove, |
854 | .init = rsnd_ssi_init, | 839 | .init = rsnd_ssi_pio_init, |
855 | .quit = rsnd_ssi_quit, | 840 | .quit = rsnd_ssi_quit, |
856 | .start = rsnd_ssi_start, | 841 | .start = rsnd_ssi_start, |
857 | .stop = rsnd_ssi_stop, | 842 | .stop = rsnd_ssi_stop, |
858 | .irq = rsnd_ssi_irq, | 843 | .irq = rsnd_ssi_irq, |
859 | .pointer= rsnd_ssi_pointer, | 844 | .pointer = rsnd_ssi_pio_pointer, |
860 | .pcm_new = rsnd_ssi_pcm_new, | 845 | .pcm_new = rsnd_ssi_pcm_new, |
861 | .hw_params = rsnd_ssi_hw_params, | 846 | .hw_params = rsnd_ssi_hw_params, |
862 | }; | 847 | }; |
diff --git a/sound/soc/soc-acpi.c b/sound/soc/soc-acpi.c index f21df28bc28e..3d7e1ff79139 100644 --- a/sound/soc/soc-acpi.c +++ b/sound/soc/soc-acpi.c | |||
@@ -16,79 +16,16 @@ | |||
16 | 16 | ||
17 | #include <sound/soc-acpi.h> | 17 | #include <sound/soc-acpi.h> |
18 | 18 | ||
19 | static acpi_status snd_soc_acpi_find_name(acpi_handle handle, u32 level, | ||
20 | void *context, void **ret) | ||
21 | { | ||
22 | struct acpi_device *adev; | ||
23 | const char *name = NULL; | ||
24 | |||
25 | if (acpi_bus_get_device(handle, &adev)) | ||
26 | return AE_OK; | ||
27 | |||
28 | if (adev->status.present && adev->status.functional) { | ||
29 | name = acpi_dev_name(adev); | ||
30 | *(const char **)ret = name; | ||
31 | return AE_CTRL_TERMINATE; | ||
32 | } | ||
33 | |||
34 | return AE_OK; | ||
35 | } | ||
36 | |||
37 | const char *snd_soc_acpi_find_name_from_hid(const u8 hid[ACPI_ID_LEN]) | ||
38 | { | ||
39 | const char *name = NULL; | ||
40 | acpi_status status; | ||
41 | |||
42 | status = acpi_get_devices(hid, snd_soc_acpi_find_name, NULL, | ||
43 | (void **)&name); | ||
44 | |||
45 | if (ACPI_FAILURE(status) || name[0] == '\0') | ||
46 | return NULL; | ||
47 | |||
48 | return name; | ||
49 | } | ||
50 | EXPORT_SYMBOL_GPL(snd_soc_acpi_find_name_from_hid); | ||
51 | |||
52 | static acpi_status snd_soc_acpi_mach_match(acpi_handle handle, u32 level, | ||
53 | void *context, void **ret) | ||
54 | { | ||
55 | unsigned long long sta; | ||
56 | acpi_status status; | ||
57 | |||
58 | *(bool *)context = true; | ||
59 | status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); | ||
60 | if (ACPI_FAILURE(status) || !(sta & ACPI_STA_DEVICE_PRESENT)) | ||
61 | *(bool *)context = false; | ||
62 | |||
63 | return AE_OK; | ||
64 | } | ||
65 | |||
66 | bool snd_soc_acpi_check_hid(const u8 hid[ACPI_ID_LEN]) | ||
67 | { | ||
68 | acpi_status status; | ||
69 | bool found = false; | ||
70 | |||
71 | status = acpi_get_devices(hid, snd_soc_acpi_mach_match, &found, NULL); | ||
72 | |||
73 | if (ACPI_FAILURE(status)) | ||
74 | return false; | ||
75 | |||
76 | return found; | ||
77 | } | ||
78 | EXPORT_SYMBOL_GPL(snd_soc_acpi_check_hid); | ||
79 | |||
80 | struct snd_soc_acpi_mach * | 19 | struct snd_soc_acpi_mach * |
81 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) | 20 | snd_soc_acpi_find_machine(struct snd_soc_acpi_mach *machines) |
82 | { | 21 | { |
83 | struct snd_soc_acpi_mach *mach; | 22 | struct snd_soc_acpi_mach *mach; |
84 | 23 | ||
85 | for (mach = machines; mach->id[0]; mach++) { | 24 | for (mach = machines; mach->id[0]; mach++) { |
86 | if (snd_soc_acpi_check_hid(mach->id) == true) { | 25 | if (acpi_dev_present(mach->id, NULL, -1)) { |
87 | if (mach->machine_quirk == NULL) | 26 | if (mach->machine_quirk) |
88 | return mach; | 27 | mach = mach->machine_quirk(mach); |
89 | 28 | return mach; | |
90 | if (mach->machine_quirk(mach) != NULL) | ||
91 | return mach; | ||
92 | } | 29 | } |
93 | } | 30 | } |
94 | return NULL; | 31 | return NULL; |
@@ -163,7 +100,7 @@ struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg) | |||
163 | return mach; | 100 | return mach; |
164 | 101 | ||
165 | for (i = 0; i < codec_list->num_codecs; i++) { | 102 | for (i = 0; i < codec_list->num_codecs; i++) { |
166 | if (snd_soc_acpi_check_hid(codec_list->codecs[i]) != true) | 103 | if (!acpi_dev_present(codec_list->codecs[i], NULL, -1)) |
167 | return NULL; | 104 | return NULL; |
168 | } | 105 | } |
169 | 106 | ||
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index d9b1e6417fb9..81232f4ab614 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c | |||
@@ -1096,7 +1096,6 @@ static struct snd_compr_ops soc_compr_dyn_ops = { | |||
1096 | */ | 1096 | */ |
1097 | int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | 1097 | int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) |
1098 | { | 1098 | { |
1099 | struct snd_soc_codec *codec = rtd->codec; | ||
1100 | struct snd_soc_platform *platform = rtd->platform; | 1099 | struct snd_soc_platform *platform = rtd->platform; |
1101 | struct snd_soc_component *component; | 1100 | struct snd_soc_component *component; |
1102 | struct snd_soc_rtdcom_list *rtdcom; | 1101 | struct snd_soc_rtdcom_list *rtdcom; |
@@ -1199,8 +1198,9 @@ int snd_soc_new_compress(struct snd_soc_pcm_runtime *rtd, int num) | |||
1199 | ret = snd_compress_new(rtd->card->snd_card, num, direction, | 1198 | ret = snd_compress_new(rtd->card->snd_card, num, direction, |
1200 | new_name, compr); | 1199 | new_name, compr); |
1201 | if (ret < 0) { | 1200 | if (ret < 0) { |
1201 | component = rtd->codec_dai->component; | ||
1202 | pr_err("compress asoc: can't create compress for codec %s\n", | 1202 | pr_err("compress asoc: can't create compress for codec %s\n", |
1203 | codec->component.name); | 1203 | component->name); |
1204 | goto compr_err; | 1204 | goto compr_err; |
1205 | } | 1205 | } |
1206 | 1206 | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c0edac80df34..e91879569a0f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -213,7 +213,7 @@ static umode_t soc_dev_attr_is_visible(struct kobject *kobj, | |||
213 | 213 | ||
214 | if (attr == &dev_attr_pmdown_time.attr) | 214 | if (attr == &dev_attr_pmdown_time.attr) |
215 | return attr->mode; /* always visible */ | 215 | return attr->mode; /* always visible */ |
216 | return rtd->codec ? attr->mode : 0; /* enabled only with codec */ | 216 | return rtd->num_codecs ? attr->mode : 0; /* enabled only with codec */ |
217 | } | 217 | } |
218 | 218 | ||
219 | static const struct attribute_group soc_dapm_dev_group = { | 219 | static const struct attribute_group soc_dapm_dev_group = { |
@@ -349,120 +349,84 @@ static void soc_init_codec_debugfs(struct snd_soc_component *component) | |||
349 | "ASoC: Failed to create codec register debugfs file\n"); | 349 | "ASoC: Failed to create codec register debugfs file\n"); |
350 | } | 350 | } |
351 | 351 | ||
352 | static ssize_t codec_list_read_file(struct file *file, char __user *user_buf, | 352 | static int codec_list_seq_show(struct seq_file *m, void *v) |
353 | size_t count, loff_t *ppos) | ||
354 | { | 353 | { |
355 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
356 | ssize_t len, ret = 0; | ||
357 | struct snd_soc_codec *codec; | 354 | struct snd_soc_codec *codec; |
358 | 355 | ||
359 | if (!buf) | ||
360 | return -ENOMEM; | ||
361 | |||
362 | mutex_lock(&client_mutex); | 356 | mutex_lock(&client_mutex); |
363 | 357 | ||
364 | list_for_each_entry(codec, &codec_list, list) { | 358 | list_for_each_entry(codec, &codec_list, list) |
365 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", | 359 | seq_printf(m, "%s\n", codec->component.name); |
366 | codec->component.name); | ||
367 | if (len >= 0) | ||
368 | ret += len; | ||
369 | if (ret > PAGE_SIZE) { | ||
370 | ret = PAGE_SIZE; | ||
371 | break; | ||
372 | } | ||
373 | } | ||
374 | 360 | ||
375 | mutex_unlock(&client_mutex); | 361 | mutex_unlock(&client_mutex); |
376 | 362 | ||
377 | if (ret >= 0) | 363 | return 0; |
378 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 364 | } |
379 | |||
380 | kfree(buf); | ||
381 | 365 | ||
382 | return ret; | 366 | static int codec_list_seq_open(struct inode *inode, struct file *file) |
367 | { | ||
368 | return single_open(file, codec_list_seq_show, NULL); | ||
383 | } | 369 | } |
384 | 370 | ||
385 | static const struct file_operations codec_list_fops = { | 371 | static const struct file_operations codec_list_fops = { |
386 | .read = codec_list_read_file, | 372 | .open = codec_list_seq_open, |
387 | .llseek = default_llseek,/* read accesses f_pos */ | 373 | .read = seq_read, |
374 | .llseek = seq_lseek, | ||
375 | .release = single_release, | ||
388 | }; | 376 | }; |
389 | 377 | ||
390 | static ssize_t dai_list_read_file(struct file *file, char __user *user_buf, | 378 | static int dai_list_seq_show(struct seq_file *m, void *v) |
391 | size_t count, loff_t *ppos) | ||
392 | { | 379 | { |
393 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
394 | ssize_t len, ret = 0; | ||
395 | struct snd_soc_component *component; | 380 | struct snd_soc_component *component; |
396 | struct snd_soc_dai *dai; | 381 | struct snd_soc_dai *dai; |
397 | 382 | ||
398 | if (!buf) | ||
399 | return -ENOMEM; | ||
400 | |||
401 | mutex_lock(&client_mutex); | 383 | mutex_lock(&client_mutex); |
402 | 384 | ||
403 | list_for_each_entry(component, &component_list, list) { | 385 | list_for_each_entry(component, &component_list, list) |
404 | list_for_each_entry(dai, &component->dai_list, list) { | 386 | list_for_each_entry(dai, &component->dai_list, list) |
405 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", | 387 | seq_printf(m, "%s\n", dai->name); |
406 | dai->name); | ||
407 | if (len >= 0) | ||
408 | ret += len; | ||
409 | if (ret > PAGE_SIZE) { | ||
410 | ret = PAGE_SIZE; | ||
411 | break; | ||
412 | } | ||
413 | } | ||
414 | } | ||
415 | 388 | ||
416 | mutex_unlock(&client_mutex); | 389 | mutex_unlock(&client_mutex); |
417 | 390 | ||
418 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 391 | return 0; |
419 | 392 | } | |
420 | kfree(buf); | ||
421 | 393 | ||
422 | return ret; | 394 | static int dai_list_seq_open(struct inode *inode, struct file *file) |
395 | { | ||
396 | return single_open(file, dai_list_seq_show, NULL); | ||
423 | } | 397 | } |
424 | 398 | ||
425 | static const struct file_operations dai_list_fops = { | 399 | static const struct file_operations dai_list_fops = { |
426 | .read = dai_list_read_file, | 400 | .open = dai_list_seq_open, |
427 | .llseek = default_llseek,/* read accesses f_pos */ | 401 | .read = seq_read, |
402 | .llseek = seq_lseek, | ||
403 | .release = single_release, | ||
428 | }; | 404 | }; |
429 | 405 | ||
430 | static ssize_t platform_list_read_file(struct file *file, | 406 | static int platform_list_seq_show(struct seq_file *m, void *v) |
431 | char __user *user_buf, | ||
432 | size_t count, loff_t *ppos) | ||
433 | { | 407 | { |
434 | char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); | ||
435 | ssize_t len, ret = 0; | ||
436 | struct snd_soc_platform *platform; | 408 | struct snd_soc_platform *platform; |
437 | 409 | ||
438 | if (!buf) | ||
439 | return -ENOMEM; | ||
440 | |||
441 | mutex_lock(&client_mutex); | 410 | mutex_lock(&client_mutex); |
442 | 411 | ||
443 | list_for_each_entry(platform, &platform_list, list) { | 412 | list_for_each_entry(platform, &platform_list, list) |
444 | len = snprintf(buf + ret, PAGE_SIZE - ret, "%s\n", | 413 | seq_printf(m, "%s\n", platform->component.name); |
445 | platform->component.name); | ||
446 | if (len >= 0) | ||
447 | ret += len; | ||
448 | if (ret > PAGE_SIZE) { | ||
449 | ret = PAGE_SIZE; | ||
450 | break; | ||
451 | } | ||
452 | } | ||
453 | 414 | ||
454 | mutex_unlock(&client_mutex); | 415 | mutex_unlock(&client_mutex); |
455 | 416 | ||
456 | ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); | 417 | return 0; |
457 | 418 | } | |
458 | kfree(buf); | ||
459 | 419 | ||
460 | return ret; | 420 | static int platform_list_seq_open(struct inode *inode, struct file *file) |
421 | { | ||
422 | return single_open(file, platform_list_seq_show, NULL); | ||
461 | } | 423 | } |
462 | 424 | ||
463 | static const struct file_operations platform_list_fops = { | 425 | static const struct file_operations platform_list_fops = { |
464 | .read = platform_list_read_file, | 426 | .open = platform_list_seq_open, |
465 | .llseek = default_llseek,/* read accesses f_pos */ | 427 | .read = seq_read, |
428 | .llseek = seq_lseek, | ||
429 | .release = single_release, | ||
466 | }; | 430 | }; |
467 | 431 | ||
468 | static void soc_init_card_debugfs(struct snd_soc_card *card) | 432 | static void soc_init_card_debugfs(struct snd_soc_card *card) |
@@ -491,7 +455,6 @@ static void soc_cleanup_card_debugfs(struct snd_soc_card *card) | |||
491 | debugfs_remove_recursive(card->debugfs_card_root); | 455 | debugfs_remove_recursive(card->debugfs_card_root); |
492 | } | 456 | } |
493 | 457 | ||
494 | |||
495 | static void snd_soc_debugfs_init(void) | 458 | static void snd_soc_debugfs_init(void) |
496 | { | 459 | { |
497 | snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); | 460 | snd_soc_debugfs_root = debugfs_create_dir("asoc", NULL); |
@@ -598,6 +561,7 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct snd_soc_pcm_runtime *rtd, | |||
598 | 561 | ||
599 | return NULL; | 562 | return NULL; |
600 | } | 563 | } |
564 | EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup); | ||
601 | 565 | ||
602 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, | 566 | struct snd_pcm_substream *snd_soc_get_dai_substream(struct snd_soc_card *card, |
603 | const char *dai_link, int stream) | 567 | const char *dai_link, int stream) |
@@ -1392,6 +1356,17 @@ static int soc_init_dai_link(struct snd_soc_card *card, | |||
1392 | return 0; | 1356 | return 0; |
1393 | } | 1357 | } |
1394 | 1358 | ||
1359 | void snd_soc_disconnect_sync(struct device *dev) | ||
1360 | { | ||
1361 | struct snd_soc_component *component = snd_soc_lookup_component(dev, NULL); | ||
1362 | |||
1363 | if (!component || !component->card) | ||
1364 | return; | ||
1365 | |||
1366 | snd_card_disconnect_sync(component->card->snd_card); | ||
1367 | } | ||
1368 | EXPORT_SYMBOL_GPL(snd_soc_disconnect_sync); | ||
1369 | |||
1395 | /** | 1370 | /** |
1396 | * snd_soc_add_dai_link - Add a DAI link dynamically | 1371 | * snd_soc_add_dai_link - Add a DAI link dynamically |
1397 | * @card: The ASoC card to which the DAI link is added | 1372 | * @card: The ASoC card to which the DAI link is added |
@@ -1945,7 +1920,9 @@ int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd, | |||
1945 | } | 1920 | } |
1946 | 1921 | ||
1947 | /* Flip the polarity for the "CPU" end of a CODEC<->CODEC link */ | 1922 | /* Flip the polarity for the "CPU" end of a CODEC<->CODEC link */ |
1948 | if (cpu_dai->codec) { | 1923 | /* the component which has non_legacy_dai_naming is Codec */ |
1924 | if (cpu_dai->codec || | ||
1925 | cpu_dai->component->driver->non_legacy_dai_naming) { | ||
1949 | unsigned int inv_dai_fmt; | 1926 | unsigned int inv_dai_fmt; |
1950 | 1927 | ||
1951 | inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK; | 1928 | inv_dai_fmt = dai_fmt & ~SND_SOC_DAIFMT_MASTER_MASK; |
@@ -3149,7 +3126,7 @@ static struct snd_soc_dai *soc_add_dai(struct snd_soc_component *component, | |||
3149 | if (!dai->driver->ops) | 3126 | if (!dai->driver->ops) |
3150 | dai->driver->ops = &null_dai_ops; | 3127 | dai->driver->ops = &null_dai_ops; |
3151 | 3128 | ||
3152 | list_add(&dai->list, &component->dai_list); | 3129 | list_add_tail(&dai->list, &component->dai_list); |
3153 | component->num_dai++; | 3130 | component->num_dai++; |
3154 | 3131 | ||
3155 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); | 3132 | dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name); |
@@ -3176,8 +3153,6 @@ static int snd_soc_register_dais(struct snd_soc_component *component, | |||
3176 | 3153 | ||
3177 | dev_dbg(dev, "ASoC: dai register %s #%zu\n", dev_name(dev), count); | 3154 | dev_dbg(dev, "ASoC: dai register %s #%zu\n", dev_name(dev), count); |
3178 | 3155 | ||
3179 | component->dai_drv = dai_drv; | ||
3180 | |||
3181 | for (i = 0; i < count; i++) { | 3156 | for (i = 0; i < count; i++) { |
3182 | 3157 | ||
3183 | dai = soc_add_dai(component, dai_drv + i, | 3158 | dai = soc_add_dai(component, dai_drv + i, |
@@ -4354,6 +4329,7 @@ int snd_soc_get_dai_name(struct of_phandle_args *args, | |||
4354 | args, | 4329 | args, |
4355 | dai_name); | 4330 | dai_name); |
4356 | } else { | 4331 | } else { |
4332 | struct snd_soc_dai *dai; | ||
4357 | int id = -1; | 4333 | int id = -1; |
4358 | 4334 | ||
4359 | switch (args->args_count) { | 4335 | switch (args->args_count) { |
@@ -4375,7 +4351,14 @@ int snd_soc_get_dai_name(struct of_phandle_args *args, | |||
4375 | 4351 | ||
4376 | ret = 0; | 4352 | ret = 0; |
4377 | 4353 | ||
4378 | *dai_name = pos->dai_drv[id].name; | 4354 | /* find target DAI */ |
4355 | list_for_each_entry(dai, &pos->dai_list, list) { | ||
4356 | if (id == 0) | ||
4357 | break; | ||
4358 | id--; | ||
4359 | } | ||
4360 | |||
4361 | *dai_name = dai->driver->name; | ||
4379 | if (!*dai_name) | 4362 | if (!*dai_name) |
4380 | *dai_name = pos->name; | 4363 | *dai_name = pos->name; |
4381 | } | 4364 | } |
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 20340ade20a7..2bc1c4c17896 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
@@ -34,6 +34,10 @@ int snd_soc_component_read(struct snd_soc_component *component, | |||
34 | ret = regmap_read(component->regmap, reg, val); | 34 | ret = regmap_read(component->regmap, reg, val); |
35 | else if (component->read) | 35 | else if (component->read) |
36 | ret = component->read(component, reg, val); | 36 | ret = component->read(component, reg, val); |
37 | else if (component->driver->read) { | ||
38 | *val = component->driver->read(component, reg); | ||
39 | ret = 0; | ||
40 | } | ||
37 | else | 41 | else |
38 | ret = -EIO; | 42 | ret = -EIO; |
39 | 43 | ||
@@ -70,6 +74,8 @@ int snd_soc_component_write(struct snd_soc_component *component, | |||
70 | return regmap_write(component->regmap, reg, val); | 74 | return regmap_write(component->regmap, reg, val); |
71 | else if (component->write) | 75 | else if (component->write) |
72 | return component->write(component, reg, val); | 76 | return component->write(component, reg, val); |
77 | else if (component->driver->write) | ||
78 | return component->driver->write(component, reg, val); | ||
73 | else | 79 | else |
74 | return -EIO; | 80 | return -EIO; |
75 | } | 81 | } |
diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 500f98c730b9..7144a51ddfa9 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c | |||
@@ -378,7 +378,7 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, | |||
378 | unsigned int rshift = mc->rshift; | 378 | unsigned int rshift = mc->rshift; |
379 | int max = mc->max; | 379 | int max = mc->max; |
380 | int min = mc->min; | 380 | int min = mc->min; |
381 | int mask = (1 << (fls(min + max) - 1)) - 1; | 381 | unsigned int mask = (1 << (fls(min + max) - 1)) - 1; |
382 | unsigned int val; | 382 | unsigned int val; |
383 | int ret; | 383 | int ret; |
384 | 384 | ||
@@ -423,7 +423,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, | |||
423 | unsigned int rshift = mc->rshift; | 423 | unsigned int rshift = mc->rshift; |
424 | int max = mc->max; | 424 | int max = mc->max; |
425 | int min = mc->min; | 425 | int min = mc->min; |
426 | int mask = (1 << (fls(min + max) - 1)) - 1; | 426 | unsigned int mask = (1 << (fls(min + max) - 1)) - 1; |
427 | int err = 0; | 427 | int err = 0; |
428 | unsigned int val, val_mask, val2 = 0; | 428 | unsigned int val, val_mask, val2 = 0; |
429 | 429 | ||
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index e30aacbcfc29..bcd3da2739e2 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -288,7 +288,7 @@ static const struct snd_soc_platform_driver dummy_platform = { | |||
288 | .ops = &dummy_dma_ops, | 288 | .ops = &dummy_dma_ops, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | static struct snd_soc_codec_driver dummy_codec; | 291 | static const struct snd_soc_codec_driver dummy_codec; |
292 | 292 | ||
293 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 | 293 | #define STUB_RATES SNDRV_PCM_RATE_8000_192000 |
294 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ | 294 | #define STUB_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ |
diff --git a/sound/soc/stm/Kconfig b/sound/soc/stm/Kconfig index 3398e6c57f37..3ad881fc40a1 100644 --- a/sound/soc/stm/Kconfig +++ b/sound/soc/stm/Kconfig | |||
@@ -28,4 +28,16 @@ config SND_SOC_STM32_SPDIFRX | |||
28 | help | 28 | help |
29 | Say Y if you want to enable S/PDIF capture for STM32 | 29 | Say Y if you want to enable S/PDIF capture for STM32 |
30 | 30 | ||
31 | config SND_SOC_STM32_DFSDM | ||
32 | tristate "SoC Audio support for STM32 DFSDM" | ||
33 | depends on ARCH_STM32 || COMPILE_TEST | ||
34 | depends on SND_SOC | ||
35 | depends on STM32_DFSDM_ADC | ||
36 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
37 | select SND_SOC_DMIC | ||
38 | select IIO_BUFFER_CB | ||
39 | help | ||
40 | Select this option to enable the STM32 Digital Filter | ||
41 | for Sigma Delta Modulators (DFSDM) driver used | ||
42 | in various STM32 series for digital microphone capture. | ||
31 | endmenu | 43 | endmenu |
diff --git a/sound/soc/stm/Makefile b/sound/soc/stm/Makefile index 5b7f0fab0bd6..3143c0b47042 100644 --- a/sound/soc/stm/Makefile +++ b/sound/soc/stm/Makefile | |||
@@ -13,3 +13,6 @@ obj-$(CONFIG_SND_SOC_STM32_I2S) += snd-soc-stm32-i2s.o | |||
13 | # SPDIFRX | 13 | # SPDIFRX |
14 | snd-soc-stm32-spdifrx-objs := stm32_spdifrx.o | 14 | snd-soc-stm32-spdifrx-objs := stm32_spdifrx.o |
15 | obj-$(CONFIG_SND_SOC_STM32_SPDIFRX) += snd-soc-stm32-spdifrx.o | 15 | obj-$(CONFIG_SND_SOC_STM32_SPDIFRX) += snd-soc-stm32-spdifrx.o |
16 | |||
17 | #DFSDM | ||
18 | obj-$(CONFIG_SND_SOC_STM32_DFSDM) += stm32_adfsdm.o | ||
diff --git a/sound/soc/stm/stm32_adfsdm.c b/sound/soc/stm/stm32_adfsdm.c new file mode 100644 index 000000000000..7306e3eca9e1 --- /dev/null +++ b/sound/soc/stm/stm32_adfsdm.c | |||
@@ -0,0 +1,347 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * This file is part of STM32 DFSDM ASoC DAI driver | ||
4 | * | ||
5 | * Copyright (C) 2017, STMicroelectronics - All Rights Reserved | ||
6 | * Authors: Arnaud Pouliquen <arnaud.pouliquen@st.com> | ||
7 | * Olivier Moysan <olivier.moysan@st.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/clk.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/slab.h> | ||
14 | |||
15 | #include <linux/iio/iio.h> | ||
16 | #include <linux/iio/consumer.h> | ||
17 | #include <linux/iio/adc/stm32-dfsdm-adc.h> | ||
18 | |||
19 | #include <sound/pcm.h> | ||
20 | #include <sound/soc.h> | ||
21 | |||
22 | #define STM32_ADFSDM_DRV_NAME "stm32-adfsdm" | ||
23 | |||
24 | #define DFSDM_MAX_PERIOD_SIZE (PAGE_SIZE / 2) | ||
25 | #define DFSDM_MAX_PERIODS 6 | ||
26 | |||
27 | struct stm32_adfsdm_priv { | ||
28 | struct snd_soc_dai_driver dai_drv; | ||
29 | struct snd_pcm_substream *substream; | ||
30 | struct device *dev; | ||
31 | |||
32 | /* IIO */ | ||
33 | struct iio_channel *iio_ch; | ||
34 | struct iio_cb_buffer *iio_cb; | ||
35 | bool iio_active; | ||
36 | |||
37 | /* PCM buffer */ | ||
38 | unsigned char *pcm_buff; | ||
39 | unsigned int pos; | ||
40 | }; | ||
41 | |||
42 | static const struct snd_pcm_hardware stm32_adfsdm_pcm_hw = { | ||
43 | .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
44 | SNDRV_PCM_INFO_PAUSE, | ||
45 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
46 | |||
47 | .rate_min = 8000, | ||
48 | .rate_max = 32000, | ||
49 | |||
50 | .channels_min = 1, | ||
51 | .channels_max = 1, | ||
52 | |||
53 | .periods_min = 2, | ||
54 | .periods_max = DFSDM_MAX_PERIODS, | ||
55 | |||
56 | .period_bytes_max = DFSDM_MAX_PERIOD_SIZE, | ||
57 | .buffer_bytes_max = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE | ||
58 | }; | ||
59 | |||
60 | static void stm32_adfsdm_shutdown(struct snd_pcm_substream *substream, | ||
61 | struct snd_soc_dai *dai) | ||
62 | { | ||
63 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | ||
64 | |||
65 | if (priv->iio_active) { | ||
66 | iio_channel_stop_all_cb(priv->iio_cb); | ||
67 | priv->iio_active = false; | ||
68 | } | ||
69 | } | ||
70 | |||
71 | static int stm32_adfsdm_dai_prepare(struct snd_pcm_substream *substream, | ||
72 | struct snd_soc_dai *dai) | ||
73 | { | ||
74 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | ||
75 | int ret; | ||
76 | |||
77 | ret = iio_write_channel_attribute(priv->iio_ch, | ||
78 | substream->runtime->rate, 0, | ||
79 | IIO_CHAN_INFO_SAMP_FREQ); | ||
80 | if (ret < 0) { | ||
81 | dev_err(dai->dev, "%s: Failed to set %d sampling rate\n", | ||
82 | __func__, substream->runtime->rate); | ||
83 | return ret; | ||
84 | } | ||
85 | |||
86 | if (!priv->iio_active) { | ||
87 | ret = iio_channel_start_all_cb(priv->iio_cb); | ||
88 | if (!ret) | ||
89 | priv->iio_active = true; | ||
90 | else | ||
91 | dev_err(dai->dev, "%s: IIO channel start failed (%d)\n", | ||
92 | __func__, ret); | ||
93 | } | ||
94 | |||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | static int stm32_adfsdm_set_sysclk(struct snd_soc_dai *dai, int clk_id, | ||
99 | unsigned int freq, int dir) | ||
100 | { | ||
101 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(dai); | ||
102 | ssize_t size; | ||
103 | char str_freq[10]; | ||
104 | |||
105 | dev_dbg(dai->dev, "%s: Enter for freq %d\n", __func__, freq); | ||
106 | |||
107 | /* Set IIO frequency if CODEC is master as clock comes from SPI_IN */ | ||
108 | |||
109 | snprintf(str_freq, sizeof(str_freq), "%d\n", freq); | ||
110 | size = iio_write_channel_ext_info(priv->iio_ch, "spi_clk_freq", | ||
111 | str_freq, sizeof(str_freq)); | ||
112 | if (size != sizeof(str_freq)) { | ||
113 | dev_err(dai->dev, "%s: Failed to set SPI clock\n", | ||
114 | __func__); | ||
115 | return -EINVAL; | ||
116 | } | ||
117 | return 0; | ||
118 | } | ||
119 | |||
120 | static const struct snd_soc_dai_ops stm32_adfsdm_dai_ops = { | ||
121 | .shutdown = stm32_adfsdm_shutdown, | ||
122 | .prepare = stm32_adfsdm_dai_prepare, | ||
123 | .set_sysclk = stm32_adfsdm_set_sysclk, | ||
124 | }; | ||
125 | |||
126 | static const struct snd_soc_dai_driver stm32_adfsdm_dai = { | ||
127 | .capture = { | ||
128 | .channels_min = 1, | ||
129 | .channels_max = 1, | ||
130 | .formats = SNDRV_PCM_FMTBIT_S32_LE, | ||
131 | .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 | | ||
132 | SNDRV_PCM_RATE_32000), | ||
133 | }, | ||
134 | .ops = &stm32_adfsdm_dai_ops, | ||
135 | }; | ||
136 | |||
137 | static const struct snd_soc_component_driver stm32_adfsdm_dai_component = { | ||
138 | .name = "stm32_dfsdm_audio", | ||
139 | }; | ||
140 | |||
141 | static int stm32_afsdm_pcm_cb(const void *data, size_t size, void *private) | ||
142 | { | ||
143 | struct stm32_adfsdm_priv *priv = private; | ||
144 | struct snd_soc_pcm_runtime *rtd = priv->substream->private_data; | ||
145 | u8 *pcm_buff = priv->pcm_buff; | ||
146 | u8 *src_buff = (u8 *)data; | ||
147 | unsigned int buff_size = snd_pcm_lib_buffer_bytes(priv->substream); | ||
148 | unsigned int period_size = snd_pcm_lib_period_bytes(priv->substream); | ||
149 | unsigned int old_pos = priv->pos; | ||
150 | unsigned int cur_size = size; | ||
151 | |||
152 | dev_dbg(rtd->dev, "%s: buff_add :%p, pos = %d, size = %zu\n", | ||
153 | __func__, &pcm_buff[priv->pos], priv->pos, size); | ||
154 | |||
155 | if ((priv->pos + size) > buff_size) { | ||
156 | memcpy(&pcm_buff[priv->pos], src_buff, buff_size - priv->pos); | ||
157 | cur_size -= buff_size - priv->pos; | ||
158 | priv->pos = 0; | ||
159 | } | ||
160 | |||
161 | memcpy(&pcm_buff[priv->pos], &src_buff[size - cur_size], cur_size); | ||
162 | priv->pos = (priv->pos + cur_size) % buff_size; | ||
163 | |||
164 | if (cur_size != size || (old_pos && (old_pos % period_size < size))) | ||
165 | snd_pcm_period_elapsed(priv->substream); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | static int stm32_adfsdm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
171 | { | ||
172 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
173 | struct stm32_adfsdm_priv *priv = | ||
174 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
175 | |||
176 | switch (cmd) { | ||
177 | case SNDRV_PCM_TRIGGER_START: | ||
178 | case SNDRV_PCM_TRIGGER_RESUME: | ||
179 | priv->pos = 0; | ||
180 | return stm32_dfsdm_get_buff_cb(priv->iio_ch->indio_dev, | ||
181 | stm32_afsdm_pcm_cb, priv); | ||
182 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
183 | case SNDRV_PCM_TRIGGER_STOP: | ||
184 | return stm32_dfsdm_release_buff_cb(priv->iio_ch->indio_dev); | ||
185 | } | ||
186 | |||
187 | return -EINVAL; | ||
188 | } | ||
189 | |||
190 | static int stm32_adfsdm_pcm_open(struct snd_pcm_substream *substream) | ||
191 | { | ||
192 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
193 | struct stm32_adfsdm_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
194 | int ret; | ||
195 | |||
196 | ret = snd_soc_set_runtime_hwparams(substream, &stm32_adfsdm_pcm_hw); | ||
197 | if (!ret) | ||
198 | priv->substream = substream; | ||
199 | |||
200 | return ret; | ||
201 | } | ||
202 | |||
203 | static int stm32_adfsdm_pcm_close(struct snd_pcm_substream *substream) | ||
204 | { | ||
205 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
206 | struct stm32_adfsdm_priv *priv = | ||
207 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
208 | |||
209 | snd_pcm_lib_free_pages(substream); | ||
210 | priv->substream = NULL; | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static snd_pcm_uframes_t stm32_adfsdm_pcm_pointer( | ||
216 | struct snd_pcm_substream *substream) | ||
217 | { | ||
218 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
219 | struct stm32_adfsdm_priv *priv = | ||
220 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
221 | |||
222 | return bytes_to_frames(substream->runtime, priv->pos); | ||
223 | } | ||
224 | |||
225 | static int stm32_adfsdm_pcm_hw_params(struct snd_pcm_substream *substream, | ||
226 | struct snd_pcm_hw_params *params) | ||
227 | { | ||
228 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
229 | struct stm32_adfsdm_priv *priv = | ||
230 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
231 | int ret; | ||
232 | |||
233 | ret = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | ||
234 | if (ret < 0) | ||
235 | return ret; | ||
236 | priv->pcm_buff = substream->runtime->dma_area; | ||
237 | |||
238 | return iio_channel_cb_set_buffer_watermark(priv->iio_cb, | ||
239 | params_period_size(params)); | ||
240 | } | ||
241 | |||
242 | static int stm32_adfsdm_pcm_hw_free(struct snd_pcm_substream *substream) | ||
243 | { | ||
244 | snd_pcm_lib_free_pages(substream); | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static struct snd_pcm_ops stm32_adfsdm_pcm_ops = { | ||
250 | .open = stm32_adfsdm_pcm_open, | ||
251 | .close = stm32_adfsdm_pcm_close, | ||
252 | .hw_params = stm32_adfsdm_pcm_hw_params, | ||
253 | .hw_free = stm32_adfsdm_pcm_hw_free, | ||
254 | .trigger = stm32_adfsdm_trigger, | ||
255 | .pointer = stm32_adfsdm_pcm_pointer, | ||
256 | }; | ||
257 | |||
258 | static int stm32_adfsdm_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
259 | { | ||
260 | struct snd_pcm *pcm = rtd->pcm; | ||
261 | struct stm32_adfsdm_priv *priv = | ||
262 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
263 | unsigned int size = DFSDM_MAX_PERIODS * DFSDM_MAX_PERIOD_SIZE; | ||
264 | |||
265 | return snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, | ||
266 | priv->dev, size, size); | ||
267 | } | ||
268 | |||
269 | static void stm32_adfsdm_pcm_free(struct snd_pcm *pcm) | ||
270 | { | ||
271 | struct snd_pcm_substream *substream; | ||
272 | struct snd_soc_pcm_runtime *rtd; | ||
273 | struct stm32_adfsdm_priv *priv; | ||
274 | |||
275 | substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; | ||
276 | if (substream) { | ||
277 | rtd = substream->private_data; | ||
278 | priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
279 | |||
280 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
281 | } | ||
282 | } | ||
283 | |||
284 | static struct snd_soc_platform_driver stm32_adfsdm_soc_platform = { | ||
285 | .ops = &stm32_adfsdm_pcm_ops, | ||
286 | .pcm_new = stm32_adfsdm_pcm_new, | ||
287 | .pcm_free = stm32_adfsdm_pcm_free, | ||
288 | }; | ||
289 | |||
290 | static const struct of_device_id stm32_adfsdm_of_match[] = { | ||
291 | {.compatible = "st,stm32h7-dfsdm-dai"}, | ||
292 | {} | ||
293 | }; | ||
294 | MODULE_DEVICE_TABLE(of, stm32_adfsdm_of_match); | ||
295 | |||
296 | static int stm32_adfsdm_probe(struct platform_device *pdev) | ||
297 | { | ||
298 | struct stm32_adfsdm_priv *priv; | ||
299 | int ret; | ||
300 | |||
301 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | ||
302 | if (!priv) | ||
303 | return -ENOMEM; | ||
304 | |||
305 | priv->dev = &pdev->dev; | ||
306 | priv->dai_drv = stm32_adfsdm_dai; | ||
307 | |||
308 | dev_set_drvdata(&pdev->dev, priv); | ||
309 | |||
310 | ret = devm_snd_soc_register_component(&pdev->dev, | ||
311 | &stm32_adfsdm_dai_component, | ||
312 | &priv->dai_drv, 1); | ||
313 | if (ret < 0) | ||
314 | return ret; | ||
315 | |||
316 | /* Associate iio channel */ | ||
317 | priv->iio_ch = devm_iio_channel_get_all(&pdev->dev); | ||
318 | if (IS_ERR(priv->iio_ch)) | ||
319 | return PTR_ERR(priv->iio_ch); | ||
320 | |||
321 | priv->iio_cb = iio_channel_get_all_cb(&pdev->dev, NULL, NULL); | ||
322 | if (IS_ERR(priv->iio_cb)) | ||
323 | return PTR_ERR(priv->iio_cb); | ||
324 | |||
325 | ret = devm_snd_soc_register_platform(&pdev->dev, | ||
326 | &stm32_adfsdm_soc_platform); | ||
327 | if (ret < 0) | ||
328 | dev_err(&pdev->dev, "%s: Failed to register PCM platform\n", | ||
329 | __func__); | ||
330 | |||
331 | return ret; | ||
332 | } | ||
333 | |||
334 | static struct platform_driver stm32_adfsdm_driver = { | ||
335 | .driver = { | ||
336 | .name = STM32_ADFSDM_DRV_NAME, | ||
337 | .of_match_table = stm32_adfsdm_of_match, | ||
338 | }, | ||
339 | .probe = stm32_adfsdm_probe, | ||
340 | }; | ||
341 | |||
342 | module_platform_driver(stm32_adfsdm_driver); | ||
343 | |||
344 | MODULE_DESCRIPTION("stm32 DFSDM DAI driver"); | ||
345 | MODULE_AUTHOR("Arnaud Pouliquen <arnaud.pouliquen@st.com>"); | ||
346 | MODULE_LICENSE("GPL v2"); | ||
347 | MODULE_ALIAS("platform:" STM32_ADFSDM_DRV_NAME); | ||
diff --git a/sound/soc/stm/stm32_sai.c b/sound/soc/stm/stm32_sai.c index d6f71a3406e9..d743b7dd52fb 100644 --- a/sound/soc/stm/stm32_sai.c +++ b/sound/soc/stm/stm32_sai.c | |||
@@ -28,16 +28,6 @@ | |||
28 | 28 | ||
29 | #include "stm32_sai.h" | 29 | #include "stm32_sai.h" |
30 | 30 | ||
31 | static LIST_HEAD(sync_providers); | ||
32 | static DEFINE_MUTEX(sync_mutex); | ||
33 | |||
34 | struct sync_provider { | ||
35 | struct list_head link; | ||
36 | struct device_node *node; | ||
37 | int (*sync_conf)(void *data, int synco); | ||
38 | void *data; | ||
39 | }; | ||
40 | |||
41 | static const struct stm32_sai_conf stm32_sai_conf_f4 = { | 31 | static const struct stm32_sai_conf stm32_sai_conf_f4 = { |
42 | .version = SAI_STM32F4, | 32 | .version = SAI_STM32F4, |
43 | }; | 33 | }; |
@@ -70,9 +60,8 @@ static int stm32_sai_sync_conf_client(struct stm32_sai_data *sai, int synci) | |||
70 | return 0; | 60 | return 0; |
71 | } | 61 | } |
72 | 62 | ||
73 | static int stm32_sai_sync_conf_provider(void *data, int synco) | 63 | static int stm32_sai_sync_conf_provider(struct stm32_sai_data *sai, int synco) |
74 | { | 64 | { |
75 | struct stm32_sai_data *sai = (struct stm32_sai_data *)data; | ||
76 | u32 prev_synco; | 65 | u32 prev_synco; |
77 | int ret; | 66 | int ret; |
78 | 67 | ||
@@ -103,83 +92,42 @@ static int stm32_sai_sync_conf_provider(void *data, int synco) | |||
103 | return 0; | 92 | return 0; |
104 | } | 93 | } |
105 | 94 | ||
106 | static int stm32_sai_set_sync_provider(struct device_node *np, int synco) | 95 | static int stm32_sai_set_sync(struct stm32_sai_data *sai_client, |
96 | struct device_node *np_provider, | ||
97 | int synco, int synci) | ||
107 | { | 98 | { |
108 | struct sync_provider *provider; | 99 | struct platform_device *pdev = of_find_device_by_node(np_provider); |
100 | struct stm32_sai_data *sai_provider; | ||
109 | int ret; | 101 | int ret; |
110 | 102 | ||
111 | mutex_lock(&sync_mutex); | 103 | if (!pdev) { |
112 | list_for_each_entry(provider, &sync_providers, link) { | 104 | dev_err(&sai_client->pdev->dev, |
113 | if (provider->node == np) { | 105 | "Device not found for node %s\n", np_provider->name); |
114 | ret = provider->sync_conf(provider->data, synco); | 106 | return -ENODEV; |
115 | mutex_unlock(&sync_mutex); | ||
116 | return ret; | ||
117 | } | ||
118 | } | 107 | } |
119 | mutex_unlock(&sync_mutex); | ||
120 | 108 | ||
121 | /* SAI sync provider not found */ | 109 | sai_provider = platform_get_drvdata(pdev); |
122 | return -ENODEV; | 110 | if (!sai_provider) { |
123 | } | 111 | dev_err(&sai_client->pdev->dev, |
124 | 112 | "SAI sync provider data not found\n"); | |
125 | static int stm32_sai_set_sync(struct stm32_sai_data *sai, | 113 | return -EINVAL; |
126 | struct device_node *np_provider, | 114 | } |
127 | int synco, int synci) | ||
128 | { | ||
129 | int ret; | ||
130 | 115 | ||
131 | /* Configure sync client */ | 116 | /* Configure sync client */ |
132 | stm32_sai_sync_conf_client(sai, synci); | 117 | ret = stm32_sai_sync_conf_client(sai_client, synci); |
118 | if (ret < 0) | ||
119 | return ret; | ||
133 | 120 | ||
134 | /* Configure sync provider */ | 121 | /* Configure sync provider */ |
135 | ret = stm32_sai_set_sync_provider(np_provider, synco); | 122 | return stm32_sai_sync_conf_provider(sai_provider, synco); |
136 | |||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | static int stm32_sai_sync_add_provider(struct platform_device *pdev, | ||
141 | void *data) | ||
142 | { | ||
143 | struct sync_provider *sp; | ||
144 | |||
145 | sp = devm_kzalloc(&pdev->dev, sizeof(*sp), GFP_KERNEL); | ||
146 | if (!sp) | ||
147 | return -ENOMEM; | ||
148 | |||
149 | sp->node = of_node_get(pdev->dev.of_node); | ||
150 | sp->data = data; | ||
151 | sp->sync_conf = &stm32_sai_sync_conf_provider; | ||
152 | |||
153 | mutex_lock(&sync_mutex); | ||
154 | list_add(&sp->link, &sync_providers); | ||
155 | mutex_unlock(&sync_mutex); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static void stm32_sai_sync_del_provider(struct device_node *np) | ||
161 | { | ||
162 | struct sync_provider *sp; | ||
163 | |||
164 | mutex_lock(&sync_mutex); | ||
165 | list_for_each_entry(sp, &sync_providers, link) { | ||
166 | if (sp->node == np) { | ||
167 | list_del(&sp->link); | ||
168 | of_node_put(sp->node); | ||
169 | break; | ||
170 | } | ||
171 | } | ||
172 | mutex_unlock(&sync_mutex); | ||
173 | } | 123 | } |
174 | 124 | ||
175 | static int stm32_sai_probe(struct platform_device *pdev) | 125 | static int stm32_sai_probe(struct platform_device *pdev) |
176 | { | 126 | { |
177 | struct device_node *np = pdev->dev.of_node; | ||
178 | struct stm32_sai_data *sai; | 127 | struct stm32_sai_data *sai; |
179 | struct reset_control *rst; | 128 | struct reset_control *rst; |
180 | struct resource *res; | 129 | struct resource *res; |
181 | const struct of_device_id *of_id; | 130 | const struct of_device_id *of_id; |
182 | int ret; | ||
183 | 131 | ||
184 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); | 132 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); |
185 | if (!sai) | 133 | if (!sai) |
@@ -231,28 +179,11 @@ static int stm32_sai_probe(struct platform_device *pdev) | |||
231 | reset_control_deassert(rst); | 179 | reset_control_deassert(rst); |
232 | } | 180 | } |
233 | 181 | ||
234 | ret = stm32_sai_sync_add_provider(pdev, sai); | ||
235 | if (ret < 0) | ||
236 | return ret; | ||
237 | sai->set_sync = &stm32_sai_set_sync; | ||
238 | |||
239 | sai->pdev = pdev; | 182 | sai->pdev = pdev; |
183 | sai->set_sync = &stm32_sai_set_sync; | ||
240 | platform_set_drvdata(pdev, sai); | 184 | platform_set_drvdata(pdev, sai); |
241 | 185 | ||
242 | ret = of_platform_populate(np, NULL, NULL, &pdev->dev); | 186 | return devm_of_platform_populate(&pdev->dev); |
243 | if (ret < 0) | ||
244 | stm32_sai_sync_del_provider(np); | ||
245 | |||
246 | return ret; | ||
247 | } | ||
248 | |||
249 | static int stm32_sai_remove(struct platform_device *pdev) | ||
250 | { | ||
251 | of_platform_depopulate(&pdev->dev); | ||
252 | |||
253 | stm32_sai_sync_del_provider(pdev->dev.of_node); | ||
254 | |||
255 | return 0; | ||
256 | } | 187 | } |
257 | 188 | ||
258 | MODULE_DEVICE_TABLE(of, stm32_sai_ids); | 189 | MODULE_DEVICE_TABLE(of, stm32_sai_ids); |
@@ -263,7 +194,6 @@ static struct platform_driver stm32_sai_driver = { | |||
263 | .of_match_table = stm32_sai_ids, | 194 | .of_match_table = stm32_sai_ids, |
264 | }, | 195 | }, |
265 | .probe = stm32_sai_probe, | 196 | .probe = stm32_sai_probe, |
266 | .remove = stm32_sai_remove, | ||
267 | }; | 197 | }; |
268 | 198 | ||
269 | module_platform_driver(stm32_sai_driver); | 199 | module_platform_driver(stm32_sai_driver); |
diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c index 5da4efe7a550..886281673972 100644 --- a/sound/soc/sunxi/sun4i-codec.c +++ b/sound/soc/sunxi/sun4i-codec.c | |||
@@ -590,12 +590,28 @@ static int sun4i_codec_hw_params(struct snd_pcm_substream *substream, | |||
590 | hwrate); | 590 | hwrate); |
591 | } | 591 | } |
592 | 592 | ||
593 | |||
594 | static unsigned int sun4i_codec_src_rates[] = { | ||
595 | 8000, 11025, 12000, 16000, 22050, 24000, 32000, | ||
596 | 44100, 48000, 96000, 192000 | ||
597 | }; | ||
598 | |||
599 | |||
600 | static struct snd_pcm_hw_constraint_list sun4i_codec_constraints = { | ||
601 | .count = ARRAY_SIZE(sun4i_codec_src_rates), | ||
602 | .list = sun4i_codec_src_rates, | ||
603 | }; | ||
604 | |||
605 | |||
593 | static int sun4i_codec_startup(struct snd_pcm_substream *substream, | 606 | static int sun4i_codec_startup(struct snd_pcm_substream *substream, |
594 | struct snd_soc_dai *dai) | 607 | struct snd_soc_dai *dai) |
595 | { | 608 | { |
596 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 609 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
597 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); | 610 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
598 | 611 | ||
612 | snd_pcm_hw_constraint_list(substream->runtime, 0, | ||
613 | SNDRV_PCM_HW_PARAM_RATE, &sun4i_codec_constraints); | ||
614 | |||
599 | /* | 615 | /* |
600 | * Stop issuing DRQ when we have room for less than 16 samples | 616 | * Stop issuing DRQ when we have room for less than 16 samples |
601 | * in our TX FIFO | 617 | * in our TX FIFO |
@@ -633,9 +649,7 @@ static struct snd_soc_dai_driver sun4i_codec_dai = { | |||
633 | .channels_max = 2, | 649 | .channels_max = 2, |
634 | .rate_min = 8000, | 650 | .rate_min = 8000, |
635 | .rate_max = 192000, | 651 | .rate_max = 192000, |
636 | .rates = SNDRV_PCM_RATE_8000_48000 | | 652 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
637 | SNDRV_PCM_RATE_96000 | | ||
638 | SNDRV_PCM_RATE_192000, | ||
639 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 653 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
640 | SNDRV_PCM_FMTBIT_S32_LE, | 654 | SNDRV_PCM_FMTBIT_S32_LE, |
641 | .sig_bits = 24, | 655 | .sig_bits = 24, |
@@ -645,11 +659,8 @@ static struct snd_soc_dai_driver sun4i_codec_dai = { | |||
645 | .channels_min = 1, | 659 | .channels_min = 1, |
646 | .channels_max = 2, | 660 | .channels_max = 2, |
647 | .rate_min = 8000, | 661 | .rate_min = 8000, |
648 | .rate_max = 192000, | 662 | .rate_max = 48000, |
649 | .rates = SNDRV_PCM_RATE_8000_48000 | | 663 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
650 | SNDRV_PCM_RATE_96000 | | ||
651 | SNDRV_PCM_RATE_192000 | | ||
652 | SNDRV_PCM_RATE_KNOT, | ||
653 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | 664 | .formats = SNDRV_PCM_FMTBIT_S16_LE | |
654 | SNDRV_PCM_FMTBIT_S32_LE, | 665 | SNDRV_PCM_FMTBIT_S32_LE, |
655 | .sig_bits = 24, | 666 | .sig_bits = 24, |
@@ -1128,7 +1139,7 @@ static const struct snd_soc_component_driver sun4i_codec_component = { | |||
1128 | .name = "sun4i-codec", | 1139 | .name = "sun4i-codec", |
1129 | }; | 1140 | }; |
1130 | 1141 | ||
1131 | #define SUN4I_CODEC_RATES SNDRV_PCM_RATE_8000_192000 | 1142 | #define SUN4I_CODEC_RATES SNDRV_PCM_RATE_CONTINUOUS |
1132 | #define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ | 1143 | #define SUN4I_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ |
1133 | SNDRV_PCM_FMTBIT_S32_LE) | 1144 | SNDRV_PCM_FMTBIT_S32_LE) |
1134 | 1145 | ||
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 04f92583a969..dca1143c1150 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c | |||
@@ -269,10 +269,11 @@ static bool sun4i_i2s_oversample_is_valid(unsigned int oversample) | |||
269 | return false; | 269 | return false; |
270 | } | 270 | } |
271 | 271 | ||
272 | static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, | 272 | static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, |
273 | unsigned int rate, | 273 | unsigned int rate, |
274 | unsigned int word_size) | 274 | unsigned int word_size) |
275 | { | 275 | { |
276 | struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai); | ||
276 | unsigned int oversample_rate, clk_rate; | 277 | unsigned int oversample_rate, clk_rate; |
277 | int bclk_div, mclk_div; | 278 | int bclk_div, mclk_div; |
278 | int ret; | 279 | int ret; |
@@ -300,6 +301,7 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, | |||
300 | break; | 301 | break; |
301 | 302 | ||
302 | default: | 303 | default: |
304 | dev_err(dai->dev, "Unsupported sample rate: %u\n", rate); | ||
303 | return -EINVAL; | 305 | return -EINVAL; |
304 | } | 306 | } |
305 | 307 | ||
@@ -308,18 +310,25 @@ static int sun4i_i2s_set_clk_rate(struct sun4i_i2s *i2s, | |||
308 | return ret; | 310 | return ret; |
309 | 311 | ||
310 | oversample_rate = i2s->mclk_freq / rate; | 312 | oversample_rate = i2s->mclk_freq / rate; |
311 | if (!sun4i_i2s_oversample_is_valid(oversample_rate)) | 313 | if (!sun4i_i2s_oversample_is_valid(oversample_rate)) { |
314 | dev_err(dai->dev, "Unsupported oversample rate: %d\n", | ||
315 | oversample_rate); | ||
312 | return -EINVAL; | 316 | return -EINVAL; |
317 | } | ||
313 | 318 | ||
314 | bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, | 319 | bclk_div = sun4i_i2s_get_bclk_div(i2s, oversample_rate, |
315 | word_size); | 320 | word_size); |
316 | if (bclk_div < 0) | 321 | if (bclk_div < 0) { |
322 | dev_err(dai->dev, "Unsupported BCLK divider: %d\n", bclk_div); | ||
317 | return -EINVAL; | 323 | return -EINVAL; |
324 | } | ||
318 | 325 | ||
319 | mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, | 326 | mclk_div = sun4i_i2s_get_mclk_div(i2s, oversample_rate, |
320 | clk_rate, rate); | 327 | clk_rate, rate); |
321 | if (mclk_div < 0) | 328 | if (mclk_div < 0) { |
329 | dev_err(dai->dev, "Unsupported MCLK divider: %d\n", mclk_div); | ||
322 | return -EINVAL; | 330 | return -EINVAL; |
331 | } | ||
323 | 332 | ||
324 | /* Adjust the clock division values if needed */ | 333 | /* Adjust the clock division values if needed */ |
325 | bclk_div += i2s->variant->bclk_offset; | 334 | bclk_div += i2s->variant->bclk_offset; |
@@ -349,8 +358,11 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
349 | u32 width; | 358 | u32 width; |
350 | 359 | ||
351 | channels = params_channels(params); | 360 | channels = params_channels(params); |
352 | if (channels != 2) | 361 | if (channels != 2) { |
362 | dev_err(dai->dev, "Unsupported number of channels: %d\n", | ||
363 | channels); | ||
353 | return -EINVAL; | 364 | return -EINVAL; |
365 | } | ||
354 | 366 | ||
355 | if (i2s->variant->has_chcfg) { | 367 | if (i2s->variant->has_chcfg) { |
356 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, | 368 | regmap_update_bits(i2s->regmap, SUN8I_I2S_CHAN_CFG_REG, |
@@ -382,6 +394,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
382 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; | 394 | width = DMA_SLAVE_BUSWIDTH_2_BYTES; |
383 | break; | 395 | break; |
384 | default: | 396 | default: |
397 | dev_err(dai->dev, "Unsupported physical sample width: %d\n", | ||
398 | params_physical_width(params)); | ||
385 | return -EINVAL; | 399 | return -EINVAL; |
386 | } | 400 | } |
387 | i2s->playback_dma_data.addr_width = width; | 401 | i2s->playback_dma_data.addr_width = width; |
@@ -393,6 +407,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
393 | break; | 407 | break; |
394 | 408 | ||
395 | default: | 409 | default: |
410 | dev_err(dai->dev, "Unsupported sample width: %d\n", | ||
411 | params_width(params)); | ||
396 | return -EINVAL; | 412 | return -EINVAL; |
397 | } | 413 | } |
398 | 414 | ||
@@ -401,7 +417,7 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream, | |||
401 | regmap_field_write(i2s->field_fmt_sr, | 417 | regmap_field_write(i2s->field_fmt_sr, |
402 | sr + i2s->variant->fmt_offset); | 418 | sr + i2s->variant->fmt_offset); |
403 | 419 | ||
404 | return sun4i_i2s_set_clk_rate(i2s, params_rate(params), | 420 | return sun4i_i2s_set_clk_rate(dai, params_rate(params), |
405 | params_width(params)); | 421 | params_width(params)); |
406 | } | 422 | } |
407 | 423 | ||
@@ -426,6 +442,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
426 | val = SUN4I_I2S_FMT0_FMT_RIGHT_J; | 442 | val = SUN4I_I2S_FMT0_FMT_RIGHT_J; |
427 | break; | 443 | break; |
428 | default: | 444 | default: |
445 | dev_err(dai->dev, "Unsupported format: %d\n", | ||
446 | fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
429 | return -EINVAL; | 447 | return -EINVAL; |
430 | } | 448 | } |
431 | 449 | ||
@@ -464,6 +482,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
464 | case SND_SOC_DAIFMT_NB_NF: | 482 | case SND_SOC_DAIFMT_NB_NF: |
465 | break; | 483 | break; |
466 | default: | 484 | default: |
485 | dev_err(dai->dev, "Unsupported clock polarity: %d\n", | ||
486 | fmt & SND_SOC_DAIFMT_INV_MASK); | ||
467 | return -EINVAL; | 487 | return -EINVAL; |
468 | } | 488 | } |
469 | 489 | ||
@@ -482,6 +502,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
482 | val = SUN4I_I2S_CTRL_MODE_SLAVE; | 502 | val = SUN4I_I2S_CTRL_MODE_SLAVE; |
483 | break; | 503 | break; |
484 | default: | 504 | default: |
505 | dev_err(dai->dev, "Unsupported slave setting: %d\n", | ||
506 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
485 | return -EINVAL; | 507 | return -EINVAL; |
486 | } | 508 | } |
487 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | 509 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, |
@@ -504,6 +526,8 @@ static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
504 | val = 0; | 526 | val = 0; |
505 | break; | 527 | break; |
506 | default: | 528 | default: |
529 | dev_err(dai->dev, "Unsupported slave setting: %d\n", | ||
530 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
507 | return -EINVAL; | 531 | return -EINVAL; |
508 | } | 532 | } |
509 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, | 533 | regmap_update_bits(i2s->regmap, SUN4I_I2S_CTRL_REG, |
@@ -897,6 +921,23 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { | |||
897 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), | 921 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), |
898 | }; | 922 | }; |
899 | 923 | ||
924 | static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { | ||
925 | .has_reset = true, | ||
926 | .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, | ||
927 | .sun4i_i2s_regmap = &sun4i_i2s_regmap_config, | ||
928 | .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 7, 7), | ||
929 | .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 2, 3), | ||
930 | .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), | ||
931 | .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), | ||
932 | .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), | ||
933 | .has_slave_select_bit = true, | ||
934 | .field_fmt_mode = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 1), | ||
935 | .field_txchanmap = REG_FIELD(SUN4I_I2S_TX_CHAN_MAP_REG, 0, 31), | ||
936 | .field_rxchanmap = REG_FIELD(SUN4I_I2S_RX_CHAN_MAP_REG, 0, 31), | ||
937 | .field_txchansel = REG_FIELD(SUN4I_I2S_TX_CHAN_SEL_REG, 0, 2), | ||
938 | .field_rxchansel = REG_FIELD(SUN4I_I2S_RX_CHAN_SEL_REG, 0, 2), | ||
939 | }; | ||
940 | |||
900 | static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { | 941 | static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { |
901 | .has_reset = true, | 942 | .has_reset = true, |
902 | .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, | 943 | .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, |
@@ -1121,6 +1162,10 @@ static const struct of_device_id sun4i_i2s_match[] = { | |||
1121 | .data = &sun6i_a31_i2s_quirks, | 1162 | .data = &sun6i_a31_i2s_quirks, |
1122 | }, | 1163 | }, |
1123 | { | 1164 | { |
1165 | .compatible = "allwinner,sun8i-a83t-i2s", | ||
1166 | .data = &sun8i_a83t_i2s_quirks, | ||
1167 | }, | ||
1168 | { | ||
1124 | .compatible = "allwinner,sun8i-h3-i2s", | 1169 | .compatible = "allwinner,sun8i-h3-i2s", |
1125 | .data = &sun8i_h3_i2s_quirks, | 1170 | .data = &sun8i_h3_i2s_quirks, |
1126 | }, | 1171 | }, |
diff --git a/sound/soc/uniphier/Kconfig b/sound/soc/uniphier/Kconfig new file mode 100644 index 000000000000..02886a457eaf --- /dev/null +++ b/sound/soc/uniphier/Kconfig | |||
@@ -0,0 +1,19 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | config SND_SOC_UNIPHIER | ||
3 | tristate "ASoC support for UniPhier" | ||
4 | depends on (ARCH_UNIPHIER || COMPILE_TEST) | ||
5 | help | ||
6 | Say Y or M if you want to add support for the Socionext | ||
7 | UniPhier SoC audio interfaces. You will also need to select the | ||
8 | audio interfaces to support below. | ||
9 | If unsure select "N". | ||
10 | |||
11 | config SND_SOC_UNIPHIER_EVEA_CODEC | ||
12 | tristate "UniPhier SoC internal audio codec" | ||
13 | depends on SND_SOC_UNIPHIER | ||
14 | select REGMAP_MMIO | ||
15 | help | ||
16 | This adds Codec driver for Socionext UniPhier LD11/20 SoC | ||
17 | internal DAC. This driver supports Line In / Out and HeadPhone. | ||
18 | Select Y if you use such device. | ||
19 | If unsure select "N". | ||
diff --git a/sound/soc/uniphier/Makefile b/sound/soc/uniphier/Makefile new file mode 100644 index 000000000000..3be00d72f5e5 --- /dev/null +++ b/sound/soc/uniphier/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | snd-soc-uniphier-evea-objs := evea.o | ||
3 | obj-$(CONFIG_SND_SOC_UNIPHIER_EVEA_CODEC) += snd-soc-uniphier-evea.o | ||
diff --git a/sound/soc/uniphier/evea.c b/sound/soc/uniphier/evea.c new file mode 100644 index 000000000000..0cc9efff1d9a --- /dev/null +++ b/sound/soc/uniphier/evea.c | |||
@@ -0,0 +1,567 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Socionext UniPhier EVEA ADC/DAC codec driver. | ||
4 | * | ||
5 | * Copyright (c) 2016-2017 Socionext Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License | ||
9 | * as published by the Free Software Foundation; version 2 | ||
10 | * of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, see <http://www.gnu.org/licenses/>. | ||
19 | */ | ||
20 | |||
21 | #include <linux/clk.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/of.h> | ||
24 | #include <linux/regmap.h> | ||
25 | #include <linux/reset.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include <sound/soc.h> | ||
28 | |||
29 | #define DRV_NAME "evea" | ||
30 | #define EVEA_RATES SNDRV_PCM_RATE_48000 | ||
31 | #define EVEA_FORMATS SNDRV_PCM_FMTBIT_S32_LE | ||
32 | |||
33 | #define AADCPOW(n) (0x0078 + 0x04 * (n)) | ||
34 | #define AADCPOW_AADC_POWD BIT(0) | ||
35 | #define AHPOUTPOW 0x0098 | ||
36 | #define AHPOUTPOW_HP_ON BIT(4) | ||
37 | #define ALINEPOW 0x009c | ||
38 | #define ALINEPOW_LIN2_POWD BIT(3) | ||
39 | #define ALINEPOW_LIN1_POWD BIT(4) | ||
40 | #define ALO1OUTPOW 0x00a8 | ||
41 | #define ALO1OUTPOW_LO1_ON BIT(4) | ||
42 | #define ALO2OUTPOW 0x00ac | ||
43 | #define ALO2OUTPOW_ADAC2_MUTE BIT(0) | ||
44 | #define ALO2OUTPOW_LO2_ON BIT(4) | ||
45 | #define AANAPOW 0x00b8 | ||
46 | #define AANAPOW_A_POWD BIT(4) | ||
47 | #define ADACSEQ1(n) (0x0144 + 0x40 * (n)) | ||
48 | #define ADACSEQ1_MMUTE BIT(1) | ||
49 | #define ADACSEQ2(n) (0x0160 + 0x40 * (n)) | ||
50 | #define ADACSEQ2_ADACIN_FIX BIT(0) | ||
51 | #define ADAC1ODC 0x0200 | ||
52 | #define ADAC1ODC_HP_DIS_RES_MASK GENMASK(2, 1) | ||
53 | #define ADAC1ODC_HP_DIS_RES_OFF (0x0 << 1) | ||
54 | #define ADAC1ODC_HP_DIS_RES_ON (0x3 << 1) | ||
55 | #define ADAC1ODC_ADAC_RAMPCLT_MASK GENMASK(8, 7) | ||
56 | #define ADAC1ODC_ADAC_RAMPCLT_NORMAL (0x0 << 7) | ||
57 | #define ADAC1ODC_ADAC_RAMPCLT_REDUCE (0x1 << 7) | ||
58 | |||
59 | struct evea_priv { | ||
60 | struct clk *clk, *clk_exiv; | ||
61 | struct reset_control *rst, *rst_exiv, *rst_adamv; | ||
62 | struct regmap *regmap; | ||
63 | |||
64 | int switch_lin; | ||
65 | int switch_lo; | ||
66 | int switch_hp; | ||
67 | }; | ||
68 | |||
69 | static const struct snd_soc_dapm_widget evea_widgets[] = { | ||
70 | SND_SOC_DAPM_ADC("ADC", "Capture", SND_SOC_NOPM, 0, 0), | ||
71 | SND_SOC_DAPM_INPUT("LIN1_LP"), | ||
72 | SND_SOC_DAPM_INPUT("LIN1_RP"), | ||
73 | SND_SOC_DAPM_INPUT("LIN2_LP"), | ||
74 | SND_SOC_DAPM_INPUT("LIN2_RP"), | ||
75 | SND_SOC_DAPM_INPUT("LIN3_LP"), | ||
76 | SND_SOC_DAPM_INPUT("LIN3_RP"), | ||
77 | |||
78 | SND_SOC_DAPM_DAC("DAC", "Playback", SND_SOC_NOPM, 0, 0), | ||
79 | SND_SOC_DAPM_OUTPUT("HP1_L"), | ||
80 | SND_SOC_DAPM_OUTPUT("HP1_R"), | ||
81 | SND_SOC_DAPM_OUTPUT("LO2_L"), | ||
82 | SND_SOC_DAPM_OUTPUT("LO2_R"), | ||
83 | }; | ||
84 | |||
85 | static const struct snd_soc_dapm_route evea_routes[] = { | ||
86 | { "ADC", NULL, "LIN1_LP" }, | ||
87 | { "ADC", NULL, "LIN1_RP" }, | ||
88 | { "ADC", NULL, "LIN2_LP" }, | ||
89 | { "ADC", NULL, "LIN2_RP" }, | ||
90 | { "ADC", NULL, "LIN3_LP" }, | ||
91 | { "ADC", NULL, "LIN3_RP" }, | ||
92 | |||
93 | { "HP1_L", NULL, "DAC" }, | ||
94 | { "HP1_R", NULL, "DAC" }, | ||
95 | { "LO2_L", NULL, "DAC" }, | ||
96 | { "LO2_R", NULL, "DAC" }, | ||
97 | }; | ||
98 | |||
99 | static void evea_set_power_state_on(struct evea_priv *evea) | ||
100 | { | ||
101 | struct regmap *map = evea->regmap; | ||
102 | |||
103 | regmap_update_bits(map, AANAPOW, AANAPOW_A_POWD, | ||
104 | AANAPOW_A_POWD); | ||
105 | |||
106 | regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK, | ||
107 | ADAC1ODC_HP_DIS_RES_ON); | ||
108 | |||
109 | regmap_update_bits(map, ADAC1ODC, ADAC1ODC_ADAC_RAMPCLT_MASK, | ||
110 | ADAC1ODC_ADAC_RAMPCLT_REDUCE); | ||
111 | |||
112 | regmap_update_bits(map, ADACSEQ2(0), ADACSEQ2_ADACIN_FIX, 0); | ||
113 | regmap_update_bits(map, ADACSEQ2(1), ADACSEQ2_ADACIN_FIX, 0); | ||
114 | regmap_update_bits(map, ADACSEQ2(2), ADACSEQ2_ADACIN_FIX, 0); | ||
115 | } | ||
116 | |||
117 | static void evea_set_power_state_off(struct evea_priv *evea) | ||
118 | { | ||
119 | struct regmap *map = evea->regmap; | ||
120 | |||
121 | regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK, | ||
122 | ADAC1ODC_HP_DIS_RES_ON); | ||
123 | |||
124 | regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE, | ||
125 | ADACSEQ1_MMUTE); | ||
126 | regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE, | ||
127 | ADACSEQ1_MMUTE); | ||
128 | regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE, | ||
129 | ADACSEQ1_MMUTE); | ||
130 | |||
131 | regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0); | ||
132 | regmap_update_bits(map, ALO2OUTPOW, ALO2OUTPOW_LO2_ON, 0); | ||
133 | regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0); | ||
134 | } | ||
135 | |||
136 | static int evea_update_switch_lin(struct evea_priv *evea) | ||
137 | { | ||
138 | struct regmap *map = evea->regmap; | ||
139 | |||
140 | if (evea->switch_lin) { | ||
141 | regmap_update_bits(map, ALINEPOW, | ||
142 | ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD, | ||
143 | ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD); | ||
144 | |||
145 | regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD, | ||
146 | AADCPOW_AADC_POWD); | ||
147 | regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD, | ||
148 | AADCPOW_AADC_POWD); | ||
149 | } else { | ||
150 | regmap_update_bits(map, AADCPOW(0), AADCPOW_AADC_POWD, 0); | ||
151 | regmap_update_bits(map, AADCPOW(1), AADCPOW_AADC_POWD, 0); | ||
152 | |||
153 | regmap_update_bits(map, ALINEPOW, | ||
154 | ALINEPOW_LIN2_POWD | ALINEPOW_LIN1_POWD, 0); | ||
155 | } | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int evea_update_switch_lo(struct evea_priv *evea) | ||
161 | { | ||
162 | struct regmap *map = evea->regmap; | ||
163 | |||
164 | if (evea->switch_lo) { | ||
165 | regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE, 0); | ||
166 | regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE, 0); | ||
167 | |||
168 | regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, | ||
169 | ALO1OUTPOW_LO1_ON); | ||
170 | regmap_update_bits(map, ALO2OUTPOW, | ||
171 | ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON, | ||
172 | ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON); | ||
173 | } else { | ||
174 | regmap_update_bits(map, ADACSEQ1(0), ADACSEQ1_MMUTE, | ||
175 | ADACSEQ1_MMUTE); | ||
176 | regmap_update_bits(map, ADACSEQ1(2), ADACSEQ1_MMUTE, | ||
177 | ADACSEQ1_MMUTE); | ||
178 | |||
179 | regmap_update_bits(map, ALO1OUTPOW, ALO1OUTPOW_LO1_ON, 0); | ||
180 | regmap_update_bits(map, ALO2OUTPOW, | ||
181 | ALO2OUTPOW_ADAC2_MUTE | ALO2OUTPOW_LO2_ON, | ||
182 | 0); | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int evea_update_switch_hp(struct evea_priv *evea) | ||
189 | { | ||
190 | struct regmap *map = evea->regmap; | ||
191 | |||
192 | if (evea->switch_hp) { | ||
193 | regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE, 0); | ||
194 | |||
195 | regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, | ||
196 | AHPOUTPOW_HP_ON); | ||
197 | |||
198 | regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK, | ||
199 | ADAC1ODC_HP_DIS_RES_OFF); | ||
200 | } else { | ||
201 | regmap_update_bits(map, ADAC1ODC, ADAC1ODC_HP_DIS_RES_MASK, | ||
202 | ADAC1ODC_HP_DIS_RES_ON); | ||
203 | |||
204 | regmap_update_bits(map, ADACSEQ1(1), ADACSEQ1_MMUTE, | ||
205 | ADACSEQ1_MMUTE); | ||
206 | |||
207 | regmap_update_bits(map, AHPOUTPOW, AHPOUTPOW_HP_ON, 0); | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static void evea_update_switch_all(struct evea_priv *evea) | ||
214 | { | ||
215 | evea_update_switch_lin(evea); | ||
216 | evea_update_switch_lo(evea); | ||
217 | evea_update_switch_hp(evea); | ||
218 | } | ||
219 | |||
220 | static int evea_get_switch_lin(struct snd_kcontrol *kcontrol, | ||
221 | struct snd_ctl_elem_value *ucontrol) | ||
222 | { | ||
223 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
224 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
225 | |||
226 | ucontrol->value.integer.value[0] = evea->switch_lin; | ||
227 | |||
228 | return 0; | ||
229 | } | ||
230 | |||
231 | static int evea_set_switch_lin(struct snd_kcontrol *kcontrol, | ||
232 | struct snd_ctl_elem_value *ucontrol) | ||
233 | { | ||
234 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
235 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
236 | |||
237 | if (evea->switch_lin == ucontrol->value.integer.value[0]) | ||
238 | return 0; | ||
239 | |||
240 | evea->switch_lin = ucontrol->value.integer.value[0]; | ||
241 | |||
242 | return evea_update_switch_lin(evea); | ||
243 | } | ||
244 | |||
245 | static int evea_get_switch_lo(struct snd_kcontrol *kcontrol, | ||
246 | struct snd_ctl_elem_value *ucontrol) | ||
247 | { | ||
248 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
249 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
250 | |||
251 | ucontrol->value.integer.value[0] = evea->switch_lo; | ||
252 | |||
253 | return 0; | ||
254 | } | ||
255 | |||
256 | static int evea_set_switch_lo(struct snd_kcontrol *kcontrol, | ||
257 | struct snd_ctl_elem_value *ucontrol) | ||
258 | { | ||
259 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
260 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
261 | |||
262 | if (evea->switch_lo == ucontrol->value.integer.value[0]) | ||
263 | return 0; | ||
264 | |||
265 | evea->switch_lo = ucontrol->value.integer.value[0]; | ||
266 | |||
267 | return evea_update_switch_lo(evea); | ||
268 | } | ||
269 | |||
270 | static int evea_get_switch_hp(struct snd_kcontrol *kcontrol, | ||
271 | struct snd_ctl_elem_value *ucontrol) | ||
272 | { | ||
273 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
274 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
275 | |||
276 | ucontrol->value.integer.value[0] = evea->switch_hp; | ||
277 | |||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int evea_set_switch_hp(struct snd_kcontrol *kcontrol, | ||
282 | struct snd_ctl_elem_value *ucontrol) | ||
283 | { | ||
284 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
285 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
286 | |||
287 | if (evea->switch_hp == ucontrol->value.integer.value[0]) | ||
288 | return 0; | ||
289 | |||
290 | evea->switch_hp = ucontrol->value.integer.value[0]; | ||
291 | |||
292 | return evea_update_switch_hp(evea); | ||
293 | } | ||
294 | |||
295 | static const struct snd_kcontrol_new eva_controls[] = { | ||
296 | SOC_SINGLE_BOOL_EXT("Line Capture Switch", 0, | ||
297 | evea_get_switch_lin, evea_set_switch_lin), | ||
298 | SOC_SINGLE_BOOL_EXT("Line Playback Switch", 0, | ||
299 | evea_get_switch_lo, evea_set_switch_lo), | ||
300 | SOC_SINGLE_BOOL_EXT("Headphone Playback Switch", 0, | ||
301 | evea_get_switch_hp, evea_set_switch_hp), | ||
302 | }; | ||
303 | |||
304 | static int evea_codec_probe(struct snd_soc_codec *codec) | ||
305 | { | ||
306 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
307 | |||
308 | evea->switch_lin = 1; | ||
309 | evea->switch_lo = 1; | ||
310 | evea->switch_hp = 1; | ||
311 | |||
312 | evea_set_power_state_on(evea); | ||
313 | evea_update_switch_all(evea); | ||
314 | |||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int evea_codec_suspend(struct snd_soc_codec *codec) | ||
319 | { | ||
320 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
321 | |||
322 | evea_set_power_state_off(evea); | ||
323 | |||
324 | reset_control_assert(evea->rst_adamv); | ||
325 | reset_control_assert(evea->rst_exiv); | ||
326 | reset_control_assert(evea->rst); | ||
327 | |||
328 | clk_disable_unprepare(evea->clk_exiv); | ||
329 | clk_disable_unprepare(evea->clk); | ||
330 | |||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static int evea_codec_resume(struct snd_soc_codec *codec) | ||
335 | { | ||
336 | struct evea_priv *evea = snd_soc_codec_get_drvdata(codec); | ||
337 | int ret; | ||
338 | |||
339 | ret = clk_prepare_enable(evea->clk); | ||
340 | if (ret) | ||
341 | return ret; | ||
342 | |||
343 | ret = clk_prepare_enable(evea->clk_exiv); | ||
344 | if (ret) | ||
345 | goto err_out_clock; | ||
346 | |||
347 | ret = reset_control_deassert(evea->rst); | ||
348 | if (ret) | ||
349 | goto err_out_clock_exiv; | ||
350 | |||
351 | ret = reset_control_deassert(evea->rst_exiv); | ||
352 | if (ret) | ||
353 | goto err_out_reset; | ||
354 | |||
355 | ret = reset_control_deassert(evea->rst_adamv); | ||
356 | if (ret) | ||
357 | goto err_out_reset_exiv; | ||
358 | |||
359 | evea_set_power_state_on(evea); | ||
360 | evea_update_switch_all(evea); | ||
361 | |||
362 | return 0; | ||
363 | |||
364 | err_out_reset_exiv: | ||
365 | reset_control_assert(evea->rst_exiv); | ||
366 | |||
367 | err_out_reset: | ||
368 | reset_control_assert(evea->rst); | ||
369 | |||
370 | err_out_clock_exiv: | ||
371 | clk_disable_unprepare(evea->clk_exiv); | ||
372 | |||
373 | err_out_clock: | ||
374 | clk_disable_unprepare(evea->clk); | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static struct snd_soc_codec_driver soc_codec_evea = { | ||
380 | .probe = evea_codec_probe, | ||
381 | .suspend = evea_codec_suspend, | ||
382 | .resume = evea_codec_resume, | ||
383 | |||
384 | .component_driver = { | ||
385 | .dapm_widgets = evea_widgets, | ||
386 | .num_dapm_widgets = ARRAY_SIZE(evea_widgets), | ||
387 | .dapm_routes = evea_routes, | ||
388 | .num_dapm_routes = ARRAY_SIZE(evea_routes), | ||
389 | .controls = eva_controls, | ||
390 | .num_controls = ARRAY_SIZE(eva_controls), | ||
391 | }, | ||
392 | }; | ||
393 | |||
394 | static struct snd_soc_dai_driver soc_dai_evea[] = { | ||
395 | { | ||
396 | .name = DRV_NAME "-line1", | ||
397 | .playback = { | ||
398 | .stream_name = "Line Out 1", | ||
399 | .formats = EVEA_FORMATS, | ||
400 | .rates = EVEA_RATES, | ||
401 | .channels_min = 2, | ||
402 | .channels_max = 2, | ||
403 | }, | ||
404 | .capture = { | ||
405 | .stream_name = "Line In 1", | ||
406 | .formats = EVEA_FORMATS, | ||
407 | .rates = EVEA_RATES, | ||
408 | .channels_min = 2, | ||
409 | .channels_max = 2, | ||
410 | }, | ||
411 | }, | ||
412 | { | ||
413 | .name = DRV_NAME "-hp1", | ||
414 | .playback = { | ||
415 | .stream_name = "Headphone 1", | ||
416 | .formats = EVEA_FORMATS, | ||
417 | .rates = EVEA_RATES, | ||
418 | .channels_min = 2, | ||
419 | .channels_max = 2, | ||
420 | }, | ||
421 | }, | ||
422 | { | ||
423 | .name = DRV_NAME "-lo2", | ||
424 | .playback = { | ||
425 | .stream_name = "Line Out 2", | ||
426 | .formats = EVEA_FORMATS, | ||
427 | .rates = EVEA_RATES, | ||
428 | .channels_min = 2, | ||
429 | .channels_max = 2, | ||
430 | }, | ||
431 | }, | ||
432 | }; | ||
433 | |||
434 | static const struct regmap_config evea_regmap_config = { | ||
435 | .reg_bits = 32, | ||
436 | .reg_stride = 4, | ||
437 | .val_bits = 32, | ||
438 | .max_register = 0xffc, | ||
439 | .cache_type = REGCACHE_NONE, | ||
440 | }; | ||
441 | |||
442 | static int evea_probe(struct platform_device *pdev) | ||
443 | { | ||
444 | struct evea_priv *evea; | ||
445 | struct resource *res; | ||
446 | void __iomem *preg; | ||
447 | int ret; | ||
448 | |||
449 | evea = devm_kzalloc(&pdev->dev, sizeof(struct evea_priv), GFP_KERNEL); | ||
450 | if (!evea) | ||
451 | return -ENOMEM; | ||
452 | |||
453 | evea->clk = devm_clk_get(&pdev->dev, "evea"); | ||
454 | if (IS_ERR(evea->clk)) | ||
455 | return PTR_ERR(evea->clk); | ||
456 | |||
457 | evea->clk_exiv = devm_clk_get(&pdev->dev, "exiv"); | ||
458 | if (IS_ERR(evea->clk_exiv)) | ||
459 | return PTR_ERR(evea->clk_exiv); | ||
460 | |||
461 | evea->rst = devm_reset_control_get_shared(&pdev->dev, "evea"); | ||
462 | if (IS_ERR(evea->rst)) | ||
463 | return PTR_ERR(evea->rst); | ||
464 | |||
465 | evea->rst_exiv = devm_reset_control_get_shared(&pdev->dev, "exiv"); | ||
466 | if (IS_ERR(evea->rst_exiv)) | ||
467 | return PTR_ERR(evea->rst_exiv); | ||
468 | |||
469 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
470 | preg = devm_ioremap_resource(&pdev->dev, res); | ||
471 | if (IS_ERR(preg)) | ||
472 | return PTR_ERR(preg); | ||
473 | |||
474 | evea->regmap = devm_regmap_init_mmio(&pdev->dev, preg, | ||
475 | &evea_regmap_config); | ||
476 | if (IS_ERR(evea->regmap)) | ||
477 | return PTR_ERR(evea->regmap); | ||
478 | |||
479 | ret = clk_prepare_enable(evea->clk); | ||
480 | if (ret) | ||
481 | return ret; | ||
482 | |||
483 | ret = clk_prepare_enable(evea->clk_exiv); | ||
484 | if (ret) | ||
485 | goto err_out_clock; | ||
486 | |||
487 | ret = reset_control_deassert(evea->rst); | ||
488 | if (ret) | ||
489 | goto err_out_clock_exiv; | ||
490 | |||
491 | ret = reset_control_deassert(evea->rst_exiv); | ||
492 | if (ret) | ||
493 | goto err_out_reset; | ||
494 | |||
495 | /* ADAMV will hangup if EXIV reset is asserted */ | ||
496 | evea->rst_adamv = devm_reset_control_get_shared(&pdev->dev, "adamv"); | ||
497 | if (IS_ERR(evea->rst_adamv)) { | ||
498 | ret = PTR_ERR(evea->rst_adamv); | ||
499 | goto err_out_reset_exiv; | ||
500 | } | ||
501 | |||
502 | ret = reset_control_deassert(evea->rst_adamv); | ||
503 | if (ret) | ||
504 | goto err_out_reset_exiv; | ||
505 | |||
506 | platform_set_drvdata(pdev, evea); | ||
507 | |||
508 | ret = snd_soc_register_codec(&pdev->dev, &soc_codec_evea, | ||
509 | soc_dai_evea, ARRAY_SIZE(soc_dai_evea)); | ||
510 | if (ret) | ||
511 | goto err_out_reset_adamv; | ||
512 | |||
513 | return 0; | ||
514 | |||
515 | err_out_reset_adamv: | ||
516 | reset_control_assert(evea->rst_adamv); | ||
517 | |||
518 | err_out_reset_exiv: | ||
519 | reset_control_assert(evea->rst_exiv); | ||
520 | |||
521 | err_out_reset: | ||
522 | reset_control_assert(evea->rst); | ||
523 | |||
524 | err_out_clock_exiv: | ||
525 | clk_disable_unprepare(evea->clk_exiv); | ||
526 | |||
527 | err_out_clock: | ||
528 | clk_disable_unprepare(evea->clk); | ||
529 | |||
530 | return ret; | ||
531 | } | ||
532 | |||
533 | static int evea_remove(struct platform_device *pdev) | ||
534 | { | ||
535 | struct evea_priv *evea = platform_get_drvdata(pdev); | ||
536 | |||
537 | snd_soc_unregister_codec(&pdev->dev); | ||
538 | |||
539 | reset_control_assert(evea->rst_adamv); | ||
540 | reset_control_assert(evea->rst_exiv); | ||
541 | reset_control_assert(evea->rst); | ||
542 | |||
543 | clk_disable_unprepare(evea->clk_exiv); | ||
544 | clk_disable_unprepare(evea->clk); | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | static const struct of_device_id evea_of_match[] = { | ||
550 | { .compatible = "socionext,uniphier-evea", }, | ||
551 | {} | ||
552 | }; | ||
553 | MODULE_DEVICE_TABLE(of, evea_of_match); | ||
554 | |||
555 | static struct platform_driver evea_codec_driver = { | ||
556 | .driver = { | ||
557 | .name = DRV_NAME, | ||
558 | .of_match_table = of_match_ptr(evea_of_match), | ||
559 | }, | ||
560 | .probe = evea_probe, | ||
561 | .remove = evea_remove, | ||
562 | }; | ||
563 | module_platform_driver(evea_codec_driver); | ||
564 | |||
565 | MODULE_AUTHOR("Katsuhiro Suzuki <suzuki.katsuhiro@socionext.com>"); | ||
566 | MODULE_DESCRIPTION("UniPhier EVEA codec driver"); | ||
567 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c index 070a6880980e..c60a57797640 100644 --- a/sound/soc/ux500/mop500.c +++ b/sound/soc/ux500/mop500.c | |||
@@ -163,3 +163,7 @@ static struct platform_driver snd_soc_mop500_driver = { | |||
163 | }; | 163 | }; |
164 | 164 | ||
165 | module_platform_driver(snd_soc_mop500_driver); | 165 | module_platform_driver(snd_soc_mop500_driver); |
166 | |||
167 | MODULE_LICENSE("GPL v2"); | ||
168 | MODULE_DESCRIPTION("ASoC MOP500 board driver"); | ||
169 | MODULE_AUTHOR("Ola Lilja"); | ||
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c index f12c01dddc8d..d35ba7700f46 100644 --- a/sound/soc/ux500/ux500_pcm.c +++ b/sound/soc/ux500/ux500_pcm.c | |||
@@ -165,3 +165,8 @@ int ux500_pcm_unregister_platform(struct platform_device *pdev) | |||
165 | return 0; | 165 | return 0; |
166 | } | 166 | } |
167 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); | 167 | EXPORT_SYMBOL_GPL(ux500_pcm_unregister_platform); |
168 | |||
169 | MODULE_AUTHOR("Ola Lilja"); | ||
170 | MODULE_AUTHOR("Roger Nilsson"); | ||
171 | MODULE_DESCRIPTION("ASoC UX500 driver"); | ||
172 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/sound_core.c b/sound/sound_core.c index 99b73c675743..b4efb22db561 100644 --- a/sound/sound_core.c +++ b/sound/sound_core.c | |||
@@ -119,13 +119,6 @@ struct sound_unit | |||
119 | char name[32]; | 119 | char name[32]; |
120 | }; | 120 | }; |
121 | 121 | ||
122 | #ifdef CONFIG_SOUND_MSNDCLAS | ||
123 | extern int msnd_classic_init(void); | ||
124 | #endif | ||
125 | #ifdef CONFIG_SOUND_MSNDPIN | ||
126 | extern int msnd_pinnacle_init(void); | ||
127 | #endif | ||
128 | |||
129 | /* | 122 | /* |
130 | * By default, OSS sound_core claims full legacy minor range (0-255) | 123 | * By default, OSS sound_core claims full legacy minor range (0-255) |
131 | * of SOUND_MAJOR to trap open attempts to any sound minor and | 124 | * of SOUND_MAJOR to trap open attempts to any sound minor and |
@@ -452,26 +445,6 @@ int register_sound_mixer(const struct file_operations *fops, int dev) | |||
452 | 445 | ||
453 | EXPORT_SYMBOL(register_sound_mixer); | 446 | EXPORT_SYMBOL(register_sound_mixer); |
454 | 447 | ||
455 | /** | ||
456 | * register_sound_midi - register a midi device | ||
457 | * @fops: File operations for the driver | ||
458 | * @dev: Unit number to allocate | ||
459 | * | ||
460 | * Allocate a midi device. Unit is the number of the midi device requested. | ||
461 | * Pass -1 to request the next free midi unit. | ||
462 | * | ||
463 | * Return: On success, the allocated number is returned. On failure, | ||
464 | * a negative error code is returned. | ||
465 | */ | ||
466 | |||
467 | int register_sound_midi(const struct file_operations *fops, int dev) | ||
468 | { | ||
469 | return sound_insert_unit(&chains[2], fops, dev, 2, 130, | ||
470 | "midi", S_IRUSR | S_IWUSR, NULL); | ||
471 | } | ||
472 | |||
473 | EXPORT_SYMBOL(register_sound_midi); | ||
474 | |||
475 | /* | 448 | /* |
476 | * DSP's are registered as a triple. Register only one and cheat | 449 | * DSP's are registered as a triple. Register only one and cheat |
477 | * in open - see below. | 450 | * in open - see below. |
@@ -533,21 +506,6 @@ void unregister_sound_mixer(int unit) | |||
533 | EXPORT_SYMBOL(unregister_sound_mixer); | 506 | EXPORT_SYMBOL(unregister_sound_mixer); |
534 | 507 | ||
535 | /** | 508 | /** |
536 | * unregister_sound_midi - unregister a midi device | ||
537 | * @unit: unit number to allocate | ||
538 | * | ||
539 | * Release a sound device that was allocated with register_sound_midi(). | ||
540 | * The unit passed is the return value from the register function. | ||
541 | */ | ||
542 | |||
543 | void unregister_sound_midi(int unit) | ||
544 | { | ||
545 | sound_remove_unit(&chains[2], unit); | ||
546 | } | ||
547 | |||
548 | EXPORT_SYMBOL(unregister_sound_midi); | ||
549 | |||
550 | /** | ||
551 | * unregister_sound_dsp - unregister a DSP device | 509 | * unregister_sound_dsp - unregister a DSP device |
552 | * @unit: unit number to allocate | 510 | * @unit: unit number to allocate |
553 | * | 511 | * |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 23d1d23aefec..8018d56cfecc 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -585,15 +585,24 @@ static int usb_audio_probe(struct usb_interface *intf, | |||
585 | * now look for an empty slot and create a new card instance | 585 | * now look for an empty slot and create a new card instance |
586 | */ | 586 | */ |
587 | for (i = 0; i < SNDRV_CARDS; i++) | 587 | for (i = 0; i < SNDRV_CARDS; i++) |
588 | if (enable[i] && ! usb_chip[i] && | 588 | if (!usb_chip[i] && |
589 | (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && | 589 | (vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) && |
590 | (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { | 590 | (pid[i] == -1 || pid[i] == USB_ID_PRODUCT(id))) { |
591 | err = snd_usb_audio_create(intf, dev, i, quirk, | 591 | if (enable[i]) { |
592 | id, &chip); | 592 | err = snd_usb_audio_create(intf, dev, i, quirk, |
593 | if (err < 0) | 593 | id, &chip); |
594 | if (err < 0) | ||
595 | goto __error; | ||
596 | chip->pm_intf = intf; | ||
597 | break; | ||
598 | } else if (vid[i] != -1 || pid[i] != -1) { | ||
599 | dev_info(&dev->dev, | ||
600 | "device (%04x:%04x) is disabled\n", | ||
601 | USB_ID_VENDOR(id), | ||
602 | USB_ID_PRODUCT(id)); | ||
603 | err = -ENOENT; | ||
594 | goto __error; | 604 | goto __error; |
595 | chip->pm_intf = intf; | 605 | } |
596 | break; | ||
597 | } | 606 | } |
598 | if (!chip) { | 607 | if (!chip) { |
599 | dev_err(&dev->dev, "no available usb audio device\n"); | 608 | dev_err(&dev->dev, "no available usb audio device\n"); |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 2b4ceda36291..9afb8ab524c7 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -656,10 +656,14 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
656 | unsigned char *name, int maxlen, int term_only) | 656 | unsigned char *name, int maxlen, int term_only) |
657 | { | 657 | { |
658 | struct iterm_name_combo *names; | 658 | struct iterm_name_combo *names; |
659 | int len; | ||
659 | 660 | ||
660 | if (iterm->name) | 661 | if (iterm->name) { |
661 | return snd_usb_copy_string_desc(state, iterm->name, | 662 | len = snd_usb_copy_string_desc(state, iterm->name, |
662 | name, maxlen); | 663 | name, maxlen); |
664 | if (len) | ||
665 | return len; | ||
666 | } | ||
663 | 667 | ||
664 | /* virtual type - not a real terminal */ | 668 | /* virtual type - not a real terminal */ |
665 | if (iterm->type >> 16) { | 669 | if (iterm->type >> 16) { |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index e1e7ce9ab217..e6359d341878 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 27 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/hid.h> | ||
30 | #include <linux/init.h> | 31 | #include <linux/init.h> |
31 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
32 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
@@ -1721,6 +1722,83 @@ static int snd_microii_controls_create(struct usb_mixer_interface *mixer) | |||
1721 | return 0; | 1722 | return 0; |
1722 | } | 1723 | } |
1723 | 1724 | ||
1725 | /* Creative Sound Blaster E1 */ | ||
1726 | |||
1727 | static int snd_soundblaster_e1_switch_get(struct snd_kcontrol *kcontrol, | ||
1728 | struct snd_ctl_elem_value *ucontrol) | ||
1729 | { | ||
1730 | ucontrol->value.integer.value[0] = kcontrol->private_value; | ||
1731 | return 0; | ||
1732 | } | ||
1733 | |||
1734 | static int snd_soundblaster_e1_switch_update(struct usb_mixer_interface *mixer, | ||
1735 | unsigned char state) | ||
1736 | { | ||
1737 | struct snd_usb_audio *chip = mixer->chip; | ||
1738 | int err; | ||
1739 | unsigned char buff[2]; | ||
1740 | |||
1741 | buff[0] = 0x02; | ||
1742 | buff[1] = state ? 0x02 : 0x00; | ||
1743 | |||
1744 | err = snd_usb_lock_shutdown(chip); | ||
1745 | if (err < 0) | ||
1746 | return err; | ||
1747 | err = snd_usb_ctl_msg(chip->dev, | ||
1748 | usb_sndctrlpipe(chip->dev, 0), HID_REQ_SET_REPORT, | ||
1749 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
1750 | 0x0202, 3, buff, 2); | ||
1751 | snd_usb_unlock_shutdown(chip); | ||
1752 | return err; | ||
1753 | } | ||
1754 | |||
1755 | static int snd_soundblaster_e1_switch_put(struct snd_kcontrol *kcontrol, | ||
1756 | struct snd_ctl_elem_value *ucontrol) | ||
1757 | { | ||
1758 | struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol); | ||
1759 | unsigned char value = !!ucontrol->value.integer.value[0]; | ||
1760 | int err; | ||
1761 | |||
1762 | if (kcontrol->private_value == value) | ||
1763 | return 0; | ||
1764 | kcontrol->private_value = value; | ||
1765 | err = snd_soundblaster_e1_switch_update(list->mixer, value); | ||
1766 | return err < 0 ? err : 1; | ||
1767 | } | ||
1768 | |||
1769 | static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list) | ||
1770 | { | ||
1771 | return snd_soundblaster_e1_switch_update(list->mixer, | ||
1772 | list->kctl->private_value); | ||
1773 | } | ||
1774 | |||
1775 | static int snd_soundblaster_e1_switch_info(struct snd_kcontrol *kcontrol, | ||
1776 | struct snd_ctl_elem_info *uinfo) | ||
1777 | { | ||
1778 | static const char *const texts[2] = { | ||
1779 | "Mic", "Aux" | ||
1780 | }; | ||
1781 | |||
1782 | return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts); | ||
1783 | } | ||
1784 | |||
1785 | static struct snd_kcontrol_new snd_soundblaster_e1_input_switch = { | ||
1786 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1787 | .name = "Input Source", | ||
1788 | .info = snd_soundblaster_e1_switch_info, | ||
1789 | .get = snd_soundblaster_e1_switch_get, | ||
1790 | .put = snd_soundblaster_e1_switch_put, | ||
1791 | .private_value = 0, | ||
1792 | }; | ||
1793 | |||
1794 | static int snd_soundblaster_e1_switch_create(struct usb_mixer_interface *mixer) | ||
1795 | { | ||
1796 | return add_single_ctl_with_resume(mixer, 0, | ||
1797 | snd_soundblaster_e1_switch_resume, | ||
1798 | &snd_soundblaster_e1_input_switch, | ||
1799 | NULL); | ||
1800 | } | ||
1801 | |||
1724 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | 1802 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
1725 | { | 1803 | { |
1726 | int err = 0; | 1804 | int err = 0; |
@@ -1802,6 +1880,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1802 | case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */ | 1880 | case USB_ID(0x1235, 0x800c): /* Focusrite Scarlett 18i20 */ |
1803 | err = snd_scarlett_controls_create(mixer); | 1881 | err = snd_scarlett_controls_create(mixer); |
1804 | break; | 1882 | break; |
1883 | |||
1884 | case USB_ID(0x041e, 0x323b): /* Creative Sound Blaster E1 */ | ||
1885 | err = snd_soundblaster_e1_switch_create(mixer); | ||
1886 | break; | ||
1805 | } | 1887 | } |
1806 | 1888 | ||
1807 | return err; | 1889 | return err; |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index 8a59d4782a0f..50252046b01d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -3277,4 +3277,52 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"), | |||
3277 | } | 3277 | } |
3278 | }, | 3278 | }, |
3279 | 3279 | ||
3280 | { | ||
3281 | /* | ||
3282 | * Nura's first gen headphones use Cambridge Silicon Radio's vendor | ||
3283 | * ID, but it looks like the product ID actually is only for Nura. | ||
3284 | * The capture interface does not work at all (even on Windows), | ||
3285 | * and only the 48 kHz sample rate works for the playback interface. | ||
3286 | */ | ||
3287 | USB_DEVICE(0x0a12, 0x1243), | ||
3288 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
3289 | .ifnum = QUIRK_ANY_INTERFACE, | ||
3290 | .type = QUIRK_COMPOSITE, | ||
3291 | .data = (const struct snd_usb_audio_quirk[]) { | ||
3292 | { | ||
3293 | .ifnum = 0, | ||
3294 | .type = QUIRK_AUDIO_STANDARD_MIXER, | ||
3295 | }, | ||
3296 | /* Capture */ | ||
3297 | { | ||
3298 | .ifnum = 1, | ||
3299 | .type = QUIRK_IGNORE_INTERFACE, | ||
3300 | }, | ||
3301 | /* Playback */ | ||
3302 | { | ||
3303 | .ifnum = 2, | ||
3304 | .type = QUIRK_AUDIO_FIXED_ENDPOINT, | ||
3305 | .data = &(const struct audioformat) { | ||
3306 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
3307 | .channels = 2, | ||
3308 | .iface = 2, | ||
3309 | .altsetting = 1, | ||
3310 | .altset_idx = 1, | ||
3311 | .attributes = UAC_EP_CS_ATTR_FILL_MAX | | ||
3312 | UAC_EP_CS_ATTR_SAMPLE_RATE, | ||
3313 | .endpoint = 0x03, | ||
3314 | .ep_attr = USB_ENDPOINT_XFER_ISOC, | ||
3315 | .rates = SNDRV_PCM_RATE_48000, | ||
3316 | .rate_min = 48000, | ||
3317 | .rate_max = 48000, | ||
3318 | .nr_rates = 1, | ||
3319 | .rate_table = (unsigned int[]) { | ||
3320 | 48000 | ||
3321 | } | ||
3322 | } | ||
3323 | }, | ||
3324 | } | ||
3325 | } | ||
3326 | }, | ||
3327 | |||
3280 | #undef USB_DEVICE_VENDOR_SPEC | 3328 | #undef USB_DEVICE_VENDOR_SPEC |