diff options
273 files changed, 19337 insertions, 4590 deletions
diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt index 1413f39912d3..8aba48821a85 100644 --- a/Documentation/devicetree/bindings/mfd/mc13xxx.txt +++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt | |||
@@ -10,6 +10,9 @@ Optional properties: | |||
10 | - fsl,mc13xxx-uses-touch : Indicate the touchscreen controller is being used | 10 | - fsl,mc13xxx-uses-touch : Indicate the touchscreen controller is being used |
11 | 11 | ||
12 | Sub-nodes: | 12 | Sub-nodes: |
13 | - codec: Contain the Audio Codec node. | ||
14 | - adc-port: Contain PMIC SSI port number used for ADC. | ||
15 | - dac-port: Contain PMIC SSI port number used for DAC. | ||
13 | - leds : Contain the led nodes and initial register values in property | 16 | - leds : Contain the led nodes and initial register values in property |
14 | "led-control". Number of register depends of used IC, for MC13783 is 6, | 17 | "led-control". Number of register depends of used IC, for MC13783 is 6, |
15 | for MC13892 is 4, for MC34708 is 1. See datasheet for bits definitions of | 18 | for MC13892 is 4, for MC34708 is 1. See datasheet for bits definitions of |
diff --git a/Documentation/devicetree/bindings/sound/ak4104.txt b/Documentation/devicetree/bindings/sound/ak4104.txt index b902ee39cf89..deca5e18f304 100644 --- a/Documentation/devicetree/bindings/sound/ak4104.txt +++ b/Documentation/devicetree/bindings/sound/ak4104.txt | |||
@@ -8,6 +8,8 @@ Required properties: | |||
8 | 8 | ||
9 | - reg : The chip select number on the SPI bus | 9 | - reg : The chip select number on the SPI bus |
10 | 10 | ||
11 | - vdd-supply : A regulator node, providing 2.7V - 3.6V | ||
12 | |||
11 | Optional properties: | 13 | Optional properties: |
12 | 14 | ||
13 | - reset-gpio : a GPIO spec for the reset pin. If specified, it will be | 15 | - reset-gpio : a GPIO spec for the reset pin. If specified, it will be |
@@ -19,4 +21,5 @@ spdif: ak4104@0 { | |||
19 | compatible = "asahi-kasei,ak4104"; | 21 | compatible = "asahi-kasei,ak4104"; |
20 | reg = <0>; | 22 | reg = <0>; |
21 | spi-max-frequency = <5000000>; | 23 | spi-max-frequency = <5000000>; |
24 | vdd-supply = <&vdd_3v3_reg>; | ||
22 | }; | 25 | }; |
diff --git a/Documentation/devicetree/bindings/sound/alc5623.txt b/Documentation/devicetree/bindings/sound/alc5623.txt new file mode 100644 index 000000000000..26c86c98d671 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/alc5623.txt | |||
@@ -0,0 +1,25 @@ | |||
1 | ALC5621/ALC5622/ALC5623 audio Codec | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: "realtek,alc5623" | ||
6 | - reg: the I2C address of the device. | ||
7 | |||
8 | Optional properties: | ||
9 | |||
10 | - add-ctrl: Default register value for Reg-40h, Additional Control | ||
11 | Register. If absent or has the value of 0, the | ||
12 | register is untouched. | ||
13 | |||
14 | - jack-det-ctrl: Default register value for Reg-5Ah, Jack Detect | ||
15 | Control Register. If absent or has value 0, the | ||
16 | register is untouched. | ||
17 | |||
18 | Example: | ||
19 | |||
20 | alc5621: alc5621@1a { | ||
21 | compatible = "alc5621"; | ||
22 | reg = <0x1a>; | ||
23 | add-ctrl = <0x3700>; | ||
24 | jack-det-ctrl = <0x4810>; | ||
25 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/cs42l56.txt b/Documentation/devicetree/bindings/sound/cs42l56.txt new file mode 100644 index 000000000000..4feb0eb27ea4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cs42l56.txt | |||
@@ -0,0 +1,63 @@ | |||
1 | CS42L52 audio CODEC | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible : "cirrus,cs42l56" | ||
6 | |||
7 | - reg : the I2C address of the device for I2C | ||
8 | |||
9 | - VA-supply, VCP-supply, VLDO-supply : power supplies for the device, | ||
10 | as covered in Documentation/devicetree/bindings/regulator/regulator.txt. | ||
11 | |||
12 | Optional properties: | ||
13 | |||
14 | - cirrus,gpio-nreset : GPIO controller's phandle and the number | ||
15 | of the GPIO used to reset the codec. | ||
16 | |||
17 | - cirrus,chgfreq-divisor : Values used to set the Charge Pump Frequency. | ||
18 | Allowable values of 0x00 through 0x0F. These are raw values written to the | ||
19 | register, not the actual frequency. The frequency is determined by the following. | ||
20 | Frequency = MCLK / 4 * (N+2) | ||
21 | N = chgfreq_val | ||
22 | MCLK = Where MCLK is the frequency of the mclk signal after the MCLKDIV2 circuit. | ||
23 | |||
24 | - cirrus,ain1a-ref-cfg, ain1b-ref-cfg : boolean, If present, AIN1A or AIN1B are configured | ||
25 | as a pseudo-differential input referenced to AIN1REF/AIN3A. | ||
26 | |||
27 | - cirrus,ain2a-ref-cfg, ain2b-ref-cfg : boolean, If present, AIN2A or AIN2B are configured | ||
28 | as a pseudo-differential input referenced to AIN2REF/AIN3B. | ||
29 | |||
30 | - cirrus,micbias-lvl: Set the output voltage level on the MICBIAS Pin. | ||
31 | 0 = 0.5 x VA | ||
32 | 1 = 0.6 x VA | ||
33 | 2 = 0.7 x VA | ||
34 | 3 = 0.8 x VA | ||
35 | 4 = 0.83 x VA | ||
36 | 5 = 0.91 x VA | ||
37 | |||
38 | - cirrus,adaptive-pwr-cfg : Configures how the power to the Headphone and Lineout | ||
39 | Amplifiers adapt to the output signal levels. | ||
40 | 0 = Adapt to Volume Mode. Voltage level determined by the sum of the relevant volume settings. | ||
41 | 1 = Fixed - Headphone and Line Amp supply = + or - VCP/2. | ||
42 | 2 = Fixed - Headphone and Line Amp supply = + or - VCP. | ||
43 | 3 = Adapted to Signal; Voltage level is dynamically determined by the output signal. | ||
44 | |||
45 | - cirrus,hpf-left-freq, hpf-right-freq : Sets the corner frequency (-3dB point) for the internal High-Pass | ||
46 | Filter. | ||
47 | 0 = 1.8Hz | ||
48 | 1 = 119Hz | ||
49 | 2 = 236Hz | ||
50 | 3 = 464Hz | ||
51 | |||
52 | |||
53 | Example: | ||
54 | |||
55 | codec: codec@4b { | ||
56 | compatible = "cirrus,cs42l56"; | ||
57 | reg = <0x4b>; | ||
58 | gpio-reset = <&gpio 10 0>; | ||
59 | cirrus,chgfreq-divisor = <0x05>; | ||
60 | cirrus.ain1_ref_cfg; | ||
61 | cirrus,micbias-lvl = <5>; | ||
62 | VA-supply = <®_audio>; | ||
63 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/fsl-sai.txt b/Documentation/devicetree/bindings/sound/fsl-sai.txt index 98611a6761c0..0f4e23828190 100644 --- a/Documentation/devicetree/bindings/sound/fsl-sai.txt +++ b/Documentation/devicetree/bindings/sound/fsl-sai.txt | |||
@@ -7,10 +7,11 @@ codec/DSP interfaces. | |||
7 | 7 | ||
8 | 8 | ||
9 | Required properties: | 9 | Required properties: |
10 | - compatible: Compatible list, contains "fsl,vf610-sai". | 10 | - compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai". |
11 | - reg: Offset and length of the register set for the device. | 11 | - reg: Offset and length of the register set for the device. |
12 | - clocks: Must contain an entry for each entry in clock-names. | 12 | - clocks: Must contain an entry for each entry in clock-names. |
13 | - clock-names : Must include the "sai" entry. | 13 | - clock-names : Must include the "bus" for register access and "mclk1" "mclk2" |
14 | "mclk3" for bit clock and frame clock providing. | ||
14 | - dmas : Generic dma devicetree binding as described in | 15 | - dmas : Generic dma devicetree binding as described in |
15 | Documentation/devicetree/bindings/dma/dma.txt. | 16 | Documentation/devicetree/bindings/dma/dma.txt. |
16 | - dma-names : Two dmas have to be defined, "tx" and "rx". | 17 | - dma-names : Two dmas have to be defined, "tx" and "rx". |
@@ -30,8 +31,10 @@ sai2: sai@40031000 { | |||
30 | reg = <0x40031000 0x1000>; | 31 | reg = <0x40031000 0x1000>; |
31 | pinctrl-names = "default"; | 32 | pinctrl-names = "default"; |
32 | pinctrl-0 = <&pinctrl_sai2_1>; | 33 | pinctrl-0 = <&pinctrl_sai2_1>; |
33 | clocks = <&clks VF610_CLK_SAI2>; | 34 | clocks = <&clks VF610_CLK_PLATFORM_BUS>, |
34 | clock-names = "sai"; | 35 | <&clks VF610_CLK_SAI2>, |
36 | <&clks 0>, <&clks 0>; | ||
37 | clock-names = "bus", "mclk1", "mclk2", "mclk3"; | ||
35 | dma-names = "tx", "rx"; | 38 | dma-names = "tx", "rx"; |
36 | dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, | 39 | dmas = <&edma0 0 VF610_EDMA_MUXID0_SAI2_TX>, |
37 | <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; | 40 | <&edma0 0 VF610_EDMA_MUXID0_SAI2_RX>; |
diff --git a/Documentation/devicetree/bindings/sound/max98095.txt b/Documentation/devicetree/bindings/sound/max98095.txt new file mode 100644 index 000000000000..bacbeaac72b5 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/max98095.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | MAX98095 audio CODEC | ||
2 | |||
3 | This device supports I2C only. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible : "maxim,max98095". | ||
8 | |||
9 | - reg : The I2C address of the device. | ||
10 | |||
11 | Example: | ||
12 | |||
13 | max98095: codec@11 { | ||
14 | compatible = "maxim,max98095"; | ||
15 | reg = <0x11>; | ||
16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/nokia,rx51.txt b/Documentation/devicetree/bindings/sound/nokia,rx51.txt new file mode 100644 index 000000000000..72f93d996273 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nokia,rx51.txt | |||
@@ -0,0 +1,27 @@ | |||
1 | * Nokia N900 audio setup | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: Should contain "nokia,n900-audio" | ||
5 | - nokia,cpu-dai: phandle for the McBSP node | ||
6 | - nokia,audio-codec: phandles for the main TLV320AIC3X node and the | ||
7 | auxiliary TLV320AIC3X node (in this order) | ||
8 | - nokia,headphone-amplifier: phandle for the TPA6130A2 node | ||
9 | - tvout-selection-gpios: GPIO for tvout selection | ||
10 | - jack-detection-gpios: GPIO for jack detection | ||
11 | - eci-switch-gpios: GPIO for ECI (Enhancement Control Interface) switch | ||
12 | - speaker-amplifier-gpios: GPIO for speaker amplifier | ||
13 | |||
14 | Example: | ||
15 | |||
16 | sound { | ||
17 | compatible = "nokia,n900-audio"; | ||
18 | |||
19 | nokia,cpu-dai = <&mcbsp2>; | ||
20 | nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>; | ||
21 | nokia,headphone-amplifier = <&tpa6130a2>; | ||
22 | |||
23 | tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */ | ||
24 | jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */ | ||
25 | eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */ | ||
26 | speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>; | ||
27 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.txt b/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.txt new file mode 100644 index 000000000000..c26f8ca97023 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/nvidia,tegra30-hda.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | NVIDIA Tegra30 HDA controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "nvidia,tegra30-hda" | ||
5 | - reg : Should contain the HDA registers location and length. | ||
6 | - interrupts : The interrupt from the HDA controller. | ||
7 | - clocks : Must contain an entry for each required entry in clock-names. | ||
8 | See ../clocks/clock-bindings.txt for details. | ||
9 | - clock-names : Must include the following entries: hda, hdacodec_2x, hda2hdmi | ||
10 | - resets : Must contain an entry for each entry in reset-names. | ||
11 | See ../reset/reset.txt for details. | ||
12 | - reset-names : Must include the following entries: hda, hdacodec_2x, hda2hdmi | ||
13 | |||
14 | Example: | ||
15 | |||
16 | hda@0,70030000 { | ||
17 | compatible = "nvidia,tegra124-hda", "nvidia,tegra30-hda"; | ||
18 | reg = <0x0 0x70030000 0x0 0x10000>; | ||
19 | interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; | ||
20 | clocks = <&tegra_car TEGRA124_CLK_HDA>, | ||
21 | <&tegra_car TEGRA124_CLK_HDA2HDMI>, | ||
22 | <&tegra_car TEGRA124_CLK_HDA2CODEC_2X>; | ||
23 | clock-names = "hda", "hda2hdmi", "hdacodec_2x"; | ||
24 | resets = <&tegra_car 125>, /* hda */ | ||
25 | <&tegra_car 128>; /* hda2hdmi */ | ||
26 | <&tegra_car 111>, /* hda2codec_2x */ | ||
27 | reset-names = "hda", "hda2hdmi", "hdacodec_2x"; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/rt5640.txt b/Documentation/devicetree/bindings/sound/rt5640.txt index 068a1141b06f..bac4d9ac1edc 100644 --- a/Documentation/devicetree/bindings/sound/rt5640.txt +++ b/Documentation/devicetree/bindings/sound/rt5640.txt | |||
@@ -1,10 +1,10 @@ | |||
1 | RT5640 audio CODEC | 1 | RT5640/RT5639 audio CODEC |
2 | 2 | ||
3 | This device supports I2C only. | 3 | This device supports I2C only. |
4 | 4 | ||
5 | Required properties: | 5 | Required properties: |
6 | 6 | ||
7 | - compatible : "realtek,rt5640". | 7 | - compatible : One of "realtek,rt5640" or "realtek,rt5639". |
8 | 8 | ||
9 | - reg : The I2C address of the device. | 9 | - reg : The I2C address of the device. |
10 | 10 | ||
@@ -18,7 +18,7 @@ Optional properties: | |||
18 | 18 | ||
19 | - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. | 19 | - realtek,ldo1-en-gpios : The GPIO that controls the CODEC's LDO1_EN pin. |
20 | 20 | ||
21 | Pins on the device (for linking into audio routes): | 21 | Pins on the device (for linking into audio routes) for RT5639/RT5640: |
22 | 22 | ||
23 | * DMIC1 | 23 | * DMIC1 |
24 | * DMIC2 | 24 | * DMIC2 |
@@ -31,13 +31,16 @@ Pins on the device (for linking into audio routes): | |||
31 | * HPOR | 31 | * HPOR |
32 | * LOUTL | 32 | * LOUTL |
33 | * LOUTR | 33 | * LOUTR |
34 | * MONOP | ||
35 | * MONON | ||
36 | * SPOLP | 34 | * SPOLP |
37 | * SPOLN | 35 | * SPOLN |
38 | * SPORP | 36 | * SPORP |
39 | * SPORN | 37 | * SPORN |
40 | 38 | ||
39 | Additional pins on the device for RT5640: | ||
40 | |||
41 | * MONOP | ||
42 | * MONON | ||
43 | |||
41 | Example: | 44 | Example: |
42 | 45 | ||
43 | rt5640 { | 46 | rt5640 { |
diff --git a/Documentation/devicetree/bindings/sound/simple-card.txt b/Documentation/devicetree/bindings/sound/simple-card.txt index 131aa2ad7f1a..9b9df146fd1a 100644 --- a/Documentation/devicetree/bindings/sound/simple-card.txt +++ b/Documentation/devicetree/bindings/sound/simple-card.txt | |||
@@ -1,6 +1,6 @@ | |||
1 | Simple-Card: | 1 | Simple-Card: |
2 | 2 | ||
3 | Simple-Card specifies audio DAI connection of SoC <-> codec. | 3 | Simple-Card specifies audio DAI connections of SoC <-> codec. |
4 | 4 | ||
5 | Required properties: | 5 | Required properties: |
6 | 6 | ||
@@ -10,26 +10,51 @@ Optional properties: | |||
10 | 10 | ||
11 | - simple-audio-card,name : User specified audio sound card name, one string | 11 | - simple-audio-card,name : User specified audio sound card name, one string |
12 | property. | 12 | property. |
13 | - simple-audio-card,format : CPU/CODEC common audio format. | ||
14 | "i2s", "right_j", "left_j" , "dsp_a" | ||
15 | "dsp_b", "ac97", "pdm", "msb", "lsb" | ||
16 | - simple-audio-card,widgets : Please refer to widgets.txt. | 13 | - simple-audio-card,widgets : Please refer to widgets.txt. |
17 | - simple-audio-card,routing : A list of the connections between audio components. | 14 | - simple-audio-card,routing : A list of the connections between audio components. |
18 | Each entry is a pair of strings, the first being the | 15 | Each entry is a pair of strings, the first being the |
19 | connection's sink, the second being the connection's | 16 | connection's sink, the second being the connection's |
20 | source. | 17 | source. |
21 | - dai-tdm-slot-num : Please refer to tdm-slot.txt. | 18 | Optional subnodes: |
22 | - dai-tdm-slot-width : Please refer to tdm-slot.txt. | 19 | |
20 | - simple-audio-card,dai-link : Container for dai-link level | ||
21 | properties and the CPU and CODEC | ||
22 | sub-nodes. This container may be | ||
23 | omitted when the card has only one | ||
24 | DAI link. See the examples and the | ||
25 | section bellow. | ||
26 | |||
27 | Dai-link subnode properties and subnodes: | ||
28 | |||
29 | If dai-link subnode is omitted and the subnode properties are directly | ||
30 | under "sound"-node the subnode property and subnode names have to be | ||
31 | prefixed with "simple-audio-card,"-prefix. | ||
23 | 32 | ||
24 | Required subnodes: | 33 | Required dai-link subnodes: |
25 | 34 | ||
26 | - simple-audio-card,dai-link : container for the CPU and CODEC sub-nodes | 35 | - cpu : CPU sub-node |
27 | This container may be omitted when the | 36 | - codec : CODEC sub-node |
28 | card has only one DAI link. | ||
29 | See the examples. | ||
30 | 37 | ||
31 | - simple-audio-card,cpu : CPU sub-node | 38 | Optional dai-link subnode properties: |
32 | - simple-audio-card,codec : CODEC sub-node | 39 | |
40 | - format : CPU/CODEC common audio format. | ||
41 | "i2s", "right_j", "left_j" , "dsp_a" | ||
42 | "dsp_b", "ac97", "pdm", "msb", "lsb" | ||
43 | - frame-master : Indicates dai-link frame master. | ||
44 | phandle to a cpu or codec subnode. | ||
45 | - bitclock-master : Indicates dai-link bit clock master. | ||
46 | phandle to a cpu or codec subnode. | ||
47 | - bitclock-inversion : bool property. Add this if the | ||
48 | dai-link uses bit clock inversion. | ||
49 | - frame-inversion : bool property. Add this if the | ||
50 | dai-link uses frame clock inversion. | ||
51 | |||
52 | For backward compatibility the frame-master and bitclock-master | ||
53 | properties can be used as booleans in codec subnode to indicate if the | ||
54 | codec is the dai-link frame or bit clock master. In this case there | ||
55 | should be no dai-link node, the same properties should not be present | ||
56 | at sound-node level, and the bitclock-inversion and frame-inversion | ||
57 | properties should also be placed in the codec node if needed. | ||
33 | 58 | ||
34 | Required CPU/CODEC subnodes properties: | 59 | Required CPU/CODEC subnodes properties: |
35 | 60 | ||
@@ -37,29 +62,21 @@ Required CPU/CODEC subnodes properties: | |||
37 | 62 | ||
38 | Optional CPU/CODEC subnodes properties: | 63 | Optional CPU/CODEC subnodes properties: |
39 | 64 | ||
40 | - format : CPU/CODEC specific audio format if needed. | 65 | - dai-tdm-slot-num : Please refer to tdm-slot.txt. |
41 | see simple-audio-card,format | 66 | - dai-tdm-slot-width : Please refer to tdm-slot.txt. |
42 | - frame-master : bool property. add this if subnode is frame master | ||
43 | - bitclock-master : bool property. add this if subnode is bitclock master | ||
44 | - bitclock-inversion : bool property. add this if subnode has clock inversion | ||
45 | - frame-inversion : bool property. add this if subnode has frame inversion | ||
46 | - clocks / system-clock-frequency : specify subnode's clock if needed. | 67 | - clocks / system-clock-frequency : specify subnode's clock if needed. |
47 | it can be specified via "clocks" if system has | 68 | it can be specified via "clocks" if system has |
48 | clock node (= common clock), or "system-clock-frequency" | 69 | clock node (= common clock), or "system-clock-frequency" |
49 | (if system doens't support common clock) | 70 | (if system doens't support common clock) |
50 | 71 | ||
51 | Note: | ||
52 | * For 'format', 'frame-master', 'bitclock-master', 'bitclock-inversion' and | ||
53 | 'frame-inversion', the simple card will use the settings of CODEC for both | ||
54 | CPU and CODEC sides as we need to keep the settings identical for both ends | ||
55 | of the link. | ||
56 | |||
57 | Example 1 - single DAI link: | 72 | Example 1 - single DAI link: |
58 | 73 | ||
59 | sound { | 74 | sound { |
60 | compatible = "simple-audio-card"; | 75 | compatible = "simple-audio-card"; |
61 | simple-audio-card,name = "VF610-Tower-Sound-Card"; | 76 | simple-audio-card,name = "VF610-Tower-Sound-Card"; |
62 | simple-audio-card,format = "left_j"; | 77 | simple-audio-card,format = "left_j"; |
78 | simple-audio-card,bitclock-master = <&dailink0_master>; | ||
79 | simple-audio-card,frame-master = <&dailink0_master>; | ||
63 | simple-audio-card,widgets = | 80 | simple-audio-card,widgets = |
64 | "Microphone", "Microphone Jack", | 81 | "Microphone", "Microphone Jack", |
65 | "Headphone", "Headphone Jack", | 82 | "Headphone", "Headphone Jack", |
@@ -69,17 +86,12 @@ sound { | |||
69 | "Headphone Jack", "HP_OUT", | 86 | "Headphone Jack", "HP_OUT", |
70 | "External Speaker", "LINE_OUT"; | 87 | "External Speaker", "LINE_OUT"; |
71 | 88 | ||
72 | dai-tdm-slot-num = <2>; | ||
73 | dai-tdm-slot-width = <8>; | ||
74 | |||
75 | simple-audio-card,cpu { | 89 | simple-audio-card,cpu { |
76 | sound-dai = <&sh_fsi2 0>; | 90 | sound-dai = <&sh_fsi2 0>; |
77 | }; | 91 | }; |
78 | 92 | ||
79 | simple-audio-card,codec { | 93 | dailink0_master: simple-audio-card,codec { |
80 | sound-dai = <&ak4648>; | 94 | sound-dai = <&ak4648>; |
81 | bitclock-master; | ||
82 | frame-master; | ||
83 | clocks = <&osc>; | 95 | clocks = <&osc>; |
84 | }; | 96 | }; |
85 | }; | 97 | }; |
@@ -105,31 +117,31 @@ Example 2 - many DAI links: | |||
105 | sound { | 117 | sound { |
106 | compatible = "simple-audio-card"; | 118 | compatible = "simple-audio-card"; |
107 | simple-audio-card,name = "Cubox Audio"; | 119 | simple-audio-card,name = "Cubox Audio"; |
108 | simple-audio-card,format = "i2s"; | ||
109 | 120 | ||
110 | simple-audio-card,dai-link@0 { /* I2S - HDMI */ | 121 | simple-audio-card,dai-link@0 { /* I2S - HDMI */ |
111 | simple-audio-card,cpu { | 122 | format = "i2s"; |
123 | cpu { | ||
112 | sound-dai = <&audio1 0>; | 124 | sound-dai = <&audio1 0>; |
113 | }; | 125 | }; |
114 | simple-audio-card,codec { | 126 | codec { |
115 | sound-dai = <&tda998x 0>; | 127 | sound-dai = <&tda998x 0>; |
116 | }; | 128 | }; |
117 | }; | 129 | }; |
118 | 130 | ||
119 | simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */ | 131 | simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */ |
120 | simple-audio-card,cpu { | 132 | cpu { |
121 | sound-dai = <&audio1 1>; | 133 | sound-dai = <&audio1 1>; |
122 | }; | 134 | }; |
123 | simple-audio-card,codec { | 135 | codec { |
124 | sound-dai = <&tda998x 1>; | 136 | sound-dai = <&tda998x 1>; |
125 | }; | 137 | }; |
126 | }; | 138 | }; |
127 | 139 | ||
128 | simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */ | 140 | simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */ |
129 | simple-audio-card,cpu { | 141 | cpu { |
130 | sound-dai = <&audio1 1>; | 142 | sound-dai = <&audio1 1>; |
131 | }; | 143 | }; |
132 | simple-audio-card,codec { | 144 | codec { |
133 | sound-dai = <&spdif_codec>; | 145 | sound-dai = <&spdif_codec>; |
134 | }; | 146 | }; |
135 | }; | 147 | }; |
diff --git a/Documentation/devicetree/bindings/sound/snow.txt b/Documentation/devicetree/bindings/sound/snow.txt new file mode 100644 index 000000000000..678b191c37b8 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/snow.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | Audio Binding for Snow boards | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : Can be one of the following, | ||
5 | "google,snow-audio-max98090" or | ||
6 | "google,snow-audio-max98095" | ||
7 | - samsung,i2s-controller: The phandle of the Samsung I2S controller | ||
8 | - samsung,audio-codec: The phandle of the audio codec | ||
9 | |||
10 | Example: | ||
11 | |||
12 | sound { | ||
13 | compatible = "google,snow-audio-max98095"; | ||
14 | |||
15 | samsung,i2s-controller = <&i2s0>; | ||
16 | samsung,audio-codec = <&max98095>; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/st,sta350.txt b/Documentation/devicetree/bindings/sound/st,sta350.txt new file mode 100644 index 000000000000..b7e71bf5caf4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/st,sta350.txt | |||
@@ -0,0 +1,131 @@ | |||
1 | STA350 audio CODEC | ||
2 | |||
3 | The driver for this device only supports I2C. | ||
4 | |||
5 | Required properties: | ||
6 | |||
7 | - compatible: "st,sta350" | ||
8 | - reg: the I2C address of the device for I2C | ||
9 | - reset-gpios: a GPIO spec for the reset pin. If specified, it will be | ||
10 | deasserted before communication to the codec starts. | ||
11 | |||
12 | - power-down-gpios: a GPIO spec for the power down pin. If specified, | ||
13 | it will be deasserted before communication to the codec | ||
14 | starts. | ||
15 | |||
16 | - vdd-dig-supply: regulator spec, providing 3.3V | ||
17 | - vdd-pll-supply: regulator spec, providing 3.3V | ||
18 | - vcc-supply: regulator spec, providing 5V - 26V | ||
19 | |||
20 | Optional properties: | ||
21 | |||
22 | - st,output-conf: number, Selects the output configuration: | ||
23 | 0: 2-channel (full-bridge) power, 2-channel data-out | ||
24 | 1: 2 (half-bridge). 1 (full-bridge) on-board power | ||
25 | 2: 2 Channel (Full-Bridge) Power, 1 Channel FFX | ||
26 | 3: 1 Channel Mono-Parallel | ||
27 | If parameter is missing, mode 0 will be enabled. | ||
28 | This property has to be specified as '/bits/ 8' value. | ||
29 | |||
30 | - st,ch1-output-mapping: Channel 1 output mapping | ||
31 | - st,ch2-output-mapping: Channel 2 output mapping | ||
32 | - st,ch3-output-mapping: Channel 3 output mapping | ||
33 | 0: Channel 1 | ||
34 | 1: Channel 2 | ||
35 | 2: Channel 3 | ||
36 | If parameter is missing, channel 1 is choosen. | ||
37 | This properties have to be specified as '/bits/ 8' values. | ||
38 | |||
39 | - st,thermal-warning-recover: | ||
40 | If present, thermal warning recovery is enabled. | ||
41 | |||
42 | - st,thermal-warning-adjustment: | ||
43 | If present, thermal warning adjustment is enabled. | ||
44 | |||
45 | - st,fault-detect-recovery: | ||
46 | If present, then fault recovery will be enabled. | ||
47 | |||
48 | - st,ffx-power-output-mode: string | ||
49 | The FFX power output mode selects how the FFX output timing is | ||
50 | configured. Must be one of these values: | ||
51 | - "drop-compensation" | ||
52 | - "tapered-compensation" | ||
53 | - "full-power-mode" | ||
54 | - "variable-drop-compensation" (default) | ||
55 | |||
56 | - st,drop-compensation-ns: number | ||
57 | Only required for "st,ffx-power-output-mode" == | ||
58 | "variable-drop-compensation". | ||
59 | Specifies the drop compensation in nanoseconds. | ||
60 | The value must be in the range of 0..300, and only | ||
61 | multiples of 20 are allowed. Default is 140ns. | ||
62 | |||
63 | - st,overcurrent-warning-adjustment: | ||
64 | If present, overcurrent warning adjustment is enabled. | ||
65 | |||
66 | - st,max-power-use-mpcc: | ||
67 | If present, then MPCC bits are used for MPC coefficients, | ||
68 | otherwise standard MPC coefficients are used. | ||
69 | |||
70 | - st,max-power-corr: | ||
71 | If present, power bridge correction for THD reduction near maximum | ||
72 | power output is enabled. | ||
73 | |||
74 | - st,am-reduction-mode: | ||
75 | If present, FFX mode runs in AM reduction mode, otherwise normal | ||
76 | FFX mode is used. | ||
77 | |||
78 | - st,odd-pwm-speed-mode: | ||
79 | If present, PWM speed mode run on odd speed mode (341.3 kHz) on all | ||
80 | channels. If not present, normal PWM spped mode (384 kHz) will be used. | ||
81 | |||
82 | - st,distortion-compensation: | ||
83 | If present, distortion compensation variable uses DCC coefficient. | ||
84 | If not present, preset DC coefficient is used. | ||
85 | |||
86 | - st,invalid-input-detect-mute: | ||
87 | If present, automatic invalid input detect mute is enabled. | ||
88 | |||
89 | - st,activate-mute-output: | ||
90 | If present, a mute output will be activated in ase the volume will | ||
91 | reach a value lower than -76 dBFS. | ||
92 | |||
93 | - st,bridge-immediate-off: | ||
94 | If present, the bridge will be switched off immediately after the | ||
95 | power-down-gpio goes low. Otherwise, the bridge will wait for 13 | ||
96 | million clock cycles to pass before shutting down. | ||
97 | |||
98 | - st,noise-shape-dc-cut: | ||
99 | If present, the noise-shaping technique on the DC cutoff filter are | ||
100 | enabled. | ||
101 | |||
102 | - st,powerdown-master-volume: | ||
103 | If present, the power-down pin and I2C power-down functions will | ||
104 | act on the master volume. Otherwise, the functions will act on the | ||
105 | mute commands. | ||
106 | |||
107 | - st,powerdown-delay-divider: | ||
108 | If present, the bridge power-down time will be divided by the provided | ||
109 | value. If not specified, a divider of 1 will be used. Allowed values | ||
110 | are 1, 2, 4, 8, 16, 32, 64 and 128. | ||
111 | This property has to be specified as '/bits/ 8' value. | ||
112 | |||
113 | Example: | ||
114 | |||
115 | codec: sta350@38 { | ||
116 | compatible = "st,sta350"; | ||
117 | reg = <0x1c>; | ||
118 | reset-gpios = <&gpio1 19 0>; | ||
119 | power-down-gpios = <&gpio1 16 0>; | ||
120 | st,output-conf = /bits/ 8 <0x3>; // set output to 2-channel | ||
121 | // (full-bridge) power, | ||
122 | // 2-channel data-out | ||
123 | st,ch1-output-mapping = /bits/ 8 <0>; // set channel 1 output ch 1 | ||
124 | st,ch2-output-mapping = /bits/ 8 <0>; // set channel 2 output ch 1 | ||
125 | st,ch3-output-mapping = /bits/ 8 <0>; // set channel 3 output ch 1 | ||
126 | st,max-power-correction; // enables power bridge | ||
127 | // correction for THD reduction | ||
128 | // near maximum power output | ||
129 | st,invalid-input-detect-mute; // mute if no valid digital | ||
130 | // audio signal is provided. | ||
131 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 6846c7c622e3..8779dae65f63 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8256,6 +8256,7 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers) | |||
8256 | W: http://www.alsa-project.org/ | 8256 | W: http://www.alsa-project.org/ |
8257 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git | 8257 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
8258 | T: git git://git.alsa-project.org/alsa-kernel.git | 8258 | T: git git://git.alsa-project.org/alsa-kernel.git |
8259 | Q: http://patchwork.kernel.org/project/alsa-devel/list/ | ||
8259 | S: Maintained | 8260 | S: Maintained |
8260 | F: Documentation/sound/ | 8261 | F: Documentation/sound/ |
8261 | F: include/sound/ | 8262 | F: include/sound/ |
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index 618e5b537eaf..10b326bdf831 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi | |||
@@ -673,7 +673,7 @@ | |||
673 | renesas,clock-indices = < | 673 | renesas,clock-indices = < |
674 | R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 | 674 | R8A7790_CLK_TMU1 R8A7790_CLK_TMU3 R8A7790_CLK_TMU2 |
675 | R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 | 675 | R8A7790_CLK_CMT0 R8A7790_CLK_TMU0 R8A7790_CLK_VSP1_DU1 |
676 | R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_RT R8A7790_CLK_VSP1_SY | 676 | R8A7790_CLK_VSP1_DU0 R8A7790_CLK_VSP1_R R8A7790_CLK_VSP1_S |
677 | >; | 677 | >; |
678 | clock-output-names = | 678 | clock-output-names = |
679 | "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", | 679 | "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", |
diff --git a/arch/arm/boot/dts/r8a7791.dtsi b/arch/arm/boot/dts/r8a7791.dtsi index 46181708e59c..aa1cba94196c 100644 --- a/arch/arm/boot/dts/r8a7791.dtsi +++ b/arch/arm/boot/dts/r8a7791.dtsi | |||
@@ -688,7 +688,7 @@ | |||
688 | renesas,clock-indices = < | 688 | renesas,clock-indices = < |
689 | R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 | 689 | R8A7791_CLK_TMU1 R8A7791_CLK_TMU3 R8A7791_CLK_TMU2 |
690 | R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 | 690 | R8A7791_CLK_CMT0 R8A7791_CLK_TMU0 R8A7791_CLK_VSP1_DU1 |
691 | R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_SY | 691 | R8A7791_CLK_VSP1_DU0 R8A7791_CLK_VSP1_S |
692 | >; | 692 | >; |
693 | clock-output-names = | 693 | clock-output-names = |
694 | "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", | 694 | "tmu1", "tmu3", "tmu2", "cmt0", "tmu0", "vsp1-du1", |
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 4caffc912a81..c12a1c50e9d2 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile | |||
@@ -21,8 +21,8 @@ obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o | |||
21 | obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o | 21 | obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o |
22 | 22 | ||
23 | # Clock objects | 23 | # Clock objects |
24 | ifndef CONFIG_COMMON_CLK | ||
25 | obj-y += clock.o | 24 | obj-y += clock.o |
25 | ifndef CONFIG_COMMON_CLK | ||
26 | obj-$(CONFIG_ARCH_SH7372) += clock-sh7372.o | 26 | obj-$(CONFIG_ARCH_SH7372) += clock-sh7372.o |
27 | obj-$(CONFIG_ARCH_SH73A0) += clock-sh73a0.o | 27 | obj-$(CONFIG_ARCH_SH73A0) += clock-sh73a0.o |
28 | obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o | 28 | obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o |
diff --git a/arch/arm/mach-shmobile/board-bockw.c b/arch/arm/mach-shmobile/board-bockw.c index b4122f8cb8d9..f444be2f241e 100644 --- a/arch/arm/mach-shmobile/board-bockw.c +++ b/arch/arm/mach-shmobile/board-bockw.c | |||
@@ -345,24 +345,39 @@ static struct rsnd_ssi_platform_info rsnd_ssi[] = { | |||
345 | RSND_SSI_UNUSED, /* SSI 0 */ | 345 | RSND_SSI_UNUSED, /* SSI 0 */ |
346 | RSND_SSI_UNUSED, /* SSI 1 */ | 346 | RSND_SSI_UNUSED, /* SSI 1 */ |
347 | RSND_SSI_UNUSED, /* SSI 2 */ | 347 | RSND_SSI_UNUSED, /* SSI 2 */ |
348 | RSND_SSI_SET(1, HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), RSND_SSI_PLAY), | 348 | RSND_SSI(HPBDMA_SLAVE_HPBIF3_TX, gic_iid(0x85), 0), |
349 | RSND_SSI_SET(2, HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE), | 349 | RSND_SSI(HPBDMA_SLAVE_HPBIF4_RX, gic_iid(0x85), RSND_SSI_CLK_PIN_SHARE), |
350 | RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), RSND_SSI_PLAY), | 350 | RSND_SSI(HPBDMA_SLAVE_HPBIF5_TX, gic_iid(0x86), 0), |
351 | RSND_SSI_SET(0, HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0), | 351 | RSND_SSI(HPBDMA_SLAVE_HPBIF6_RX, gic_iid(0x86), 0), |
352 | RSND_SSI_SET(3, HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), RSND_SSI_PLAY), | 352 | RSND_SSI(HPBDMA_SLAVE_HPBIF7_TX, gic_iid(0x86), 0), |
353 | RSND_SSI_SET(4, HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE), | 353 | RSND_SSI(HPBDMA_SLAVE_HPBIF8_RX, gic_iid(0x86), RSND_SSI_CLK_PIN_SHARE), |
354 | }; | 354 | }; |
355 | 355 | ||
356 | static struct rsnd_scu_platform_info rsnd_scu[9] = { | 356 | static struct rsnd_src_platform_info rsnd_src[9] = { |
357 | { .flags = 0, }, /* SRU 0 */ | 357 | RSND_SRC_UNUSED, /* SRU 0 */ |
358 | { .flags = 0, }, /* SRU 1 */ | 358 | RSND_SRC_UNUSED, /* SRU 1 */ |
359 | { .flags = 0, }, /* SRU 2 */ | 359 | RSND_SRC_UNUSED, /* SRU 2 */ |
360 | { .flags = RSND_SCU_USE_HPBIF, }, | 360 | RSND_SRC(0, 0), |
361 | { .flags = RSND_SCU_USE_HPBIF, }, | 361 | RSND_SRC(0, 0), |
362 | { .flags = RSND_SCU_USE_HPBIF, }, | 362 | RSND_SRC(0, 0), |
363 | { .flags = RSND_SCU_USE_HPBIF, }, | 363 | RSND_SRC(0, 0), |
364 | { .flags = RSND_SCU_USE_HPBIF, }, | 364 | RSND_SRC(0, 0), |
365 | { .flags = RSND_SCU_USE_HPBIF, }, | 365 | RSND_SRC(0, 0), |
366 | }; | ||
367 | |||
368 | static struct rsnd_dai_platform_info rsnd_dai[] = { | ||
369 | { | ||
370 | .playback = { .ssi = &rsnd_ssi[5], .src = &rsnd_src[5] }, | ||
371 | .capture = { .ssi = &rsnd_ssi[6], .src = &rsnd_src[6] }, | ||
372 | }, { | ||
373 | .playback = { .ssi = &rsnd_ssi[3], .src = &rsnd_src[3] }, | ||
374 | }, { | ||
375 | .capture = { .ssi = &rsnd_ssi[4], .src = &rsnd_src[4] }, | ||
376 | }, { | ||
377 | .playback = { .ssi = &rsnd_ssi[7], .src = &rsnd_src[7] }, | ||
378 | }, { | ||
379 | .capture = { .ssi = &rsnd_ssi[8], .src = &rsnd_src[8] }, | ||
380 | }, | ||
366 | }; | 381 | }; |
367 | 382 | ||
368 | enum { | 383 | enum { |
@@ -437,8 +452,10 @@ static struct rcar_snd_info rsnd_info = { | |||
437 | .flags = RSND_GEN1, | 452 | .flags = RSND_GEN1, |
438 | .ssi_info = rsnd_ssi, | 453 | .ssi_info = rsnd_ssi, |
439 | .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), | 454 | .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), |
440 | .scu_info = rsnd_scu, | 455 | .src_info = rsnd_src, |
441 | .scu_info_nr = ARRAY_SIZE(rsnd_scu), | 456 | .src_info_nr = ARRAY_SIZE(rsnd_src), |
457 | .dai_info = rsnd_dai, | ||
458 | .dai_info_nr = ARRAY_SIZE(rsnd_dai), | ||
442 | .start = rsnd_start, | 459 | .start = rsnd_start, |
443 | .stop = rsnd_stop, | 460 | .stop = rsnd_stop, |
444 | }; | 461 | }; |
@@ -591,6 +608,7 @@ static void __init bockw_init(void) | |||
591 | { | 608 | { |
592 | void __iomem *base; | 609 | void __iomem *base; |
593 | struct clk *clk; | 610 | struct clk *clk; |
611 | struct platform_device *pdev; | ||
594 | int i; | 612 | int i; |
595 | 613 | ||
596 | r8a7778_clock_init(); | 614 | r8a7778_clock_init(); |
@@ -673,9 +691,6 @@ static void __init bockw_init(void) | |||
673 | } | 691 | } |
674 | 692 | ||
675 | /* for Audio */ | 693 | /* for Audio */ |
676 | clk = clk_get(NULL, "audio_clk_b"); | ||
677 | clk_set_rate(clk, 24576000); | ||
678 | clk_put(clk); | ||
679 | rsnd_codec_power(5, 1); /* enable ak4642 */ | 694 | rsnd_codec_power(5, 1); /* enable ak4642 */ |
680 | 695 | ||
681 | platform_device_register_simple( | 696 | platform_device_register_simple( |
@@ -684,11 +699,15 @@ static void __init bockw_init(void) | |||
684 | platform_device_register_simple( | 699 | platform_device_register_simple( |
685 | "ak4554-adc-dac", 1, NULL, 0); | 700 | "ak4554-adc-dac", 1, NULL, 0); |
686 | 701 | ||
687 | platform_device_register_resndata( | 702 | pdev = platform_device_register_resndata( |
688 | &platform_bus, "rcar_sound", -1, | 703 | &platform_bus, "rcar_sound", -1, |
689 | rsnd_resources, ARRAY_SIZE(rsnd_resources), | 704 | rsnd_resources, ARRAY_SIZE(rsnd_resources), |
690 | &rsnd_info, sizeof(rsnd_info)); | 705 | &rsnd_info, sizeof(rsnd_info)); |
691 | 706 | ||
707 | clk = clk_get(&pdev->dev, "clk_b"); | ||
708 | clk_set_rate(clk, 24576000); | ||
709 | clk_put(clk); | ||
710 | |||
692 | for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { | 711 | for (i = 0; i < ARRAY_SIZE(rsnd_card_info); i++) { |
693 | struct platform_device_info cardinfo = { | 712 | struct platform_device_info cardinfo = { |
694 | .parent = &platform_bus, | 713 | .parent = &platform_bus, |
diff --git a/arch/arm/mach-shmobile/board-koelsch-reference.c b/arch/arm/mach-shmobile/board-koelsch-reference.c index a3fd30242bd8..941f8b394e84 100644 --- a/arch/arm/mach-shmobile/board-koelsch-reference.c +++ b/arch/arm/mach-shmobile/board-koelsch-reference.c | |||
@@ -19,12 +19,11 @@ | |||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/clk.h> | ||
23 | #include <linux/clkdev.h> | ||
24 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
25 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
26 | #include <linux/of_platform.h> | 24 | #include <linux/of_platform.h> |
27 | #include <linux/platform_data/rcar-du.h> | 25 | #include <linux/platform_data/rcar-du.h> |
26 | #include <mach/clock.h> | ||
28 | #include <mach/common.h> | 27 | #include <mach/common.h> |
29 | #include <mach/irqs.h> | 28 | #include <mach/irqs.h> |
30 | #include <mach/rcar-gen2.h> | 29 | #include <mach/rcar-gen2.h> |
@@ -82,49 +81,50 @@ static void __init koelsch_add_du_device(void) | |||
82 | platform_device_register_full(&info); | 81 | platform_device_register_full(&info); |
83 | } | 82 | } |
84 | 83 | ||
85 | static void __init koelsch_add_standard_devices(void) | 84 | /* |
86 | { | 85 | * This is a really crude hack to provide clkdev support to platform |
87 | /* | 86 | * devices until they get moved to DT. |
88 | * This is a really crude hack to provide clkdev support to the CMT and | 87 | */ |
89 | * DU devices until they get moved to DT. | 88 | static const struct clk_name clk_names[] __initconst = { |
90 | */ | 89 | { "cmt0", NULL, "sh_cmt.0" }, |
91 | static const struct clk_name { | 90 | { "scifa0", NULL, "sh-sci.0" }, |
92 | const char *clk; | 91 | { "scifa1", NULL, "sh-sci.1" }, |
93 | const char *con_id; | 92 | { "scifb0", NULL, "sh-sci.2" }, |
94 | const char *dev_id; | 93 | { "scifb1", NULL, "sh-sci.3" }, |
95 | } clk_names[] = { | 94 | { "scifb2", NULL, "sh-sci.4" }, |
96 | { "cmt0", NULL, "sh_cmt.0" }, | 95 | { "scifa2", NULL, "sh-sci.5" }, |
97 | { "scifa0", NULL, "sh-sci.0" }, | 96 | { "scif0", NULL, "sh-sci.6" }, |
98 | { "scifa1", NULL, "sh-sci.1" }, | 97 | { "scif1", NULL, "sh-sci.7" }, |
99 | { "scifb0", NULL, "sh-sci.2" }, | 98 | { "scif2", NULL, "sh-sci.8" }, |
100 | { "scifb1", NULL, "sh-sci.3" }, | 99 | { "scif3", NULL, "sh-sci.9" }, |
101 | { "scifb2", NULL, "sh-sci.4" }, | 100 | { "scif4", NULL, "sh-sci.10" }, |
102 | { "scifa2", NULL, "sh-sci.5" }, | 101 | { "scif5", NULL, "sh-sci.11" }, |
103 | { "scif0", NULL, "sh-sci.6" }, | 102 | { "scifa3", NULL, "sh-sci.12" }, |
104 | { "scif1", NULL, "sh-sci.7" }, | 103 | { "scifa4", NULL, "sh-sci.13" }, |
105 | { "scif2", NULL, "sh-sci.8" }, | 104 | { "scifa5", NULL, "sh-sci.14" }, |
106 | { "scif3", NULL, "sh-sci.9" }, | 105 | { "du0", "du.0", "rcar-du-r8a7791" }, |
107 | { "scif4", NULL, "sh-sci.10" }, | 106 | { "du1", "du.1", "rcar-du-r8a7791" }, |
108 | { "scif5", NULL, "sh-sci.11" }, | 107 | { "lvds0", "lvds.0", "rcar-du-r8a7791" }, |
109 | { "scifa3", NULL, "sh-sci.12" }, | 108 | }; |
110 | { "scifa4", NULL, "sh-sci.13" }, | ||
111 | { "scifa5", NULL, "sh-sci.14" }, | ||
112 | { "du0", "du.0", "rcar-du-r8a7791" }, | ||
113 | { "du1", "du.1", "rcar-du-r8a7791" }, | ||
114 | { "lvds0", "lvds.0", "rcar-du-r8a7791" }, | ||
115 | }; | ||
116 | struct clk *clk; | ||
117 | unsigned int i; | ||
118 | 109 | ||
119 | for (i = 0; i < ARRAY_SIZE(clk_names); ++i) { | 110 | /* |
120 | clk = clk_get(NULL, clk_names[i].clk); | 111 | * This is a really crude hack to work around core platform clock issues |
121 | if (!IS_ERR(clk)) { | 112 | */ |
122 | clk_register_clkdev(clk, clk_names[i].con_id, | 113 | static const struct clk_name clk_enables[] __initconst = { |
123 | clk_names[i].dev_id); | 114 | { "ether", NULL, "ee700000.ethernet" }, |
124 | clk_put(clk); | 115 | { "i2c2", NULL, "e6530000.i2c" }, |
125 | } | 116 | { "msiof0", NULL, "e6e20000.spi" }, |
126 | } | 117 | { "qspi_mod", NULL, "e6b10000.spi" }, |
118 | { "sdhi0", NULL, "ee100000.sd" }, | ||
119 | { "sdhi1", NULL, "ee140000.sd" }, | ||
120 | { "sdhi2", NULL, "ee160000.sd" }, | ||
121 | { "thermal", NULL, "e61f0000.thermal" }, | ||
122 | }; | ||
127 | 123 | ||
124 | static void __init koelsch_add_standard_devices(void) | ||
125 | { | ||
126 | shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); | ||
127 | shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true); | ||
128 | r8a7791_add_dt_devices(); | 128 | r8a7791_add_dt_devices(); |
129 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 129 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
130 | 130 | ||
diff --git a/arch/arm/mach-shmobile/board-koelsch.c b/arch/arm/mach-shmobile/board-koelsch.c index 5a034ff405d0..a12a9d3b4b6e 100644 --- a/arch/arm/mach-shmobile/board-koelsch.c +++ b/arch/arm/mach-shmobile/board-koelsch.c | |||
@@ -216,7 +216,7 @@ static const struct spi_board_info spi_info[] __initconst = { | |||
216 | { | 216 | { |
217 | .modalias = "m25p80", | 217 | .modalias = "m25p80", |
218 | .platform_data = &spi_flash_data, | 218 | .platform_data = &spi_flash_data, |
219 | .mode = SPI_MODE_0, | 219 | .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD, |
220 | .max_speed_hz = 30000000, | 220 | .max_speed_hz = 30000000, |
221 | .bus_num = 0, | 221 | .bus_num = 0, |
222 | .chip_select = 0, | 222 | .chip_select = 0, |
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c index 440aac36d693..1eb48cffb4c5 100644 --- a/arch/arm/mach-shmobile/board-lager-reference.c +++ b/arch/arm/mach-shmobile/board-lager-reference.c | |||
@@ -18,12 +18,11 @@ | |||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/clkdev.h> | ||
23 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
24 | #include <linux/init.h> | 22 | #include <linux/init.h> |
25 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
26 | #include <linux/platform_data/rcar-du.h> | 24 | #include <linux/platform_data/rcar-du.h> |
25 | #include <mach/clock.h> | ||
27 | #include <mach/common.h> | 26 | #include <mach/common.h> |
28 | #include <mach/irqs.h> | 27 | #include <mach/irqs.h> |
29 | #include <mach/rcar-gen2.h> | 28 | #include <mach/rcar-gen2.h> |
@@ -86,46 +85,46 @@ static void __init lager_add_du_device(void) | |||
86 | platform_device_register_full(&info); | 85 | platform_device_register_full(&info); |
87 | } | 86 | } |
88 | 87 | ||
89 | static void __init lager_add_standard_devices(void) | 88 | /* |
90 | { | 89 | * This is a really crude hack to provide clkdev support to platform |
91 | /* | 90 | * devices until they get moved to DT. |
92 | * This is a really crude hack to provide clkdev support to platform | 91 | */ |
93 | * devices until they get moved to DT. | 92 | static const struct clk_name clk_names[] __initconst = { |
94 | */ | 93 | { "cmt0", NULL, "sh_cmt.0" }, |
95 | static const struct clk_name { | 94 | { "scifa0", NULL, "sh-sci.0" }, |
96 | const char *clk; | 95 | { "scifa1", NULL, "sh-sci.1" }, |
97 | const char *con_id; | 96 | { "scifb0", NULL, "sh-sci.2" }, |
98 | const char *dev_id; | 97 | { "scifb1", NULL, "sh-sci.3" }, |
99 | } clk_names[] = { | 98 | { "scifb2", NULL, "sh-sci.4" }, |
100 | { "cmt0", NULL, "sh_cmt.0" }, | 99 | { "scifa2", NULL, "sh-sci.5" }, |
101 | { "scifa0", NULL, "sh-sci.0" }, | 100 | { "scif0", NULL, "sh-sci.6" }, |
102 | { "scifa1", NULL, "sh-sci.1" }, | 101 | { "scif1", NULL, "sh-sci.7" }, |
103 | { "scifb0", NULL, "sh-sci.2" }, | 102 | { "hscif0", NULL, "sh-sci.8" }, |
104 | { "scifb1", NULL, "sh-sci.3" }, | 103 | { "hscif1", NULL, "sh-sci.9" }, |
105 | { "scifb2", NULL, "sh-sci.4" }, | 104 | { "du0", "du.0", "rcar-du-r8a7790" }, |
106 | { "scifa2", NULL, "sh-sci.5" }, | 105 | { "du1", "du.1", "rcar-du-r8a7790" }, |
107 | { "scif0", NULL, "sh-sci.6" }, | 106 | { "du2", "du.2", "rcar-du-r8a7790" }, |
108 | { "scif1", NULL, "sh-sci.7" }, | 107 | { "lvds0", "lvds.0", "rcar-du-r8a7790" }, |
109 | { "hscif0", NULL, "sh-sci.8" }, | 108 | { "lvds1", "lvds.1", "rcar-du-r8a7790" }, |
110 | { "hscif1", NULL, "sh-sci.9" }, | 109 | }; |
111 | { "du0", "du.0", "rcar-du-r8a7790" }, | ||
112 | { "du1", "du.1", "rcar-du-r8a7790" }, | ||
113 | { "du2", "du.2", "rcar-du-r8a7790" }, | ||
114 | { "lvds0", "lvds.0", "rcar-du-r8a7790" }, | ||
115 | { "lvds1", "lvds.1", "rcar-du-r8a7790" }, | ||
116 | }; | ||
117 | struct clk *clk; | ||
118 | unsigned int i; | ||
119 | 110 | ||
120 | for (i = 0; i < ARRAY_SIZE(clk_names); ++i) { | 111 | /* |
121 | clk = clk_get(NULL, clk_names[i].clk); | 112 | * This is a really crude hack to work around core platform clock issues |
122 | if (!IS_ERR(clk)) { | 113 | */ |
123 | clk_register_clkdev(clk, clk_names[i].con_id, | 114 | static const struct clk_name clk_enables[] __initconst = { |
124 | clk_names[i].dev_id); | 115 | { "ether", NULL, "ee700000.ethernet" }, |
125 | clk_put(clk); | 116 | { "msiof1", NULL, "e6e10000.spi" }, |
126 | } | 117 | { "mmcif1", NULL, "ee220000.mmc" }, |
127 | } | 118 | { "qspi_mod", NULL, "e6b10000.spi" }, |
119 | { "sdhi0", NULL, "ee100000.sd" }, | ||
120 | { "sdhi2", NULL, "ee140000.sd" }, | ||
121 | { "thermal", NULL, "e61f0000.thermal" }, | ||
122 | }; | ||
128 | 123 | ||
124 | static void __init lager_add_standard_devices(void) | ||
125 | { | ||
126 | shmobile_clk_workaround(clk_names, ARRAY_SIZE(clk_names), false); | ||
127 | shmobile_clk_workaround(clk_enables, ARRAY_SIZE(clk_enables), true); | ||
129 | r8a7790_add_dt_devices(); | 128 | r8a7790_add_dt_devices(); |
130 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); | 129 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
131 | 130 | ||
diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 18c7e0311aa6..f8b1e05463cc 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c | |||
@@ -325,12 +325,12 @@ static const struct rspi_plat_data qspi_pdata __initconst = { | |||
325 | 325 | ||
326 | static const struct spi_board_info spi_info[] __initconst = { | 326 | static const struct spi_board_info spi_info[] __initconst = { |
327 | { | 327 | { |
328 | .modalias = "m25p80", | 328 | .modalias = "m25p80", |
329 | .platform_data = &spi_flash_data, | 329 | .platform_data = &spi_flash_data, |
330 | .mode = SPI_MODE_0, | 330 | .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD, |
331 | .max_speed_hz = 30000000, | 331 | .max_speed_hz = 30000000, |
332 | .bus_num = 0, | 332 | .bus_num = 0, |
333 | .chip_select = 0, | 333 | .chip_select = 0, |
334 | }, | 334 | }, |
335 | }; | 335 | }; |
336 | 336 | ||
@@ -567,20 +567,27 @@ static struct resource rsnd_resources[] __initdata = { | |||
567 | }; | 567 | }; |
568 | 568 | ||
569 | static struct rsnd_ssi_platform_info rsnd_ssi[] = { | 569 | static struct rsnd_ssi_platform_info rsnd_ssi[] = { |
570 | RSND_SSI_SET(0, 0, gic_spi(370), RSND_SSI_PLAY), | 570 | RSND_SSI(0, gic_spi(370), 0), |
571 | RSND_SSI_SET(0, 0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE), | 571 | RSND_SSI(0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE), |
572 | }; | 572 | }; |
573 | 573 | ||
574 | static struct rsnd_scu_platform_info rsnd_scu[2] = { | 574 | static struct rsnd_src_platform_info rsnd_src[2] = { |
575 | /* no member at this point */ | 575 | /* no member at this point */ |
576 | }; | 576 | }; |
577 | 577 | ||
578 | static struct rsnd_dai_platform_info rsnd_dai = { | ||
579 | .playback = { .ssi = &rsnd_ssi[0], }, | ||
580 | .capture = { .ssi = &rsnd_ssi[1], }, | ||
581 | }; | ||
582 | |||
578 | static struct rcar_snd_info rsnd_info = { | 583 | static struct rcar_snd_info rsnd_info = { |
579 | .flags = RSND_GEN2, | 584 | .flags = RSND_GEN2, |
580 | .ssi_info = rsnd_ssi, | 585 | .ssi_info = rsnd_ssi, |
581 | .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), | 586 | .ssi_info_nr = ARRAY_SIZE(rsnd_ssi), |
582 | .scu_info = rsnd_scu, | 587 | .src_info = rsnd_src, |
583 | .scu_info_nr = ARRAY_SIZE(rsnd_scu), | 588 | .src_info_nr = ARRAY_SIZE(rsnd_src), |
589 | .dai_info = &rsnd_dai, | ||
590 | .dai_info_nr = 1, | ||
584 | }; | 591 | }; |
585 | 592 | ||
586 | static struct asoc_simple_card_info rsnd_card_info = { | 593 | static struct asoc_simple_card_info rsnd_card_info = { |
diff --git a/arch/arm/mach-shmobile/clock-r8a7778.c b/arch/arm/mach-shmobile/clock-r8a7778.c index 9989b1b06ffd..6609beb9b9b4 100644 --- a/arch/arm/mach-shmobile/clock-r8a7778.c +++ b/arch/arm/mach-shmobile/clock-r8a7778.c | |||
@@ -175,10 +175,6 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
175 | 175 | ||
176 | static struct clk_lookup lookups[] = { | 176 | static struct clk_lookup lookups[] = { |
177 | /* main */ | 177 | /* main */ |
178 | CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), | ||
179 | CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), | ||
180 | CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), | ||
181 | CLKDEV_CON_ID("audio_clk_internal", &s1_clk), | ||
182 | CLKDEV_CON_ID("shyway_clk", &s_clk), | 178 | CLKDEV_CON_ID("shyway_clk", &s_clk), |
183 | CLKDEV_CON_ID("peripheral_clk", &p_clk), | 179 | CLKDEV_CON_ID("peripheral_clk", &p_clk), |
184 | 180 | ||
@@ -234,15 +230,15 @@ static struct clk_lookup lookups[] = { | |||
234 | CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), | 230 | CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP309]), |
235 | CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), | 231 | CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP308]), |
236 | CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), | 232 | CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP307]), |
237 | CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP531]), | 233 | CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP531]), |
238 | CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP530]), | 234 | CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP530]), |
239 | CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP529]), | 235 | CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP529]), |
240 | CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP528]), | 236 | CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP528]), |
241 | CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP527]), | 237 | CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP527]), |
242 | CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP526]), | 238 | CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP526]), |
243 | CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP525]), | 239 | CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP525]), |
244 | CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP524]), | 240 | CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP524]), |
245 | CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP523]), | 241 | CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP523]), |
246 | }; | 242 | }; |
247 | 243 | ||
248 | void __init r8a7778_clock_init(void) | 244 | void __init r8a7778_clock_init(void) |
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index 3f93503f5b96..a936ae7de083 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c | |||
@@ -249,10 +249,10 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
249 | [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */ | 249 | [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */ |
250 | [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */ | 250 | [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */ |
251 | [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */ | 251 | [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */ |
252 | [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ | 252 | [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ |
253 | [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ | 253 | [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ |
254 | [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ | 254 | [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ |
255 | [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ | 255 | [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ |
256 | [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ | 256 | [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ |
257 | [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ | 257 | [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ |
258 | [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ | 258 | [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ |
@@ -294,10 +294,6 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
294 | static struct clk_lookup lookups[] = { | 294 | static struct clk_lookup lookups[] = { |
295 | 295 | ||
296 | /* main clocks */ | 296 | /* main clocks */ |
297 | CLKDEV_CON_ID("audio_clk_a", &audio_clk_a), | ||
298 | CLKDEV_CON_ID("audio_clk_b", &audio_clk_b), | ||
299 | CLKDEV_CON_ID("audio_clk_c", &audio_clk_c), | ||
300 | CLKDEV_CON_ID("audio_clk_internal", &m2_clk), | ||
301 | CLKDEV_CON_ID("extal", &extal_clk), | 297 | CLKDEV_CON_ID("extal", &extal_clk), |
302 | CLKDEV_CON_ID("extal_div2", &extal_div2_clk), | 298 | CLKDEV_CON_ID("extal_div2", &extal_div2_clk), |
303 | CLKDEV_CON_ID("main", &main_clk), | 299 | CLKDEV_CON_ID("main", &main_clk), |
@@ -381,16 +377,16 @@ static struct clk_lookup lookups[] = { | |||
381 | CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), | 377 | CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b), |
382 | CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), | 378 | CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c), |
383 | CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk), | 379 | CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk), |
384 | CLKDEV_ICK_ID("scu.0", "rcar_sound", &mstp_clks[MSTP1031]), | 380 | CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP1031]), |
385 | CLKDEV_ICK_ID("scu.1", "rcar_sound", &mstp_clks[MSTP1030]), | 381 | CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP1030]), |
386 | CLKDEV_ICK_ID("scu.2", "rcar_sound", &mstp_clks[MSTP1029]), | 382 | CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP1029]), |
387 | CLKDEV_ICK_ID("scu.3", "rcar_sound", &mstp_clks[MSTP1028]), | 383 | CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP1028]), |
388 | CLKDEV_ICK_ID("scu.4", "rcar_sound", &mstp_clks[MSTP1027]), | 384 | CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP1027]), |
389 | CLKDEV_ICK_ID("scu.5", "rcar_sound", &mstp_clks[MSTP1026]), | 385 | CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP1026]), |
390 | CLKDEV_ICK_ID("scu.6", "rcar_sound", &mstp_clks[MSTP1025]), | 386 | CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP1025]), |
391 | CLKDEV_ICK_ID("scu.7", "rcar_sound", &mstp_clks[MSTP1024]), | 387 | CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP1024]), |
392 | CLKDEV_ICK_ID("scu.8", "rcar_sound", &mstp_clks[MSTP1023]), | 388 | CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP1023]), |
393 | CLKDEV_ICK_ID("scu.9", "rcar_sound", &mstp_clks[MSTP1022]), | 389 | CLKDEV_ICK_ID("src.9", "rcar_sound", &mstp_clks[MSTP1022]), |
394 | CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]), | 390 | CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]), |
395 | CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]), | 391 | CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]), |
396 | CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]), | 392 | CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]), |
diff --git a/arch/arm/mach-shmobile/clock-r8a7791.c b/arch/arm/mach-shmobile/clock-r8a7791.c index 701383fe3267..3b26c7eee873 100644 --- a/arch/arm/mach-shmobile/clock-r8a7791.c +++ b/arch/arm/mach-shmobile/clock-r8a7791.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/clkdev.h> | 25 | #include <linux/clkdev.h> |
26 | #include <mach/clock.h> | 26 | #include <mach/clock.h> |
27 | #include <mach/common.h> | 27 | #include <mach/common.h> |
28 | #include <mach/rcar-gen2.h> | ||
28 | 29 | ||
29 | /* | 30 | /* |
30 | * MD EXTAL PLL0 PLL1 PLL3 | 31 | * MD EXTAL PLL0 PLL1 PLL3 |
@@ -43,8 +44,6 @@ | |||
43 | * see "p1 / 2" on R8A7791_CLOCK_ROOT() below | 44 | * see "p1 / 2" on R8A7791_CLOCK_ROOT() below |
44 | */ | 45 | */ |
45 | 46 | ||
46 | #define MD(nr) (1 << nr) | ||
47 | |||
48 | #define CPG_BASE 0xe6150000 | 47 | #define CPG_BASE 0xe6150000 |
49 | #define CPG_LEN 0x1000 | 48 | #define CPG_LEN 0x1000 |
50 | 49 | ||
@@ -68,7 +67,6 @@ | |||
68 | #define MSTPSR9 IOMEM(0xe61509a4) | 67 | #define MSTPSR9 IOMEM(0xe61509a4) |
69 | #define MSTPSR11 IOMEM(0xe61509ac) | 68 | #define MSTPSR11 IOMEM(0xe61509ac) |
70 | 69 | ||
71 | #define MODEMR 0xE6160060 | ||
72 | #define SDCKCR 0xE6150074 | 70 | #define SDCKCR 0xE6150074 |
73 | #define SD1CKCR 0xE6150078 | 71 | #define SD1CKCR 0xE6150078 |
74 | #define SD2CKCR 0xE615026c | 72 | #define SD2CKCR 0xE615026c |
@@ -190,12 +188,12 @@ static struct clk mstp_clks[MSTP_NR] = { | |||
190 | [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */ | 188 | [MSTP1108] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 8, MSTPSR11, 0), /* SCIFA5 */ |
191 | [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */ | 189 | [MSTP1107] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 7, MSTPSR11, 0), /* SCIFA4 */ |
192 | [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */ | 190 | [MSTP1106] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR11, 6, MSTPSR11, 0), /* SCIFA3 */ |
193 | [MSTP931] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ | 191 | [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */ |
194 | [MSTP930] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ | 192 | [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */ |
195 | [MSTP929] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ | 193 | [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */ |
196 | [MSTP928] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ | 194 | [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */ |
197 | [MSTP927] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */ | 195 | [MSTP927] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 27, MSTPSR9, 0), /* I2C4 */ |
198 | [MSTP925] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */ | 196 | [MSTP925] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 25, MSTPSR9, 0), /* I2C5 */ |
199 | [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ | 197 | [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */ |
200 | [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ | 198 | [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */ |
201 | [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ | 199 | [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */ |
@@ -295,14 +293,9 @@ static struct clk_lookup lookups[] = { | |||
295 | 293 | ||
296 | void __init r8a7791_clock_init(void) | 294 | void __init r8a7791_clock_init(void) |
297 | { | 295 | { |
298 | void __iomem *modemr = ioremap_nocache(MODEMR, PAGE_SIZE); | 296 | u32 mode = rcar_gen2_read_mode_pins(); |
299 | u32 mode; | ||
300 | int k, ret = 0; | 297 | int k, ret = 0; |
301 | 298 | ||
302 | BUG_ON(!modemr); | ||
303 | mode = ioread32(modemr); | ||
304 | iounmap(modemr); | ||
305 | |||
306 | switch (mode & (MD(14) | MD(13))) { | 299 | switch (mode & (MD(14) | MD(13))) { |
307 | case 0: | 300 | case 0: |
308 | R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); | 301 | R8A7791_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88); |
diff --git a/arch/arm/mach-shmobile/clock.c b/arch/arm/mach-shmobile/clock.c index ad7df629d995..e7232a0373b9 100644 --- a/arch/arm/mach-shmobile/clock.c +++ b/arch/arm/mach-shmobile/clock.c | |||
@@ -21,6 +21,32 @@ | |||
21 | */ | 21 | */ |
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | |||
25 | #ifdef CONFIG_COMMON_CLK | ||
26 | #include <linux/clk.h> | ||
27 | #include <linux/clkdev.h> | ||
28 | #include <mach/clock.h> | ||
29 | |||
30 | void __init shmobile_clk_workaround(const struct clk_name *clks, | ||
31 | int nr_clks, bool enable) | ||
32 | { | ||
33 | const struct clk_name *clkn; | ||
34 | struct clk *clk; | ||
35 | unsigned int i; | ||
36 | |||
37 | for (i = 0; i < nr_clks; ++i) { | ||
38 | clkn = clks + i; | ||
39 | clk = clk_get(NULL, clkn->clk); | ||
40 | if (!IS_ERR(clk)) { | ||
41 | clk_register_clkdev(clk, clkn->con_id, clkn->dev_id); | ||
42 | if (enable) | ||
43 | clk_prepare_enable(clk); | ||
44 | clk_put(clk); | ||
45 | } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | #else /* CONFIG_COMMON_CLK */ | ||
24 | #include <linux/sh_clk.h> | 50 | #include <linux/sh_clk.h> |
25 | #include <linux/export.h> | 51 | #include <linux/export.h> |
26 | #include <mach/clock.h> | 52 | #include <mach/clock.h> |
@@ -58,3 +84,5 @@ void __clk_put(struct clk *clk) | |||
58 | { | 84 | { |
59 | } | 85 | } |
60 | EXPORT_SYMBOL(__clk_put); | 86 | EXPORT_SYMBOL(__clk_put); |
87 | |||
88 | #endif /* CONFIG_COMMON_CLK */ | ||
diff --git a/arch/arm/mach-shmobile/include/mach/clock.h b/arch/arm/mach-shmobile/include/mach/clock.h index 03e56074928c..9a93cf924b9c 100644 --- a/arch/arm/mach-shmobile/include/mach/clock.h +++ b/arch/arm/mach-shmobile/include/mach/clock.h | |||
@@ -1,6 +1,21 @@ | |||
1 | #ifndef CLOCK_H | 1 | #ifndef CLOCK_H |
2 | #define CLOCK_H | 2 | #define CLOCK_H |
3 | 3 | ||
4 | #ifdef CONFIG_COMMON_CLK | ||
5 | /* temporary clock configuration helper for platform devices */ | ||
6 | |||
7 | struct clk_name { | ||
8 | const char *clk; | ||
9 | const char *con_id; | ||
10 | const char *dev_id; | ||
11 | }; | ||
12 | |||
13 | void shmobile_clk_workaround(const struct clk_name *clks, int nr_clks, | ||
14 | bool enable); | ||
15 | |||
16 | #else /* CONFIG_COMMON_CLK */ | ||
17 | /* legacy clock implementation */ | ||
18 | |||
4 | unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk); | 19 | unsigned long shmobile_fixed_ratio_clk_recalc(struct clk *clk); |
5 | extern struct sh_clk_ops shmobile_fixed_ratio_clk_ops; | 20 | extern struct sh_clk_ops shmobile_fixed_ratio_clk_ops; |
6 | 21 | ||
@@ -36,4 +51,5 @@ do { \ | |||
36 | (p)->div = d; \ | 51 | (p)->div = d; \ |
37 | } while (0) | 52 | } while (0) |
38 | 53 | ||
54 | #endif /* CONFIG_COMMON_CLK */ | ||
39 | #endif | 55 | #endif |
diff --git a/arch/mips/include/asm/mach-jz4740/dma.h b/arch/mips/include/asm/mach-jz4740/dma.h index 509cd5828044..14ecc5313d2d 100644 --- a/arch/mips/include/asm/mach-jz4740/dma.h +++ b/arch/mips/include/asm/mach-jz4740/dma.h | |||
@@ -22,8 +22,6 @@ enum jz4740_dma_request_type { | |||
22 | JZ4740_DMA_TYPE_UART_RECEIVE = 21, | 22 | JZ4740_DMA_TYPE_UART_RECEIVE = 21, |
23 | JZ4740_DMA_TYPE_SPI_TRANSMIT = 22, | 23 | JZ4740_DMA_TYPE_SPI_TRANSMIT = 22, |
24 | JZ4740_DMA_TYPE_SPI_RECEIVE = 23, | 24 | JZ4740_DMA_TYPE_SPI_RECEIVE = 23, |
25 | JZ4740_DMA_TYPE_AIC_TRANSMIT = 24, | ||
26 | JZ4740_DMA_TYPE_AIC_RECEIVE = 25, | ||
27 | JZ4740_DMA_TYPE_MMC_TRANSMIT = 26, | 25 | JZ4740_DMA_TYPE_MMC_TRANSMIT = 26, |
28 | JZ4740_DMA_TYPE_MMC_RECEIVE = 27, | 26 | JZ4740_DMA_TYPE_MMC_RECEIVE = 27, |
29 | JZ4740_DMA_TYPE_TCU = 28, | 27 | JZ4740_DMA_TYPE_TCU = 28, |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index c01900e5d078..088e92a79ae6 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -425,6 +425,15 @@ static struct platform_device qi_lb60_audio_device = { | |||
425 | .id = -1, | 425 | .id = -1, |
426 | }; | 426 | }; |
427 | 427 | ||
428 | static struct gpiod_lookup_table qi_lb60_audio_gpio_table = { | ||
429 | .dev_id = "qi-lb60-audio", | ||
430 | .table = { | ||
431 | GPIO_LOOKUP("Bank B", 29, "snd", 0), | ||
432 | GPIO_LOOKUP("Bank D", 4, "amp", 0), | ||
433 | { }, | ||
434 | }, | ||
435 | }; | ||
436 | |||
428 | static struct platform_device *jz_platform_devices[] __initdata = { | 437 | static struct platform_device *jz_platform_devices[] __initdata = { |
429 | &jz4740_udc_device, | 438 | &jz4740_udc_device, |
430 | &jz4740_udc_xceiv_device, | 439 | &jz4740_udc_xceiv_device, |
@@ -461,6 +470,8 @@ static int __init qi_lb60_init_platform_devices(void) | |||
461 | jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata; | 470 | jz4740_adc_device.dev.platform_data = &qi_lb60_battery_pdata; |
462 | jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata; | 471 | jz4740_mmc_device.dev.platform_data = &qi_lb60_mmc_pdata; |
463 | 472 | ||
473 | gpiod_add_lookup_table(&qi_lb60_audio_gpio_table); | ||
474 | |||
464 | jz4740_serial_device_register(); | 475 | jz4740_serial_device_register(); |
465 | 476 | ||
466 | spi_register_board_info(qi_lb60_spi_board_info, | 477 | spi_register_board_info(qi_lb60_spi_board_info, |
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index 06e64b6fcb89..0c6c21c5b1a8 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -673,9 +673,13 @@ int mc13xxx_common_init(struct device *dev) | |||
673 | if (mc13xxx->flags & MC13XXX_USE_ADC) | 673 | if (mc13xxx->flags & MC13XXX_USE_ADC) |
674 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); | 674 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); |
675 | 675 | ||
676 | if (mc13xxx->flags & MC13XXX_USE_CODEC) | 676 | if (mc13xxx->flags & MC13XXX_USE_CODEC) { |
677 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", | 677 | if (pdata) |
678 | pdata->codec, sizeof(*pdata->codec)); | 678 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", |
679 | pdata->codec, sizeof(*pdata->codec)); | ||
680 | else | ||
681 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); | ||
682 | } | ||
679 | 683 | ||
680 | if (mc13xxx->flags & MC13XXX_USE_RTC) | 684 | if (mc13xxx->flags & MC13XXX_USE_RTC) |
681 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | 685 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); |
diff --git a/include/dt-bindings/clock/r8a7790-clock.h b/include/dt-bindings/clock/r8a7790-clock.h index 6548a5fbcf4a..9a7c4c5a35d1 100644 --- a/include/dt-bindings/clock/r8a7790-clock.h +++ b/include/dt-bindings/clock/r8a7790-clock.h | |||
@@ -33,8 +33,8 @@ | |||
33 | #define R8A7790_CLK_TMU0 25 | 33 | #define R8A7790_CLK_TMU0 25 |
34 | #define R8A7790_CLK_VSP1_DU1 27 | 34 | #define R8A7790_CLK_VSP1_DU1 27 |
35 | #define R8A7790_CLK_VSP1_DU0 28 | 35 | #define R8A7790_CLK_VSP1_DU0 28 |
36 | #define R8A7790_CLK_VSP1_RT 30 | 36 | #define R8A7790_CLK_VSP1_R 30 |
37 | #define R8A7790_CLK_VSP1_SY 31 | 37 | #define R8A7790_CLK_VSP1_S 31 |
38 | 38 | ||
39 | /* MSTP2 */ | 39 | /* MSTP2 */ |
40 | #define R8A7790_CLK_SCIFA2 2 | 40 | #define R8A7790_CLK_SCIFA2 2 |
diff --git a/include/dt-bindings/clock/r8a7791-clock.h b/include/dt-bindings/clock/r8a7791-clock.h index 30f82f286e29..f069bc6627cb 100644 --- a/include/dt-bindings/clock/r8a7791-clock.h +++ b/include/dt-bindings/clock/r8a7791-clock.h | |||
@@ -32,7 +32,7 @@ | |||
32 | #define R8A7791_CLK_TMU0 25 | 32 | #define R8A7791_CLK_TMU0 25 |
33 | #define R8A7791_CLK_VSP1_DU1 27 | 33 | #define R8A7791_CLK_VSP1_DU1 27 |
34 | #define R8A7791_CLK_VSP1_DU0 28 | 34 | #define R8A7791_CLK_VSP1_DU0 28 |
35 | #define R8A7791_CLK_VSP1_SY 31 | 35 | #define R8A7791_CLK_VSP1_S 31 |
36 | 36 | ||
37 | /* MSTP2 */ | 37 | /* MSTP2 */ |
38 | #define R8A7791_CLK_SCIFA2 2 | 38 | #define R8A7791_CLK_SCIFA2 2 |
diff --git a/include/sound/atmel-ac97c.h b/include/sound/atmel-ac97c.h index e6aabdb45865..00e6c289a936 100644 --- a/include/sound/atmel-ac97c.h +++ b/include/sound/atmel-ac97c.h | |||
@@ -23,7 +23,6 @@ | |||
23 | * @reset_pin: GPIO pin wired to the reset input on the external AC97 codec, | 23 | * @reset_pin: GPIO pin wired to the reset input on the external AC97 codec, |
24 | * optional to use, set to -ENODEV if not in use. AC97 layer will | 24 | * optional to use, set to -ENODEV if not in use. AC97 layer will |
25 | * try to do a software reset of the external codec anyway. | 25 | * try to do a software reset of the external codec anyway. |
26 | * @flags: Flags for which directions should be enabled. | ||
27 | * | 26 | * |
28 | * If the user do not want to use a DMA channel for playback or capture, i.e. | 27 | * If the user do not want to use a DMA channel for playback or capture, i.e. |
29 | * only one feature is required on the board. The slave for playback or capture | 28 | * only one feature is required on the board. The slave for playback or capture |
@@ -33,7 +32,6 @@ | |||
33 | struct ac97c_platform_data { | 32 | struct ac97c_platform_data { |
34 | struct dw_dma_slave rx_dws; | 33 | struct dw_dma_slave rx_dws; |
35 | struct dw_dma_slave tx_dws; | 34 | struct dw_dma_slave tx_dws; |
36 | unsigned int flags; | ||
37 | int reset_pin; | 35 | int reset_pin; |
38 | }; | 36 | }; |
39 | 37 | ||
diff --git a/include/sound/core.h b/include/sound/core.h index d3f5f818e0b9..eedda2cdfe57 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -282,13 +282,6 @@ int snd_card_new(struct device *parent, int idx, const char *xid, | |||
282 | struct module *module, int extra_size, | 282 | struct module *module, int extra_size, |
283 | struct snd_card **card_ret); | 283 | struct snd_card **card_ret); |
284 | 284 | ||
285 | static inline int __deprecated | ||
286 | snd_card_create(int idx, const char *id, struct module *module, int extra_size, | ||
287 | struct snd_card **ret) | ||
288 | { | ||
289 | return snd_card_new(NULL, idx, id, module, extra_size, ret); | ||
290 | } | ||
291 | |||
292 | int snd_card_disconnect(struct snd_card *card); | 285 | int snd_card_disconnect(struct snd_card *card); |
293 | int snd_card_free(struct snd_card *card); | 286 | int snd_card_free(struct snd_card *card); |
294 | int snd_card_free_when_closed(struct snd_card *card); | 287 | int snd_card_free_when_closed(struct snd_card *card); |
diff --git a/include/sound/cs42l56.h b/include/sound/cs42l56.h new file mode 100644 index 000000000000..2467c8ff132c --- /dev/null +++ b/include/sound/cs42l56.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /* | ||
2 | * linux/sound/cs42l56.h -- Platform data for CS42L56 | ||
3 | * | ||
4 | * Copyright (c) 2014 Cirrus Logic Inc. | ||
5 | * | ||
6 | * This program 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 | |||
11 | #ifndef __CS42L56_H | ||
12 | #define __CS42L56_H | ||
13 | |||
14 | struct cs42l56_platform_data { | ||
15 | |||
16 | /* GPIO for Reset */ | ||
17 | unsigned int gpio_nreset; | ||
18 | |||
19 | /* MICBIAS Level. Check datasheet Pg48 */ | ||
20 | unsigned int micbias_lvl; | ||
21 | |||
22 | /* Analog Input 1A Reference 0=Single 1=Pseudo-Differential */ | ||
23 | unsigned int ain1a_ref_cfg; | ||
24 | |||
25 | /* Analog Input 2A Reference 0=Single 1=Pseudo-Differential */ | ||
26 | unsigned int ain2a_ref_cfg; | ||
27 | |||
28 | /* Analog Input 1B Reference 0=Single 1=Pseudo-Differential */ | ||
29 | unsigned int ain1b_ref_cfg; | ||
30 | |||
31 | /* Analog Input 2B Reference 0=Single 1=Pseudo-Differential */ | ||
32 | unsigned int ain2b_ref_cfg; | ||
33 | |||
34 | /* Charge Pump Freq. Check datasheet Pg62 */ | ||
35 | unsigned int chgfreq; | ||
36 | |||
37 | /* HighPass Filter Right Channel Corner Frequency */ | ||
38 | unsigned int hpfb_freq; | ||
39 | |||
40 | /* HighPass Filter Left Channel Corner Frequency */ | ||
41 | unsigned int hpfa_freq; | ||
42 | |||
43 | /* Adaptive Power Control for LO/HP */ | ||
44 | unsigned int adaptive_pwr; | ||
45 | |||
46 | }; | ||
47 | |||
48 | #endif /* __CS42L56_H */ | ||
diff --git a/include/sound/rcar_snd.h b/include/sound/rcar_snd.h index 34a3c02a4576..f4a706f82cb7 100644 --- a/include/sound/rcar_snd.h +++ b/include/sound/rcar_snd.h | |||
@@ -34,47 +34,39 @@ | |||
34 | * B : SSI direction | 34 | * B : SSI direction |
35 | */ | 35 | */ |
36 | #define RSND_SSI_CLK_PIN_SHARE (1 << 31) | 36 | #define RSND_SSI_CLK_PIN_SHARE (1 << 31) |
37 | #define RSND_SSI_PLAY (1 << 24) | ||
38 | 37 | ||
39 | #define RSND_SSI(_dma_id, _pio_irq, _flags) \ | 38 | #define RSND_SSI(_dma_id, _pio_irq, _flags) \ |
40 | { .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } | 39 | { .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } |
41 | #define RSND_SSI_SET(_dai_id, _dma_id, _pio_irq, _flags) \ | ||
42 | { .dai_id = _dai_id, .dma_id = _dma_id, .pio_irq = _pio_irq, .flags = _flags } | ||
43 | #define RSND_SSI_UNUSED \ | 40 | #define RSND_SSI_UNUSED \ |
44 | { .dai_id = -1, .dma_id = -1, .pio_irq = -1, .flags = 0 } | 41 | { .dma_id = -1, .pio_irq = -1, .flags = 0 } |
45 | 42 | ||
46 | struct rsnd_ssi_platform_info { | 43 | struct rsnd_ssi_platform_info { |
47 | int dai_id; /* will be removed */ | ||
48 | int dma_id; | 44 | int dma_id; |
49 | int pio_irq; | 45 | int pio_irq; |
50 | u32 flags; | 46 | u32 flags; |
51 | }; | 47 | }; |
52 | 48 | ||
53 | /* | ||
54 | * flags | ||
55 | */ | ||
56 | #define RSND_SCU_USE_HPBIF (1 << 31) /* it needs RSND_SSI_DEPENDENT */ | ||
57 | |||
58 | #define RSND_SRC(rate, _dma_id) \ | 49 | #define RSND_SRC(rate, _dma_id) \ |
59 | { .flags = RSND_SCU_USE_HPBIF, .convert_rate = rate, .dma_id = _dma_id, } | 50 | { .convert_rate = rate, .dma_id = _dma_id, } |
60 | #define RSND_SRC_SET(rate, _dma_id) \ | ||
61 | { .flags = RSND_SCU_USE_HPBIF, .convert_rate = rate, .dma_id = _dma_id, } | ||
62 | #define RSND_SRC_UNUSED \ | 51 | #define RSND_SRC_UNUSED \ |
63 | { .flags = 0, .convert_rate = 0, .dma_id = 0, } | 52 | { .convert_rate = 0, .dma_id = -1, } |
64 | |||
65 | #define rsnd_scu_platform_info rsnd_src_platform_info | ||
66 | #define src_info scu_info | ||
67 | #define src_info_nr scu_info_nr | ||
68 | 53 | ||
69 | struct rsnd_src_platform_info { | 54 | struct rsnd_src_platform_info { |
70 | u32 flags; | ||
71 | u32 convert_rate; /* sampling rate convert */ | 55 | u32 convert_rate; /* sampling rate convert */ |
72 | int dma_id; /* for Gen2 SCU */ | 56 | int dma_id; /* for Gen2 SCU */ |
73 | }; | 57 | }; |
74 | 58 | ||
59 | /* | ||
60 | * flags | ||
61 | */ | ||
62 | struct rsnd_dvc_platform_info { | ||
63 | u32 flags; | ||
64 | }; | ||
65 | |||
75 | struct rsnd_dai_path_info { | 66 | struct rsnd_dai_path_info { |
76 | struct rsnd_ssi_platform_info *ssi; | 67 | struct rsnd_ssi_platform_info *ssi; |
77 | struct rsnd_src_platform_info *src; | 68 | struct rsnd_src_platform_info *src; |
69 | struct rsnd_dvc_platform_info *dvc; | ||
78 | }; | 70 | }; |
79 | 71 | ||
80 | struct rsnd_dai_platform_info { | 72 | struct rsnd_dai_platform_info { |
@@ -99,6 +91,8 @@ struct rcar_snd_info { | |||
99 | int ssi_info_nr; | 91 | int ssi_info_nr; |
100 | struct rsnd_src_platform_info *src_info; | 92 | struct rsnd_src_platform_info *src_info; |
101 | int src_info_nr; | 93 | int src_info_nr; |
94 | struct rsnd_dvc_platform_info *dvc_info; | ||
95 | int dvc_info_nr; | ||
102 | struct rsnd_dai_platform_info *dai_info; | 96 | struct rsnd_dai_platform_info *dai_info; |
103 | int dai_info_nr; | 97 | int dai_info_nr; |
104 | int (*start)(int id); | 98 | int (*start)(int id); |
diff --git a/include/sound/rt5640.h b/include/sound/rt5640.h index 27cc75ed67f8..59d26dd81e45 100644 --- a/include/sound/rt5640.h +++ b/include/sound/rt5640.h | |||
@@ -16,6 +16,10 @@ struct rt5640_platform_data { | |||
16 | bool in1_diff; | 16 | bool in1_diff; |
17 | bool in2_diff; | 17 | bool in2_diff; |
18 | 18 | ||
19 | bool dmic_en; | ||
20 | bool dmic1_data_pin; /* 0 = IN1P; 1 = GPIO3 */ | ||
21 | bool dmic2_data_pin; /* 0 = IN1N; 1 = GPIO4 */ | ||
22 | |||
19 | int ldo1_en; /* GPIO for LDO1_EN */ | 23 | int ldo1_en; /* GPIO for LDO1_EN */ |
20 | }; | 24 | }; |
21 | 25 | ||
diff --git a/include/sound/rt5645.h b/include/sound/rt5645.h new file mode 100644 index 000000000000..1de744c242f6 --- /dev/null +++ b/include/sound/rt5645.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * linux/sound/rt5645.h -- Platform data for RT5645 | ||
3 | * | ||
4 | * Copyright 2013 Realtek Microelectronics | ||
5 | * | ||
6 | * This program 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 | |||
11 | #ifndef __LINUX_SND_RT5645_H | ||
12 | #define __LINUX_SND_RT5645_H | ||
13 | |||
14 | struct rt5645_platform_data { | ||
15 | /* IN2 can optionally be differential */ | ||
16 | bool in2_diff; | ||
17 | |||
18 | bool dmic_en; | ||
19 | unsigned int dmic1_data_pin; | ||
20 | /* 0 = IN2N; 1 = GPIO5; 2 = GPIO11 */ | ||
21 | unsigned int dmic2_data_pin; | ||
22 | /* 0 = IN2P; 1 = GPIO6; 2 = GPIO10; 3 = GPIO12 */ | ||
23 | }; | ||
24 | |||
25 | #endif | ||
diff --git a/include/sound/rt5651.h b/include/sound/rt5651.h new file mode 100644 index 000000000000..d35de758dfb5 --- /dev/null +++ b/include/sound/rt5651.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * linux/sound/rt286.h -- Platform data for RT286 | ||
3 | * | ||
4 | * Copyright 2013 Realtek Microelectronics | ||
5 | * | ||
6 | * This program 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 | |||
11 | #ifndef __LINUX_SND_RT5651_H | ||
12 | #define __LINUX_SND_RT5651_H | ||
13 | |||
14 | struct rt5651_platform_data { | ||
15 | /* IN2 can optionally be differential */ | ||
16 | bool in2_diff; | ||
17 | |||
18 | bool dmic_en; | ||
19 | }; | ||
20 | |||
21 | #endif | ||
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index fad76769f153..688f2ba8009f 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
@@ -252,7 +252,6 @@ struct snd_soc_dai { | |||
252 | unsigned int symmetric_rates:1; | 252 | unsigned int symmetric_rates:1; |
253 | unsigned int symmetric_channels:1; | 253 | unsigned int symmetric_channels:1; |
254 | unsigned int symmetric_samplebits:1; | 254 | unsigned int symmetric_samplebits:1; |
255 | struct snd_pcm_runtime *runtime; | ||
256 | unsigned int active; | 255 | unsigned int active; |
257 | unsigned char probed:1; | 256 | unsigned char probed:1; |
258 | 257 | ||
@@ -277,7 +276,6 @@ struct snd_soc_dai { | |||
277 | struct snd_soc_card *card; | 276 | struct snd_soc_card *card; |
278 | 277 | ||
279 | struct list_head list; | 278 | struct list_head list; |
280 | struct list_head card_list; | ||
281 | }; | 279 | }; |
282 | 280 | ||
283 | static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai, | 281 | static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai, |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index ef78f562f4a8..6b59471cdf44 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
@@ -107,10 +107,6 @@ struct device; | |||
107 | { .id = snd_soc_dapm_mux, .name = wname, \ | 107 | { .id = snd_soc_dapm_mux, .name = wname, \ |
108 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ | 108 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ |
109 | .kcontrol_news = wcontrols, .num_kcontrols = 1} | 109 | .kcontrol_news = wcontrols, .num_kcontrols = 1} |
110 | #define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \ | ||
111 | SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) | ||
112 | #define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \ | ||
113 | SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) | ||
114 | 110 | ||
115 | /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ | 111 | /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ |
116 | #define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ | 112 | #define SOC_PGA_ARRAY(wname, wreg, wshift, winvert,\ |
@@ -166,10 +162,6 @@ struct device; | |||
166 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ | 162 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ |
167 | .kcontrol_news = wcontrols, .num_kcontrols = 1, \ | 163 | .kcontrol_news = wcontrols, .num_kcontrols = 1, \ |
168 | .event = wevent, .event_flags = wflags} | 164 | .event = wevent, .event_flags = wflags} |
169 | #define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ | ||
170 | wevent, wflags) \ | ||
171 | SND_SOC_DAPM_MUX_E(wname, wreg, wshift, winvert, wcontrols, wevent, \ | ||
172 | wflags) | ||
173 | 165 | ||
174 | /* additional sequencing control within an event type */ | 166 | /* additional sequencing control within an event type */ |
175 | #define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \ | 167 | #define SND_SOC_DAPM_PGA_S(wname, wsubseq, wreg, wshift, winvert, \ |
@@ -256,9 +248,8 @@ struct device; | |||
256 | /* generic widgets */ | 248 | /* generic widgets */ |
257 | #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ | 249 | #define SND_SOC_DAPM_REG(wid, wname, wreg, wshift, wmask, won_val, woff_val) \ |
258 | { .id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \ | 250 | { .id = wid, .name = wname, .kcontrol_news = NULL, .num_kcontrols = 0, \ |
259 | .reg = -((wreg) + 1), .shift = wshift, .mask = wmask, \ | 251 | .reg = wreg, .shift = wshift, .mask = wmask, \ |
260 | .on_val = won_val, .off_val = woff_val, .event = dapm_reg_event, \ | 252 | .on_val = won_val, .off_val = woff_val, } |
261 | .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD} | ||
262 | #define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \ | 253 | #define SND_SOC_DAPM_SUPPLY(wname, wreg, wshift, winvert, wevent, wflags) \ |
263 | { .id = snd_soc_dapm_supply, .name = wname, \ | 254 | { .id = snd_soc_dapm_supply, .name = wname, \ |
264 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ | 255 | SND_SOC_DAPM_INIT_REG_VAL(wreg, wshift, winvert), \ |
@@ -305,16 +296,12 @@ struct device; | |||
305 | .get = snd_soc_dapm_get_enum_double, \ | 296 | .get = snd_soc_dapm_get_enum_double, \ |
306 | .put = snd_soc_dapm_put_enum_double, \ | 297 | .put = snd_soc_dapm_put_enum_double, \ |
307 | .private_value = (unsigned long)&xenum } | 298 | .private_value = (unsigned long)&xenum } |
308 | #define SOC_DAPM_ENUM_VIRT(xname, xenum) \ | ||
309 | SOC_DAPM_ENUM(xname, xenum) | ||
310 | #define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \ | 299 | #define SOC_DAPM_ENUM_EXT(xname, xenum, xget, xput) \ |
311 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 300 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
312 | .info = snd_soc_info_enum_double, \ | 301 | .info = snd_soc_info_enum_double, \ |
313 | .get = xget, \ | 302 | .get = xget, \ |
314 | .put = xput, \ | 303 | .put = xput, \ |
315 | .private_value = (unsigned long)&xenum } | 304 | .private_value = (unsigned long)&xenum } |
316 | #define SOC_DAPM_VALUE_ENUM(xname, xenum) \ | ||
317 | SOC_DAPM_ENUM(xname, xenum) | ||
318 | #define SOC_DAPM_PIN_SWITCH(xname) \ | 305 | #define SOC_DAPM_PIN_SWITCH(xname) \ |
319 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ | 306 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname " Switch", \ |
320 | .info = snd_soc_dapm_info_pin_switch, \ | 307 | .info = snd_soc_dapm_info_pin_switch, \ |
@@ -362,8 +349,6 @@ struct regulator; | |||
362 | struct snd_soc_dapm_widget_list; | 349 | struct snd_soc_dapm_widget_list; |
363 | struct snd_soc_dapm_update; | 350 | struct snd_soc_dapm_update; |
364 | 351 | ||
365 | int dapm_reg_event(struct snd_soc_dapm_widget *w, | ||
366 | struct snd_kcontrol *kcontrol, int event); | ||
367 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, | 352 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, |
368 | struct snd_kcontrol *kcontrol, int event); | 353 | struct snd_kcontrol *kcontrol, int event); |
369 | int dapm_clock_event(struct snd_soc_dapm_widget *w, | 354 | int dapm_clock_event(struct snd_soc_dapm_widget *w, |
@@ -606,6 +591,7 @@ struct snd_soc_dapm_context { | |||
606 | enum snd_soc_dapm_type, int); | 591 | enum snd_soc_dapm_type, int); |
607 | 592 | ||
608 | struct device *dev; /* from parent - for debug */ | 593 | struct device *dev; /* from parent - for debug */ |
594 | struct snd_soc_component *component; /* parent component */ | ||
609 | struct snd_soc_codec *codec; /* parent codec */ | 595 | struct snd_soc_codec *codec; /* parent codec */ |
610 | struct snd_soc_platform *platform; /* parent platform */ | 596 | struct snd_soc_platform *platform; /* parent platform */ |
611 | struct snd_soc_card *card; /* parent card */ | 597 | struct snd_soc_card *card; /* parent card */ |
diff --git a/include/sound/soc.h b/include/sound/soc.h index 0b83168d8ff4..dcdcc95efd1d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -196,8 +196,6 @@ | |||
196 | .info = snd_soc_info_enum_double, \ | 196 | .info = snd_soc_info_enum_double, \ |
197 | .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ | 197 | .get = snd_soc_get_enum_double, .put = snd_soc_put_enum_double, \ |
198 | .private_value = (unsigned long)&xenum } | 198 | .private_value = (unsigned long)&xenum } |
199 | #define SOC_VALUE_ENUM(xname, xenum) \ | ||
200 | SOC_ENUM(xname, xenum) | ||
201 | #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\ | 199 | #define SOC_SINGLE_EXT(xname, xreg, xshift, xmax, xinvert,\ |
202 | xhandler_get, xhandler_put) \ | 200 | xhandler_get, xhandler_put) \ |
203 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 201 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
@@ -266,6 +264,13 @@ | |||
266 | {.base = xbase, .num_regs = xregs, \ | 264 | {.base = xbase, .num_regs = xregs, \ |
267 | .mask = xmask }) } | 265 | .mask = xmask }) } |
268 | 266 | ||
267 | #define SND_SOC_BYTES_EXT(xname, xcount, xhandler_get, xhandler_put) \ | ||
268 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
269 | .info = snd_soc_bytes_info_ext, \ | ||
270 | .get = xhandler_get, .put = xhandler_put, \ | ||
271 | .private_value = (unsigned long)&(struct soc_bytes_ext) \ | ||
272 | {.max = xcount} } | ||
273 | |||
269 | #define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \ | 274 | #define SOC_SINGLE_XR_SX(xname, xregbase, xregcount, xnbits, \ |
270 | xmin, xmax, xinvert) \ | 275 | xmin, xmax, xinvert) \ |
271 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 276 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
@@ -377,6 +382,8 @@ int snd_soc_resume(struct device *dev); | |||
377 | int snd_soc_poweroff(struct device *dev); | 382 | int snd_soc_poweroff(struct device *dev); |
378 | int snd_soc_register_platform(struct device *dev, | 383 | int snd_soc_register_platform(struct device *dev, |
379 | const struct snd_soc_platform_driver *platform_drv); | 384 | const struct snd_soc_platform_driver *platform_drv); |
385 | int devm_snd_soc_register_platform(struct device *dev, | ||
386 | const struct snd_soc_platform_driver *platform_drv); | ||
380 | void snd_soc_unregister_platform(struct device *dev); | 387 | void snd_soc_unregister_platform(struct device *dev); |
381 | int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, | 388 | int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, |
382 | const struct snd_soc_platform_driver *platform_drv); | 389 | const struct snd_soc_platform_driver *platform_drv); |
@@ -393,14 +400,6 @@ int devm_snd_soc_register_component(struct device *dev, | |||
393 | const struct snd_soc_component_driver *cmpnt_drv, | 400 | const struct snd_soc_component_driver *cmpnt_drv, |
394 | struct snd_soc_dai_driver *dai_drv, int num_dai); | 401 | struct snd_soc_dai_driver *dai_drv, int num_dai); |
395 | void snd_soc_unregister_component(struct device *dev); | 402 | void snd_soc_unregister_component(struct device *dev); |
396 | int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, | ||
397 | unsigned int reg); | ||
398 | int snd_soc_codec_readable_register(struct snd_soc_codec *codec, | ||
399 | unsigned int reg); | ||
400 | int snd_soc_codec_writable_register(struct snd_soc_codec *codec, | ||
401 | unsigned int reg); | ||
402 | int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | ||
403 | struct regmap *regmap); | ||
404 | int snd_soc_cache_sync(struct snd_soc_codec *codec); | 403 | int snd_soc_cache_sync(struct snd_soc_codec *codec); |
405 | int snd_soc_cache_init(struct snd_soc_codec *codec); | 404 | int snd_soc_cache_init(struct snd_soc_codec *codec); |
406 | int snd_soc_cache_exit(struct snd_soc_codec *codec); | 405 | int snd_soc_cache_exit(struct snd_soc_codec *codec); |
@@ -469,12 +468,12 @@ static inline void snd_soc_jack_free_gpios(struct snd_soc_jack *jack, int count, | |||
469 | #endif | 468 | #endif |
470 | 469 | ||
471 | /* codec register bit access */ | 470 | /* codec register bit access */ |
472 | int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, | 471 | int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg, |
473 | unsigned int mask, unsigned int value); | 472 | unsigned int mask, unsigned int value); |
474 | int snd_soc_update_bits_locked(struct snd_soc_codec *codec, | 473 | int snd_soc_update_bits_locked(struct snd_soc_codec *codec, |
475 | unsigned short reg, unsigned int mask, | 474 | unsigned int reg, unsigned int mask, |
476 | unsigned int value); | 475 | unsigned int value); |
477 | int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, | 476 | int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, |
478 | unsigned int mask, unsigned int value); | 477 | unsigned int mask, unsigned int value); |
479 | 478 | ||
480 | int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, | 479 | int snd_soc_new_ac97_codec(struct snd_soc_codec *codec, |
@@ -540,6 +539,8 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, | |||
540 | struct snd_ctl_elem_value *ucontrol); | 539 | struct snd_ctl_elem_value *ucontrol); |
541 | int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | 540 | int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, |
542 | struct snd_ctl_elem_value *ucontrol); | 541 | struct snd_ctl_elem_value *ucontrol); |
542 | int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, | ||
543 | struct snd_ctl_elem_info *ucontrol); | ||
543 | int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, | 544 | int snd_soc_info_xr_sx(struct snd_kcontrol *kcontrol, |
544 | struct snd_ctl_elem_info *uinfo); | 545 | struct snd_ctl_elem_info *uinfo); |
545 | int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, | 546 | int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, |
@@ -668,6 +669,7 @@ struct snd_soc_component { | |||
668 | unsigned int active; | 669 | unsigned int active; |
669 | 670 | ||
670 | unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ | 671 | unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ |
672 | unsigned int registered_as_component:1; | ||
671 | 673 | ||
672 | struct list_head list; | 674 | struct list_head list; |
673 | 675 | ||
@@ -677,6 +679,14 @@ struct snd_soc_component { | |||
677 | const struct snd_soc_component_driver *driver; | 679 | const struct snd_soc_component_driver *driver; |
678 | 680 | ||
679 | struct list_head dai_list; | 681 | struct list_head dai_list; |
682 | |||
683 | int (*read)(struct snd_soc_component *, unsigned int, unsigned int *); | ||
684 | int (*write)(struct snd_soc_component *, unsigned int, unsigned int); | ||
685 | |||
686 | struct regmap *regmap; | ||
687 | int val_bytes; | ||
688 | |||
689 | struct mutex io_mutex; | ||
680 | }; | 690 | }; |
681 | 691 | ||
682 | /* SoC Audio Codec device */ | 692 | /* SoC Audio Codec device */ |
@@ -691,10 +701,6 @@ struct snd_soc_codec { | |||
691 | struct snd_soc_card *card; | 701 | struct snd_soc_card *card; |
692 | struct list_head list; | 702 | struct list_head list; |
693 | struct list_head card_list; | 703 | struct list_head card_list; |
694 | int num_dai; | ||
695 | int (*volatile_register)(struct snd_soc_codec *, unsigned int); | ||
696 | int (*readable_register)(struct snd_soc_codec *, unsigned int); | ||
697 | int (*writable_register)(struct snd_soc_codec *, unsigned int); | ||
698 | 704 | ||
699 | /* runtime */ | 705 | /* runtime */ |
700 | struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ | 706 | struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ |
@@ -704,18 +710,14 @@ struct snd_soc_codec { | |||
704 | unsigned int ac97_registered:1; /* Codec has been AC97 registered */ | 710 | unsigned int ac97_registered:1; /* Codec has been AC97 registered */ |
705 | unsigned int ac97_created:1; /* Codec has been created by SoC */ | 711 | unsigned int ac97_created:1; /* Codec has been created by SoC */ |
706 | unsigned int cache_init:1; /* codec cache has been initialized */ | 712 | unsigned int cache_init:1; /* codec cache has been initialized */ |
707 | unsigned int using_regmap:1; /* using regmap access */ | ||
708 | u32 cache_only; /* Suppress writes to hardware */ | 713 | u32 cache_only; /* Suppress writes to hardware */ |
709 | u32 cache_sync; /* Cache needs to be synced to hardware */ | 714 | u32 cache_sync; /* Cache needs to be synced to hardware */ |
710 | 715 | ||
711 | /* codec IO */ | 716 | /* codec IO */ |
712 | void *control_data; /* codec control (i2c/3wire) data */ | 717 | void *control_data; /* codec control (i2c/3wire) data */ |
713 | hw_write_t hw_write; | 718 | hw_write_t hw_write; |
714 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); | ||
715 | int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); | ||
716 | void *reg_cache; | 719 | void *reg_cache; |
717 | struct mutex cache_rw_mutex; | 720 | struct mutex cache_rw_mutex; |
718 | int val_bytes; | ||
719 | 721 | ||
720 | /* component */ | 722 | /* component */ |
721 | struct snd_soc_component component; | 723 | struct snd_soc_component component; |
@@ -754,13 +756,9 @@ struct snd_soc_codec_driver { | |||
754 | unsigned int freq_in, unsigned int freq_out); | 756 | unsigned int freq_in, unsigned int freq_out); |
755 | 757 | ||
756 | /* codec IO */ | 758 | /* codec IO */ |
759 | struct regmap *(*get_regmap)(struct device *); | ||
757 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); | 760 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); |
758 | int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); | 761 | int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); |
759 | int (*display_register)(struct snd_soc_codec *, char *, | ||
760 | size_t, unsigned int); | ||
761 | int (*volatile_register)(struct snd_soc_codec *, unsigned int); | ||
762 | int (*readable_register)(struct snd_soc_codec *, unsigned int); | ||
763 | int (*writable_register)(struct snd_soc_codec *, unsigned int); | ||
764 | unsigned int reg_cache_size; | 762 | unsigned int reg_cache_size; |
765 | short reg_cache_step; | 763 | short reg_cache_step; |
766 | short reg_word_size; | 764 | short reg_word_size; |
@@ -791,6 +789,7 @@ struct snd_soc_platform_driver { | |||
791 | int (*remove)(struct snd_soc_platform *); | 789 | int (*remove)(struct snd_soc_platform *); |
792 | int (*suspend)(struct snd_soc_dai *dai); | 790 | int (*suspend)(struct snd_soc_dai *dai); |
793 | int (*resume)(struct snd_soc_dai *dai); | 791 | int (*resume)(struct snd_soc_dai *dai); |
792 | struct snd_soc_component_driver component_driver; | ||
794 | 793 | ||
795 | /* pcm creation and destruction */ | 794 | /* pcm creation and destruction */ |
796 | int (*pcm_new)(struct snd_soc_pcm_runtime *); | 795 | int (*pcm_new)(struct snd_soc_pcm_runtime *); |
@@ -835,7 +834,6 @@ struct snd_soc_platform { | |||
835 | int id; | 834 | int id; |
836 | struct device *dev; | 835 | struct device *dev; |
837 | const struct snd_soc_platform_driver *driver; | 836 | const struct snd_soc_platform_driver *driver; |
838 | struct mutex mutex; | ||
839 | 837 | ||
840 | unsigned int suspended:1; /* platform is suspended */ | 838 | unsigned int suspended:1; /* platform is suspended */ |
841 | unsigned int probed:1; | 839 | unsigned int probed:1; |
@@ -844,6 +842,8 @@ struct snd_soc_platform { | |||
844 | struct list_head list; | 842 | struct list_head list; |
845 | struct list_head card_list; | 843 | struct list_head card_list; |
846 | 844 | ||
845 | struct snd_soc_component component; | ||
846 | |||
847 | struct snd_soc_dapm_context dapm; | 847 | struct snd_soc_dapm_context dapm; |
848 | 848 | ||
849 | #ifdef CONFIG_DEBUG_FS | 849 | #ifdef CONFIG_DEBUG_FS |
@@ -931,7 +931,12 @@ struct snd_soc_dai_link { | |||
931 | }; | 931 | }; |
932 | 932 | ||
933 | struct snd_soc_codec_conf { | 933 | struct snd_soc_codec_conf { |
934 | /* | ||
935 | * specify device either by device name, or by | ||
936 | * DT/OF node, but not both. | ||
937 | */ | ||
934 | const char *dev_name; | 938 | const char *dev_name; |
939 | const struct device_node *of_node; | ||
935 | 940 | ||
936 | /* | 941 | /* |
937 | * optional map of kcontrol, widget and path name prefixes that are | 942 | * optional map of kcontrol, widget and path name prefixes that are |
@@ -942,7 +947,13 @@ struct snd_soc_codec_conf { | |||
942 | 947 | ||
943 | struct snd_soc_aux_dev { | 948 | struct snd_soc_aux_dev { |
944 | const char *name; /* Codec name */ | 949 | const char *name; /* Codec name */ |
945 | const char *codec_name; /* for multi-codec */ | 950 | |
951 | /* | ||
952 | * specify multi-codec either by device name, or by | ||
953 | * DT/OF node, but not both. | ||
954 | */ | ||
955 | const char *codec_name; | ||
956 | const struct device_node *codec_of_node; | ||
946 | 957 | ||
947 | /* codec/machine specific init - e.g. add machine controls */ | 958 | /* codec/machine specific init - e.g. add machine controls */ |
948 | int (*init)(struct snd_soc_dapm_context *dapm); | 959 | int (*init)(struct snd_soc_dapm_context *dapm); |
@@ -957,7 +968,6 @@ struct snd_soc_card { | |||
957 | struct snd_card *snd_card; | 968 | struct snd_card *snd_card; |
958 | struct module *owner; | 969 | struct module *owner; |
959 | 970 | ||
960 | struct list_head list; | ||
961 | struct mutex mutex; | 971 | struct mutex mutex; |
962 | struct mutex dapm_mutex; | 972 | struct mutex dapm_mutex; |
963 | 973 | ||
@@ -1020,7 +1030,6 @@ struct snd_soc_card { | |||
1020 | /* lists of probed devices belonging to this card */ | 1030 | /* lists of probed devices belonging to this card */ |
1021 | struct list_head codec_dev_list; | 1031 | struct list_head codec_dev_list; |
1022 | struct list_head platform_dev_list; | 1032 | struct list_head platform_dev_list; |
1023 | struct list_head dai_dev_list; | ||
1024 | 1033 | ||
1025 | struct list_head widgets; | 1034 | struct list_head widgets; |
1026 | struct list_head paths; | 1035 | struct list_head paths; |
@@ -1090,6 +1099,10 @@ struct soc_bytes { | |||
1090 | u32 mask; | 1099 | u32 mask; |
1091 | }; | 1100 | }; |
1092 | 1101 | ||
1102 | struct soc_bytes_ext { | ||
1103 | int max; | ||
1104 | }; | ||
1105 | |||
1093 | /* multi register control */ | 1106 | /* multi register control */ |
1094 | struct soc_mreg_control { | 1107 | struct soc_mreg_control { |
1095 | long min, max; | 1108 | long min, max; |
@@ -1120,10 +1133,39 @@ static inline struct snd_soc_codec *snd_soc_component_to_codec( | |||
1120 | return container_of(component, struct snd_soc_codec, component); | 1133 | return container_of(component, struct snd_soc_codec, component); |
1121 | } | 1134 | } |
1122 | 1135 | ||
1136 | /** | ||
1137 | * snd_soc_component_to_platform() - Casts a component to the platform it is embedded in | ||
1138 | * @component: The component to cast to a platform | ||
1139 | * | ||
1140 | * This function must only be used on components that are known to be platforms. | ||
1141 | * Otherwise the behavior is undefined. | ||
1142 | */ | ||
1143 | static inline struct snd_soc_platform *snd_soc_component_to_platform( | ||
1144 | struct snd_soc_component *component) | ||
1145 | { | ||
1146 | return container_of(component, struct snd_soc_platform, component); | ||
1147 | } | ||
1148 | |||
1123 | /* codec IO */ | 1149 | /* codec IO */ |
1124 | unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); | 1150 | unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); |
1125 | unsigned int snd_soc_write(struct snd_soc_codec *codec, | 1151 | int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg, |
1126 | unsigned int reg, unsigned int val); | 1152 | unsigned int val); |
1153 | |||
1154 | /* component IO */ | ||
1155 | int snd_soc_component_read(struct snd_soc_component *component, | ||
1156 | unsigned int reg, unsigned int *val); | ||
1157 | int snd_soc_component_write(struct snd_soc_component *component, | ||
1158 | unsigned int reg, unsigned int val); | ||
1159 | int snd_soc_component_update_bits(struct snd_soc_component *component, | ||
1160 | unsigned int reg, unsigned int mask, unsigned int val); | ||
1161 | int snd_soc_component_update_bits_async(struct snd_soc_component *component, | ||
1162 | unsigned int reg, unsigned int mask, unsigned int val); | ||
1163 | void snd_soc_component_async_complete(struct snd_soc_component *component); | ||
1164 | int snd_soc_component_test_bits(struct snd_soc_component *component, | ||
1165 | unsigned int reg, unsigned int mask, unsigned int value); | ||
1166 | |||
1167 | int snd_soc_component_init_io(struct snd_soc_component *component, | ||
1168 | struct regmap *regmap); | ||
1127 | 1169 | ||
1128 | /* device driver data */ | 1170 | /* device driver data */ |
1129 | 1171 | ||
@@ -1173,7 +1215,6 @@ static inline void *snd_soc_pcm_get_drvdata(struct snd_soc_pcm_runtime *rtd) | |||
1173 | 1215 | ||
1174 | static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) | 1216 | static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) |
1175 | { | 1217 | { |
1176 | INIT_LIST_HEAD(&card->dai_dev_list); | ||
1177 | INIT_LIST_HEAD(&card->codec_dev_list); | 1218 | INIT_LIST_HEAD(&card->codec_dev_list); |
1178 | INIT_LIST_HEAD(&card->platform_dev_list); | 1219 | INIT_LIST_HEAD(&card->platform_dev_list); |
1179 | INIT_LIST_HEAD(&card->widgets); | 1220 | INIT_LIST_HEAD(&card->widgets); |
@@ -1228,6 +1269,50 @@ static inline bool snd_soc_codec_is_active(struct snd_soc_codec *codec) | |||
1228 | return snd_soc_component_is_active(&codec->component); | 1269 | return snd_soc_component_is_active(&codec->component); |
1229 | } | 1270 | } |
1230 | 1271 | ||
1272 | /** | ||
1273 | * snd_soc_kcontrol_component() - Returns the component that registered the | ||
1274 | * control | ||
1275 | * @kcontrol: The control for which to get the component | ||
1276 | * | ||
1277 | * Note: This function will work correctly if the control has been registered | ||
1278 | * for a component. Either with snd_soc_add_codec_controls() or | ||
1279 | * snd_soc_add_platform_controls() or via table based setup for either a | ||
1280 | * CODEC, a platform or component driver. Otherwise the behavior is undefined. | ||
1281 | */ | ||
1282 | static inline struct snd_soc_component *snd_soc_kcontrol_component( | ||
1283 | struct snd_kcontrol *kcontrol) | ||
1284 | { | ||
1285 | return snd_kcontrol_chip(kcontrol); | ||
1286 | } | ||
1287 | |||
1288 | /** | ||
1289 | * snd_soc_kcontrol_codec() - Returns the CODEC that registered the control | ||
1290 | * @kcontrol: The control for which to get the CODEC | ||
1291 | * | ||
1292 | * Note: This function will only work correctly if the control has been | ||
1293 | * registered with snd_soc_add_codec_controls() or via table based setup of | ||
1294 | * snd_soc_codec_driver. Otherwise the behavior is undefined. | ||
1295 | */ | ||
1296 | static inline struct snd_soc_codec *snd_soc_kcontrol_codec( | ||
1297 | struct snd_kcontrol *kcontrol) | ||
1298 | { | ||
1299 | return snd_soc_component_to_codec(snd_soc_kcontrol_component(kcontrol)); | ||
1300 | } | ||
1301 | |||
1302 | /** | ||
1303 | * snd_soc_kcontrol_platform() - Returns the platform that registerd the control | ||
1304 | * @kcontrol: The control for which to get the platform | ||
1305 | * | ||
1306 | * Note: This function will only work correctly if the control has been | ||
1307 | * registered with snd_soc_add_platform_controls() or via table based setup of | ||
1308 | * a snd_soc_platform_driver. Otherwise the behavior is undefined. | ||
1309 | */ | ||
1310 | static inline struct snd_soc_platform *snd_soc_kcontrol_platform( | ||
1311 | struct snd_kcontrol *kcontrol) | ||
1312 | { | ||
1313 | return snd_soc_component_to_platform(snd_soc_kcontrol_component(kcontrol)); | ||
1314 | } | ||
1315 | |||
1231 | int snd_soc_util_init(void); | 1316 | int snd_soc_util_init(void); |
1232 | void snd_soc_util_exit(void); | 1317 | void snd_soc_util_exit(void); |
1233 | 1318 | ||
@@ -1241,7 +1326,9 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, | |||
1241 | int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | 1326 | int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, |
1242 | const char *propname); | 1327 | const char *propname); |
1243 | unsigned int snd_soc_of_parse_daifmt(struct device_node *np, | 1328 | unsigned int snd_soc_of_parse_daifmt(struct device_node *np, |
1244 | const char *prefix); | 1329 | const char *prefix, |
1330 | struct device_node **bitclkmaster, | ||
1331 | struct device_node **framemaster); | ||
1245 | int snd_soc_of_get_dai_name(struct device_node *of_node, | 1332 | int snd_soc_of_get_dai_name(struct device_node *of_node, |
1246 | const char **dai_name); | 1333 | const char **dai_name); |
1247 | 1334 | ||
diff --git a/include/sound/sta350.h b/include/sound/sta350.h new file mode 100644 index 000000000000..42edceb096a0 --- /dev/null +++ b/include/sound/sta350.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Platform data for ST STA350 ASoC codec driver. | ||
3 | * | ||
4 | * Copyright: 2014 Raumfeld GmbH | ||
5 | * Author: Sven Brandau <info@brandau.biz> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #ifndef __LINUX_SND__STA350_H | ||
13 | #define __LINUX_SND__STA350_H | ||
14 | |||
15 | #define STA350_OCFG_2CH 0 | ||
16 | #define STA350_OCFG_2_1CH 1 | ||
17 | #define STA350_OCFG_1CH 3 | ||
18 | |||
19 | #define STA350_OM_CH1 0 | ||
20 | #define STA350_OM_CH2 1 | ||
21 | #define STA350_OM_CH3 2 | ||
22 | |||
23 | #define STA350_THERMAL_ADJUSTMENT_ENABLE 1 | ||
24 | #define STA350_THERMAL_RECOVERY_ENABLE 2 | ||
25 | #define STA350_FAULT_DETECT_RECOVERY_BYPASS 1 | ||
26 | |||
27 | #define STA350_FFX_PM_DROP_COMP 0 | ||
28 | #define STA350_FFX_PM_TAPERED_COMP 1 | ||
29 | #define STA350_FFX_PM_FULL_POWER 2 | ||
30 | #define STA350_FFX_PM_VARIABLE_DROP_COMP 3 | ||
31 | |||
32 | |||
33 | struct sta350_platform_data { | ||
34 | u8 output_conf; | ||
35 | u8 ch1_output_mapping; | ||
36 | u8 ch2_output_mapping; | ||
37 | u8 ch3_output_mapping; | ||
38 | u8 ffx_power_output_mode; | ||
39 | u8 drop_compensation_ns; | ||
40 | u8 powerdown_delay_divider; | ||
41 | unsigned int thermal_warning_recovery:1; | ||
42 | unsigned int thermal_warning_adjustment:1; | ||
43 | unsigned int fault_detect_recovery:1; | ||
44 | unsigned int oc_warning_adjustment:1; | ||
45 | unsigned int max_power_use_mpcc:1; | ||
46 | unsigned int max_power_correction:1; | ||
47 | unsigned int am_reduction_mode:1; | ||
48 | unsigned int odd_pwm_speed_mode:1; | ||
49 | unsigned int distortion_compensation:1; | ||
50 | unsigned int invalid_input_detect_mute:1; | ||
51 | unsigned int activate_mute_output:1; | ||
52 | unsigned int bridge_immediate_off:1; | ||
53 | unsigned int noise_shape_dc_cut:1; | ||
54 | unsigned int powerdown_master_vol:1; | ||
55 | }; | ||
56 | |||
57 | #endif /* __LINUX_SND__STA350_H */ | ||
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index 03996b2bb04f..c75c795a377b 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h | |||
@@ -11,102 +11,10 @@ | |||
11 | 11 | ||
12 | struct snd_soc_jack; | 12 | struct snd_soc_jack; |
13 | struct snd_soc_codec; | 13 | struct snd_soc_codec; |
14 | struct snd_soc_platform; | ||
15 | struct snd_soc_card; | 14 | struct snd_soc_card; |
16 | struct snd_soc_dapm_widget; | 15 | struct snd_soc_dapm_widget; |
17 | struct snd_soc_dapm_path; | 16 | struct snd_soc_dapm_path; |
18 | 17 | ||
19 | /* | ||
20 | * Log register events | ||
21 | */ | ||
22 | DECLARE_EVENT_CLASS(snd_soc_reg, | ||
23 | |||
24 | TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, | ||
25 | unsigned int val), | ||
26 | |||
27 | TP_ARGS(codec, reg, val), | ||
28 | |||
29 | TP_STRUCT__entry( | ||
30 | __string( name, codec->name ) | ||
31 | __field( int, id ) | ||
32 | __field( unsigned int, reg ) | ||
33 | __field( unsigned int, val ) | ||
34 | ), | ||
35 | |||
36 | TP_fast_assign( | ||
37 | __assign_str(name, codec->name); | ||
38 | __entry->id = codec->id; | ||
39 | __entry->reg = reg; | ||
40 | __entry->val = val; | ||
41 | ), | ||
42 | |||
43 | TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), | ||
44 | (int)__entry->id, (unsigned int)__entry->reg, | ||
45 | (unsigned int)__entry->val) | ||
46 | ); | ||
47 | |||
48 | DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, | ||
49 | |||
50 | TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, | ||
51 | unsigned int val), | ||
52 | |||
53 | TP_ARGS(codec, reg, val) | ||
54 | |||
55 | ); | ||
56 | |||
57 | DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, | ||
58 | |||
59 | TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, | ||
60 | unsigned int val), | ||
61 | |||
62 | TP_ARGS(codec, reg, val) | ||
63 | |||
64 | ); | ||
65 | |||
66 | DECLARE_EVENT_CLASS(snd_soc_preg, | ||
67 | |||
68 | TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, | ||
69 | unsigned int val), | ||
70 | |||
71 | TP_ARGS(platform, reg, val), | ||
72 | |||
73 | TP_STRUCT__entry( | ||
74 | __string( name, platform->name ) | ||
75 | __field( int, id ) | ||
76 | __field( unsigned int, reg ) | ||
77 | __field( unsigned int, val ) | ||
78 | ), | ||
79 | |||
80 | TP_fast_assign( | ||
81 | __assign_str(name, platform->name); | ||
82 | __entry->id = platform->id; | ||
83 | __entry->reg = reg; | ||
84 | __entry->val = val; | ||
85 | ), | ||
86 | |||
87 | TP_printk("platform=%s.%d reg=%x val=%x", __get_str(name), | ||
88 | (int)__entry->id, (unsigned int)__entry->reg, | ||
89 | (unsigned int)__entry->val) | ||
90 | ); | ||
91 | |||
92 | DEFINE_EVENT(snd_soc_preg, snd_soc_preg_write, | ||
93 | |||
94 | TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, | ||
95 | unsigned int val), | ||
96 | |||
97 | TP_ARGS(platform, reg, val) | ||
98 | |||
99 | ); | ||
100 | |||
101 | DEFINE_EVENT(snd_soc_preg, snd_soc_preg_read, | ||
102 | |||
103 | TP_PROTO(struct snd_soc_platform *platform, unsigned int reg, | ||
104 | unsigned int val), | ||
105 | |||
106 | TP_ARGS(platform, reg, val) | ||
107 | |||
108 | ); | ||
109 | |||
110 | DECLARE_EVENT_CLASS(snd_soc_card, | 18 | DECLARE_EVENT_CLASS(snd_soc_card, |
111 | 19 | ||
112 | TP_PROTO(struct snd_soc_card *card, int val), | 20 | TP_PROTO(struct snd_soc_card *card, int val), |
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index f01bffb702bc..401107b85d30 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c | |||
@@ -241,7 +241,7 @@ static struct snd_kcontrol_new inputgain_control = { | |||
241 | static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol, | 241 | static int onyx_snd_capture_source_info(struct snd_kcontrol *kcontrol, |
242 | struct snd_ctl_elem_info *uinfo) | 242 | struct snd_ctl_elem_info *uinfo) |
243 | { | 243 | { |
244 | static char *texts[] = { "Line-In", "Microphone" }; | 244 | static const char * const texts[] = { "Line-In", "Microphone" }; |
245 | 245 | ||
246 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 246 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
247 | uinfo->count = 1; | 247 | uinfo->count = 1; |
diff --git a/sound/arm/pxa2xx-pcm.c b/sound/arm/pxa2xx-pcm.c index e6c727b317fb..83be8e3f095e 100644 --- a/sound/arm/pxa2xx-pcm.c +++ b/sound/arm/pxa2xx-pcm.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/dma-mapping.h> | 14 | #include <linux/dma-mapping.h> |
15 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
16 | 16 | ||
17 | #include <mach/dma.h> | ||
18 | |||
17 | #include <sound/core.h> | 19 | #include <sound/core.h> |
18 | #include <sound/pxa2xx-lib.h> | 20 | #include <sound/pxa2xx-lib.h> |
19 | #include <sound/dmaengine_pcm.h> | 21 | #include <sound/dmaengine_pcm.h> |
diff --git a/sound/arm/pxa2xx-pcm.h b/sound/arm/pxa2xx-pcm.h index 2a8fc08d52a1..00330985beec 100644 --- a/sound/arm/pxa2xx-pcm.h +++ b/sound/arm/pxa2xx-pcm.h | |||
@@ -9,12 +9,11 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | #include <mach/dma.h> | ||
13 | 12 | ||
14 | struct pxa2xx_runtime_data { | 13 | struct pxa2xx_runtime_data { |
15 | int dma_ch; | 14 | int dma_ch; |
16 | struct snd_dmaengine_dai_dma_data *params; | 15 | struct snd_dmaengine_dai_dma_data *params; |
17 | pxa_dma_desc *dma_desc_array; | 16 | struct pxa_dma_desc *dma_desc_array; |
18 | dma_addr_t dma_desc_array_phys; | 17 | dma_addr_t dma_desc_array_phys; |
19 | }; | 18 | }; |
20 | 19 | ||
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index 05ec049c9faf..a04d23174dc2 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -1198,6 +1198,7 @@ static int atmel_ac97c_remove(struct platform_device *pdev) | |||
1198 | } | 1198 | } |
1199 | 1199 | ||
1200 | static struct platform_driver atmel_ac97c_driver = { | 1200 | static struct platform_driver atmel_ac97c_driver = { |
1201 | .probe = atmel_ac97c_probe, | ||
1201 | .remove = atmel_ac97c_remove, | 1202 | .remove = atmel_ac97c_remove, |
1202 | .driver = { | 1203 | .driver = { |
1203 | .name = "atmel_ac97c", | 1204 | .name = "atmel_ac97c", |
@@ -1205,19 +1206,7 @@ static struct platform_driver atmel_ac97c_driver = { | |||
1205 | .pm = ATMEL_AC97C_PM_OPS, | 1206 | .pm = ATMEL_AC97C_PM_OPS, |
1206 | }, | 1207 | }, |
1207 | }; | 1208 | }; |
1208 | 1209 | module_platform_driver(atmel_ac97c_driver); | |
1209 | static int __init atmel_ac97c_init(void) | ||
1210 | { | ||
1211 | return platform_driver_probe(&atmel_ac97c_driver, | ||
1212 | atmel_ac97c_probe); | ||
1213 | } | ||
1214 | module_init(atmel_ac97c_init); | ||
1215 | |||
1216 | static void __exit atmel_ac97c_exit(void) | ||
1217 | { | ||
1218 | platform_driver_unregister(&atmel_ac97c_driver); | ||
1219 | } | ||
1220 | module_exit(atmel_ac97c_exit); | ||
1221 | 1210 | ||
1222 | MODULE_LICENSE("GPL"); | 1211 | MODULE_LICENSE("GPL"); |
1223 | MODULE_DESCRIPTION("Driver for Atmel AC97 controller"); | 1212 | MODULE_DESCRIPTION("Driver for Atmel AC97 controller"); |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index ce83def9f43b..9acc77eae487 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -345,7 +345,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
345 | snd_pcm_debug_name(substream, name, sizeof(name)); | 345 | snd_pcm_debug_name(substream, name, sizeof(name)); |
346 | xrun_log_show(substream); | 346 | xrun_log_show(substream); |
347 | pcm_err(substream->pcm, | 347 | pcm_err(substream->pcm, |
348 | "BUG: %s, pos = %ld, buffer size = %ld, period size = %ld\n", | 348 | "XRUN: %s, pos = %ld, buffer size = %ld, period size = %ld\n", |
349 | name, pos, runtime->buffer_size, | 349 | name, pos, runtime->buffer_size, |
350 | runtime->period_size); | 350 | runtime->period_size); |
351 | } | 351 | } |
diff --git a/sound/core/seq/seq_midi.c b/sound/core/seq/seq_midi.c index 3e05c55a2880..a1fd77af6059 100644 --- a/sound/core/seq/seq_midi.c +++ b/sound/core/seq/seq_midi.c | |||
@@ -362,13 +362,13 @@ snd_seq_midisynth_register_port(struct snd_seq_device *dev) | |||
362 | if (! port->name[0]) { | 362 | if (! port->name[0]) { |
363 | if (info->name[0]) { | 363 | if (info->name[0]) { |
364 | if (ports > 1) | 364 | if (ports > 1) |
365 | snprintf(port->name, sizeof(port->name), "%s-%d", info->name, p); | 365 | snprintf(port->name, sizeof(port->name), "%s-%u", info->name, p); |
366 | else | 366 | else |
367 | snprintf(port->name, sizeof(port->name), "%s", info->name); | 367 | snprintf(port->name, sizeof(port->name), "%s", info->name); |
368 | } else { | 368 | } else { |
369 | /* last resort */ | 369 | /* last resort */ |
370 | if (ports > 1) | 370 | if (ports > 1) |
371 | sprintf(port->name, "MIDI %d-%d-%d", card->number, device, p); | 371 | sprintf(port->name, "MIDI %d-%d-%u", card->number, device, p); |
372 | else | 372 | else |
373 | sprintf(port->name, "MIDI %d-%d", card->number, device); | 373 | sprintf(port->name, "MIDI %d-%d", card->number, device); |
374 | } | 374 | } |
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c index 25e4609f8339..3bbc3ec5be82 100644 --- a/sound/oss/mpu401.c +++ b/sound/oss/mpu401.c | |||
@@ -567,7 +567,6 @@ static int mpu401_out(int dev, unsigned char midi_byte) | |||
567 | static int mpu401_command(int dev, mpu_command_rec * cmd) | 567 | static int mpu401_command(int dev, mpu_command_rec * cmd) |
568 | { | 568 | { |
569 | int i, timeout, ok; | 569 | int i, timeout, ok; |
570 | int ret = 0; | ||
571 | unsigned long flags; | 570 | unsigned long flags; |
572 | struct mpu_config *devc; | 571 | struct mpu_config *devc; |
573 | 572 | ||
@@ -644,7 +643,6 @@ retry: | |||
644 | } | 643 | } |
645 | } | 644 | } |
646 | } | 645 | } |
647 | ret = 0; | ||
648 | cmd->data[0] = 0; | 646 | cmd->data[0] = 0; |
649 | 647 | ||
650 | if (cmd->nr_returns) | 648 | if (cmd->nr_returns) |
@@ -666,7 +664,7 @@ retry: | |||
666 | } | 664 | } |
667 | } | 665 | } |
668 | spin_unlock_irqrestore(&devc->lock,flags); | 666 | spin_unlock_irqrestore(&devc->lock,flags); |
669 | return ret; | 667 | return 0; |
670 | } | 668 | } |
671 | 669 | ||
672 | static int mpu_cmd(int dev, int cmd, int data) | 670 | static int mpu_cmd(int dev, int cmd, int data) |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index db18ccabadd6..529f5f4f4c9c 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> | ||
26 | #include <linux/pci.h> | 27 | #include <linux/pci.h> |
27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
28 | #include <linux/module.h> | 29 | #include <linux/module.h> |
@@ -34,8 +35,6 @@ | |||
34 | #include <sound/opl3.h> | 35 | #include <sound/opl3.h> |
35 | #include <sound/initval.h> | 36 | #include <sound/initval.h> |
36 | 37 | ||
37 | #include <asm/io.h> | ||
38 | |||
39 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 38 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
40 | #include <media/tea575x.h> | 39 | #include <media/tea575x.h> |
41 | #endif | 40 | #endif |
@@ -80,7 +79,10 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers"); | |||
80 | * Direct registers | 79 | * Direct registers |
81 | */ | 80 | */ |
82 | 81 | ||
83 | #define FM801_REG(chip, reg) (chip->port + FM801_##reg) | 82 | #define fm801_writew(chip,reg,value) outw((value), chip->port + FM801_##reg) |
83 | #define fm801_readw(chip,reg) inw(chip->port + FM801_##reg) | ||
84 | |||
85 | #define fm801_writel(chip,reg,value) outl((value), chip->port + FM801_##reg) | ||
84 | 86 | ||
85 | #define FM801_PCM_VOL 0x00 /* PCM Output Volume */ | 87 | #define FM801_PCM_VOL 0x00 /* PCM Output Volume */ |
86 | #define FM801_FM_VOL 0x02 /* FM Output Volume */ | 88 | #define FM801_FM_VOL 0x02 /* FM Output Volume */ |
@@ -156,21 +158,27 @@ MODULE_PARM_DESC(radio_nr, "Radio device numbers"); | |||
156 | #define FM801_GPIO_GS3 (1<<15) | 158 | #define FM801_GPIO_GS3 (1<<15) |
157 | #define FM801_GPIO_GS(x) (1<<(12+(x))) | 159 | #define FM801_GPIO_GS(x) (1<<(12+(x))) |
158 | 160 | ||
159 | /* | 161 | /** |
160 | 162 | * struct fm801 - describes FM801 chip | |
163 | * @port: I/O port number | ||
164 | * @multichannel: multichannel support | ||
165 | * @secondary: secondary codec | ||
166 | * @secondary_addr: address of the secondary codec | ||
167 | * @tea575x_tuner: tuner access method & flags | ||
168 | * @ply_ctrl: playback control | ||
169 | * @cap_ctrl: capture control | ||
161 | */ | 170 | */ |
162 | |||
163 | struct fm801 { | 171 | struct fm801 { |
164 | int irq; | 172 | int irq; |
165 | 173 | ||
166 | unsigned long port; /* I/O port number */ | 174 | unsigned long port; |
167 | unsigned int multichannel: 1, /* multichannel support */ | 175 | unsigned int multichannel: 1, |
168 | secondary: 1; /* secondary codec */ | 176 | secondary: 1; |
169 | unsigned char secondary_addr; /* address of the secondary codec */ | 177 | unsigned char secondary_addr; |
170 | unsigned int tea575x_tuner; /* tuner access method & flags */ | 178 | unsigned int tea575x_tuner; |
171 | 179 | ||
172 | unsigned short ply_ctrl; /* playback control */ | 180 | unsigned short ply_ctrl; |
173 | unsigned short cap_ctrl; /* capture control */ | 181 | unsigned short cap_ctrl; |
174 | 182 | ||
175 | unsigned long ply_buffer; | 183 | unsigned long ply_buffer; |
176 | unsigned int ply_buf; | 184 | unsigned int ply_buf; |
@@ -222,6 +230,30 @@ MODULE_DEVICE_TABLE(pci, snd_fm801_ids); | |||
222 | * common I/O routines | 230 | * common I/O routines |
223 | */ | 231 | */ |
224 | 232 | ||
233 | static bool fm801_ac97_is_ready(struct fm801 *chip, unsigned int iterations) | ||
234 | { | ||
235 | unsigned int idx; | ||
236 | |||
237 | for (idx = 0; idx < iterations; idx++) { | ||
238 | if (!(fm801_readw(chip, AC97_CMD) & FM801_AC97_BUSY)) | ||
239 | return true; | ||
240 | udelay(10); | ||
241 | } | ||
242 | return false; | ||
243 | } | ||
244 | |||
245 | static bool fm801_ac97_is_valid(struct fm801 *chip, unsigned int iterations) | ||
246 | { | ||
247 | unsigned int idx; | ||
248 | |||
249 | for (idx = 0; idx < iterations; idx++) { | ||
250 | if (fm801_readw(chip, AC97_CMD) & FM801_AC97_VALID) | ||
251 | return true; | ||
252 | udelay(10); | ||
253 | } | ||
254 | return false; | ||
255 | } | ||
256 | |||
225 | static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg, | 257 | static int snd_fm801_update_bits(struct fm801 *chip, unsigned short reg, |
226 | unsigned short mask, unsigned short value) | 258 | unsigned short mask, unsigned short value) |
227 | { | 259 | { |
@@ -244,73 +276,54 @@ static void snd_fm801_codec_write(struct snd_ac97 *ac97, | |||
244 | unsigned short val) | 276 | unsigned short val) |
245 | { | 277 | { |
246 | struct fm801 *chip = ac97->private_data; | 278 | struct fm801 *chip = ac97->private_data; |
247 | int idx; | ||
248 | 279 | ||
249 | /* | 280 | /* |
250 | * Wait until the codec interface is not ready.. | 281 | * Wait until the codec interface is not ready.. |
251 | */ | 282 | */ |
252 | for (idx = 0; idx < 100; idx++) { | 283 | if (!fm801_ac97_is_ready(chip, 100)) { |
253 | if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY)) | 284 | dev_err(chip->card->dev, "AC'97 interface is busy (1)\n"); |
254 | goto ok1; | 285 | return; |
255 | udelay(10); | ||
256 | } | 286 | } |
257 | dev_err(chip->card->dev, "AC'97 interface is busy (1)\n"); | ||
258 | return; | ||
259 | 287 | ||
260 | ok1: | ||
261 | /* write data and address */ | 288 | /* write data and address */ |
262 | outw(val, FM801_REG(chip, AC97_DATA)); | 289 | fm801_writew(chip, AC97_DATA, val); |
263 | outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT), FM801_REG(chip, AC97_CMD)); | 290 | fm801_writew(chip, AC97_CMD, reg | (ac97->addr << FM801_AC97_ADDR_SHIFT)); |
264 | /* | 291 | /* |
265 | * Wait until the write command is not completed.. | 292 | * Wait until the write command is not completed.. |
266 | */ | 293 | */ |
267 | for (idx = 0; idx < 1000; idx++) { | 294 | if (!fm801_ac97_is_ready(chip, 1000)) |
268 | if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY)) | 295 | dev_err(chip->card->dev, "AC'97 interface #%d is busy (2)\n", |
269 | return; | 296 | ac97->num); |
270 | udelay(10); | ||
271 | } | ||
272 | dev_err(chip->card->dev, "AC'97 interface #%d is busy (2)\n", ac97->num); | ||
273 | } | 297 | } |
274 | 298 | ||
275 | static unsigned short snd_fm801_codec_read(struct snd_ac97 *ac97, unsigned short reg) | 299 | static unsigned short snd_fm801_codec_read(struct snd_ac97 *ac97, unsigned short reg) |
276 | { | 300 | { |
277 | struct fm801 *chip = ac97->private_data; | 301 | struct fm801 *chip = ac97->private_data; |
278 | int idx; | ||
279 | 302 | ||
280 | /* | 303 | /* |
281 | * Wait until the codec interface is not ready.. | 304 | * Wait until the codec interface is not ready.. |
282 | */ | 305 | */ |
283 | for (idx = 0; idx < 100; idx++) { | 306 | if (!fm801_ac97_is_ready(chip, 100)) { |
284 | if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY)) | 307 | dev_err(chip->card->dev, "AC'97 interface is busy (1)\n"); |
285 | goto ok1; | 308 | return 0; |
286 | udelay(10); | ||
287 | } | 309 | } |
288 | dev_err(chip->card->dev, "AC'97 interface is busy (1)\n"); | ||
289 | return 0; | ||
290 | 310 | ||
291 | ok1: | ||
292 | /* read command */ | 311 | /* read command */ |
293 | outw(reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ, | 312 | fm801_writew(chip, AC97_CMD, |
294 | FM801_REG(chip, AC97_CMD)); | 313 | reg | (ac97->addr << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ); |
295 | for (idx = 0; idx < 100; idx++) { | 314 | if (!fm801_ac97_is_ready(chip, 100)) { |
296 | if (!(inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_BUSY)) | 315 | dev_err(chip->card->dev, "AC'97 interface #%d is busy (2)\n", |
297 | goto ok2; | 316 | ac97->num); |
298 | udelay(10); | 317 | return 0; |
299 | } | 318 | } |
300 | dev_err(chip->card->dev, "AC'97 interface #%d is busy (2)\n", ac97->num); | ||
301 | return 0; | ||
302 | 319 | ||
303 | ok2: | 320 | if (!fm801_ac97_is_valid(chip, 1000)) { |
304 | for (idx = 0; idx < 1000; idx++) { | 321 | dev_err(chip->card->dev, |
305 | if (inw(FM801_REG(chip, AC97_CMD)) & FM801_AC97_VALID) | 322 | "AC'97 interface #%d is not valid (2)\n", ac97->num); |
306 | goto ok3; | 323 | return 0; |
307 | udelay(10); | ||
308 | } | 324 | } |
309 | dev_err(chip->card->dev, "AC'97 interface #%d is not valid (2)\n", ac97->num); | ||
310 | return 0; | ||
311 | 325 | ||
312 | ok3: | 326 | return fm801_readw(chip, AC97_DATA); |
313 | return inw(FM801_REG(chip, AC97_DATA)); | ||
314 | } | 327 | } |
315 | 328 | ||
316 | static unsigned int rates[] = { | 329 | static unsigned int rates[] = { |
@@ -384,7 +397,7 @@ static int snd_fm801_playback_trigger(struct snd_pcm_substream *substream, | |||
384 | snd_BUG(); | 397 | snd_BUG(); |
385 | return -EINVAL; | 398 | return -EINVAL; |
386 | } | 399 | } |
387 | outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL)); | 400 | fm801_writew(chip, PLY_CTRL, chip->ply_ctrl); |
388 | spin_unlock(&chip->reg_lock); | 401 | spin_unlock(&chip->reg_lock); |
389 | return 0; | 402 | return 0; |
390 | } | 403 | } |
@@ -419,7 +432,7 @@ static int snd_fm801_capture_trigger(struct snd_pcm_substream *substream, | |||
419 | snd_BUG(); | 432 | snd_BUG(); |
420 | return -EINVAL; | 433 | return -EINVAL; |
421 | } | 434 | } |
422 | outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL)); | 435 | fm801_writew(chip, CAP_CTRL, chip->cap_ctrl); |
423 | spin_unlock(&chip->reg_lock); | 436 | spin_unlock(&chip->reg_lock); |
424 | return 0; | 437 | return 0; |
425 | } | 438 | } |
@@ -457,12 +470,13 @@ static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream) | |||
457 | } | 470 | } |
458 | chip->ply_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT; | 471 | chip->ply_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT; |
459 | chip->ply_buf = 0; | 472 | chip->ply_buf = 0; |
460 | outw(chip->ply_ctrl, FM801_REG(chip, PLY_CTRL)); | 473 | fm801_writew(chip, PLY_CTRL, chip->ply_ctrl); |
461 | outw(chip->ply_count - 1, FM801_REG(chip, PLY_COUNT)); | 474 | fm801_writew(chip, PLY_COUNT, chip->ply_count - 1); |
462 | chip->ply_buffer = runtime->dma_addr; | 475 | chip->ply_buffer = runtime->dma_addr; |
463 | chip->ply_pos = 0; | 476 | chip->ply_pos = 0; |
464 | outl(chip->ply_buffer, FM801_REG(chip, PLY_BUF1)); | 477 | fm801_writel(chip, PLY_BUF1, chip->ply_buffer); |
465 | outl(chip->ply_buffer + (chip->ply_count % chip->ply_size), FM801_REG(chip, PLY_BUF2)); | 478 | fm801_writel(chip, PLY_BUF2, |
479 | chip->ply_buffer + (chip->ply_count % chip->ply_size)); | ||
466 | spin_unlock_irq(&chip->reg_lock); | 480 | spin_unlock_irq(&chip->reg_lock); |
467 | return 0; | 481 | return 0; |
468 | } | 482 | } |
@@ -483,12 +497,13 @@ static int snd_fm801_capture_prepare(struct snd_pcm_substream *substream) | |||
483 | chip->cap_ctrl |= FM801_STEREO; | 497 | chip->cap_ctrl |= FM801_STEREO; |
484 | chip->cap_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT; | 498 | chip->cap_ctrl |= snd_fm801_rate_bits(runtime->rate) << FM801_RATE_SHIFT; |
485 | chip->cap_buf = 0; | 499 | chip->cap_buf = 0; |
486 | outw(chip->cap_ctrl, FM801_REG(chip, CAP_CTRL)); | 500 | fm801_writew(chip, CAP_CTRL, chip->cap_ctrl); |
487 | outw(chip->cap_count - 1, FM801_REG(chip, CAP_COUNT)); | 501 | fm801_writew(chip, CAP_COUNT, chip->cap_count - 1); |
488 | chip->cap_buffer = runtime->dma_addr; | 502 | chip->cap_buffer = runtime->dma_addr; |
489 | chip->cap_pos = 0; | 503 | chip->cap_pos = 0; |
490 | outl(chip->cap_buffer, FM801_REG(chip, CAP_BUF1)); | 504 | fm801_writel(chip, CAP_BUF1, chip->cap_buffer); |
491 | outl(chip->cap_buffer + (chip->cap_count % chip->cap_size), FM801_REG(chip, CAP_BUF2)); | 505 | fm801_writel(chip, CAP_BUF2, |
506 | chip->cap_buffer + (chip->cap_count % chip->cap_size)); | ||
492 | spin_unlock_irq(&chip->reg_lock); | 507 | spin_unlock_irq(&chip->reg_lock); |
493 | return 0; | 508 | return 0; |
494 | } | 509 | } |
@@ -501,8 +516,8 @@ static snd_pcm_uframes_t snd_fm801_playback_pointer(struct snd_pcm_substream *su | |||
501 | if (!(chip->ply_ctrl & FM801_START)) | 516 | if (!(chip->ply_ctrl & FM801_START)) |
502 | return 0; | 517 | return 0; |
503 | spin_lock(&chip->reg_lock); | 518 | spin_lock(&chip->reg_lock); |
504 | ptr = chip->ply_pos + (chip->ply_count - 1) - inw(FM801_REG(chip, PLY_COUNT)); | 519 | ptr = chip->ply_pos + (chip->ply_count - 1) - fm801_readw(chip, PLY_COUNT); |
505 | if (inw(FM801_REG(chip, IRQ_STATUS)) & FM801_IRQ_PLAYBACK) { | 520 | if (fm801_readw(chip, IRQ_STATUS) & FM801_IRQ_PLAYBACK) { |
506 | ptr += chip->ply_count; | 521 | ptr += chip->ply_count; |
507 | ptr %= chip->ply_size; | 522 | ptr %= chip->ply_size; |
508 | } | 523 | } |
@@ -518,8 +533,8 @@ static snd_pcm_uframes_t snd_fm801_capture_pointer(struct snd_pcm_substream *sub | |||
518 | if (!(chip->cap_ctrl & FM801_START)) | 533 | if (!(chip->cap_ctrl & FM801_START)) |
519 | return 0; | 534 | return 0; |
520 | spin_lock(&chip->reg_lock); | 535 | spin_lock(&chip->reg_lock); |
521 | ptr = chip->cap_pos + (chip->cap_count - 1) - inw(FM801_REG(chip, CAP_COUNT)); | 536 | ptr = chip->cap_pos + (chip->cap_count - 1) - fm801_readw(chip, CAP_COUNT); |
522 | if (inw(FM801_REG(chip, IRQ_STATUS)) & FM801_IRQ_CAPTURE) { | 537 | if (fm801_readw(chip, IRQ_STATUS) & FM801_IRQ_CAPTURE) { |
523 | ptr += chip->cap_count; | 538 | ptr += chip->cap_count; |
524 | ptr %= chip->cap_size; | 539 | ptr %= chip->cap_size; |
525 | } | 540 | } |
@@ -533,12 +548,12 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) | |||
533 | unsigned short status; | 548 | unsigned short status; |
534 | unsigned int tmp; | 549 | unsigned int tmp; |
535 | 550 | ||
536 | status = inw(FM801_REG(chip, IRQ_STATUS)); | 551 | status = fm801_readw(chip, IRQ_STATUS); |
537 | status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME; | 552 | status &= FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU|FM801_IRQ_VOLUME; |
538 | if (! status) | 553 | if (! status) |
539 | return IRQ_NONE; | 554 | return IRQ_NONE; |
540 | /* ack first */ | 555 | /* ack first */ |
541 | outw(status, FM801_REG(chip, IRQ_STATUS)); | 556 | fm801_writew(chip, IRQ_STATUS, status); |
542 | if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) { | 557 | if (chip->pcm && (status & FM801_IRQ_PLAYBACK) && chip->playback_substream) { |
543 | spin_lock(&chip->reg_lock); | 558 | spin_lock(&chip->reg_lock); |
544 | chip->ply_buf++; | 559 | chip->ply_buf++; |
@@ -546,10 +561,10 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) | |||
546 | chip->ply_pos %= chip->ply_size; | 561 | chip->ply_pos %= chip->ply_size; |
547 | tmp = chip->ply_pos + chip->ply_count; | 562 | tmp = chip->ply_pos + chip->ply_count; |
548 | tmp %= chip->ply_size; | 563 | tmp %= chip->ply_size; |
549 | outl(chip->ply_buffer + tmp, | 564 | if (chip->ply_buf & 1) |
550 | (chip->ply_buf & 1) ? | 565 | fm801_writel(chip, PLY_BUF1, chip->ply_buffer + tmp); |
551 | FM801_REG(chip, PLY_BUF1) : | 566 | else |
552 | FM801_REG(chip, PLY_BUF2)); | 567 | fm801_writel(chip, PLY_BUF2, chip->ply_buffer + tmp); |
553 | spin_unlock(&chip->reg_lock); | 568 | spin_unlock(&chip->reg_lock); |
554 | snd_pcm_period_elapsed(chip->playback_substream); | 569 | snd_pcm_period_elapsed(chip->playback_substream); |
555 | } | 570 | } |
@@ -560,10 +575,10 @@ static irqreturn_t snd_fm801_interrupt(int irq, void *dev_id) | |||
560 | chip->cap_pos %= chip->cap_size; | 575 | chip->cap_pos %= chip->cap_size; |
561 | tmp = chip->cap_pos + chip->cap_count; | 576 | tmp = chip->cap_pos + chip->cap_count; |
562 | tmp %= chip->cap_size; | 577 | tmp %= chip->cap_size; |
563 | outl(chip->cap_buffer + tmp, | 578 | if (chip->cap_buf & 1) |
564 | (chip->cap_buf & 1) ? | 579 | fm801_writel(chip, CAP_BUF1, chip->cap_buffer + tmp); |
565 | FM801_REG(chip, CAP_BUF1) : | 580 | else |
566 | FM801_REG(chip, CAP_BUF2)); | 581 | fm801_writel(chip, CAP_BUF2, chip->cap_buffer + tmp); |
567 | spin_unlock(&chip->reg_lock); | 582 | spin_unlock(&chip->reg_lock); |
568 | snd_pcm_period_elapsed(chip->capture_substream); | 583 | snd_pcm_period_elapsed(chip->capture_substream); |
569 | } | 584 | } |
@@ -747,7 +762,7 @@ static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = { | |||
747 | static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) | 762 | static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) |
748 | { | 763 | { |
749 | struct fm801 *chip = tea->private_data; | 764 | struct fm801 *chip = tea->private_data; |
750 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 765 | unsigned short reg = fm801_readw(chip, GPIO_CTRL); |
751 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); | 766 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
752 | 767 | ||
753 | reg &= ~(FM801_GPIO_GP(gpio.data) | | 768 | reg &= ~(FM801_GPIO_GP(gpio.data) | |
@@ -759,13 +774,13 @@ static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) | |||
759 | /* WRITE_ENABLE is inverted */ | 774 | /* WRITE_ENABLE is inverted */ |
760 | reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren); | 775 | reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren); |
761 | 776 | ||
762 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 777 | fm801_writew(chip, GPIO_CTRL, reg); |
763 | } | 778 | } |
764 | 779 | ||
765 | static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) | 780 | static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) |
766 | { | 781 | { |
767 | struct fm801 *chip = tea->private_data; | 782 | struct fm801 *chip = tea->private_data; |
768 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 783 | unsigned short reg = fm801_readw(chip, GPIO_CTRL); |
769 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); | 784 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
770 | u8 ret; | 785 | u8 ret; |
771 | 786 | ||
@@ -780,7 +795,7 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) | |||
780 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) | 795 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
781 | { | 796 | { |
782 | struct fm801 *chip = tea->private_data; | 797 | struct fm801 *chip = tea->private_data; |
783 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 798 | unsigned short reg = fm801_readw(chip, GPIO_CTRL); |
784 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); | 799 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
785 | 800 | ||
786 | /* use GPIO lines and set write enable bit */ | 801 | /* use GPIO lines and set write enable bit */ |
@@ -811,7 +826,7 @@ static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output | |||
811 | FM801_GPIO_GP(gpio.clk)); | 826 | FM801_GPIO_GP(gpio.clk)); |
812 | } | 827 | } |
813 | 828 | ||
814 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 829 | fm801_writew(chip, GPIO_CTRL, reg); |
815 | } | 830 | } |
816 | 831 | ||
817 | static struct snd_tea575x_ops snd_fm801_tea_ops = { | 832 | static struct snd_tea575x_ops snd_fm801_tea_ops = { |
@@ -962,7 +977,7 @@ static int snd_fm801_get_mux(struct snd_kcontrol *kcontrol, | |||
962 | struct fm801 *chip = snd_kcontrol_chip(kcontrol); | 977 | struct fm801 *chip = snd_kcontrol_chip(kcontrol); |
963 | unsigned short val; | 978 | unsigned short val; |
964 | 979 | ||
965 | val = inw(FM801_REG(chip, REC_SRC)) & 7; | 980 | val = fm801_readw(chip, REC_SRC) & 7; |
966 | if (val > 4) | 981 | if (val > 4) |
967 | val = 4; | 982 | val = 4; |
968 | ucontrol->value.enumerated.item[0] = val; | 983 | ucontrol->value.enumerated.item[0] = val; |
@@ -1073,12 +1088,12 @@ static int wait_for_codec(struct fm801 *chip, unsigned int codec_id, | |||
1073 | { | 1088 | { |
1074 | unsigned long timeout = jiffies + waits; | 1089 | unsigned long timeout = jiffies + waits; |
1075 | 1090 | ||
1076 | outw(FM801_AC97_READ | (codec_id << FM801_AC97_ADDR_SHIFT) | reg, | 1091 | fm801_writew(chip, AC97_CMD, |
1077 | FM801_REG(chip, AC97_CMD)); | 1092 | reg | (codec_id << FM801_AC97_ADDR_SHIFT) | FM801_AC97_READ); |
1078 | udelay(5); | 1093 | udelay(5); |
1079 | do { | 1094 | do { |
1080 | if ((inw(FM801_REG(chip, AC97_CMD)) & (FM801_AC97_VALID|FM801_AC97_BUSY)) | 1095 | if ((fm801_readw(chip, AC97_CMD) & |
1081 | == FM801_AC97_VALID) | 1096 | (FM801_AC97_VALID | FM801_AC97_BUSY)) == FM801_AC97_VALID) |
1082 | return 0; | 1097 | return 0; |
1083 | schedule_timeout_uninterruptible(1); | 1098 | schedule_timeout_uninterruptible(1); |
1084 | } while (time_after(timeout, jiffies)); | 1099 | } while (time_after(timeout, jiffies)); |
@@ -1093,10 +1108,10 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume) | |||
1093 | goto __ac97_ok; | 1108 | goto __ac97_ok; |
1094 | 1109 | ||
1095 | /* codec cold reset + AC'97 warm reset */ | 1110 | /* codec cold reset + AC'97 warm reset */ |
1096 | outw((1<<5) | (1<<6), FM801_REG(chip, CODEC_CTRL)); | 1111 | fm801_writew(chip, CODEC_CTRL, (1 << 5) | (1 << 6)); |
1097 | inw(FM801_REG(chip, CODEC_CTRL)); /* flush posting data */ | 1112 | fm801_readw(chip, CODEC_CTRL); /* flush posting data */ |
1098 | udelay(100); | 1113 | udelay(100); |
1099 | outw(0, FM801_REG(chip, CODEC_CTRL)); | 1114 | fm801_writew(chip, CODEC_CTRL, 0); |
1100 | 1115 | ||
1101 | if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) | 1116 | if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) |
1102 | if (!resume) { | 1117 | if (!resume) { |
@@ -1117,7 +1132,7 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume) | |||
1117 | for (i = 3; i > 0; i--) { | 1132 | for (i = 3; i > 0; i--) { |
1118 | if (!wait_for_codec(chip, i, AC97_VENDOR_ID1, | 1133 | if (!wait_for_codec(chip, i, AC97_VENDOR_ID1, |
1119 | msecs_to_jiffies(50))) { | 1134 | msecs_to_jiffies(50))) { |
1120 | cmdw = inw(FM801_REG(chip, AC97_DATA)); | 1135 | cmdw = fm801_readw(chip, AC97_DATA); |
1121 | if (cmdw != 0xffff && cmdw != 0) { | 1136 | if (cmdw != 0xffff && cmdw != 0) { |
1122 | chip->secondary = 1; | 1137 | chip->secondary = 1; |
1123 | chip->secondary_addr = i; | 1138 | chip->secondary_addr = i; |
@@ -1135,23 +1150,24 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume) | |||
1135 | __ac97_ok: | 1150 | __ac97_ok: |
1136 | 1151 | ||
1137 | /* init volume */ | 1152 | /* init volume */ |
1138 | outw(0x0808, FM801_REG(chip, PCM_VOL)); | 1153 | fm801_writew(chip, PCM_VOL, 0x0808); |
1139 | outw(0x9f1f, FM801_REG(chip, FM_VOL)); | 1154 | fm801_writew(chip, FM_VOL, 0x9f1f); |
1140 | outw(0x8808, FM801_REG(chip, I2S_VOL)); | 1155 | fm801_writew(chip, I2S_VOL, 0x8808); |
1141 | 1156 | ||
1142 | /* I2S control - I2S mode */ | 1157 | /* I2S control - I2S mode */ |
1143 | outw(0x0003, FM801_REG(chip, I2S_MODE)); | 1158 | fm801_writew(chip, I2S_MODE, 0x0003); |
1144 | 1159 | ||
1145 | /* interrupt setup */ | 1160 | /* interrupt setup */ |
1146 | cmdw = inw(FM801_REG(chip, IRQ_MASK)); | 1161 | cmdw = fm801_readw(chip, IRQ_MASK); |
1147 | if (chip->irq < 0) | 1162 | if (chip->irq < 0) |
1148 | cmdw |= 0x00c3; /* mask everything, no PCM nor MPU */ | 1163 | cmdw |= 0x00c3; /* mask everything, no PCM nor MPU */ |
1149 | else | 1164 | else |
1150 | cmdw &= ~0x0083; /* unmask MPU, PLAYBACK & CAPTURE */ | 1165 | cmdw &= ~0x0083; /* unmask MPU, PLAYBACK & CAPTURE */ |
1151 | outw(cmdw, FM801_REG(chip, IRQ_MASK)); | 1166 | fm801_writew(chip, IRQ_MASK, cmdw); |
1152 | 1167 | ||
1153 | /* interrupt clear */ | 1168 | /* interrupt clear */ |
1154 | outw(FM801_IRQ_PLAYBACK|FM801_IRQ_CAPTURE|FM801_IRQ_MPU, FM801_REG(chip, IRQ_STATUS)); | 1169 | fm801_writew(chip, IRQ_STATUS, |
1170 | FM801_IRQ_PLAYBACK | FM801_IRQ_CAPTURE | FM801_IRQ_MPU); | ||
1155 | 1171 | ||
1156 | return 0; | 1172 | return 0; |
1157 | } | 1173 | } |
@@ -1165,9 +1181,9 @@ static int snd_fm801_free(struct fm801 *chip) | |||
1165 | goto __end_hw; | 1181 | goto __end_hw; |
1166 | 1182 | ||
1167 | /* interrupt setup - mask everything */ | 1183 | /* interrupt setup - mask everything */ |
1168 | cmdw = inw(FM801_REG(chip, IRQ_MASK)); | 1184 | cmdw = fm801_readw(chip, IRQ_MASK); |
1169 | cmdw |= 0x00c3; | 1185 | cmdw |= 0x00c3; |
1170 | outw(cmdw, FM801_REG(chip, IRQ_MASK)); | 1186 | fm801_writew(chip, IRQ_MASK, cmdw); |
1171 | 1187 | ||
1172 | __end_hw: | 1188 | __end_hw: |
1173 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 1189 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
@@ -1339,15 +1355,15 @@ static int snd_card_fm801_probe(struct pci_dev *pci, | |||
1339 | return err; | 1355 | return err; |
1340 | } | 1356 | } |
1341 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, | 1357 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, |
1342 | FM801_REG(chip, MPU401_DATA), | 1358 | chip->port + FM801_MPU401_DATA, |
1343 | MPU401_INFO_INTEGRATED | | 1359 | MPU401_INFO_INTEGRATED | |
1344 | MPU401_INFO_IRQ_HOOK, | 1360 | MPU401_INFO_IRQ_HOOK, |
1345 | -1, &chip->rmidi)) < 0) { | 1361 | -1, &chip->rmidi)) < 0) { |
1346 | snd_card_free(card); | 1362 | snd_card_free(card); |
1347 | return err; | 1363 | return err; |
1348 | } | 1364 | } |
1349 | if ((err = snd_opl3_create(card, FM801_REG(chip, OPL3_BANK0), | 1365 | if ((err = snd_opl3_create(card, chip->port + FM801_OPL3_BANK0, |
1350 | FM801_REG(chip, OPL3_BANK1), | 1366 | chip->port + FM801_OPL3_BANK1, |
1351 | OPL3_HW_OPL3_FM801, 1, &opl3)) < 0) { | 1367 | OPL3_HW_OPL3_FM801, 1, &opl3)) < 0) { |
1352 | snd_card_free(card); | 1368 | snd_card_free(card); |
1353 | return err; | 1369 | return err; |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index ac17c3fc9388..ebf4c2fb99df 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -20,6 +20,21 @@ config SND_HDA_INTEL | |||
20 | To compile this driver as a module, choose M here: the module | 20 | To compile this driver as a module, choose M here: the module |
21 | will be called snd-hda-intel. | 21 | will be called snd-hda-intel. |
22 | 22 | ||
23 | config SND_HDA_TEGRA | ||
24 | tristate "NVIDIA Tegra HD Audio" | ||
25 | depends on ARCH_TEGRA | ||
26 | select SND_HDA | ||
27 | help | ||
28 | Say Y here to support the HDA controller present in NVIDIA | ||
29 | Tegra SoCs | ||
30 | |||
31 | This options enables support for the HD Audio controller | ||
32 | present in some NVIDIA Tegra SoCs, used to communicate audio | ||
33 | to the HDMI output. | ||
34 | |||
35 | To compile this driver as a module, choose M here: the module | ||
36 | will be called snd-hda-tegra. | ||
37 | |||
23 | if SND_HDA | 38 | if SND_HDA |
24 | 39 | ||
25 | config SND_HDA_DSP_LOADER | 40 | config SND_HDA_DSP_LOADER |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index d0d0c19ddfc2..194f30935e77 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | snd-hda-intel-objs := hda_intel.o | 1 | snd-hda-intel-objs := hda_intel.o |
2 | snd-hda-controller-objs := hda_controller.o | 2 | snd-hda-controller-objs := hda_controller.o |
3 | snd-hda-tegra-objs := hda_tegra.o | ||
3 | # for haswell power well | 4 | # for haswell power well |
4 | snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o | 5 | snd-hda-intel-$(CONFIG_SND_HDA_I915) += hda_i915.o |
5 | 6 | ||
@@ -47,3 +48,4 @@ obj-$(CONFIG_SND_HDA_CODEC_HDMI) += snd-hda-codec-hdmi.o | |||
47 | # otherwise the codec patches won't be hooked before the PCI probe | 48 | # otherwise the codec patches won't be hooked before the PCI probe |
48 | # when built in kernel | 49 | # when built in kernel |
49 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o | 50 | obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o |
51 | obj-$(CONFIG_SND_HDA_TEGRA) += snd-hda-tegra.o | ||
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 90d2fda6c8f9..3cf913772e9b 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -839,6 +839,44 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action) | |||
839 | } | 839 | } |
840 | EXPORT_SYMBOL_GPL(snd_hda_apply_fixup); | 840 | EXPORT_SYMBOL_GPL(snd_hda_apply_fixup); |
841 | 841 | ||
842 | static bool pin_config_match(struct hda_codec *codec, | ||
843 | const struct hda_pintbl *pins) | ||
844 | { | ||
845 | for (; pins->nid; pins++) { | ||
846 | u32 def_conf = snd_hda_codec_get_pincfg(codec, pins->nid); | ||
847 | u32 mask = 0xffffff00; | ||
848 | if ((pins->val & mask) != (def_conf & mask)) | ||
849 | return false; | ||
850 | } | ||
851 | return true; | ||
852 | } | ||
853 | |||
854 | void snd_hda_pick_pin_fixup(struct hda_codec *codec, | ||
855 | const struct snd_hda_pin_quirk *pin_quirk, | ||
856 | const struct hda_fixup *fixlist) | ||
857 | { | ||
858 | const struct snd_hda_pin_quirk *pq; | ||
859 | |||
860 | if (codec->fixup_forced) | ||
861 | return; | ||
862 | |||
863 | for (pq = pin_quirk; pq->subvendor; pq++) { | ||
864 | if ((codec->subsystem_id & 0xffff0000) != (pq->subvendor << 16)) | ||
865 | continue; | ||
866 | if (codec->vendor_id != pq->codec) | ||
867 | continue; | ||
868 | if (pin_config_match(codec, pq->pins)) { | ||
869 | codec->fixup_id = pq->value; | ||
870 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
871 | codec->fixup_name = pq->name; | ||
872 | #endif | ||
873 | codec->fixup_list = fixlist; | ||
874 | return; | ||
875 | } | ||
876 | } | ||
877 | } | ||
878 | EXPORT_SYMBOL_GPL(snd_hda_pick_pin_fixup); | ||
879 | |||
842 | void snd_hda_pick_fixup(struct hda_codec *codec, | 880 | void snd_hda_pick_fixup(struct hda_codec *codec, |
843 | const struct hda_model_fixup *models, | 881 | const struct hda_model_fixup *models, |
844 | const struct snd_pci_quirk *quirk, | 882 | const struct snd_pci_quirk *quirk, |
@@ -852,15 +890,17 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
852 | if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { | 890 | if (codec->modelname && !strcmp(codec->modelname, "nofixup")) { |
853 | codec->fixup_list = NULL; | 891 | codec->fixup_list = NULL; |
854 | codec->fixup_id = -1; | 892 | codec->fixup_id = -1; |
893 | codec->fixup_forced = 1; | ||
855 | return; | 894 | return; |
856 | } | 895 | } |
857 | 896 | ||
858 | if (codec->modelname && models) { | 897 | if (codec->modelname && models) { |
859 | while (models->name) { | 898 | while (models->name) { |
860 | if (!strcmp(codec->modelname, models->name)) { | 899 | if (!strcmp(codec->modelname, models->name)) { |
861 | id = models->id; | 900 | codec->fixup_id = models->id; |
862 | name = models->name; | 901 | codec->fixup_name = models->name; |
863 | break; | 902 | codec->fixup_forced = 1; |
903 | return; | ||
864 | } | 904 | } |
865 | models++; | 905 | models++; |
866 | } | 906 | } |
@@ -889,6 +929,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
889 | } | 929 | } |
890 | } | 930 | } |
891 | 931 | ||
932 | codec->fixup_forced = 0; | ||
892 | codec->fixup_id = id; | 933 | codec->fixup_id = id; |
893 | if (id >= 0) { | 934 | if (id >= 0) { |
894 | codec->fixup_list = fixlist; | 935 | codec->fixup_list = fixlist; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index a4233136cb93..5825aa17d8e3 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -402,6 +402,7 @@ struct hda_codec { | |||
402 | 402 | ||
403 | /* fix-up list */ | 403 | /* fix-up list */ |
404 | int fixup_id; | 404 | int fixup_id; |
405 | unsigned int fixup_forced:1; /* fixup explicitly set by user */ | ||
405 | const struct hda_fixup *fixup_list; | 406 | const struct hda_fixup *fixup_list; |
406 | const char *fixup_name; | 407 | const char *fixup_name; |
407 | 408 | ||
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 16133881e967..589e47c5aeb3 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -3722,7 +3722,7 @@ static void parse_digital(struct hda_codec *codec) | |||
3722 | } else { | 3722 | } else { |
3723 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | 3723 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; |
3724 | if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | 3724 | if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1) |
3725 | break; | 3725 | break; |
3726 | spec->slave_dig_outs[nums - 1] = dig_nid; | 3726 | spec->slave_dig_outs[nums - 1] = dig_nid; |
3727 | } | 3727 | } |
3728 | nums++; | 3728 | nums++; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 2c54629d62d1..ab0fd6d4961b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -1730,7 +1730,7 @@ static void azx_remove(struct pci_dev *pci) | |||
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | /* PCI IDs */ | 1732 | /* PCI IDs */ |
1733 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | 1733 | static const struct pci_device_id azx_ids[] = { |
1734 | /* CPT */ | 1734 | /* CPT */ |
1735 | { PCI_DEVICE(0x8086, 0x1c20), | 1735 | { PCI_DEVICE(0x8086, 0x1c20), |
1736 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, | 1736 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_PCH_NOPM }, |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index e51d15529215..ebd1fa6f015c 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -407,6 +407,16 @@ struct hda_fixup { | |||
407 | } v; | 407 | } v; |
408 | }; | 408 | }; |
409 | 409 | ||
410 | struct snd_hda_pin_quirk { | ||
411 | unsigned int codec; /* Codec vendor/device ID */ | ||
412 | unsigned short subvendor; /* PCI subvendor ID */ | ||
413 | const struct hda_pintbl *pins; /* list of matching pins */ | ||
414 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
415 | const char *name; | ||
416 | #endif | ||
417 | int value; /* quirk value */ | ||
418 | }; | ||
419 | |||
410 | /* fixup types */ | 420 | /* fixup types */ |
411 | enum { | 421 | enum { |
412 | HDA_FIXUP_INVALID, | 422 | HDA_FIXUP_INVALID, |
@@ -434,6 +444,10 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
434 | const struct hda_model_fixup *models, | 444 | const struct hda_model_fixup *models, |
435 | const struct snd_pci_quirk *quirk, | 445 | const struct snd_pci_quirk *quirk, |
436 | const struct hda_fixup *fixlist); | 446 | const struct hda_fixup *fixlist); |
447 | void snd_hda_pick_pin_fixup(struct hda_codec *codec, | ||
448 | const struct snd_hda_pin_quirk *pin_quirk, | ||
449 | const struct hda_fixup *fixlist); | ||
450 | |||
437 | 451 | ||
438 | /* | 452 | /* |
439 | * unsolicited event handler | 453 | * unsolicited event handler |
diff --git a/sound/pci/hda/hda_tegra.c b/sound/pci/hda/hda_tegra.c new file mode 100644 index 000000000000..a366ba9293a8 --- /dev/null +++ b/sound/pci/hda/hda_tegra.c | |||
@@ -0,0 +1,588 @@ | |||
1 | /* | ||
2 | * | ||
3 | * Implementation of primary ALSA driver code base for NVIDIA Tegra HDA. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms and conditions of the GNU General Public License, | ||
7 | * version 2, as published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/clk.h> | ||
20 | #include <linux/clocksource.h> | ||
21 | #include <linux/completion.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/dma-mapping.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/moduleparam.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/of_device.h> | ||
32 | #include <linux/reboot.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/time.h> | ||
35 | |||
36 | #include <sound/core.h> | ||
37 | #include <sound/initval.h> | ||
38 | |||
39 | #include "hda_codec.h" | ||
40 | #include "hda_controller.h" | ||
41 | #include "hda_priv.h" | ||
42 | |||
43 | /* Defines for Nvidia Tegra HDA support */ | ||
44 | #define HDA_BAR0 0x8000 | ||
45 | |||
46 | #define HDA_CFG_CMD 0x1004 | ||
47 | #define HDA_CFG_BAR0 0x1010 | ||
48 | |||
49 | #define HDA_ENABLE_IO_SPACE (1 << 0) | ||
50 | #define HDA_ENABLE_MEM_SPACE (1 << 1) | ||
51 | #define HDA_ENABLE_BUS_MASTER (1 << 2) | ||
52 | #define HDA_ENABLE_SERR (1 << 8) | ||
53 | #define HDA_DISABLE_INTR (1 << 10) | ||
54 | #define HDA_BAR0_INIT_PROGRAM 0xFFFFFFFF | ||
55 | #define HDA_BAR0_FINAL_PROGRAM (1 << 14) | ||
56 | |||
57 | /* IPFS */ | ||
58 | #define HDA_IPFS_CONFIG 0x180 | ||
59 | #define HDA_IPFS_EN_FPCI 0x1 | ||
60 | |||
61 | #define HDA_IPFS_FPCI_BAR0 0x80 | ||
62 | #define HDA_FPCI_BAR0_START 0x40 | ||
63 | |||
64 | #define HDA_IPFS_INTR_MASK 0x188 | ||
65 | #define HDA_IPFS_EN_INTR (1 << 16) | ||
66 | |||
67 | /* max number of SDs */ | ||
68 | #define NUM_CAPTURE_SD 1 | ||
69 | #define NUM_PLAYBACK_SD 1 | ||
70 | |||
71 | struct hda_tegra { | ||
72 | struct azx chip; | ||
73 | struct device *dev; | ||
74 | struct clk *hda_clk; | ||
75 | struct clk *hda2codec_2x_clk; | ||
76 | struct clk *hda2hdmi_clk; | ||
77 | void __iomem *regs; | ||
78 | }; | ||
79 | |||
80 | #ifdef CONFIG_PM | ||
81 | static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; | ||
82 | module_param(power_save, bint, 0644); | ||
83 | MODULE_PARM_DESC(power_save, | ||
84 | "Automatic power-saving timeout (in seconds, 0 = disable)."); | ||
85 | #else | ||
86 | static int power_save = 0; | ||
87 | #endif | ||
88 | |||
89 | /* | ||
90 | * DMA page allocation ops. | ||
91 | */ | ||
92 | static int dma_alloc_pages(struct azx *chip, int type, size_t size, | ||
93 | struct snd_dma_buffer *buf) | ||
94 | { | ||
95 | return snd_dma_alloc_pages(type, chip->card->dev, size, buf); | ||
96 | } | ||
97 | |||
98 | static void dma_free_pages(struct azx *chip, struct snd_dma_buffer *buf) | ||
99 | { | ||
100 | snd_dma_free_pages(buf); | ||
101 | } | ||
102 | |||
103 | static int substream_alloc_pages(struct azx *chip, | ||
104 | struct snd_pcm_substream *substream, | ||
105 | size_t size) | ||
106 | { | ||
107 | struct azx_dev *azx_dev = get_azx_dev(substream); | ||
108 | |||
109 | azx_dev->bufsize = 0; | ||
110 | azx_dev->period_bytes = 0; | ||
111 | azx_dev->format_val = 0; | ||
112 | return snd_pcm_lib_malloc_pages(substream, size); | ||
113 | } | ||
114 | |||
115 | static int substream_free_pages(struct azx *chip, | ||
116 | struct snd_pcm_substream *substream) | ||
117 | { | ||
118 | return snd_pcm_lib_free_pages(substream); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * Register access ops. Tegra HDA register access is DWORD only. | ||
123 | */ | ||
124 | static void hda_tegra_writel(u32 value, u32 *addr) | ||
125 | { | ||
126 | writel(value, addr); | ||
127 | } | ||
128 | |||
129 | static u32 hda_tegra_readl(u32 *addr) | ||
130 | { | ||
131 | return readl(addr); | ||
132 | } | ||
133 | |||
134 | static void hda_tegra_writew(u16 value, u16 *addr) | ||
135 | { | ||
136 | unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | ||
137 | void *dword_addr = (void *)((unsigned long)(addr) & ~0x3); | ||
138 | u32 v; | ||
139 | |||
140 | v = readl(dword_addr); | ||
141 | v &= ~(0xffff << shift); | ||
142 | v |= value << shift; | ||
143 | writel(v, dword_addr); | ||
144 | } | ||
145 | |||
146 | static u16 hda_tegra_readw(u16 *addr) | ||
147 | { | ||
148 | unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | ||
149 | void *dword_addr = (void *)((unsigned long)(addr) & ~0x3); | ||
150 | u32 v; | ||
151 | |||
152 | v = readl(dword_addr); | ||
153 | return (v >> shift) & 0xffff; | ||
154 | } | ||
155 | |||
156 | static void hda_tegra_writeb(u8 value, u8 *addr) | ||
157 | { | ||
158 | unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | ||
159 | void *dword_addr = (void *)((unsigned long)(addr) & ~0x3); | ||
160 | u32 v; | ||
161 | |||
162 | v = readl(dword_addr); | ||
163 | v &= ~(0xff << shift); | ||
164 | v |= value << shift; | ||
165 | writel(v, dword_addr); | ||
166 | } | ||
167 | |||
168 | static u8 hda_tegra_readb(u8 *addr) | ||
169 | { | ||
170 | unsigned int shift = ((unsigned long)(addr) & 0x3) << 3; | ||
171 | void *dword_addr = (void *)((unsigned long)(addr) & ~0x3); | ||
172 | u32 v; | ||
173 | |||
174 | v = readl(dword_addr); | ||
175 | return (v >> shift) & 0xff; | ||
176 | } | ||
177 | |||
178 | static const struct hda_controller_ops hda_tegra_ops = { | ||
179 | .reg_writel = hda_tegra_writel, | ||
180 | .reg_readl = hda_tegra_readl, | ||
181 | .reg_writew = hda_tegra_writew, | ||
182 | .reg_readw = hda_tegra_readw, | ||
183 | .reg_writeb = hda_tegra_writeb, | ||
184 | .reg_readb = hda_tegra_readb, | ||
185 | .dma_alloc_pages = dma_alloc_pages, | ||
186 | .dma_free_pages = dma_free_pages, | ||
187 | .substream_alloc_pages = substream_alloc_pages, | ||
188 | .substream_free_pages = substream_free_pages, | ||
189 | }; | ||
190 | |||
191 | static void hda_tegra_init(struct hda_tegra *hda) | ||
192 | { | ||
193 | u32 v; | ||
194 | |||
195 | /* Enable PCI access */ | ||
196 | v = readl(hda->regs + HDA_IPFS_CONFIG); | ||
197 | v |= HDA_IPFS_EN_FPCI; | ||
198 | writel(v, hda->regs + HDA_IPFS_CONFIG); | ||
199 | |||
200 | /* Enable MEM/IO space and bus master */ | ||
201 | v = readl(hda->regs + HDA_CFG_CMD); | ||
202 | v &= ~HDA_DISABLE_INTR; | ||
203 | v |= HDA_ENABLE_MEM_SPACE | HDA_ENABLE_IO_SPACE | | ||
204 | HDA_ENABLE_BUS_MASTER | HDA_ENABLE_SERR; | ||
205 | writel(v, hda->regs + HDA_CFG_CMD); | ||
206 | |||
207 | writel(HDA_BAR0_INIT_PROGRAM, hda->regs + HDA_CFG_BAR0); | ||
208 | writel(HDA_BAR0_FINAL_PROGRAM, hda->regs + HDA_CFG_BAR0); | ||
209 | writel(HDA_FPCI_BAR0_START, hda->regs + HDA_IPFS_FPCI_BAR0); | ||
210 | |||
211 | v = readl(hda->regs + HDA_IPFS_INTR_MASK); | ||
212 | v |= HDA_IPFS_EN_INTR; | ||
213 | writel(v, hda->regs + HDA_IPFS_INTR_MASK); | ||
214 | } | ||
215 | |||
216 | static int hda_tegra_enable_clocks(struct hda_tegra *data) | ||
217 | { | ||
218 | int rc; | ||
219 | |||
220 | rc = clk_prepare_enable(data->hda_clk); | ||
221 | if (rc) | ||
222 | return rc; | ||
223 | rc = clk_prepare_enable(data->hda2codec_2x_clk); | ||
224 | if (rc) | ||
225 | goto disable_hda; | ||
226 | rc = clk_prepare_enable(data->hda2hdmi_clk); | ||
227 | if (rc) | ||
228 | goto disable_codec_2x; | ||
229 | |||
230 | return 0; | ||
231 | |||
232 | disable_codec_2x: | ||
233 | clk_disable_unprepare(data->hda2codec_2x_clk); | ||
234 | disable_hda: | ||
235 | clk_disable_unprepare(data->hda_clk); | ||
236 | return rc; | ||
237 | } | ||
238 | |||
239 | static void hda_tegra_disable_clocks(struct hda_tegra *data) | ||
240 | { | ||
241 | clk_disable_unprepare(data->hda2hdmi_clk); | ||
242 | clk_disable_unprepare(data->hda2codec_2x_clk); | ||
243 | clk_disable_unprepare(data->hda_clk); | ||
244 | } | ||
245 | |||
246 | #ifdef CONFIG_PM_SLEEP | ||
247 | /* | ||
248 | * power management | ||
249 | */ | ||
250 | static int hda_tegra_suspend(struct device *dev) | ||
251 | { | ||
252 | struct snd_card *card = dev_get_drvdata(dev); | ||
253 | struct azx *chip = card->private_data; | ||
254 | struct azx_pcm *p; | ||
255 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); | ||
256 | |||
257 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
258 | list_for_each_entry(p, &chip->pcm_list, list) | ||
259 | snd_pcm_suspend_all(p->pcm); | ||
260 | if (chip->initialized) | ||
261 | snd_hda_suspend(chip->bus); | ||
262 | |||
263 | azx_stop_chip(chip); | ||
264 | azx_enter_link_reset(chip); | ||
265 | hda_tegra_disable_clocks(hda); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int hda_tegra_resume(struct device *dev) | ||
271 | { | ||
272 | struct snd_card *card = dev_get_drvdata(dev); | ||
273 | struct azx *chip = card->private_data; | ||
274 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); | ||
275 | int status; | ||
276 | |||
277 | hda_tegra_enable_clocks(hda); | ||
278 | |||
279 | /* Read STATESTS before controller reset */ | ||
280 | status = azx_readw(chip, STATESTS); | ||
281 | |||
282 | hda_tegra_init(hda); | ||
283 | |||
284 | azx_init_chip(chip, 1); | ||
285 | |||
286 | snd_hda_resume(chip->bus); | ||
287 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | #endif /* CONFIG_PM_SLEEP */ | ||
292 | |||
293 | static const struct dev_pm_ops hda_tegra_pm = { | ||
294 | SET_SYSTEM_SLEEP_PM_OPS(hda_tegra_suspend, hda_tegra_resume) | ||
295 | }; | ||
296 | |||
297 | /* | ||
298 | * reboot notifier for hang-up problem at power-down | ||
299 | */ | ||
300 | static int hda_tegra_halt(struct notifier_block *nb, unsigned long event, | ||
301 | void *buf) | ||
302 | { | ||
303 | struct azx *chip = container_of(nb, struct azx, reboot_notifier); | ||
304 | snd_hda_bus_reboot_notify(chip->bus); | ||
305 | azx_stop_chip(chip); | ||
306 | return NOTIFY_OK; | ||
307 | } | ||
308 | |||
309 | static void hda_tegra_notifier_register(struct azx *chip) | ||
310 | { | ||
311 | chip->reboot_notifier.notifier_call = hda_tegra_halt; | ||
312 | register_reboot_notifier(&chip->reboot_notifier); | ||
313 | } | ||
314 | |||
315 | static void hda_tegra_notifier_unregister(struct azx *chip) | ||
316 | { | ||
317 | if (chip->reboot_notifier.notifier_call) | ||
318 | unregister_reboot_notifier(&chip->reboot_notifier); | ||
319 | } | ||
320 | |||
321 | /* | ||
322 | * destructor | ||
323 | */ | ||
324 | static int hda_tegra_dev_free(struct snd_device *device) | ||
325 | { | ||
326 | int i; | ||
327 | struct azx *chip = device->device_data; | ||
328 | |||
329 | hda_tegra_notifier_unregister(chip); | ||
330 | |||
331 | if (chip->initialized) { | ||
332 | for (i = 0; i < chip->num_streams; i++) | ||
333 | azx_stream_stop(chip, &chip->azx_dev[i]); | ||
334 | azx_stop_chip(chip); | ||
335 | } | ||
336 | |||
337 | azx_free_stream_pages(chip); | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int hda_tegra_init_chip(struct azx *chip, struct platform_device *pdev) | ||
343 | { | ||
344 | struct hda_tegra *hda = container_of(chip, struct hda_tegra, chip); | ||
345 | struct device *dev = hda->dev; | ||
346 | struct resource *res; | ||
347 | int err; | ||
348 | |||
349 | hda->hda_clk = devm_clk_get(dev, "hda"); | ||
350 | if (IS_ERR(hda->hda_clk)) | ||
351 | return PTR_ERR(hda->hda_clk); | ||
352 | hda->hda2codec_2x_clk = devm_clk_get(dev, "hda2codec_2x"); | ||
353 | if (IS_ERR(hda->hda2codec_2x_clk)) | ||
354 | return PTR_ERR(hda->hda2codec_2x_clk); | ||
355 | hda->hda2hdmi_clk = devm_clk_get(dev, "hda2hdmi"); | ||
356 | if (IS_ERR(hda->hda2hdmi_clk)) | ||
357 | return PTR_ERR(hda->hda2hdmi_clk); | ||
358 | |||
359 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
360 | hda->regs = devm_ioremap_resource(dev, res); | ||
361 | if (IS_ERR(chip->remap_addr)) | ||
362 | return PTR_ERR(chip->remap_addr); | ||
363 | |||
364 | chip->remap_addr = hda->regs + HDA_BAR0; | ||
365 | chip->addr = res->start + HDA_BAR0; | ||
366 | |||
367 | err = hda_tegra_enable_clocks(hda); | ||
368 | if (err) | ||
369 | return err; | ||
370 | |||
371 | hda_tegra_init(hda); | ||
372 | |||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | /* | ||
377 | * The codecs were powered up in snd_hda_codec_new(). | ||
378 | * Now all initialization done, so turn them down if possible | ||
379 | */ | ||
380 | static void power_down_all_codecs(struct azx *chip) | ||
381 | { | ||
382 | struct hda_codec *codec; | ||
383 | list_for_each_entry(codec, &chip->bus->codec_list, list) | ||
384 | snd_hda_power_down(codec); | ||
385 | } | ||
386 | |||
387 | static int hda_tegra_first_init(struct azx *chip, struct platform_device *pdev) | ||
388 | { | ||
389 | struct snd_card *card = chip->card; | ||
390 | int err; | ||
391 | unsigned short gcap; | ||
392 | int irq_id = platform_get_irq(pdev, 0); | ||
393 | |||
394 | err = hda_tegra_init_chip(chip, pdev); | ||
395 | if (err) | ||
396 | return err; | ||
397 | |||
398 | err = devm_request_irq(chip->card->dev, irq_id, azx_interrupt, | ||
399 | IRQF_SHARED, KBUILD_MODNAME, chip); | ||
400 | if (err) { | ||
401 | dev_err(chip->card->dev, | ||
402 | "unable to request IRQ %d, disabling device\n", | ||
403 | irq_id); | ||
404 | return err; | ||
405 | } | ||
406 | chip->irq = irq_id; | ||
407 | |||
408 | synchronize_irq(chip->irq); | ||
409 | |||
410 | gcap = azx_readw(chip, GCAP); | ||
411 | dev_dbg(card->dev, "chipset global capabilities = 0x%x\n", gcap); | ||
412 | |||
413 | /* read number of streams from GCAP register instead of using | ||
414 | * hardcoded value | ||
415 | */ | ||
416 | chip->capture_streams = (gcap >> 8) & 0x0f; | ||
417 | chip->playback_streams = (gcap >> 12) & 0x0f; | ||
418 | if (!chip->playback_streams && !chip->capture_streams) { | ||
419 | /* gcap didn't give any info, switching to old method */ | ||
420 | chip->playback_streams = NUM_PLAYBACK_SD; | ||
421 | chip->capture_streams = NUM_CAPTURE_SD; | ||
422 | } | ||
423 | chip->capture_index_offset = 0; | ||
424 | chip->playback_index_offset = chip->capture_streams; | ||
425 | chip->num_streams = chip->playback_streams + chip->capture_streams; | ||
426 | chip->azx_dev = devm_kcalloc(card->dev, chip->num_streams, | ||
427 | sizeof(*chip->azx_dev), GFP_KERNEL); | ||
428 | if (!chip->azx_dev) | ||
429 | return -ENOMEM; | ||
430 | |||
431 | err = azx_alloc_stream_pages(chip); | ||
432 | if (err < 0) | ||
433 | return err; | ||
434 | |||
435 | /* initialize streams */ | ||
436 | azx_init_stream(chip); | ||
437 | |||
438 | /* initialize chip */ | ||
439 | azx_init_chip(chip, 1); | ||
440 | |||
441 | /* codec detection */ | ||
442 | if (!chip->codec_mask) { | ||
443 | dev_err(card->dev, "no codecs found!\n"); | ||
444 | return -ENODEV; | ||
445 | } | ||
446 | |||
447 | strcpy(card->driver, "tegra-hda"); | ||
448 | strcpy(card->shortname, "tegra-hda"); | ||
449 | snprintf(card->longname, sizeof(card->longname), | ||
450 | "%s at 0x%lx irq %i", | ||
451 | card->shortname, chip->addr, chip->irq); | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * constructor | ||
458 | */ | ||
459 | static int hda_tegra_create(struct snd_card *card, | ||
460 | unsigned int driver_caps, | ||
461 | const struct hda_controller_ops *hda_ops, | ||
462 | struct hda_tegra *hda) | ||
463 | { | ||
464 | static struct snd_device_ops ops = { | ||
465 | .dev_free = hda_tegra_dev_free, | ||
466 | }; | ||
467 | struct azx *chip; | ||
468 | int err; | ||
469 | |||
470 | chip = &hda->chip; | ||
471 | |||
472 | spin_lock_init(&chip->reg_lock); | ||
473 | mutex_init(&chip->open_mutex); | ||
474 | chip->card = card; | ||
475 | chip->ops = hda_ops; | ||
476 | chip->irq = -1; | ||
477 | chip->driver_caps = driver_caps; | ||
478 | chip->driver_type = driver_caps & 0xff; | ||
479 | chip->dev_index = 0; | ||
480 | INIT_LIST_HEAD(&chip->pcm_list); | ||
481 | INIT_LIST_HEAD(&chip->list); | ||
482 | |||
483 | chip->position_fix[0] = POS_FIX_AUTO; | ||
484 | chip->position_fix[1] = POS_FIX_AUTO; | ||
485 | chip->codec_probe_mask = -1; | ||
486 | |||
487 | chip->single_cmd = false; | ||
488 | chip->snoop = true; | ||
489 | |||
490 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | ||
491 | if (err < 0) { | ||
492 | dev_err(card->dev, "Error creating device\n"); | ||
493 | return err; | ||
494 | } | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static const struct of_device_id hda_tegra_match[] = { | ||
500 | { .compatible = "nvidia,tegra30-hda" }, | ||
501 | {}, | ||
502 | }; | ||
503 | MODULE_DEVICE_TABLE(of, hda_tegra_match); | ||
504 | |||
505 | static int hda_tegra_probe(struct platform_device *pdev) | ||
506 | { | ||
507 | struct snd_card *card; | ||
508 | struct azx *chip; | ||
509 | struct hda_tegra *hda; | ||
510 | int err; | ||
511 | const unsigned int driver_flags = AZX_DCAPS_RIRB_DELAY; | ||
512 | |||
513 | hda = devm_kzalloc(&pdev->dev, sizeof(*hda), GFP_KERNEL); | ||
514 | if (!hda) | ||
515 | return -ENOMEM; | ||
516 | hda->dev = &pdev->dev; | ||
517 | chip = &hda->chip; | ||
518 | |||
519 | err = snd_card_new(&pdev->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, | ||
520 | THIS_MODULE, 0, &card); | ||
521 | if (err < 0) { | ||
522 | dev_err(&pdev->dev, "Error creating card!\n"); | ||
523 | return err; | ||
524 | } | ||
525 | |||
526 | err = hda_tegra_create(card, driver_flags, &hda_tegra_ops, hda); | ||
527 | if (err < 0) | ||
528 | goto out_free; | ||
529 | card->private_data = chip; | ||
530 | |||
531 | dev_set_drvdata(&pdev->dev, card); | ||
532 | |||
533 | err = hda_tegra_first_init(chip, pdev); | ||
534 | if (err < 0) | ||
535 | goto out_free; | ||
536 | |||
537 | /* create codec instances */ | ||
538 | err = azx_codec_create(chip, NULL, 0, &power_save); | ||
539 | if (err < 0) | ||
540 | goto out_free; | ||
541 | |||
542 | err = azx_codec_configure(chip); | ||
543 | if (err < 0) | ||
544 | goto out_free; | ||
545 | |||
546 | /* create PCM streams */ | ||
547 | err = snd_hda_build_pcms(chip->bus); | ||
548 | if (err < 0) | ||
549 | goto out_free; | ||
550 | |||
551 | /* create mixer controls */ | ||
552 | err = azx_mixer_create(chip); | ||
553 | if (err < 0) | ||
554 | goto out_free; | ||
555 | |||
556 | err = snd_card_register(chip->card); | ||
557 | if (err < 0) | ||
558 | goto out_free; | ||
559 | |||
560 | chip->running = 1; | ||
561 | power_down_all_codecs(chip); | ||
562 | hda_tegra_notifier_register(chip); | ||
563 | |||
564 | return 0; | ||
565 | |||
566 | out_free: | ||
567 | snd_card_free(card); | ||
568 | return err; | ||
569 | } | ||
570 | |||
571 | static int hda_tegra_remove(struct platform_device *pdev) | ||
572 | { | ||
573 | return snd_card_free(dev_get_drvdata(&pdev->dev)); | ||
574 | } | ||
575 | |||
576 | static struct platform_driver tegra_platform_hda = { | ||
577 | .driver = { | ||
578 | .name = "tegra-hda", | ||
579 | .pm = &hda_tegra_pm, | ||
580 | .of_match_table = hda_tegra_match, | ||
581 | }, | ||
582 | .probe = hda_tegra_probe, | ||
583 | .remove = hda_tegra_remove, | ||
584 | }; | ||
585 | module_platform_driver(tegra_platform_hda); | ||
586 | |||
587 | MODULE_DESCRIPTION("Tegra HDA bus driver"); | ||
588 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index b4218a19df22..be0a9ee0b804 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -1127,10 +1127,6 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, | |||
1127 | AMP_OUT_UNMUTE); | 1127 | AMP_OUT_UNMUTE); |
1128 | 1128 | ||
1129 | eld = &per_pin->sink_eld; | 1129 | eld = &per_pin->sink_eld; |
1130 | if (!eld->monitor_present) { | ||
1131 | hdmi_set_channel_count(codec, per_pin->cvt_nid, channels); | ||
1132 | return; | ||
1133 | } | ||
1134 | 1130 | ||
1135 | if (!non_pcm && per_pin->chmap_set) | 1131 | if (!non_pcm && per_pin->chmap_set) |
1136 | ca = hdmi_manual_channel_allocation(channels, per_pin->chmap); | 1132 | ca = hdmi_manual_channel_allocation(channels, per_pin->chmap); |
@@ -3324,6 +3320,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
3324 | { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi }, | 3320 | { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi }, |
3325 | { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi }, | 3321 | { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi }, |
3326 | { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi }, | 3322 | { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi }, |
3323 | { .id = 0x10de0028, .name = "Tegra12x HDMI", .patch = patch_nvhdmi }, | ||
3327 | { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi }, | 3324 | { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi }, |
3328 | { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi }, | 3325 | { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi }, |
3329 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi }, | 3326 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi }, |
@@ -3380,6 +3377,7 @@ MODULE_ALIAS("snd-hda-codec-id:10de0019"); | |||
3380 | MODULE_ALIAS("snd-hda-codec-id:10de001a"); | 3377 | MODULE_ALIAS("snd-hda-codec-id:10de001a"); |
3381 | MODULE_ALIAS("snd-hda-codec-id:10de001b"); | 3378 | MODULE_ALIAS("snd-hda-codec-id:10de001b"); |
3382 | MODULE_ALIAS("snd-hda-codec-id:10de001c"); | 3379 | MODULE_ALIAS("snd-hda-codec-id:10de001c"); |
3380 | MODULE_ALIAS("snd-hda-codec-id:10de0028"); | ||
3383 | MODULE_ALIAS("snd-hda-codec-id:10de0040"); | 3381 | MODULE_ALIAS("snd-hda-codec-id:10de0040"); |
3384 | MODULE_ALIAS("snd-hda-codec-id:10de0041"); | 3382 | MODULE_ALIAS("snd-hda-codec-id:10de0041"); |
3385 | MODULE_ALIAS("snd-hda-codec-id:10de0042"); | 3383 | MODULE_ALIAS("snd-hda-codec-id:10de0042"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 49e884fb3e5d..08bb06969a57 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -951,7 +951,9 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = { | |||
951 | { 0x10ec0280, 0x1028, 0, "ALC3220" }, | 951 | { 0x10ec0280, 0x1028, 0, "ALC3220" }, |
952 | { 0x10ec0282, 0x1028, 0, "ALC3221" }, | 952 | { 0x10ec0282, 0x1028, 0, "ALC3221" }, |
953 | { 0x10ec0283, 0x1028, 0, "ALC3223" }, | 953 | { 0x10ec0283, 0x1028, 0, "ALC3223" }, |
954 | { 0x10ec0288, 0x1028, 0, "ALC3263" }, | ||
954 | { 0x10ec0292, 0x1028, 0, "ALC3226" }, | 955 | { 0x10ec0292, 0x1028, 0, "ALC3226" }, |
956 | { 0x10ec0293, 0x1028, 0, "ALC3235" }, | ||
955 | { 0x10ec0255, 0x1028, 0, "ALC3234" }, | 957 | { 0x10ec0255, 0x1028, 0, "ALC3234" }, |
956 | { 0x10ec0668, 0x1028, 0, "ALC3661" }, | 958 | { 0x10ec0668, 0x1028, 0, "ALC3661" }, |
957 | { } /* terminator */ | 959 | { } /* terminator */ |
@@ -3522,6 +3524,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) | |||
3522 | /* Direct Drive HP Amp control */ | 3524 | /* Direct Drive HP Amp control */ |
3523 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3525 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3524 | break; | 3526 | break; |
3527 | case 0x10ec0233: | ||
3525 | case 0x10ec0283: | 3528 | case 0x10ec0283: |
3526 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3529 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3527 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3530 | alc_write_coef_idx(codec, 0x45, 0xc429); |
@@ -3538,6 +3541,25 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec) | |||
3538 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3541 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3539 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3542 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3540 | break; | 3543 | break; |
3544 | case 0x10ec0293: | ||
3545 | /* SET Line1 JD to 0 */ | ||
3546 | val = alc_read_coef_idx(codec, 0x10); | ||
3547 | alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 6<<8); | ||
3548 | /* SET charge pump by verb */ | ||
3549 | val = alc_read_coefex_idx(codec, 0x57, 0x05); | ||
3550 | alc_write_coefex_idx(codec, 0x57, 0x05, (val & ~(1<<15|1<<13)) | 0x0); | ||
3551 | /* SET EN_OSW to 1 */ | ||
3552 | val = alc_read_coefex_idx(codec, 0x57, 0x03); | ||
3553 | alc_write_coefex_idx(codec, 0x57, 0x03, (val & ~(1<<10)) | (1<<10) ); | ||
3554 | /* Combo JD gating with LINE1-VREFO */ | ||
3555 | val = alc_read_coef_idx(codec, 0x1a); | ||
3556 | alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | (1<<3)); | ||
3557 | /* Set to TRS type */ | ||
3558 | alc_write_coef_idx(codec, 0x45, 0xc429); | ||
3559 | /* Combo Jack auto detect */ | ||
3560 | val = alc_read_coef_idx(codec, 0x4a); | ||
3561 | alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x000e); | ||
3562 | break; | ||
3541 | case 0x10ec0668: | 3563 | case 0x10ec0668: |
3542 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3564 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3543 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3565 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
@@ -3561,6 +3583,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
3561 | alc_write_coef_idx(codec, 0x06, 0x6100); | 3583 | alc_write_coef_idx(codec, 0x06, 0x6100); |
3562 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3584 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3563 | break; | 3585 | break; |
3586 | case 0x10ec0233: | ||
3564 | case 0x10ec0283: | 3587 | case 0x10ec0283: |
3565 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3588 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3566 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3589 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
@@ -3576,6 +3599,21 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
3576 | alc_write_coef_idx(codec, 0x19, 0xa208); | 3599 | alc_write_coef_idx(codec, 0x19, 0xa208); |
3577 | alc_write_coef_idx(codec, 0x2e, 0xacf0); | 3600 | alc_write_coef_idx(codec, 0x2e, 0xacf0); |
3578 | break; | 3601 | break; |
3602 | case 0x10ec0293: | ||
3603 | /* Set to TRS mode */ | ||
3604 | alc_write_coef_idx(codec, 0x45, 0xc429); | ||
3605 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | ||
3606 | /* SET charge pump by verb */ | ||
3607 | val = alc_read_coefex_idx(codec, 0x57, 0x05); | ||
3608 | alc_write_coefex_idx(codec, 0x57, 0x05, (val & ~(1<<15|1<<13)) | (1<<15|1<<13)); | ||
3609 | /* SET EN_OSW to 0 */ | ||
3610 | val = alc_read_coefex_idx(codec, 0x57, 0x03); | ||
3611 | alc_write_coefex_idx(codec, 0x57, 0x03, (val & ~(1<<10)) | 0x0); | ||
3612 | /* Combo JD gating without LINE1-VREFO */ | ||
3613 | val = alc_read_coef_idx(codec, 0x1a); | ||
3614 | alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | 0x0); | ||
3615 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | ||
3616 | break; | ||
3579 | case 0x10ec0668: | 3617 | case 0x10ec0668: |
3580 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3618 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3581 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3619 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
@@ -3591,6 +3629,8 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | |||
3591 | 3629 | ||
3592 | static void alc_headset_mode_default(struct hda_codec *codec) | 3630 | static void alc_headset_mode_default(struct hda_codec *codec) |
3593 | { | 3631 | { |
3632 | int val; | ||
3633 | |||
3594 | switch (codec->vendor_id) { | 3634 | switch (codec->vendor_id) { |
3595 | case 0x10ec0255: | 3635 | case 0x10ec0255: |
3596 | alc_write_coef_idx(codec, 0x45, 0xc089); | 3636 | alc_write_coef_idx(codec, 0x45, 0xc089); |
@@ -3598,6 +3638,7 @@ static void alc_headset_mode_default(struct hda_codec *codec) | |||
3598 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3638 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3599 | alc_write_coef_idx(codec, 0x49, 0x0049); | 3639 | alc_write_coef_idx(codec, 0x49, 0x0049); |
3600 | break; | 3640 | break; |
3641 | case 0x10ec0233: | ||
3601 | case 0x10ec0283: | 3642 | case 0x10ec0283: |
3602 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3643 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3603 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3644 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
@@ -3608,6 +3649,16 @@ static void alc_headset_mode_default(struct hda_codec *codec) | |||
3608 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3649 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3609 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3650 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3610 | break; | 3651 | break; |
3652 | case 0x10ec0293: | ||
3653 | /* Combo Jack auto detect */ | ||
3654 | val = alc_read_coef_idx(codec, 0x4a); | ||
3655 | alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x000e); | ||
3656 | /* Set to TRS type */ | ||
3657 | alc_write_coef_idx(codec, 0x45, 0xC429); | ||
3658 | /* Combo JD gating without LINE1-VREFO */ | ||
3659 | val = alc_read_coef_idx(codec, 0x1a); | ||
3660 | alc_write_coef_idx(codec, 0x1a, (val & ~(1<<3)) | 0x0); | ||
3661 | break; | ||
3611 | case 0x10ec0668: | 3662 | case 0x10ec0668: |
3612 | alc_write_coef_idx(codec, 0x11, 0x0041); | 3663 | alc_write_coef_idx(codec, 0x11, 0x0041); |
3613 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3664 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
@@ -3620,6 +3671,8 @@ static void alc_headset_mode_default(struct hda_codec *codec) | |||
3620 | /* Iphone type */ | 3671 | /* Iphone type */ |
3621 | static void alc_headset_mode_ctia(struct hda_codec *codec) | 3672 | static void alc_headset_mode_ctia(struct hda_codec *codec) |
3622 | { | 3673 | { |
3674 | int val; | ||
3675 | |||
3623 | switch (codec->vendor_id) { | 3676 | switch (codec->vendor_id) { |
3624 | case 0x10ec0255: | 3677 | case 0x10ec0255: |
3625 | /* Set to CTIA type */ | 3678 | /* Set to CTIA type */ |
@@ -3627,6 +3680,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) | |||
3627 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3680 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3628 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3681 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3629 | break; | 3682 | break; |
3683 | case 0x10ec0233: | ||
3630 | case 0x10ec0283: | 3684 | case 0x10ec0283: |
3631 | alc_write_coef_idx(codec, 0x45, 0xd429); | 3685 | alc_write_coef_idx(codec, 0x45, 0xd429); |
3632 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3686 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
@@ -3637,6 +3691,13 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) | |||
3637 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3691 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3638 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3692 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3639 | break; | 3693 | break; |
3694 | case 0x10ec0293: | ||
3695 | /* Set to ctia type */ | ||
3696 | alc_write_coef_idx(codec, 0x45, 0xd429); | ||
3697 | /* SET Line1 JD to 1 */ | ||
3698 | val = alc_read_coef_idx(codec, 0x10); | ||
3699 | alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 7<<8); | ||
3700 | break; | ||
3640 | case 0x10ec0668: | 3701 | case 0x10ec0668: |
3641 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3702 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3642 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3703 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
@@ -3649,6 +3710,8 @@ static void alc_headset_mode_ctia(struct hda_codec *codec) | |||
3649 | /* Nokia type */ | 3710 | /* Nokia type */ |
3650 | static void alc_headset_mode_omtp(struct hda_codec *codec) | 3711 | static void alc_headset_mode_omtp(struct hda_codec *codec) |
3651 | { | 3712 | { |
3713 | int val; | ||
3714 | |||
3652 | switch (codec->vendor_id) { | 3715 | switch (codec->vendor_id) { |
3653 | case 0x10ec0255: | 3716 | case 0x10ec0255: |
3654 | /* Set to OMTP Type */ | 3717 | /* Set to OMTP Type */ |
@@ -3656,6 +3719,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) | |||
3656 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3719 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3657 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3720 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3658 | break; | 3721 | break; |
3722 | case 0x10ec0233: | ||
3659 | case 0x10ec0283: | 3723 | case 0x10ec0283: |
3660 | alc_write_coef_idx(codec, 0x45, 0xe429); | 3724 | alc_write_coef_idx(codec, 0x45, 0xe429); |
3661 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3725 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
@@ -3666,6 +3730,13 @@ static void alc_headset_mode_omtp(struct hda_codec *codec) | |||
3666 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3730 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3667 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3731 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3668 | break; | 3732 | break; |
3733 | case 0x10ec0293: | ||
3734 | /* Set to omtp type */ | ||
3735 | alc_write_coef_idx(codec, 0x45, 0xe429); | ||
3736 | /* SET Line1 JD to 1 */ | ||
3737 | val = alc_read_coef_idx(codec, 0x10); | ||
3738 | alc_write_coef_idx(codec, 0x10, (val & ~(7<<8)) | 7<<8); | ||
3739 | break; | ||
3669 | case 0x10ec0668: | 3740 | case 0x10ec0668: |
3670 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3741 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3671 | alc_write_coef_idx(codec, 0x15, 0x0d50); | 3742 | alc_write_coef_idx(codec, 0x15, 0x0d50); |
@@ -3691,6 +3762,7 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
3691 | val = alc_read_coef_idx(codec, 0x46); | 3762 | val = alc_read_coef_idx(codec, 0x46); |
3692 | is_ctia = (val & 0x0070) == 0x0070; | 3763 | is_ctia = (val & 0x0070) == 0x0070; |
3693 | break; | 3764 | break; |
3765 | case 0x10ec0233: | ||
3694 | case 0x10ec0283: | 3766 | case 0x10ec0283: |
3695 | alc_write_coef_idx(codec, 0x45, 0xd029); | 3767 | alc_write_coef_idx(codec, 0x45, 0xd029); |
3696 | msleep(300); | 3768 | msleep(300); |
@@ -3703,6 +3775,16 @@ static void alc_determine_headset_type(struct hda_codec *codec) | |||
3703 | val = alc_read_coef_idx(codec, 0x6c); | 3775 | val = alc_read_coef_idx(codec, 0x6c); |
3704 | is_ctia = (val & 0x001c) == 0x001c; | 3776 | is_ctia = (val & 0x001c) == 0x001c; |
3705 | break; | 3777 | break; |
3778 | case 0x10ec0293: | ||
3779 | /* Combo Jack auto detect */ | ||
3780 | val = alc_read_coef_idx(codec, 0x4a); | ||
3781 | alc_write_coef_idx(codec, 0x4a, (val & 0xfff0) | 0x0008); | ||
3782 | /* Set to ctia type */ | ||
3783 | alc_write_coef_idx(codec, 0x45, 0xD429); | ||
3784 | msleep(300); | ||
3785 | val = alc_read_coef_idx(codec, 0x46); | ||
3786 | is_ctia = (val & 0x0070) == 0x0070; | ||
3787 | break; | ||
3706 | case 0x10ec0668: | 3788 | case 0x10ec0668: |
3707 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3789 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3708 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3790 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
@@ -3894,6 +3976,39 @@ static void alc_fixup_no_shutup(struct hda_codec *codec, | |||
3894 | } | 3976 | } |
3895 | } | 3977 | } |
3896 | 3978 | ||
3979 | static void alc_fixup_disable_aamix(struct hda_codec *codec, | ||
3980 | const struct hda_fixup *fix, int action) | ||
3981 | { | ||
3982 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | ||
3983 | struct alc_spec *spec = codec->spec; | ||
3984 | /* Disable AA-loopback as it causes white noise */ | ||
3985 | spec->gen.mixer_nid = 0; | ||
3986 | } | ||
3987 | } | ||
3988 | |||
3989 | static unsigned int alc_power_filter_xps13(struct hda_codec *codec, | ||
3990 | hda_nid_t nid, | ||
3991 | unsigned int power_state) | ||
3992 | { | ||
3993 | struct alc_spec *spec = codec->spec; | ||
3994 | |||
3995 | /* Avoid pop noises when headphones are plugged in */ | ||
3996 | if (spec->gen.hp_jack_present) | ||
3997 | if (nid == codec->afg || nid == 0x02) | ||
3998 | return AC_PWRST_D0; | ||
3999 | return power_state; | ||
4000 | } | ||
4001 | |||
4002 | static void alc_fixup_dell_xps13(struct hda_codec *codec, | ||
4003 | const struct hda_fixup *fix, int action) | ||
4004 | { | ||
4005 | if (action == HDA_FIXUP_ACT_PROBE) { | ||
4006 | struct alc_spec *spec = codec->spec; | ||
4007 | spec->shutup = alc_no_shutup; | ||
4008 | codec->power_filter = alc_power_filter_xps13; | ||
4009 | } | ||
4010 | } | ||
4011 | |||
3897 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | 4012 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, |
3898 | const struct hda_fixup *fix, int action) | 4013 | const struct hda_fixup *fix, int action) |
3899 | { | 4014 | { |
@@ -4110,6 +4225,7 @@ enum { | |||
4110 | ALC269_FIXUP_ASUS_G73JW, | 4225 | ALC269_FIXUP_ASUS_G73JW, |
4111 | ALC269_FIXUP_LENOVO_EAPD, | 4226 | ALC269_FIXUP_LENOVO_EAPD, |
4112 | ALC275_FIXUP_SONY_HWEQ, | 4227 | ALC275_FIXUP_SONY_HWEQ, |
4228 | ALC275_FIXUP_SONY_DISABLE_AAMIX, | ||
4113 | ALC271_FIXUP_DMIC, | 4229 | ALC271_FIXUP_DMIC, |
4114 | ALC269_FIXUP_PCM_44K, | 4230 | ALC269_FIXUP_PCM_44K, |
4115 | ALC269_FIXUP_STEREO_DMIC, | 4231 | ALC269_FIXUP_STEREO_DMIC, |
@@ -4159,6 +4275,8 @@ enum { | |||
4159 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, | 4275 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, |
4160 | ALC255_FIXUP_HEADSET_MODE, | 4276 | ALC255_FIXUP_HEADSET_MODE, |
4161 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4277 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4278 | ALC293_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
4279 | ALC292_FIXUP_TPT440_DOCK, | ||
4162 | }; | 4280 | }; |
4163 | 4281 | ||
4164 | static const struct hda_fixup alc269_fixups[] = { | 4282 | static const struct hda_fixup alc269_fixups[] = { |
@@ -4213,6 +4331,12 @@ static const struct hda_fixup alc269_fixups[] = { | |||
4213 | .chained = true, | 4331 | .chained = true, |
4214 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 | 4332 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 |
4215 | }, | 4333 | }, |
4334 | [ALC275_FIXUP_SONY_DISABLE_AAMIX] = { | ||
4335 | .type = HDA_FIXUP_FUNC, | ||
4336 | .v.func = alc_fixup_disable_aamix, | ||
4337 | .chained = true, | ||
4338 | .chain_id = ALC269_FIXUP_SONY_VAIO | ||
4339 | }, | ||
4216 | [ALC271_FIXUP_DMIC] = { | 4340 | [ALC271_FIXUP_DMIC] = { |
4217 | .type = HDA_FIXUP_FUNC, | 4341 | .type = HDA_FIXUP_FUNC, |
4218 | .v.func = alc271_fixup_dmic, | 4342 | .v.func = alc271_fixup_dmic, |
@@ -4552,6 +4676,26 @@ static const struct hda_fixup alc269_fixups[] = { | |||
4552 | .type = HDA_FIXUP_FUNC, | 4676 | .type = HDA_FIXUP_FUNC, |
4553 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, | 4677 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, |
4554 | }, | 4678 | }, |
4679 | [ALC293_FIXUP_DELL1_MIC_NO_PRESENCE] = { | ||
4680 | .type = HDA_FIXUP_PINS, | ||
4681 | .v.pins = (const struct hda_pintbl[]) { | ||
4682 | { 0x18, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | ||
4683 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | ||
4684 | { } | ||
4685 | }, | ||
4686 | .chained = true, | ||
4687 | .chain_id = ALC269_FIXUP_HEADSET_MODE | ||
4688 | }, | ||
4689 | [ALC292_FIXUP_TPT440_DOCK] = { | ||
4690 | .type = HDA_FIXUP_PINS, | ||
4691 | .v.pins = (const struct hda_pintbl[]) { | ||
4692 | { 0x16, 0x21211010 }, /* dock headphone */ | ||
4693 | { 0x19, 0x21a11010 }, /* dock mic */ | ||
4694 | { } | ||
4695 | }, | ||
4696 | .chained = true, | ||
4697 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | ||
4698 | }, | ||
4555 | }; | 4699 | }; |
4556 | 4700 | ||
4557 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4701 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
@@ -4604,11 +4748,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4604 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4748 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4605 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4749 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4606 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4750 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4607 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4608 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4609 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), | 4751 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), |
4610 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4752 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4611 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4753 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4754 | SND_PCI_QUIRK(0x1028, 0x064a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4755 | SND_PCI_QUIRK(0x1028, 0x064b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4612 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4756 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4613 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4757 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4614 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4758 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
@@ -4629,6 +4773,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4629 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4773 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4630 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4774 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4631 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4775 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4776 | SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4777 | SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4632 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4778 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
4633 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 4779 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
4634 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4780 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
@@ -4702,6 +4848,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4702 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 4848 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
4703 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4849 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4704 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4850 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4851 | SND_PCI_QUIRK(0x104d, 0x9099, "Sony VAIO S13", ALC275_FIXUP_SONY_DISABLE_AAMIX), | ||
4705 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 4852 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
4706 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), | 4853 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), |
4707 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 4854 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
@@ -4715,7 +4862,8 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4715 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), | 4862 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), |
4716 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), | 4863 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), |
4717 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), | 4864 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), |
4718 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4865 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad T440s", ALC292_FIXUP_TPT440_DOCK), |
4866 | SND_PCI_QUIRK(0x17aa, 0x220e, "Thinkpad T440p", ALC292_FIXUP_TPT440_DOCK), | ||
4719 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4867 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4720 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4868 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4721 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4869 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
@@ -4793,9 +4941,54 @@ static const struct hda_model_fixup alc269_fixup_models[] = { | |||
4793 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, | 4941 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, |
4794 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, | 4942 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, |
4795 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, | 4943 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, |
4944 | {.id = ALC292_FIXUP_TPT440_DOCK, .name = "tpt440-dock"}, | ||
4796 | {} | 4945 | {} |
4797 | }; | 4946 | }; |
4798 | 4947 | ||
4948 | static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = { | ||
4949 | { | ||
4950 | .codec = 0x10ec0293, | ||
4951 | .subvendor = 0x1028, | ||
4952 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
4953 | .name = "Dell", | ||
4954 | #endif | ||
4955 | .pins = (const struct hda_pintbl[]) { | ||
4956 | {0x12, 0x40000000}, | ||
4957 | {0x13, 0x90a60140}, | ||
4958 | {0x14, 0x90170110}, | ||
4959 | {0x15, 0x0221401f}, | ||
4960 | {0x16, 0x21014020}, | ||
4961 | {0x18, 0x411111f0}, | ||
4962 | {0x19, 0x21a19030}, | ||
4963 | {0x1a, 0x411111f0}, | ||
4964 | {0x1b, 0x411111f0}, | ||
4965 | {0x1d, 0x40700001}, | ||
4966 | {0x1e, 0x411111f0}, | ||
4967 | }, | ||
4968 | .value = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
4969 | }, | ||
4970 | { | ||
4971 | .codec = 0x10ec0255, | ||
4972 | .subvendor = 0x1028, | ||
4973 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
4974 | .name = "Dell", | ||
4975 | #endif | ||
4976 | .pins = (const struct hda_pintbl[]) { | ||
4977 | {0x12, 0x90a60140}, | ||
4978 | {0x14, 0x90170110}, | ||
4979 | {0x17, 0x40000000}, | ||
4980 | {0x18, 0x411111f0}, | ||
4981 | {0x19, 0x411111f0}, | ||
4982 | {0x1a, 0x411111f0}, | ||
4983 | {0x1b, 0x411111f0}, | ||
4984 | {0x1d, 0x40700001}, | ||
4985 | {0x1e, 0x411111f0}, | ||
4986 | {0x21, 0x02211020}, | ||
4987 | }, | ||
4988 | .value = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | ||
4989 | }, | ||
4990 | {} | ||
4991 | }; | ||
4799 | 4992 | ||
4800 | static void alc269_fill_coef(struct hda_codec *codec) | 4993 | static void alc269_fill_coef(struct hda_codec *codec) |
4801 | { | 4994 | { |
@@ -4857,6 +5050,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
4857 | 5050 | ||
4858 | snd_hda_pick_fixup(codec, alc269_fixup_models, | 5051 | snd_hda_pick_fixup(codec, alc269_fixup_models, |
4859 | alc269_fixup_tbl, alc269_fixups); | 5052 | alc269_fixup_tbl, alc269_fixups); |
5053 | snd_hda_pick_pin_fixup(codec, alc269_pin_fixup_tbl, alc269_fixups); | ||
4860 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5054 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
4861 | 5055 | ||
4862 | alc_auto_parse_customize_define(codec); | 5056 | alc_auto_parse_customize_define(codec); |
@@ -5313,6 +5507,8 @@ enum { | |||
5313 | ALC662_FIXUP_BASS_1A, | 5507 | ALC662_FIXUP_BASS_1A, |
5314 | ALC662_FIXUP_BASS_CHMAP, | 5508 | ALC662_FIXUP_BASS_CHMAP, |
5315 | ALC668_FIXUP_AUTO_MUTE, | 5509 | ALC668_FIXUP_AUTO_MUTE, |
5510 | ALC668_FIXUP_DELL_DISABLE_AAMIX, | ||
5511 | ALC668_FIXUP_DELL_XPS13, | ||
5316 | }; | 5512 | }; |
5317 | 5513 | ||
5318 | static const struct hda_fixup alc662_fixups[] = { | 5514 | static const struct hda_fixup alc662_fixups[] = { |
@@ -5479,6 +5675,18 @@ static const struct hda_fixup alc662_fixups[] = { | |||
5479 | .type = HDA_FIXUP_FUNC, | 5675 | .type = HDA_FIXUP_FUNC, |
5480 | .v.func = alc_fixup_inv_dmic_0x12, | 5676 | .v.func = alc_fixup_inv_dmic_0x12, |
5481 | }, | 5677 | }, |
5678 | [ALC668_FIXUP_DELL_XPS13] = { | ||
5679 | .type = HDA_FIXUP_FUNC, | ||
5680 | .v.func = alc_fixup_dell_xps13, | ||
5681 | .chained = true, | ||
5682 | .chain_id = ALC668_FIXUP_DELL_DISABLE_AAMIX | ||
5683 | }, | ||
5684 | [ALC668_FIXUP_DELL_DISABLE_AAMIX] = { | ||
5685 | .type = HDA_FIXUP_FUNC, | ||
5686 | .v.func = alc_fixup_disable_aamix, | ||
5687 | .chained = true, | ||
5688 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE | ||
5689 | }, | ||
5482 | [ALC668_FIXUP_AUTO_MUTE] = { | 5690 | [ALC668_FIXUP_AUTO_MUTE] = { |
5483 | .type = HDA_FIXUP_FUNC, | 5691 | .type = HDA_FIXUP_FUNC, |
5484 | .v.func = alc_fixup_auto_mute_via_amp, | 5692 | .v.func = alc_fixup_auto_mute_via_amp, |
@@ -5539,7 +5747,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = { | |||
5539 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 5747 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
5540 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5748 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5541 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5749 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5542 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5750 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_XPS13), |
5543 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5751 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5544 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5752 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5545 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5753 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 75515b494034..7f40a150899c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -795,7 +795,7 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) | |||
795 | } | 795 | } |
796 | 796 | ||
797 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { | 797 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { |
798 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", | 798 | if (sscanf(dev->name, "HP_Mute_LED_%u_%x", |
799 | &spec->gpio_led_polarity, | 799 | &spec->gpio_led_polarity, |
800 | &spec->gpio_led) == 2) { | 800 | &spec->gpio_led) == 2) { |
801 | unsigned int max_gpio; | 801 | unsigned int max_gpio; |
@@ -808,7 +808,7 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) | |||
808 | spec->vref_mute_led_nid = spec->gpio_led; | 808 | spec->vref_mute_led_nid = spec->gpio_led; |
809 | return 1; | 809 | return 1; |
810 | } | 810 | } |
811 | if (sscanf(dev->name, "HP_Mute_LED_%d", | 811 | if (sscanf(dev->name, "HP_Mute_LED_%u", |
812 | &spec->gpio_led_polarity) == 1) { | 812 | &spec->gpio_led_polarity) == 1) { |
813 | set_hp_led_gpio(codec); | 813 | set_hp_led_gpio(codec); |
814 | return 1; | 814 | return 1; |
diff --git a/sound/pci/lola/lola_proc.c b/sound/pci/lola/lola_proc.c index 04df83defc09..c241dc06dd92 100644 --- a/sound/pci/lola/lola_proc.c +++ b/sound/pci/lola/lola_proc.c | |||
@@ -151,7 +151,7 @@ static void lola_proc_codec_rw_write(struct snd_info_entry *entry, | |||
151 | char line[64]; | 151 | char line[64]; |
152 | unsigned int id, verb, data, extdata; | 152 | unsigned int id, verb, data, extdata; |
153 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | 153 | while (!snd_info_get_line(buffer, line, sizeof(line))) { |
154 | if (sscanf(line, "%i %i %i %i", &id, &verb, &data, &extdata) != 4) | 154 | if (sscanf(line, "%u %u %u %u", &id, &verb, &data, &extdata) != 4) |
155 | continue; | 155 | continue; |
156 | lola_codec_read(chip, id, verb, data, extdata, | 156 | lola_codec_read(chip, id, verb, data, extdata, |
157 | &chip->debug_res, | 157 | &chip->debug_res, |
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 2d8e95e9fbe5..e8f38e5df10a 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | /* #define RMH_DEBUG 1 */ | 25 | /* #define RMH_DEBUG 1 */ |
26 | 26 | ||
27 | #include <linux/bitops.h> | ||
27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
28 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
@@ -429,11 +430,6 @@ int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data) | |||
429 | return ret; | 430 | return ret; |
430 | } | 431 | } |
431 | 432 | ||
432 | #define CSES_TIMEOUT 100 /* microseconds */ | ||
433 | #define CSES_CE 0x0001 | ||
434 | #define CSES_BROADCAST 0x0002 | ||
435 | #define CSES_UPDATE_LDSV 0x0004 | ||
436 | |||
437 | #define PIPE_INFO_TO_CMD(capture, pipe) \ | 433 | #define PIPE_INFO_TO_CMD(capture, pipe) \ |
438 | ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET) | 434 | ((u32)((u32)(pipe) | ((capture) ? ID_IS_CAPTURE : 0L)) << ID_OFFSET) |
439 | 435 | ||
@@ -519,7 +515,6 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, | |||
519 | *r_needed += 1; | 515 | *r_needed += 1; |
520 | } | 516 | } |
521 | 517 | ||
522 | #if 0 | ||
523 | dev_dbg(chip->card->dev, | 518 | dev_dbg(chip->card->dev, |
524 | "CMD_08_ASK_BUFFERS: needed %d, freed %d\n", | 519 | "CMD_08_ASK_BUFFERS: needed %d, freed %d\n", |
525 | *r_needed, *r_freed); | 520 | *r_needed, *r_freed); |
@@ -530,7 +525,6 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, | |||
530 | chip->rmh.stat[i], | 525 | chip->rmh.stat[i], |
531 | chip->rmh.stat[i] & MASK_DATA_SIZE); | 526 | chip->rmh.stat[i] & MASK_DATA_SIZE); |
532 | } | 527 | } |
533 | #endif | ||
534 | } | 528 | } |
535 | 529 | ||
536 | spin_unlock_irqrestore(&chip->msg_lock, flags); | 530 | spin_unlock_irqrestore(&chip->msg_lock, flags); |
@@ -971,9 +965,9 @@ int lx_level_peaks(struct lx6464es *chip, int is_capture, int channels, | |||
971 | 965 | ||
972 | /* interrupt handling */ | 966 | /* interrupt handling */ |
973 | #define PCX_IRQ_NONE 0 | 967 | #define PCX_IRQ_NONE 0 |
974 | #define IRQCS_ACTIVE_PCIDB 0x00002000L /* Bit nø 13 */ | 968 | #define IRQCS_ACTIVE_PCIDB BIT(13) |
975 | #define IRQCS_ENABLE_PCIIRQ 0x00000100L /* Bit nø 08 */ | 969 | #define IRQCS_ENABLE_PCIIRQ BIT(8) |
976 | #define IRQCS_ENABLE_PCIDB 0x00000200L /* Bit nø 09 */ | 970 | #define IRQCS_ENABLE_PCIDB BIT(9) |
977 | 971 | ||
978 | static u32 lx_interrupt_test_ack(struct lx6464es *chip) | 972 | static u32 lx_interrupt_test_ack(struct lx6464es *chip) |
979 | { | 973 | { |
@@ -1030,25 +1024,21 @@ static int lx_interrupt_handle_async_events(struct lx6464es *chip, u32 irqsrc, | |||
1030 | int err; | 1024 | int err; |
1031 | u32 stat[9]; /* answer from CMD_04_GET_EVENT */ | 1025 | u32 stat[9]; /* answer from CMD_04_GET_EVENT */ |
1032 | 1026 | ||
1033 | /* On peut optimiser pour ne pas lire les evenements vides | 1027 | /* We can optimize this to not read dumb events. |
1034 | * les mots de réponse sont dans l'ordre suivant : | 1028 | * Answer words are in the following order: |
1035 | * Stat[0] mot de status général | 1029 | * Stat[0] general status |
1036 | * Stat[1] fin de buffer OUT pF | 1030 | * Stat[1] end of buffer OUT pF |
1037 | * Stat[2] fin de buffer OUT pf | 1031 | * Stat[2] end of buffer OUT pf |
1038 | * Stat[3] fin de buffer IN pF | 1032 | * Stat[3] end of buffer IN pF |
1039 | * Stat[4] fin de buffer IN pf | 1033 | * Stat[4] end of buffer IN pf |
1040 | * Stat[5] underrun poid fort | 1034 | * Stat[5] MSB underrun |
1041 | * Stat[6] underrun poid faible | 1035 | * Stat[6] LSB underrun |
1042 | * Stat[7] overrun poid fort | 1036 | * Stat[7] MSB overrun |
1043 | * Stat[8] overrun poid faible | 1037 | * Stat[8] LSB overrun |
1044 | * */ | 1038 | * */ |
1045 | 1039 | ||
1046 | u64 orun_mask; | 1040 | u64 orun_mask; |
1047 | u64 urun_mask; | 1041 | u64 urun_mask; |
1048 | #if 0 | ||
1049 | int has_underrun = (irqsrc & MASK_SYS_STATUS_URUN) ? 1 : 0; | ||
1050 | int has_overrun = (irqsrc & MASK_SYS_STATUS_ORUN) ? 1 : 0; | ||
1051 | #endif | ||
1052 | int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0; | 1042 | int eb_pending_out = (irqsrc & MASK_SYS_STATUS_EOBO) ? 1 : 0; |
1053 | int eb_pending_in = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0; | 1043 | int eb_pending_in = (irqsrc & MASK_SYS_STATUS_EOBI) ? 1 : 0; |
1054 | 1044 | ||
@@ -1199,9 +1189,8 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) | |||
1199 | if (irqsrc & MASK_SYS_STATUS_CMD_DONE) | 1189 | if (irqsrc & MASK_SYS_STATUS_CMD_DONE) |
1200 | goto exit; | 1190 | goto exit; |
1201 | 1191 | ||
1202 | #if 0 | ||
1203 | if (irqsrc & MASK_SYS_STATUS_EOBI) | 1192 | if (irqsrc & MASK_SYS_STATUS_EOBI) |
1204 | dev_dgg(chip->card->dev, "interrupt: EOBI\n"); | 1193 | dev_dbg(chip->card->dev, "interrupt: EOBI\n"); |
1205 | 1194 | ||
1206 | if (irqsrc & MASK_SYS_STATUS_EOBO) | 1195 | if (irqsrc & MASK_SYS_STATUS_EOBO) |
1207 | dev_dbg(chip->card->dev, "interrupt: EOBO\n"); | 1196 | dev_dbg(chip->card->dev, "interrupt: EOBO\n"); |
@@ -1211,7 +1200,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) | |||
1211 | 1200 | ||
1212 | if (irqsrc & MASK_SYS_STATUS_ORUN) | 1201 | if (irqsrc & MASK_SYS_STATUS_ORUN) |
1213 | dev_dbg(chip->card->dev, "interrupt: ORUN\n"); | 1202 | dev_dbg(chip->card->dev, "interrupt: ORUN\n"); |
1214 | #endif | ||
1215 | 1203 | ||
1216 | if (async_pending) { | 1204 | if (async_pending) { |
1217 | u64 notified_in_pipe_mask = 0; | 1205 | u64 notified_in_pipe_mask = 0; |
@@ -1238,7 +1226,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) | |||
1238 | } | 1226 | } |
1239 | 1227 | ||
1240 | if (async_escmd) { | 1228 | if (async_escmd) { |
1241 | #if 0 | ||
1242 | /* backdoor for ethersound commands | 1229 | /* backdoor for ethersound commands |
1243 | * | 1230 | * |
1244 | * for now, we do not need this | 1231 | * for now, we do not need this |
@@ -1246,7 +1233,6 @@ irqreturn_t lx_interrupt(int irq, void *dev_id) | |||
1246 | * */ | 1233 | * */ |
1247 | 1234 | ||
1248 | dev_dbg(chip->card->dev, "interrupt requests escmd handling\n"); | 1235 | dev_dbg(chip->card->dev, "interrupt requests escmd handling\n"); |
1249 | #endif | ||
1250 | } | 1236 | } |
1251 | 1237 | ||
1252 | exit: | 1238 | exit: |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index 4789619a52d8..27e3fc4a536b 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -35,7 +35,7 @@ config SND_AT91_SOC_SAM9G20_WM8731 | |||
35 | 35 | ||
36 | config SND_ATMEL_SOC_WM8904 | 36 | config SND_ATMEL_SOC_WM8904 |
37 | tristate "Atmel ASoC driver for boards using WM8904 codec" | 37 | tristate "Atmel ASoC driver for boards using WM8904 codec" |
38 | depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC | 38 | depends on ARCH_AT91 && ATMEL_SSC && SND_ATMEL_SOC && I2C |
39 | select SND_ATMEL_SOC_SSC | 39 | select SND_ATMEL_SOC_SSC |
40 | select SND_ATMEL_SOC_DMA | 40 | select SND_ATMEL_SOC_DMA |
41 | select SND_SOC_WM8904 | 41 | select SND_SOC_WM8904 |
diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c index 33ec592ecd75..a366b3503c28 100644 --- a/sound/soc/atmel/atmel-pcm-pdc.c +++ b/sound/soc/atmel/atmel-pcm-pdc.c | |||
@@ -76,12 +76,6 @@ struct atmel_runtime_data { | |||
76 | size_t period_size; | 76 | size_t period_size; |
77 | 77 | ||
78 | dma_addr_t period_ptr; /* physical address of next period */ | 78 | dma_addr_t period_ptr; /* physical address of next period */ |
79 | |||
80 | /* PDC register save */ | ||
81 | u32 pdc_xpr_save; | ||
82 | u32 pdc_xcr_save; | ||
83 | u32 pdc_xnpr_save; | ||
84 | u32 pdc_xncr_save; | ||
85 | }; | 79 | }; |
86 | 80 | ||
87 | /*--------------------------------------------------------------------------*\ | 81 | /*--------------------------------------------------------------------------*\ |
@@ -320,67 +314,10 @@ static struct snd_pcm_ops atmel_pcm_ops = { | |||
320 | .mmap = atmel_pcm_mmap, | 314 | .mmap = atmel_pcm_mmap, |
321 | }; | 315 | }; |
322 | 316 | ||
323 | |||
324 | /*--------------------------------------------------------------------------*\ | ||
325 | * ASoC platform driver | ||
326 | \*--------------------------------------------------------------------------*/ | ||
327 | #ifdef CONFIG_PM | ||
328 | static int atmel_pcm_suspend(struct snd_soc_dai *dai) | ||
329 | { | ||
330 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
331 | struct atmel_runtime_data *prtd; | ||
332 | struct atmel_pcm_dma_params *params; | ||
333 | |||
334 | if (!runtime) | ||
335 | return 0; | ||
336 | |||
337 | prtd = runtime->private_data; | ||
338 | params = prtd->params; | ||
339 | |||
340 | /* disable the PDC and save the PDC registers */ | ||
341 | |||
342 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable); | ||
343 | |||
344 | prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr); | ||
345 | prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr); | ||
346 | prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr); | ||
347 | prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr); | ||
348 | |||
349 | return 0; | ||
350 | } | ||
351 | |||
352 | static int atmel_pcm_resume(struct snd_soc_dai *dai) | ||
353 | { | ||
354 | struct snd_pcm_runtime *runtime = dai->runtime; | ||
355 | struct atmel_runtime_data *prtd; | ||
356 | struct atmel_pcm_dma_params *params; | ||
357 | |||
358 | if (!runtime) | ||
359 | return 0; | ||
360 | |||
361 | prtd = runtime->private_data; | ||
362 | params = prtd->params; | ||
363 | |||
364 | /* restore the PDC registers and enable the PDC */ | ||
365 | ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save); | ||
366 | ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save); | ||
367 | ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save); | ||
368 | ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save); | ||
369 | |||
370 | ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable); | ||
371 | return 0; | ||
372 | } | ||
373 | #else | ||
374 | #define atmel_pcm_suspend NULL | ||
375 | #define atmel_pcm_resume NULL | ||
376 | #endif | ||
377 | |||
378 | static struct snd_soc_platform_driver atmel_soc_platform = { | 317 | static struct snd_soc_platform_driver atmel_soc_platform = { |
379 | .ops = &atmel_pcm_ops, | 318 | .ops = &atmel_pcm_ops, |
380 | .pcm_new = atmel_pcm_new, | 319 | .pcm_new = atmel_pcm_new, |
381 | .pcm_free = atmel_pcm_free, | 320 | .pcm_free = atmel_pcm_free, |
382 | .suspend = atmel_pcm_suspend, | ||
383 | .resume = atmel_pcm_resume, | ||
384 | }; | 321 | }; |
385 | 322 | ||
386 | int atmel_pcm_pdc_platform_register(struct device *dev) | 323 | int atmel_pcm_pdc_platform_register(struct device *dev) |
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index f65f08beac31..9579799ace54 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c | |||
@@ -80,17 +80,6 @@ static const struct snd_soc_dapm_route afeb9260_audio_map[] = { | |||
80 | {"MICIN", NULL, "Mic Jack"}, | 80 | {"MICIN", NULL, "Mic Jack"}, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | ||
84 | { | ||
85 | struct snd_soc_codec *codec = rtd->codec; | ||
86 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
87 | |||
88 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
89 | snd_soc_dapm_enable_pin(dapm, "Line In"); | ||
90 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | 83 | ||
95 | /* Digital audio interface glue - connects codec <--> CPU */ | 84 | /* Digital audio interface glue - connects codec <--> CPU */ |
96 | static struct snd_soc_dai_link afeb9260_dai = { | 85 | static struct snd_soc_dai_link afeb9260_dai = { |
@@ -100,7 +89,6 @@ static struct snd_soc_dai_link afeb9260_dai = { | |||
100 | .codec_dai_name = "tlv320aic23-hifi", | 89 | .codec_dai_name = "tlv320aic23-hifi", |
101 | .platform_name = "atmel_pcm-audio", | 90 | .platform_name = "atmel_pcm-audio", |
102 | .codec_name = "tlv320aic23-codec.0-001a", | 91 | .codec_name = "tlv320aic23-codec.0-001a", |
103 | .init = afeb9260_tlv320aic23_init, | ||
104 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | | 92 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_IF | |
105 | SND_SOC_DAIFMT_CBM_CFM, | 93 | SND_SOC_DAIFMT_CBM_CFM, |
106 | .ops = &afeb9260_ops, | 94 | .ops = &afeb9260_ops, |
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index b07e17160f94..3c4b10ff48c1 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
@@ -276,7 +276,7 @@ static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, | |||
276 | { | 276 | { |
277 | struct soc_mixer_control *mc = | 277 | struct soc_mixer_control *mc = |
278 | (struct soc_mixer_control *)kcontrol->private_value; | 278 | (struct soc_mixer_control *)kcontrol->private_value; |
279 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 279 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
280 | unsigned int reg = mc->reg; | 280 | unsigned int reg = mc->reg; |
281 | unsigned int reg2 = mc->rreg; | 281 | unsigned int reg2 = mc->rreg; |
282 | int val[2], val2[2], i; | 282 | int val[2], val2[2], i; |
@@ -300,7 +300,7 @@ static int snd_soc_put_volsw_2r_st(struct snd_kcontrol *kcontrol, | |||
300 | { | 300 | { |
301 | struct soc_mixer_control *mc = | 301 | struct soc_mixer_control *mc = |
302 | (struct soc_mixer_control *)kcontrol->private_value; | 302 | (struct soc_mixer_control *)kcontrol->private_value; |
303 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 303 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
304 | unsigned int reg = mc->reg; | 304 | unsigned int reg = mc->reg; |
305 | unsigned int reg2 = mc->rreg; | 305 | unsigned int reg2 = mc->rreg; |
306 | int err; | 306 | int err; |
@@ -333,7 +333,7 @@ static int snd_soc_get_volsw_2r_out(struct snd_kcontrol *kcontrol, | |||
333 | { | 333 | { |
334 | struct soc_mixer_control *mc = | 334 | struct soc_mixer_control *mc = |
335 | (struct soc_mixer_control *)kcontrol->private_value; | 335 | (struct soc_mixer_control *)kcontrol->private_value; |
336 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 336 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
337 | unsigned int reg = mc->reg; | 337 | unsigned int reg = mc->reg; |
338 | unsigned int reg2 = mc->rreg; | 338 | unsigned int reg2 = mc->rreg; |
339 | unsigned int shift = mc->shift; | 339 | unsigned int shift = mc->shift; |
@@ -353,7 +353,7 @@ static int snd_soc_put_volsw_2r_out(struct snd_kcontrol *kcontrol, | |||
353 | { | 353 | { |
354 | struct soc_mixer_control *mc = | 354 | struct soc_mixer_control *mc = |
355 | (struct soc_mixer_control *)kcontrol->private_value; | 355 | (struct soc_mixer_control *)kcontrol->private_value; |
356 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 356 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
357 | unsigned int reg = mc->reg; | 357 | unsigned int reg = mc->reg; |
358 | unsigned int reg2 = mc->rreg; | 358 | unsigned int reg2 = mc->rreg; |
359 | unsigned int shift = mc->shift; | 359 | unsigned int shift = mc->shift; |
@@ -1327,10 +1327,6 @@ static int pm860x_probe(struct snd_soc_codec *codec) | |||
1327 | 1327 | ||
1328 | pm860x->codec = codec; | 1328 | pm860x->codec = codec; |
1329 | 1329 | ||
1330 | ret = snd_soc_codec_set_cache_io(codec, pm860x->regmap); | ||
1331 | if (ret) | ||
1332 | return ret; | ||
1333 | |||
1334 | for (i = 0; i < 4; i++) { | 1330 | for (i = 0; i < 4; i++) { |
1335 | ret = request_threaded_irq(pm860x->irq[i], NULL, | 1331 | ret = request_threaded_irq(pm860x->irq[i], NULL, |
1336 | pm860x_codec_handler, IRQF_ONESHOT, | 1332 | pm860x_codec_handler, IRQF_ONESHOT, |
@@ -1362,10 +1358,18 @@ static int pm860x_remove(struct snd_soc_codec *codec) | |||
1362 | return 0; | 1358 | return 0; |
1363 | } | 1359 | } |
1364 | 1360 | ||
1361 | static struct regmap *pm860x_get_regmap(struct device *dev) | ||
1362 | { | ||
1363 | struct pm860x_priv *pm860x = dev_get_drvdata(dev); | ||
1364 | |||
1365 | return pm860x->regmap; | ||
1366 | } | ||
1367 | |||
1365 | static struct snd_soc_codec_driver soc_codec_dev_pm860x = { | 1368 | static struct snd_soc_codec_driver soc_codec_dev_pm860x = { |
1366 | .probe = pm860x_probe, | 1369 | .probe = pm860x_probe, |
1367 | .remove = pm860x_remove, | 1370 | .remove = pm860x_remove, |
1368 | .set_bias_level = pm860x_set_bias_level, | 1371 | .set_bias_level = pm860x_set_bias_level, |
1372 | .get_regmap = pm860x_get_regmap, | ||
1369 | 1373 | ||
1370 | .controls = pm860x_snd_controls, | 1374 | .controls = pm860x_snd_controls, |
1371 | .num_controls = ARRAY_SIZE(pm860x_snd_controls), | 1375 | .num_controls = ARRAY_SIZE(pm860x_snd_controls), |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index f0e840137887..c59943a19f94 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
@@ -39,8 +39,9 @@ config SND_SOC_ALL_CODECS | |||
39 | select SND_SOC_ALC5623 if I2C | 39 | select SND_SOC_ALC5623 if I2C |
40 | select SND_SOC_ALC5632 if I2C | 40 | select SND_SOC_ALC5632 if I2C |
41 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC | 41 | select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC |
42 | select SND_SOC_CS42L51 if I2C | 42 | select SND_SOC_CS42L51_I2C if I2C |
43 | select SND_SOC_CS42L52 if I2C | 43 | select SND_SOC_CS42L52 if I2C && INPUT |
44 | select SND_SOC_CS42L56 if I2C && INPUT | ||
44 | select SND_SOC_CS42L73 if I2C | 45 | select SND_SOC_CS42L73 if I2C |
45 | select SND_SOC_CS4270 if I2C | 46 | select SND_SOC_CS4270 if I2C |
46 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI | 47 | select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI |
@@ -71,6 +72,8 @@ config SND_SOC_ALL_CODECS | |||
71 | select SND_SOC_PCM512x_SPI if SPI_MASTER | 72 | select SND_SOC_PCM512x_SPI if SPI_MASTER |
72 | select SND_SOC_RT5631 if I2C | 73 | select SND_SOC_RT5631 if I2C |
73 | select SND_SOC_RT5640 if I2C | 74 | select SND_SOC_RT5640 if I2C |
75 | select SND_SOC_RT5645 if I2C | ||
76 | select SND_SOC_RT5651 if I2C | ||
74 | select SND_SOC_SGTL5000 if I2C | 77 | select SND_SOC_SGTL5000 if I2C |
75 | select SND_SOC_SI476X if MFD_SI476X_CORE | 78 | select SND_SOC_SI476X if MFD_SI476X_CORE |
76 | select SND_SOC_SIRF_AUDIO_CODEC | 79 | select SND_SOC_SIRF_AUDIO_CODEC |
@@ -80,6 +83,7 @@ config SND_SOC_ALL_CODECS | |||
80 | select SND_SOC_SSM2602_SPI if SPI_MASTER | 83 | select SND_SOC_SSM2602_SPI if SPI_MASTER |
81 | select SND_SOC_SSM2602_I2C if I2C | 84 | select SND_SOC_SSM2602_I2C if I2C |
82 | select SND_SOC_STA32X if I2C | 85 | select SND_SOC_STA32X if I2C |
86 | select SND_SOC_STA350 if I2C | ||
83 | select SND_SOC_STA529 if I2C | 87 | select SND_SOC_STA529 if I2C |
84 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS | 88 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS |
85 | select SND_SOC_TAS5086 if I2C | 89 | select SND_SOC_TAS5086 if I2C |
@@ -127,7 +131,7 @@ config SND_SOC_ALL_CODECS | |||
127 | select SND_SOC_WM8955 if I2C | 131 | select SND_SOC_WM8955 if I2C |
128 | select SND_SOC_WM8960 if I2C | 132 | select SND_SOC_WM8960 if I2C |
129 | select SND_SOC_WM8961 if I2C | 133 | select SND_SOC_WM8961 if I2C |
130 | select SND_SOC_WM8962 if I2C | 134 | select SND_SOC_WM8962 if I2C && INPUT |
131 | select SND_SOC_WM8971 if I2C | 135 | select SND_SOC_WM8971 if I2C |
132 | select SND_SOC_WM8974 if I2C | 136 | select SND_SOC_WM8974 if I2C |
133 | select SND_SOC_WM8978 if I2C | 137 | select SND_SOC_WM8978 if I2C |
@@ -269,7 +273,7 @@ config SND_SOC_AK5386 | |||
269 | tristate "AKM AK5638 CODEC" | 273 | tristate "AKM AK5638 CODEC" |
270 | 274 | ||
271 | config SND_SOC_ALC5623 | 275 | config SND_SOC_ALC5623 |
272 | tristate | 276 | tristate "Realtek ALC5623 CODEC" |
273 | 277 | ||
274 | config SND_SOC_ALC5632 | 278 | config SND_SOC_ALC5632 |
275 | tristate | 279 | tristate |
@@ -280,9 +284,17 @@ config SND_SOC_CQ0093VC | |||
280 | config SND_SOC_CS42L51 | 284 | config SND_SOC_CS42L51 |
281 | tristate | 285 | tristate |
282 | 286 | ||
287 | config SND_SOC_CS42L51_I2C | ||
288 | tristate | ||
289 | select SND_SOC_CS42L51 | ||
290 | |||
283 | config SND_SOC_CS42L52 | 291 | config SND_SOC_CS42L52 |
284 | tristate "Cirrus Logic CS42L52 CODEC" | 292 | tristate "Cirrus Logic CS42L52 CODEC" |
285 | depends on I2C | 293 | depends on I2C && INPUT |
294 | |||
295 | config SND_SOC_CS42L56 | ||
296 | tristate "Cirrus Logic CS42L56 CODEC" | ||
297 | depends on I2C && INPUT | ||
286 | 298 | ||
287 | config SND_SOC_CS42L73 | 299 | config SND_SOC_CS42L73 |
288 | tristate "Cirrus Logic CS42L73 CODEC" | 300 | tristate "Cirrus Logic CS42L73 CODEC" |
@@ -396,6 +408,12 @@ config SND_SOC_RT5631 | |||
396 | config SND_SOC_RT5640 | 408 | config SND_SOC_RT5640 |
397 | tristate | 409 | tristate |
398 | 410 | ||
411 | config SND_SOC_RT5645 | ||
412 | tristate | ||
413 | |||
414 | config SND_SOC_RT5651 | ||
415 | tristate | ||
416 | |||
399 | #Freescale sgtl5000 codec | 417 | #Freescale sgtl5000 codec |
400 | config SND_SOC_SGTL5000 | 418 | config SND_SOC_SGTL5000 |
401 | tristate "Freescale SGTL5000 CODEC" | 419 | tristate "Freescale SGTL5000 CODEC" |
@@ -435,6 +453,10 @@ config SND_SOC_SSM2602_I2C | |||
435 | config SND_SOC_STA32X | 453 | config SND_SOC_STA32X |
436 | tristate | 454 | tristate |
437 | 455 | ||
456 | config SND_SOC_STA350 | ||
457 | tristate "STA350 speaker amplifier" | ||
458 | depends on I2C | ||
459 | |||
438 | config SND_SOC_STA529 | 460 | config SND_SOC_STA529 |
439 | tristate | 461 | tristate |
440 | 462 | ||
@@ -598,7 +620,7 @@ config SND_SOC_WM8961 | |||
598 | 620 | ||
599 | config SND_SOC_WM8962 | 621 | config SND_SOC_WM8962 |
600 | tristate "Wolfson Microelectronics WM8962 CODEC" | 622 | tristate "Wolfson Microelectronics WM8962 CODEC" |
601 | depends on I2C | 623 | depends on I2C && INPUT |
602 | 624 | ||
603 | config SND_SOC_WM8971 | 625 | config SND_SOC_WM8971 |
604 | tristate | 626 | tristate |
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3c4d275d064b..1ccdaf0c0e3e 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
@@ -26,7 +26,9 @@ snd-soc-ak5386-objs := ak5386.o | |||
26 | snd-soc-arizona-objs := arizona.o | 26 | snd-soc-arizona-objs := arizona.o |
27 | snd-soc-cq93vc-objs := cq93vc.o | 27 | snd-soc-cq93vc-objs := cq93vc.o |
28 | snd-soc-cs42l51-objs := cs42l51.o | 28 | snd-soc-cs42l51-objs := cs42l51.o |
29 | snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o | ||
29 | snd-soc-cs42l52-objs := cs42l52.o | 30 | snd-soc-cs42l52-objs := cs42l52.o |
31 | snd-soc-cs42l56-objs := cs42l56.o | ||
30 | snd-soc-cs42l73-objs := cs42l73.o | 32 | snd-soc-cs42l73-objs := cs42l73.o |
31 | snd-soc-cs4270-objs := cs4270.o | 33 | snd-soc-cs4270-objs := cs4270.o |
32 | snd-soc-cs4271-objs := cs4271.o | 34 | snd-soc-cs4271-objs := cs4271.o |
@@ -60,6 +62,8 @@ snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o | |||
60 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o | 62 | snd-soc-pcm512x-spi-objs := pcm512x-spi.o |
61 | snd-soc-rt5631-objs := rt5631.o | 63 | snd-soc-rt5631-objs := rt5631.o |
62 | snd-soc-rt5640-objs := rt5640.o | 64 | snd-soc-rt5640-objs := rt5640.o |
65 | snd-soc-rt5645-objs := rt5645.o | ||
66 | snd-soc-rt5651-objs := rt5651.o | ||
63 | snd-soc-sgtl5000-objs := sgtl5000.o | 67 | snd-soc-sgtl5000-objs := sgtl5000.o |
64 | snd-soc-alc5623-objs := alc5623.o | 68 | snd-soc-alc5623-objs := alc5623.o |
65 | snd-soc-alc5632-objs := alc5632.o | 69 | snd-soc-alc5632-objs := alc5632.o |
@@ -74,6 +78,7 @@ snd-soc-ssm2602-objs := ssm2602.o | |||
74 | snd-soc-ssm2602-spi-objs := ssm2602-spi.o | 78 | snd-soc-ssm2602-spi-objs := ssm2602-spi.o |
75 | snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o | 79 | snd-soc-ssm2602-i2c-objs := ssm2602-i2c.o |
76 | snd-soc-sta32x-objs := sta32x.o | 80 | snd-soc-sta32x-objs := sta32x.o |
81 | snd-soc-sta350-objs := sta350.o | ||
77 | snd-soc-sta529-objs := sta529.o | 82 | snd-soc-sta529-objs := sta529.o |
78 | snd-soc-stac9766-objs := stac9766.o | 83 | snd-soc-stac9766-objs := stac9766.o |
79 | snd-soc-tas5086-objs := tas5086.o | 84 | snd-soc-tas5086-objs := tas5086.o |
@@ -177,7 +182,9 @@ obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o | |||
177 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o | 182 | obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o |
178 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o | 183 | obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o |
179 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o | 184 | obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o |
185 | obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o | ||
180 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o | 186 | obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o |
187 | obj-$(CONFIG_SND_SOC_CS42L56) += snd-soc-cs42l56.o | ||
181 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o | 188 | obj-$(CONFIG_SND_SOC_CS42L73) += snd-soc-cs42l73.o |
182 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o | 189 | obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o |
183 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o | 190 | obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o |
@@ -211,6 +218,8 @@ obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o | |||
211 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o | 218 | obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o |
212 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | 219 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o |
213 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o | 220 | obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o |
221 | obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o | ||
222 | obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o | ||
214 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 223 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
215 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o | 224 | obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o |
216 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o | 225 | obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o |
@@ -221,6 +230,7 @@ obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o | |||
221 | obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o | 230 | obj-$(CONFIG_SND_SOC_SSM2602_SPI) += snd-soc-ssm2602-spi.o |
222 | obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o | 231 | obj-$(CONFIG_SND_SOC_SSM2602_I2C) += snd-soc-ssm2602-i2c.o |
223 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o | 232 | obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o |
233 | obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o | ||
224 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o | 234 | obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o |
225 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o | 235 | obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o |
226 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o | 236 | obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o |
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 1ad92cbf0b24..1fb4402bf72d 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -1139,7 +1139,7 @@ static void anc_configure(struct snd_soc_codec *codec, | |||
1139 | static int sid_status_control_get(struct snd_kcontrol *kcontrol, | 1139 | static int sid_status_control_get(struct snd_kcontrol *kcontrol, |
1140 | struct snd_ctl_elem_value *ucontrol) | 1140 | struct snd_ctl_elem_value *ucontrol) |
1141 | { | 1141 | { |
1142 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1142 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1143 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | 1143 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); |
1144 | 1144 | ||
1145 | mutex_lock(&codec->mutex); | 1145 | mutex_lock(&codec->mutex); |
@@ -1153,7 +1153,7 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol, | |||
1153 | static int sid_status_control_put(struct snd_kcontrol *kcontrol, | 1153 | static int sid_status_control_put(struct snd_kcontrol *kcontrol, |
1154 | struct snd_ctl_elem_value *ucontrol) | 1154 | struct snd_ctl_elem_value *ucontrol) |
1155 | { | 1155 | { |
1156 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1156 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1157 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | 1157 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); |
1158 | unsigned int param, sidconf, val; | 1158 | unsigned int param, sidconf, val; |
1159 | int status = 1; | 1159 | int status = 1; |
@@ -1208,7 +1208,7 @@ out: | |||
1208 | static int anc_status_control_get(struct snd_kcontrol *kcontrol, | 1208 | static int anc_status_control_get(struct snd_kcontrol *kcontrol, |
1209 | struct snd_ctl_elem_value *ucontrol) | 1209 | struct snd_ctl_elem_value *ucontrol) |
1210 | { | 1210 | { |
1211 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1211 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1212 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | 1212 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); |
1213 | 1213 | ||
1214 | mutex_lock(&codec->mutex); | 1214 | mutex_lock(&codec->mutex); |
@@ -1221,7 +1221,7 @@ static int anc_status_control_get(struct snd_kcontrol *kcontrol, | |||
1221 | static int anc_status_control_put(struct snd_kcontrol *kcontrol, | 1221 | static int anc_status_control_put(struct snd_kcontrol *kcontrol, |
1222 | struct snd_ctl_elem_value *ucontrol) | 1222 | struct snd_ctl_elem_value *ucontrol) |
1223 | { | 1223 | { |
1224 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1224 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1225 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); | 1225 | struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev); |
1226 | struct device *dev = codec->dev; | 1226 | struct device *dev = codec->dev; |
1227 | bool apply_fir, apply_iir; | 1227 | bool apply_fir, apply_iir; |
@@ -1306,7 +1306,7 @@ static int filter_control_info(struct snd_kcontrol *kcontrol, | |||
1306 | static int filter_control_get(struct snd_kcontrol *kcontrol, | 1306 | static int filter_control_get(struct snd_kcontrol *kcontrol, |
1307 | struct snd_ctl_elem_value *ucontrol) | 1307 | struct snd_ctl_elem_value *ucontrol) |
1308 | { | 1308 | { |
1309 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1309 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1310 | struct filter_control *fc = | 1310 | struct filter_control *fc = |
1311 | (struct filter_control *)kcontrol->private_value; | 1311 | (struct filter_control *)kcontrol->private_value; |
1312 | unsigned int i; | 1312 | unsigned int i; |
@@ -1322,7 +1322,7 @@ static int filter_control_get(struct snd_kcontrol *kcontrol, | |||
1322 | static int filter_control_put(struct snd_kcontrol *kcontrol, | 1322 | static int filter_control_put(struct snd_kcontrol *kcontrol, |
1323 | struct snd_ctl_elem_value *ucontrol) | 1323 | struct snd_ctl_elem_value *ucontrol) |
1324 | { | 1324 | { |
1325 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1325 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1326 | struct filter_control *fc = | 1326 | struct filter_control *fc = |
1327 | (struct filter_control *)kcontrol->private_value; | 1327 | (struct filter_control *)kcontrol->private_value; |
1328 | unsigned int i; | 1328 | unsigned int i; |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 34d965a4a040..304d3003339a 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -189,28 +189,27 @@ static struct snd_soc_dai_driver ad1980_dai = { | |||
189 | 189 | ||
190 | static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) | 190 | static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) |
191 | { | 191 | { |
192 | u16 retry_cnt = 0; | 192 | unsigned int retry_cnt = 0; |
193 | 193 | ||
194 | retry: | 194 | do { |
195 | if (try_warm && soc_ac97_ops->warm_reset) { | 195 | if (try_warm && soc_ac97_ops->warm_reset) { |
196 | soc_ac97_ops->warm_reset(codec->ac97); | 196 | soc_ac97_ops->warm_reset(codec->ac97); |
197 | if (ac97_read(codec, AC97_RESET) == 0x0090) | 197 | if (ac97_read(codec, AC97_RESET) == 0x0090) |
198 | return 1; | 198 | return 1; |
199 | } | 199 | } |
200 | |||
201 | soc_ac97_ops->reset(codec->ac97); | ||
202 | /* Set bit 16slot in register 74h, then every slot will has only 16 | ||
203 | * bits. This command is sent out in 20bit mode, in which case the | ||
204 | * first nibble of data is eaten by the addr. (Tag is always 16 bit)*/ | ||
205 | ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900); | ||
206 | |||
207 | if (ac97_read(codec, AC97_RESET) != 0x0090) | ||
208 | goto err; | ||
209 | return 0; | ||
210 | 200 | ||
211 | err: | 201 | soc_ac97_ops->reset(codec->ac97); |
212 | while (retry_cnt++ < 10) | 202 | /* |
213 | goto retry; | 203 | * Set bit 16slot in register 74h, then every slot will has only |
204 | * 16 bits. This command is sent out in 20bit mode, in which | ||
205 | * case the first nibble of data is eaten by the addr. (Tag is | ||
206 | * always 16 bit) | ||
207 | */ | ||
208 | ac97_write(codec, AC97_AD_SERIAL_CFG, 0x9900); | ||
209 | |||
210 | if (ac97_read(codec, AC97_RESET) == 0x0090) | ||
211 | return 0; | ||
212 | } while (retry_cnt++ < 10); | ||
214 | 213 | ||
215 | printk(KERN_ERR "AD1980 AC97 reset failed\n"); | 214 | printk(KERN_ERR "AD1980 AC97 reset failed\n"); |
216 | return -EIO; | 215 | return -EIO; |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 877f5737bb6b..1ff7d4d027e9 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -519,8 +519,7 @@ static const struct snd_kcontrol_new adau1373_controls[] = { | |||
519 | SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum), | 519 | SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum), |
520 | 520 | ||
521 | SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum), | 521 | SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum), |
522 | SOC_VALUE_ENUM("Bass Clip Level Threshold", | 522 | SOC_ENUM("Bass Clip Level Threshold", adau1373_bass_clip_level_enum), |
523 | adau1373_bass_clip_level_enum), | ||
524 | SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum), | 523 | SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum), |
525 | SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0), | 524 | SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0), |
526 | SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0, | 525 | SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0, |
@@ -580,7 +579,7 @@ static SOC_ENUM_SINGLE_VIRT_DECL(adau1373_decimator_enum, | |||
580 | adau1373_decimator_text); | 579 | adau1373_decimator_text); |
581 | 580 | ||
582 | static const struct snd_kcontrol_new adau1373_decimator_mux = | 581 | static const struct snd_kcontrol_new adau1373_decimator_mux = |
583 | SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); | 582 | SOC_DAPM_ENUM("Decimator Mux", adau1373_decimator_enum); |
584 | 583 | ||
585 | static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = { | 584 | static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = { |
586 | SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0), | 585 | SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0), |
@@ -694,7 +693,7 @@ static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = { | |||
694 | SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0), | 693 | SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0), |
695 | SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0), | 694 | SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0), |
696 | 695 | ||
697 | SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, | 696 | SND_SOC_DAPM_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, |
698 | &adau1373_decimator_mux), | 697 | &adau1373_decimator_mux), |
699 | 698 | ||
700 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0), | 699 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0), |
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 5062e34ee8dc..c43b93fdf0df 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
@@ -172,14 +172,14 @@ static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3); | |||
172 | static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3); | 172 | static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3); |
173 | 173 | ||
174 | static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl = | 174 | static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl = |
175 | SOC_DAPM_VALUE_ENUM("Route", adav80x_aux_capture_enum); | 175 | SOC_DAPM_ENUM("Route", adav80x_aux_capture_enum); |
176 | static const struct snd_kcontrol_new adav80x_capture_mux_ctrl = | 176 | static const struct snd_kcontrol_new adav80x_capture_mux_ctrl = |
177 | SOC_DAPM_VALUE_ENUM("Route", adav80x_capture_enum); | 177 | SOC_DAPM_ENUM("Route", adav80x_capture_enum); |
178 | static const struct snd_kcontrol_new adav80x_dac_mux_ctrl = | 178 | static const struct snd_kcontrol_new adav80x_dac_mux_ctrl = |
179 | SOC_DAPM_VALUE_ENUM("Route", adav80x_dac_enum); | 179 | SOC_DAPM_ENUM("Route", adav80x_dac_enum); |
180 | 180 | ||
181 | #define ADAV80X_MUX(name, ctrl) \ | 181 | #define ADAV80X_MUX(name, ctrl) \ |
182 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | 182 | SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) |
183 | 183 | ||
184 | static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = { | 184 | static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = { |
185 | SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1), | 185 | SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1), |
@@ -315,7 +315,7 @@ static int adav80x_set_deemph(struct snd_soc_codec *codec) | |||
315 | static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, | 315 | static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, |
316 | struct snd_ctl_elem_value *ucontrol) | 316 | struct snd_ctl_elem_value *ucontrol) |
317 | { | 317 | { |
318 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 318 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
319 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 319 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
320 | unsigned int deemph = ucontrol->value.enumerated.item[0]; | 320 | unsigned int deemph = ucontrol->value.enumerated.item[0]; |
321 | 321 | ||
@@ -330,7 +330,7 @@ static int adav80x_put_deemph(struct snd_kcontrol *kcontrol, | |||
330 | static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, | 330 | static int adav80x_get_deemph(struct snd_kcontrol *kcontrol, |
331 | struct snd_ctl_elem_value *ucontrol) | 331 | struct snd_ctl_elem_value *ucontrol) |
332 | { | 332 | { |
333 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 333 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
334 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 334 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
335 | 335 | ||
336 | ucontrol->value.enumerated.item[0] = adav80x->deemph; | 336 | ucontrol->value.enumerated.item[0] = adav80x->deemph; |
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index 10adf25d4c14..1fd7f72b2a62 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
@@ -11,13 +11,14 @@ | |||
11 | 11 | ||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <sound/core.h> | ||
15 | #include <sound/soc.h> | ||
16 | #include <sound/initval.h> | ||
17 | #include <linux/spi/spi.h> | 14 | #include <linux/spi/spi.h> |
18 | #include <linux/of_device.h> | 15 | #include <linux/of_device.h> |
19 | #include <linux/of_gpio.h> | 16 | #include <linux/of_gpio.h> |
17 | #include <linux/regulator/consumer.h> | ||
20 | #include <sound/asoundef.h> | 18 | #include <sound/asoundef.h> |
19 | #include <sound/core.h> | ||
20 | #include <sound/soc.h> | ||
21 | #include <sound/initval.h> | ||
21 | 22 | ||
22 | /* AK4104 registers addresses */ | 23 | /* AK4104 registers addresses */ |
23 | #define AK4104_REG_CONTROL1 0x00 | 24 | #define AK4104_REG_CONTROL1 0x00 |
@@ -47,6 +48,7 @@ | |||
47 | 48 | ||
48 | struct ak4104_private { | 49 | struct ak4104_private { |
49 | struct regmap *regmap; | 50 | struct regmap *regmap; |
51 | struct regulator *regulator; | ||
50 | }; | 52 | }; |
51 | 53 | ||
52 | static const struct snd_soc_dapm_widget ak4104_dapm_widgets[] = { | 54 | static const struct snd_soc_dapm_widget ak4104_dapm_widgets[] = { |
@@ -174,20 +176,30 @@ static int ak4104_probe(struct snd_soc_codec *codec) | |||
174 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); | 176 | struct ak4104_private *ak4104 = snd_soc_codec_get_drvdata(codec); |
175 | int ret; | 177 | int ret; |
176 | 178 | ||
179 | ret = regulator_enable(ak4104->regulator); | ||
180 | if (ret < 0) { | ||
181 | dev_err(codec->dev, "Unable to enable regulator: %d\n", ret); | ||
182 | return ret; | ||
183 | } | ||
184 | |||
177 | /* set power-up and non-reset bits */ | 185 | /* set power-up and non-reset bits */ |
178 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, | 186 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, |
179 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, | 187 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, |
180 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); | 188 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN); |
181 | if (ret < 0) | 189 | if (ret < 0) |
182 | return ret; | 190 | goto exit_disable_regulator; |
183 | 191 | ||
184 | /* enable transmitter */ | 192 | /* enable transmitter */ |
185 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX, | 193 | ret = regmap_update_bits(ak4104->regmap, AK4104_REG_TX, |
186 | AK4104_TX_TXE, AK4104_TX_TXE); | 194 | AK4104_TX_TXE, AK4104_TX_TXE); |
187 | if (ret < 0) | 195 | if (ret < 0) |
188 | return ret; | 196 | goto exit_disable_regulator; |
189 | 197 | ||
190 | return 0; | 198 | return 0; |
199 | |||
200 | exit_disable_regulator: | ||
201 | regulator_disable(ak4104->regulator); | ||
202 | return ret; | ||
191 | } | 203 | } |
192 | 204 | ||
193 | static int ak4104_remove(struct snd_soc_codec *codec) | 205 | static int ak4104_remove(struct snd_soc_codec *codec) |
@@ -196,13 +208,42 @@ static int ak4104_remove(struct snd_soc_codec *codec) | |||
196 | 208 | ||
197 | regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, | 209 | regmap_update_bits(ak4104->regmap, AK4104_REG_CONTROL1, |
198 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); | 210 | AK4104_CONTROL1_PW | AK4104_CONTROL1_RSTN, 0); |
211 | regulator_disable(ak4104->regulator); | ||
199 | 212 | ||
200 | return 0; | 213 | return 0; |
201 | } | 214 | } |
202 | 215 | ||
216 | #ifdef CONFIG_PM | ||
217 | static int ak4104_soc_suspend(struct snd_soc_codec *codec) | ||
218 | { | ||
219 | struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec); | ||
220 | |||
221 | regulator_disable(priv->regulator); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | static int ak4104_soc_resume(struct snd_soc_codec *codec) | ||
227 | { | ||
228 | struct ak4104_private *priv = snd_soc_codec_get_drvdata(codec); | ||
229 | int ret; | ||
230 | |||
231 | ret = regulator_enable(priv->regulator); | ||
232 | if (ret < 0) | ||
233 | return ret; | ||
234 | |||
235 | return 0; | ||
236 | } | ||
237 | #else | ||
238 | #define ak4104_soc_suspend NULL | ||
239 | #define ak4104_soc_resume NULL | ||
240 | #endif /* CONFIG_PM */ | ||
241 | |||
203 | static struct snd_soc_codec_driver soc_codec_device_ak4104 = { | 242 | static struct snd_soc_codec_driver soc_codec_device_ak4104 = { |
204 | .probe = ak4104_probe, | 243 | .probe = ak4104_probe, |
205 | .remove = ak4104_remove, | 244 | .remove = ak4104_remove, |
245 | .suspend = ak4104_soc_suspend, | ||
246 | .resume = ak4104_soc_resume, | ||
206 | 247 | ||
207 | .dapm_widgets = ak4104_dapm_widgets, | 248 | .dapm_widgets = ak4104_dapm_widgets, |
208 | .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), | 249 | .num_dapm_widgets = ARRAY_SIZE(ak4104_dapm_widgets), |
@@ -239,6 +280,13 @@ static int ak4104_spi_probe(struct spi_device *spi) | |||
239 | if (ak4104 == NULL) | 280 | if (ak4104 == NULL) |
240 | return -ENOMEM; | 281 | return -ENOMEM; |
241 | 282 | ||
283 | ak4104->regulator = devm_regulator_get(&spi->dev, "vdd"); | ||
284 | if (IS_ERR(ak4104->regulator)) { | ||
285 | ret = PTR_ERR(ak4104->regulator); | ||
286 | dev_err(&spi->dev, "Unable to get Vdd regulator: %d\n", ret); | ||
287 | return ret; | ||
288 | } | ||
289 | |||
242 | ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap); | 290 | ak4104->regmap = devm_regmap_init_spi(spi, &ak4104_regmap); |
243 | if (IS_ERR(ak4104->regmap)) { | 291 | if (IS_ERR(ak4104->regmap)) { |
244 | ret = PTR_ERR(ak4104->regmap); | 292 | ret = PTR_ERR(ak4104->regmap); |
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 868c0e2da1ec..7afe8f482088 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c | |||
@@ -74,7 +74,7 @@ static int ak4641_set_deemph(struct snd_soc_codec *codec) | |||
74 | static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, | 74 | static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, |
75 | struct snd_ctl_elem_value *ucontrol) | 75 | struct snd_ctl_elem_value *ucontrol) |
76 | { | 76 | { |
77 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 77 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
78 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | 78 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); |
79 | int deemph = ucontrol->value.enumerated.item[0]; | 79 | int deemph = ucontrol->value.enumerated.item[0]; |
80 | 80 | ||
@@ -89,7 +89,7 @@ static int ak4641_put_deemph(struct snd_kcontrol *kcontrol, | |||
89 | static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, | 89 | static int ak4641_get_deemph(struct snd_kcontrol *kcontrol, |
90 | struct snd_ctl_elem_value *ucontrol) | 90 | struct snd_ctl_elem_value *ucontrol) |
91 | { | 91 | { |
92 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 92 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
93 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); | 93 | struct ak4641_priv *ak4641 = snd_soc_codec_get_drvdata(codec); |
94 | 94 | ||
95 | ucontrol->value.enumerated.item[0] = ak4641->deemph; | 95 | ucontrol->value.enumerated.item[0] = ak4641->deemph; |
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 92655cc189ae..3ba4c0f11418 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -98,7 +98,7 @@ | |||
98 | #define MGAIN0 (1 << 0) /* MIC amp gain*/ | 98 | #define MGAIN0 (1 << 0) /* MIC amp gain*/ |
99 | 99 | ||
100 | /* TIMER */ | 100 | /* TIMER */ |
101 | #define ZTM(param) ((param & 0x3) << 4) /* ALC Zoro Crossing TimeOut */ | 101 | #define ZTM(param) ((param & 0x3) << 4) /* ALC Zero Crossing TimeOut */ |
102 | #define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2)) | 102 | #define WTM(param) (((param & 0x4) << 4) | ((param & 0x3) << 2)) |
103 | 103 | ||
104 | /* ALC_CTL1 */ | 104 | /* ALC_CTL1 */ |
@@ -134,6 +134,15 @@ | |||
134 | /* MD_CTL4 */ | 134 | /* MD_CTL4 */ |
135 | #define DACH (1 << 0) | 135 | #define DACH (1 << 0) |
136 | 136 | ||
137 | struct ak4642_drvdata { | ||
138 | const struct regmap_config *regmap_config; | ||
139 | int extended_frequencies; | ||
140 | }; | ||
141 | |||
142 | struct ak4642_priv { | ||
143 | const struct ak4642_drvdata *drvdata; | ||
144 | }; | ||
145 | |||
137 | /* | 146 | /* |
138 | * Playback Volume (table 39) | 147 | * Playback Volume (table 39) |
139 | * | 148 | * |
@@ -148,6 +157,8 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { | |||
148 | 157 | ||
149 | SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, | 158 | SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC, |
150 | 0, 0xFF, 1, out_tlv), | 159 | 0, 0xFF, 1, out_tlv), |
160 | SOC_SINGLE("ALC Capture Switch", ALC_CTL1, 5, 1, 0), | ||
161 | SOC_SINGLE("ALC Capture ZC Switch", ALC_CTL1, 4, 1, 1), | ||
151 | }; | 162 | }; |
152 | 163 | ||
153 | static const struct snd_kcontrol_new ak4642_headphone_control = | 164 | static const struct snd_kcontrol_new ak4642_headphone_control = |
@@ -287,7 +298,9 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai, | |||
287 | int clk_id, unsigned int freq, int dir) | 298 | int clk_id, unsigned int freq, int dir) |
288 | { | 299 | { |
289 | struct snd_soc_codec *codec = codec_dai->codec; | 300 | struct snd_soc_codec *codec = codec_dai->codec; |
301 | struct ak4642_priv *priv = snd_soc_codec_get_drvdata(codec); | ||
290 | u8 pll; | 302 | u8 pll; |
303 | int extended_freq = 0; | ||
291 | 304 | ||
292 | switch (freq) { | 305 | switch (freq) { |
293 | case 11289600: | 306 | case 11289600: |
@@ -308,9 +321,25 @@ static int ak4642_dai_set_sysclk(struct snd_soc_dai *codec_dai, | |||
308 | case 27000000: | 321 | case 27000000: |
309 | pll = PLL3 | PLL2 | PLL0; | 322 | pll = PLL3 | PLL2 | PLL0; |
310 | break; | 323 | break; |
324 | case 19200000: | ||
325 | pll = PLL3; | ||
326 | extended_freq = 1; | ||
327 | break; | ||
328 | case 13000000: | ||
329 | pll = PLL3 | PLL2 | PLL1; | ||
330 | extended_freq = 1; | ||
331 | break; | ||
332 | case 26000000: | ||
333 | pll = PLL3 | PLL2 | PLL1 | PLL0; | ||
334 | extended_freq = 1; | ||
335 | break; | ||
311 | default: | 336 | default: |
312 | return -EINVAL; | 337 | return -EINVAL; |
313 | } | 338 | } |
339 | |||
340 | if (extended_freq && !priv->drvdata->extended_frequencies) | ||
341 | return -EINVAL; | ||
342 | |||
314 | snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll); | 343 | snd_soc_update_bits(codec, MD_CTL1, PLL_MASK, pll); |
315 | 344 | ||
316 | return 0; | 345 | return 0; |
@@ -505,30 +534,52 @@ static const struct regmap_config ak4648_regmap = { | |||
505 | .num_reg_defaults = ARRAY_SIZE(ak4648_reg), | 534 | .num_reg_defaults = ARRAY_SIZE(ak4648_reg), |
506 | }; | 535 | }; |
507 | 536 | ||
537 | static const struct ak4642_drvdata ak4642_drvdata = { | ||
538 | .regmap_config = &ak4642_regmap, | ||
539 | }; | ||
540 | |||
541 | static const struct ak4642_drvdata ak4643_drvdata = { | ||
542 | .regmap_config = &ak4642_regmap, | ||
543 | }; | ||
544 | |||
545 | static const struct ak4642_drvdata ak4648_drvdata = { | ||
546 | .regmap_config = &ak4648_regmap, | ||
547 | .extended_frequencies = 1, | ||
548 | }; | ||
549 | |||
508 | static struct of_device_id ak4642_of_match[]; | 550 | static struct of_device_id ak4642_of_match[]; |
509 | static int ak4642_i2c_probe(struct i2c_client *i2c, | 551 | static int ak4642_i2c_probe(struct i2c_client *i2c, |
510 | const struct i2c_device_id *id) | 552 | const struct i2c_device_id *id) |
511 | { | 553 | { |
512 | struct device_node *np = i2c->dev.of_node; | 554 | struct device_node *np = i2c->dev.of_node; |
513 | const struct regmap_config *regmap_config = NULL; | 555 | const struct ak4642_drvdata *drvdata = NULL; |
514 | struct regmap *regmap; | 556 | struct regmap *regmap; |
557 | struct ak4642_priv *priv; | ||
515 | 558 | ||
516 | if (np) { | 559 | if (np) { |
517 | const struct of_device_id *of_id; | 560 | const struct of_device_id *of_id; |
518 | 561 | ||
519 | of_id = of_match_device(ak4642_of_match, &i2c->dev); | 562 | of_id = of_match_device(ak4642_of_match, &i2c->dev); |
520 | if (of_id) | 563 | if (of_id) |
521 | regmap_config = of_id->data; | 564 | drvdata = of_id->data; |
522 | } else { | 565 | } else { |
523 | regmap_config = (const struct regmap_config *)id->driver_data; | 566 | drvdata = (const struct ak4642_drvdata *)id->driver_data; |
524 | } | 567 | } |
525 | 568 | ||
526 | if (!regmap_config) { | 569 | if (!drvdata) { |
527 | dev_err(&i2c->dev, "Unknown device type\n"); | 570 | dev_err(&i2c->dev, "Unknown device type\n"); |
528 | return -EINVAL; | 571 | return -EINVAL; |
529 | } | 572 | } |
530 | 573 | ||
531 | regmap = devm_regmap_init_i2c(i2c, regmap_config); | 574 | priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL); |
575 | if (!priv) | ||
576 | return -ENOMEM; | ||
577 | |||
578 | priv->drvdata = drvdata; | ||
579 | |||
580 | i2c_set_clientdata(i2c, priv); | ||
581 | |||
582 | regmap = devm_regmap_init_i2c(i2c, drvdata->regmap_config); | ||
532 | if (IS_ERR(regmap)) | 583 | if (IS_ERR(regmap)) |
533 | return PTR_ERR(regmap); | 584 | return PTR_ERR(regmap); |
534 | 585 | ||
@@ -543,17 +594,17 @@ static int ak4642_i2c_remove(struct i2c_client *client) | |||
543 | } | 594 | } |
544 | 595 | ||
545 | static struct of_device_id ak4642_of_match[] = { | 596 | static struct of_device_id ak4642_of_match[] = { |
546 | { .compatible = "asahi-kasei,ak4642", .data = &ak4642_regmap}, | 597 | { .compatible = "asahi-kasei,ak4642", .data = &ak4642_drvdata}, |
547 | { .compatible = "asahi-kasei,ak4643", .data = &ak4642_regmap}, | 598 | { .compatible = "asahi-kasei,ak4643", .data = &ak4643_drvdata}, |
548 | { .compatible = "asahi-kasei,ak4648", .data = &ak4648_regmap}, | 599 | { .compatible = "asahi-kasei,ak4648", .data = &ak4648_drvdata}, |
549 | {}, | 600 | {}, |
550 | }; | 601 | }; |
551 | MODULE_DEVICE_TABLE(of, ak4642_of_match); | 602 | MODULE_DEVICE_TABLE(of, ak4642_of_match); |
552 | 603 | ||
553 | static const struct i2c_device_id ak4642_i2c_id[] = { | 604 | static const struct i2c_device_id ak4642_i2c_id[] = { |
554 | { "ak4642", (kernel_ulong_t)&ak4642_regmap }, | 605 | { "ak4642", (kernel_ulong_t)&ak4642_drvdata }, |
555 | { "ak4643", (kernel_ulong_t)&ak4642_regmap }, | 606 | { "ak4643", (kernel_ulong_t)&ak4643_drvdata }, |
556 | { "ak4648", (kernel_ulong_t)&ak4648_regmap }, | 607 | { "ak4648", (kernel_ulong_t)&ak4648_drvdata }, |
557 | { } | 608 | { } |
558 | }; | 609 | }; |
559 | MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id); | 610 | MODULE_DEVICE_TABLE(i2c, ak4642_i2c_id); |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 2acf82f4a08a..9d0755aa1d16 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/of.h> | ||
26 | #include <sound/core.h> | 27 | #include <sound/core.h> |
27 | #include <sound/pcm.h> | 28 | #include <sound/pcm.h> |
28 | #include <sound/pcm_params.h> | 29 | #include <sound/pcm_params.h> |
@@ -998,8 +999,10 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
998 | { | 999 | { |
999 | struct alc5623_platform_data *pdata; | 1000 | struct alc5623_platform_data *pdata; |
1000 | struct alc5623_priv *alc5623; | 1001 | struct alc5623_priv *alc5623; |
1002 | struct device_node *np; | ||
1001 | unsigned int vid1, vid2; | 1003 | unsigned int vid1, vid2; |
1002 | int ret; | 1004 | int ret; |
1005 | u32 val32; | ||
1003 | 1006 | ||
1004 | alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), | 1007 | alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv), |
1005 | GFP_KERNEL); | 1008 | GFP_KERNEL); |
@@ -1040,6 +1043,16 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
1040 | if (pdata) { | 1043 | if (pdata) { |
1041 | alc5623->add_ctrl = pdata->add_ctrl; | 1044 | alc5623->add_ctrl = pdata->add_ctrl; |
1042 | alc5623->jack_det_ctrl = pdata->jack_det_ctrl; | 1045 | alc5623->jack_det_ctrl = pdata->jack_det_ctrl; |
1046 | } else { | ||
1047 | if (client->dev.of_node) { | ||
1048 | np = client->dev.of_node; | ||
1049 | ret = of_property_read_u32(np, "add-ctrl", &val32); | ||
1050 | if (!ret) | ||
1051 | alc5623->add_ctrl = val32; | ||
1052 | ret = of_property_read_u32(np, "jack-det-ctrl", &val32); | ||
1053 | if (!ret) | ||
1054 | alc5623->jack_det_ctrl = val32; | ||
1055 | } | ||
1043 | } | 1056 | } |
1044 | 1057 | ||
1045 | alc5623->id = vid2; | 1058 | alc5623->id = vid2; |
@@ -1081,11 +1094,18 @@ static const struct i2c_device_id alc5623_i2c_table[] = { | |||
1081 | }; | 1094 | }; |
1082 | MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); | 1095 | MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); |
1083 | 1096 | ||
1097 | static const struct of_device_id alc5623_of_match[] = { | ||
1098 | { .compatible = "realtek,alc5623", }, | ||
1099 | { } | ||
1100 | }; | ||
1101 | MODULE_DEVICE_TABLE(of, alc5623_of_match); | ||
1102 | |||
1084 | /* i2c codec control layer */ | 1103 | /* i2c codec control layer */ |
1085 | static struct i2c_driver alc5623_i2c_driver = { | 1104 | static struct i2c_driver alc5623_i2c_driver = { |
1086 | .driver = { | 1105 | .driver = { |
1087 | .name = "alc562x-codec", | 1106 | .name = "alc562x-codec", |
1088 | .owner = THIS_MODULE, | 1107 | .owner = THIS_MODULE, |
1108 | .of_match_table = of_match_ptr(alc5623_of_match), | ||
1089 | }, | 1109 | }, |
1090 | .probe = alc5623_i2c_probe, | 1110 | .probe = alc5623_i2c_probe, |
1091 | .remove = alc5623_i2c_remove, | 1111 | .remove = alc5623_i2c_remove, |
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h index 16df0f913353..05ae17f5bca3 100644 --- a/sound/soc/codecs/arizona.h +++ b/sound/soc/codecs/arizona.h | |||
@@ -107,7 +107,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
107 | 107 | ||
108 | #define ARIZONA_MUX_CTL_DECL(name) \ | 108 | #define ARIZONA_MUX_CTL_DECL(name) \ |
109 | const struct snd_kcontrol_new name##_mux = \ | 109 | const struct snd_kcontrol_new name##_mux = \ |
110 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | 110 | SOC_DAPM_ENUM("Route", name##_enum) |
111 | 111 | ||
112 | #define ARIZONA_MUX_ENUMS(name, base_reg) \ | 112 | #define ARIZONA_MUX_ENUMS(name, base_reg) \ |
113 | static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ | 113 | static ARIZONA_MUX_ENUM_DECL(name##_enum, base_reg); \ |
@@ -128,7 +128,7 @@ extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS]; | |||
128 | ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) | 128 | ARIZONA_MUX_ENUMS(name##_aux6, base_reg + 40) |
129 | 129 | ||
130 | #define ARIZONA_MUX(name, ctrl) \ | 130 | #define ARIZONA_MUX(name, ctrl) \ |
131 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | 131 | SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) |
132 | 132 | ||
133 | #define ARIZONA_MUX_WIDGETS(name, name_str) \ | 133 | #define ARIZONA_MUX_WIDGETS(name, name_str) \ |
134 | ARIZONA_MUX(name_str " Input", &name##_mux) | 134 | ARIZONA_MUX(name_str " Input", &name##_mux) |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 1e25c7af853b..537327c7f7f1 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -139,8 +139,6 @@ static int cq93vc_probe(struct snd_soc_codec *codec) | |||
139 | 139 | ||
140 | davinci_vc->cq93vc.codec = codec; | 140 | davinci_vc->cq93vc.codec = codec; |
141 | 141 | ||
142 | snd_soc_codec_set_cache_io(codec, davinci_vc->regmap); | ||
143 | |||
144 | /* Off, with power on */ | 142 | /* Off, with power on */ |
145 | cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 143 | cq93vc_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
146 | 144 | ||
@@ -154,11 +152,19 @@ static int cq93vc_remove(struct snd_soc_codec *codec) | |||
154 | return 0; | 152 | return 0; |
155 | } | 153 | } |
156 | 154 | ||
155 | static struct regmap *cq93vc_get_regmap(struct device *dev) | ||
156 | { | ||
157 | struct davinci_vc *davinci_vc = dev->platform_data; | ||
158 | |||
159 | return davinci_vc->regmap; | ||
160 | } | ||
161 | |||
157 | static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { | 162 | static struct snd_soc_codec_driver soc_codec_dev_cq93vc = { |
158 | .set_bias_level = cq93vc_set_bias_level, | 163 | .set_bias_level = cq93vc_set_bias_level, |
159 | .probe = cq93vc_probe, | 164 | .probe = cq93vc_probe, |
160 | .remove = cq93vc_remove, | 165 | .remove = cq93vc_remove, |
161 | .resume = cq93vc_resume, | 166 | .resume = cq93vc_resume, |
167 | .get_regmap = cq93vc_get_regmap, | ||
162 | .controls = cq93vc_snd_controls, | 168 | .controls = cq93vc_snd_controls, |
163 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), | 169 | .num_controls = ARRAY_SIZE(cq93vc_snd_controls), |
164 | }; | 170 | }; |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 3920e6264948..9947a9583679 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -438,7 +438,7 @@ static int cs4270_dai_mute(struct snd_soc_dai *dai, int mute) | |||
438 | static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol, | 438 | static int cs4270_soc_put_mute(struct snd_kcontrol *kcontrol, |
439 | struct snd_ctl_elem_value *ucontrol) | 439 | struct snd_ctl_elem_value *ucontrol) |
440 | { | 440 | { |
441 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 441 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
442 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 442 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
443 | int left = !ucontrol->value.integer.value[0]; | 443 | int left = !ucontrol->value.integer.value[0]; |
444 | int right = !ucontrol->value.integer.value[1]; | 444 | int right = !ucontrol->value.integer.value[1]; |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index aef4965750c7..93cec52f4733 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -284,7 +284,7 @@ static int cs4271_set_deemph(struct snd_soc_codec *codec) | |||
284 | static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, | 284 | static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, |
285 | struct snd_ctl_elem_value *ucontrol) | 285 | struct snd_ctl_elem_value *ucontrol) |
286 | { | 286 | { |
287 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 287 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
288 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 288 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
289 | 289 | ||
290 | ucontrol->value.enumerated.item[0] = cs4271->deemph; | 290 | ucontrol->value.enumerated.item[0] = cs4271->deemph; |
@@ -294,7 +294,7 @@ static int cs4271_get_deemph(struct snd_kcontrol *kcontrol, | |||
294 | static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, | 294 | static int cs4271_put_deemph(struct snd_kcontrol *kcontrol, |
295 | struct snd_ctl_elem_value *ucontrol) | 295 | struct snd_ctl_elem_value *ucontrol) |
296 | { | 296 | { |
297 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 297 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
298 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); | 298 | struct cs4271_private *cs4271 = snd_soc_codec_get_drvdata(codec); |
299 | 299 | ||
300 | cs4271->deemph = ucontrol->value.enumerated.item[0]; | 300 | cs4271->deemph = ucontrol->value.enumerated.item[0]; |
diff --git a/sound/soc/codecs/cs42l51-i2c.c b/sound/soc/codecs/cs42l51-i2c.c new file mode 100644 index 000000000000..cee51ae177c1 --- /dev/null +++ b/sound/soc/codecs/cs42l51-i2c.c | |||
@@ -0,0 +1,59 @@ | |||
1 | /* | ||
2 | * cs42l56.c -- CS42L51 ALSA SoC I2C audio driver | ||
3 | * | ||
4 | * Copyright 2014 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/i2c.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <sound/soc.h> | ||
17 | |||
18 | #include "cs42l51.h" | ||
19 | |||
20 | static struct i2c_device_id cs42l51_i2c_id[] = { | ||
21 | {"cs42l51", 0}, | ||
22 | {} | ||
23 | }; | ||
24 | MODULE_DEVICE_TABLE(i2c, cs42l51_i2c_id); | ||
25 | |||
26 | static int cs42l51_i2c_probe(struct i2c_client *i2c, | ||
27 | const struct i2c_device_id *id) | ||
28 | { | ||
29 | struct regmap_config config; | ||
30 | |||
31 | config = cs42l51_regmap; | ||
32 | config.val_bits = 8; | ||
33 | config.reg_bits = 8; | ||
34 | |||
35 | return cs42l51_probe(&i2c->dev, devm_regmap_init_i2c(i2c, &config)); | ||
36 | } | ||
37 | |||
38 | static int cs42l51_i2c_remove(struct i2c_client *i2c) | ||
39 | { | ||
40 | snd_soc_unregister_codec(&i2c->dev); | ||
41 | |||
42 | return 0; | ||
43 | } | ||
44 | |||
45 | static struct i2c_driver cs42l51_i2c_driver = { | ||
46 | .driver = { | ||
47 | .name = "cs42l51", | ||
48 | .owner = THIS_MODULE, | ||
49 | }, | ||
50 | .probe = cs42l51_i2c_probe, | ||
51 | .remove = cs42l51_i2c_remove, | ||
52 | .id_table = cs42l51_i2c_id, | ||
53 | }; | ||
54 | |||
55 | module_i2c_driver(cs42l51_i2c_driver); | ||
56 | |||
57 | MODULE_DESCRIPTION("ASoC CS42L51 I2C Driver"); | ||
58 | MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); | ||
59 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 6c0da2baa154..09488d97de60 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <sound/initval.h> | 29 | #include <sound/initval.h> |
30 | #include <sound/pcm_params.h> | 30 | #include <sound/pcm_params.h> |
31 | #include <sound/pcm.h> | 31 | #include <sound/pcm.h> |
32 | #include <linux/i2c.h> | ||
33 | #include <linux/regmap.h> | 32 | #include <linux/regmap.h> |
34 | 33 | ||
35 | #include "cs42l51.h" | 34 | #include "cs42l51.h" |
@@ -55,7 +54,7 @@ struct cs42l51_private { | |||
55 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, | 54 | static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, |
56 | struct snd_ctl_elem_value *ucontrol) | 55 | struct snd_ctl_elem_value *ucontrol) |
57 | { | 56 | { |
58 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 57 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
59 | unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3; | 58 | unsigned long value = snd_soc_read(codec, CS42L51_PCM_MIXER)&3; |
60 | 59 | ||
61 | switch (value) { | 60 | switch (value) { |
@@ -83,7 +82,7 @@ static int cs42l51_get_chan_mix(struct snd_kcontrol *kcontrol, | |||
83 | static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, | 82 | static int cs42l51_set_chan_mix(struct snd_kcontrol *kcontrol, |
84 | struct snd_ctl_elem_value *ucontrol) | 83 | struct snd_ctl_elem_value *ucontrol) |
85 | { | 84 | { |
86 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 85 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
87 | unsigned char val; | 86 | unsigned char val; |
88 | 87 | ||
89 | switch (ucontrol->value.integer.value[0]) { | 88 | switch (ucontrol->value.integer.value[0]) { |
@@ -483,7 +482,7 @@ static struct snd_soc_dai_driver cs42l51_dai = { | |||
483 | .ops = &cs42l51_dai_ops, | 482 | .ops = &cs42l51_dai_ops, |
484 | }; | 483 | }; |
485 | 484 | ||
486 | static int cs42l51_probe(struct snd_soc_codec *codec) | 485 | static int cs42l51_codec_probe(struct snd_soc_codec *codec) |
487 | { | 486 | { |
488 | int ret, reg; | 487 | int ret, reg; |
489 | 488 | ||
@@ -504,7 +503,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
504 | } | 503 | } |
505 | 504 | ||
506 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 505 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
507 | .probe = cs42l51_probe, | 506 | .probe = cs42l51_codec_probe, |
508 | 507 | ||
509 | .controls = cs42l51_snd_controls, | 508 | .controls = cs42l51_snd_controls, |
510 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), | 509 | .num_controls = ARRAY_SIZE(cs42l51_snd_controls), |
@@ -514,91 +513,56 @@ static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | |||
514 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), | 513 | .num_dapm_routes = ARRAY_SIZE(cs42l51_routes), |
515 | }; | 514 | }; |
516 | 515 | ||
517 | static const struct regmap_config cs42l51_regmap = { | 516 | const struct regmap_config cs42l51_regmap = { |
518 | .reg_bits = 8, | ||
519 | .val_bits = 8, | ||
520 | |||
521 | .max_register = CS42L51_CHARGE_FREQ, | 517 | .max_register = CS42L51_CHARGE_FREQ, |
522 | .cache_type = REGCACHE_RBTREE, | 518 | .cache_type = REGCACHE_RBTREE, |
523 | }; | 519 | }; |
520 | EXPORT_SYMBOL_GPL(cs42l51_regmap); | ||
524 | 521 | ||
525 | static int cs42l51_i2c_probe(struct i2c_client *i2c_client, | 522 | int cs42l51_probe(struct device *dev, struct regmap *regmap) |
526 | const struct i2c_device_id *id) | ||
527 | { | 523 | { |
528 | struct cs42l51_private *cs42l51; | 524 | struct cs42l51_private *cs42l51; |
529 | struct regmap *regmap; | ||
530 | unsigned int val; | 525 | unsigned int val; |
531 | int ret; | 526 | int ret; |
532 | 527 | ||
533 | regmap = devm_regmap_init_i2c(i2c_client, &cs42l51_regmap); | 528 | if (IS_ERR(regmap)) |
534 | if (IS_ERR(regmap)) { | 529 | return PTR_ERR(regmap); |
535 | ret = PTR_ERR(regmap); | 530 | |
536 | dev_err(&i2c_client->dev, "Failed to create regmap: %d\n", | 531 | cs42l51 = devm_kzalloc(dev, sizeof(struct cs42l51_private), |
537 | ret); | 532 | GFP_KERNEL); |
538 | return ret; | 533 | if (!cs42l51) |
539 | } | 534 | return -ENOMEM; |
535 | |||
536 | dev_set_drvdata(dev, cs42l51); | ||
540 | 537 | ||
541 | /* Verify that we have a CS42L51 */ | 538 | /* Verify that we have a CS42L51 */ |
542 | ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); | 539 | ret = regmap_read(regmap, CS42L51_CHIP_REV_ID, &val); |
543 | if (ret < 0) { | 540 | if (ret < 0) { |
544 | dev_err(&i2c_client->dev, "failed to read I2C\n"); | 541 | dev_err(dev, "failed to read I2C\n"); |
545 | goto error; | 542 | goto error; |
546 | } | 543 | } |
547 | 544 | ||
548 | if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && | 545 | if ((val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_A)) && |
549 | (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { | 546 | (val != CS42L51_MK_CHIP_REV(CS42L51_CHIP_ID, CS42L51_CHIP_REV_B))) { |
550 | dev_err(&i2c_client->dev, "Invalid chip id: %x\n", val); | 547 | dev_err(dev, "Invalid chip id: %x\n", val); |
551 | ret = -ENODEV; | 548 | ret = -ENODEV; |
552 | goto error; | 549 | goto error; |
553 | } | 550 | } |
551 | dev_info(dev, "Cirrus Logic CS42L51, Revision: %02X\n", | ||
552 | val & CS42L51_CHIP_REV_MASK); | ||
554 | 553 | ||
555 | dev_info(&i2c_client->dev, "found device cs42l51 rev %d\n", | 554 | ret = snd_soc_register_codec(dev, |
556 | val & 7); | ||
557 | |||
558 | cs42l51 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l51_private), | ||
559 | GFP_KERNEL); | ||
560 | if (!cs42l51) | ||
561 | return -ENOMEM; | ||
562 | |||
563 | i2c_set_clientdata(i2c_client, cs42l51); | ||
564 | |||
565 | ret = snd_soc_register_codec(&i2c_client->dev, | ||
566 | &soc_codec_device_cs42l51, &cs42l51_dai, 1); | 555 | &soc_codec_device_cs42l51, &cs42l51_dai, 1); |
567 | error: | 556 | error: |
568 | return ret; | 557 | return ret; |
569 | } | 558 | } |
570 | 559 | EXPORT_SYMBOL_GPL(cs42l51_probe); | |
571 | static int cs42l51_i2c_remove(struct i2c_client *client) | ||
572 | { | ||
573 | snd_soc_unregister_codec(&client->dev); | ||
574 | return 0; | ||
575 | } | ||
576 | |||
577 | static const struct i2c_device_id cs42l51_id[] = { | ||
578 | {"cs42l51", 0}, | ||
579 | {} | ||
580 | }; | ||
581 | MODULE_DEVICE_TABLE(i2c, cs42l51_id); | ||
582 | 560 | ||
583 | static const struct of_device_id cs42l51_of_match[] = { | 561 | static const struct of_device_id cs42l51_of_match[] = { |
584 | { .compatible = "cirrus,cs42l51", }, | 562 | { .compatible = "cirrus,cs42l51", }, |
585 | { } | 563 | { } |
586 | }; | 564 | }; |
587 | MODULE_DEVICE_TABLE(of, cs42l51_of_match); | 565 | MODULE_DEVICE_TABLE(of, cs42l51_of_match); |
588 | |||
589 | static struct i2c_driver cs42l51_i2c_driver = { | ||
590 | .driver = { | ||
591 | .name = "cs42l51-codec", | ||
592 | .owner = THIS_MODULE, | ||
593 | .of_match_table = cs42l51_of_match, | ||
594 | }, | ||
595 | .id_table = cs42l51_id, | ||
596 | .probe = cs42l51_i2c_probe, | ||
597 | .remove = cs42l51_i2c_remove, | ||
598 | }; | ||
599 | |||
600 | module_i2c_driver(cs42l51_i2c_driver); | ||
601 | |||
602 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); | 566 | MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>"); |
603 | MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); | 567 | MODULE_DESCRIPTION("Cirrus Logic CS42L51 ALSA SoC Codec Driver"); |
604 | MODULE_LICENSE("GPL"); | 568 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/codecs/cs42l51.h b/sound/soc/codecs/cs42l51.h index 2beeb171db4b..8c55bf384bc6 100644 --- a/sound/soc/codecs/cs42l51.h +++ b/sound/soc/codecs/cs42l51.h | |||
@@ -18,9 +18,15 @@ | |||
18 | #ifndef _CS42L51_H | 18 | #ifndef _CS42L51_H |
19 | #define _CS42L51_H | 19 | #define _CS42L51_H |
20 | 20 | ||
21 | struct device; | ||
22 | |||
23 | extern const struct regmap_config cs42l51_regmap; | ||
24 | int cs42l51_probe(struct device *dev, struct regmap *regmap); | ||
25 | |||
21 | #define CS42L51_CHIP_ID 0x1B | 26 | #define CS42L51_CHIP_ID 0x1B |
22 | #define CS42L51_CHIP_REV_A 0x00 | 27 | #define CS42L51_CHIP_REV_A 0x00 |
23 | #define CS42L51_CHIP_REV_B 0x01 | 28 | #define CS42L51_CHIP_REV_B 0x01 |
29 | #define CS42L51_CHIP_REV_MASK 0x07 | ||
24 | 30 | ||
25 | #define CS42L51_CHIP_REV_ID 0x01 | 31 | #define CS42L51_CHIP_REV_ID 0x01 |
26 | #define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b)) | 32 | #define CS42L51_MK_CHIP_REV(a, b) ((a)<<3|(b)) |
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c index 2213a037c893..071fc77f2f06 100644 --- a/sound/soc/codecs/cs42l52.c +++ b/sound/soc/codecs/cs42l52.c | |||
@@ -50,11 +50,9 @@ struct cs42l52_private { | |||
50 | u8 mclksel; | 50 | u8 mclksel; |
51 | u32 mclk; | 51 | u32 mclk; |
52 | u8 flags; | 52 | u8 flags; |
53 | #if IS_ENABLED(CONFIG_INPUT) | ||
54 | struct input_dev *beep; | 53 | struct input_dev *beep; |
55 | struct work_struct beep_work; | 54 | struct work_struct beep_work; |
56 | int beep_rate; | 55 | int beep_rate; |
57 | #endif | ||
58 | }; | 56 | }; |
59 | 57 | ||
60 | static const struct reg_default cs42l52_reg_defaults[] = { | 58 | static const struct reg_default cs42l52_reg_defaults[] = { |
@@ -962,7 +960,6 @@ static int cs42l52_resume(struct snd_soc_codec *codec) | |||
962 | return 0; | 960 | return 0; |
963 | } | 961 | } |
964 | 962 | ||
965 | #if IS_ENABLED(CONFIG_INPUT) | ||
966 | static int beep_rates[] = { | 963 | static int beep_rates[] = { |
967 | 261, 522, 585, 667, 706, 774, 889, 1000, | 964 | 261, 522, 585, 667, 706, 774, 889, 1000, |
968 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 | 965 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 |
@@ -1096,15 +1093,6 @@ static void cs42l52_free_beep(struct snd_soc_codec *codec) | |||
1096 | snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL, | 1093 | snd_soc_update_bits(codec, CS42L52_BEEP_TONE_CTL, |
1097 | CS42L52_BEEP_EN_MASK, 0); | 1094 | CS42L52_BEEP_EN_MASK, 0); |
1098 | } | 1095 | } |
1099 | #else | ||
1100 | static void cs42l52_init_beep(struct snd_soc_codec *codec) | ||
1101 | { | ||
1102 | } | ||
1103 | |||
1104 | static void cs42l52_free_beep(struct snd_soc_codec *codec) | ||
1105 | { | ||
1106 | } | ||
1107 | #endif | ||
1108 | 1096 | ||
1109 | static int cs42l52_probe(struct snd_soc_codec *codec) | 1097 | static int cs42l52_probe(struct snd_soc_codec *codec) |
1110 | { | 1098 | { |
diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c new file mode 100644 index 000000000000..5bb134b4ab9b --- /dev/null +++ b/sound/soc/codecs/cs42l56.c | |||
@@ -0,0 +1,1427 @@ | |||
1 | /* | ||
2 | * cs42l56.c -- CS42L56 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2014 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/moduleparam.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/pm.h> | ||
20 | #include <linux/i2c.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/regmap.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/regulator/consumer.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #include <linux/of_gpio.h> | ||
29 | #include <sound/core.h> | ||
30 | #include <sound/pcm.h> | ||
31 | #include <sound/pcm_params.h> | ||
32 | #include <sound/soc.h> | ||
33 | #include <sound/soc-dapm.h> | ||
34 | #include <sound/initval.h> | ||
35 | #include <sound/tlv.h> | ||
36 | #include <sound/cs42l56.h> | ||
37 | #include "cs42l56.h" | ||
38 | |||
39 | #define CS42L56_NUM_SUPPLIES 3 | ||
40 | static const char *const cs42l56_supply_names[CS42L56_NUM_SUPPLIES] = { | ||
41 | "VA", | ||
42 | "VCP", | ||
43 | "VLDO", | ||
44 | }; | ||
45 | |||
46 | struct cs42l56_private { | ||
47 | struct regmap *regmap; | ||
48 | struct snd_soc_codec *codec; | ||
49 | struct device *dev; | ||
50 | struct cs42l56_platform_data pdata; | ||
51 | struct regulator_bulk_data supplies[CS42L56_NUM_SUPPLIES]; | ||
52 | u32 mclk; | ||
53 | u8 mclk_prediv; | ||
54 | u8 mclk_div2; | ||
55 | u8 mclk_ratio; | ||
56 | u8 iface; | ||
57 | u8 iface_fmt; | ||
58 | u8 iface_inv; | ||
59 | #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | ||
60 | struct input_dev *beep; | ||
61 | struct work_struct beep_work; | ||
62 | int beep_rate; | ||
63 | #endif | ||
64 | }; | ||
65 | |||
66 | static const struct reg_default cs42l56_reg_defaults[] = { | ||
67 | { 1, 0x56 }, /* r01 - ID 1 */ | ||
68 | { 2, 0x04 }, /* r02 - ID 2 */ | ||
69 | { 3, 0x7f }, /* r03 - Power Ctl 1 */ | ||
70 | { 4, 0xff }, /* r04 - Power Ctl 2 */ | ||
71 | { 5, 0x00 }, /* ro5 - Clocking Ctl 1 */ | ||
72 | { 6, 0x0b }, /* r06 - Clocking Ctl 2 */ | ||
73 | { 7, 0x00 }, /* r07 - Serial Format */ | ||
74 | { 8, 0x05 }, /* r08 - Class H Ctl */ | ||
75 | { 9, 0x0c }, /* r09 - Misc Ctl */ | ||
76 | { 10, 0x80 }, /* r0a - INT Status */ | ||
77 | { 11, 0x00 }, /* r0b - Playback Ctl */ | ||
78 | { 12, 0x0c }, /* r0c - DSP Mute Ctl */ | ||
79 | { 13, 0x00 }, /* r0d - ADCA Mixer Volume */ | ||
80 | { 14, 0x00 }, /* r0e - ADCB Mixer Volume */ | ||
81 | { 15, 0x00 }, /* r0f - PCMA Mixer Volume */ | ||
82 | { 16, 0x00 }, /* r10 - PCMB Mixer Volume */ | ||
83 | { 17, 0x00 }, /* r11 - Analog Input Advisory Volume */ | ||
84 | { 18, 0x00 }, /* r12 - Digital Input Advisory Volume */ | ||
85 | { 19, 0x00 }, /* r13 - Master A Volume */ | ||
86 | { 20, 0x00 }, /* r14 - Master B Volume */ | ||
87 | { 21, 0x00 }, /* r15 - Beep Freq / On Time */ | ||
88 | { 22, 0x00 }, /* r16 - Beep Volume / Off Time */ | ||
89 | { 23, 0x00 }, /* r17 - Beep Tone Ctl */ | ||
90 | { 24, 0x88 }, /* r18 - Tone Ctl */ | ||
91 | { 25, 0x00 }, /* r19 - Channel Mixer & Swap */ | ||
92 | { 26, 0x00 }, /* r1a - AIN Ref Config / ADC Mux */ | ||
93 | { 27, 0xa0 }, /* r1b - High-Pass Filter Ctl */ | ||
94 | { 28, 0x00 }, /* r1c - Misc ADC Ctl */ | ||
95 | { 29, 0x00 }, /* r1d - Gain & Bias Ctl */ | ||
96 | { 30, 0x00 }, /* r1e - PGAA Mux & Volume */ | ||
97 | { 31, 0x00 }, /* r1f - PGAB Mux & Volume */ | ||
98 | { 32, 0x00 }, /* r20 - ADCA Attenuator */ | ||
99 | { 33, 0x00 }, /* r21 - ADCB Attenuator */ | ||
100 | { 34, 0x00 }, /* r22 - ALC Enable & Attack Rate */ | ||
101 | { 35, 0xbf }, /* r23 - ALC Release Rate */ | ||
102 | { 36, 0x00 }, /* r24 - ALC Threshold */ | ||
103 | { 37, 0x00 }, /* r25 - Noise Gate Ctl */ | ||
104 | { 38, 0x00 }, /* r26 - ALC, Limiter, SFT, ZeroCross */ | ||
105 | { 39, 0x00 }, /* r27 - Analog Mute, LO & HP Mux */ | ||
106 | { 40, 0x00 }, /* r28 - HP A Volume */ | ||
107 | { 41, 0x00 }, /* r29 - HP B Volume */ | ||
108 | { 42, 0x00 }, /* r2a - LINEOUT A Volume */ | ||
109 | { 43, 0x00 }, /* r2b - LINEOUT B Volume */ | ||
110 | { 44, 0x00 }, /* r2c - Limit Threshold Ctl */ | ||
111 | { 45, 0x7f }, /* r2d - Limiter Ctl & Release Rate */ | ||
112 | { 46, 0x00 }, /* r2e - Limiter Attack Rate */ | ||
113 | }; | ||
114 | |||
115 | static bool cs42l56_readable_register(struct device *dev, unsigned int reg) | ||
116 | { | ||
117 | switch (reg) { | ||
118 | case CS42L56_CHIP_ID_1: | ||
119 | case CS42L56_CHIP_ID_2: | ||
120 | case CS42L56_PWRCTL_1: | ||
121 | case CS42L56_PWRCTL_2: | ||
122 | case CS42L56_CLKCTL_1: | ||
123 | case CS42L56_CLKCTL_2: | ||
124 | case CS42L56_SERIAL_FMT: | ||
125 | case CS42L56_CLASSH_CTL: | ||
126 | case CS42L56_MISC_CTL: | ||
127 | case CS42L56_INT_STATUS: | ||
128 | case CS42L56_PLAYBACK_CTL: | ||
129 | case CS42L56_DSP_MUTE_CTL: | ||
130 | case CS42L56_ADCA_MIX_VOLUME: | ||
131 | case CS42L56_ADCB_MIX_VOLUME: | ||
132 | case CS42L56_PCMA_MIX_VOLUME: | ||
133 | case CS42L56_PCMB_MIX_VOLUME: | ||
134 | case CS42L56_ANAINPUT_ADV_VOLUME: | ||
135 | case CS42L56_DIGINPUT_ADV_VOLUME: | ||
136 | case CS42L56_MASTER_A_VOLUME: | ||
137 | case CS42L56_MASTER_B_VOLUME: | ||
138 | case CS42L56_BEEP_FREQ_ONTIME: | ||
139 | case CS42L56_BEEP_FREQ_OFFTIME: | ||
140 | case CS42L56_BEEP_TONE_CFG: | ||
141 | case CS42L56_TONE_CTL: | ||
142 | case CS42L56_CHAN_MIX_SWAP: | ||
143 | case CS42L56_AIN_REFCFG_ADC_MUX: | ||
144 | case CS42L56_HPF_CTL: | ||
145 | case CS42L56_MISC_ADC_CTL: | ||
146 | case CS42L56_GAIN_BIAS_CTL: | ||
147 | case CS42L56_PGAA_MUX_VOLUME: | ||
148 | case CS42L56_PGAB_MUX_VOLUME: | ||
149 | case CS42L56_ADCA_ATTENUATOR: | ||
150 | case CS42L56_ADCB_ATTENUATOR: | ||
151 | case CS42L56_ALC_EN_ATTACK_RATE: | ||
152 | case CS42L56_ALC_RELEASE_RATE: | ||
153 | case CS42L56_ALC_THRESHOLD: | ||
154 | case CS42L56_NOISE_GATE_CTL: | ||
155 | case CS42L56_ALC_LIM_SFT_ZC: | ||
156 | case CS42L56_AMUTE_HPLO_MUX: | ||
157 | case CS42L56_HPA_VOLUME: | ||
158 | case CS42L56_HPB_VOLUME: | ||
159 | case CS42L56_LOA_VOLUME: | ||
160 | case CS42L56_LOB_VOLUME: | ||
161 | case CS42L56_LIM_THRESHOLD_CTL: | ||
162 | case CS42L56_LIM_CTL_RELEASE_RATE: | ||
163 | case CS42L56_LIM_ATTACK_RATE: | ||
164 | return true; | ||
165 | default: | ||
166 | return false; | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static bool cs42l56_volatile_register(struct device *dev, unsigned int reg) | ||
171 | { | ||
172 | switch (reg) { | ||
173 | case CS42L56_INT_STATUS: | ||
174 | return 1; | ||
175 | default: | ||
176 | return 0; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | static DECLARE_TLV_DB_SCALE(beep_tlv, -5000, 200, 0); | ||
181 | static DECLARE_TLV_DB_SCALE(hl_tlv, -6000, 50, 0); | ||
182 | static DECLARE_TLV_DB_SCALE(adv_tlv, -10200, 50, 0); | ||
183 | static DECLARE_TLV_DB_SCALE(adc_tlv, -9600, 100, 0); | ||
184 | static DECLARE_TLV_DB_SCALE(tone_tlv, -1050, 150, 0); | ||
185 | static DECLARE_TLV_DB_SCALE(preamp_tlv, 0, 1000, 0); | ||
186 | static DECLARE_TLV_DB_SCALE(pga_tlv, -600, 50, 0); | ||
187 | |||
188 | static const unsigned int ngnb_tlv[] = { | ||
189 | TLV_DB_RANGE_HEAD(2), | ||
190 | 0, 1, TLV_DB_SCALE_ITEM(-8200, 600, 0), | ||
191 | 2, 5, TLV_DB_SCALE_ITEM(-7600, 300, 0), | ||
192 | }; | ||
193 | static const unsigned int ngb_tlv[] = { | ||
194 | TLV_DB_RANGE_HEAD(2), | ||
195 | 0, 2, TLV_DB_SCALE_ITEM(-6400, 600, 0), | ||
196 | 3, 7, TLV_DB_SCALE_ITEM(-4600, 300, 0), | ||
197 | }; | ||
198 | static const unsigned int alc_tlv[] = { | ||
199 | TLV_DB_RANGE_HEAD(2), | ||
200 | 0, 2, TLV_DB_SCALE_ITEM(-3000, 600, 0), | ||
201 | 3, 7, TLV_DB_SCALE_ITEM(-1200, 300, 0), | ||
202 | }; | ||
203 | |||
204 | static const char * const beep_config_text[] = { | ||
205 | "Off", "Single", "Multiple", "Continuous" | ||
206 | }; | ||
207 | |||
208 | static const struct soc_enum beep_config_enum = | ||
209 | SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 6, | ||
210 | ARRAY_SIZE(beep_config_text), beep_config_text); | ||
211 | |||
212 | static const char * const beep_pitch_text[] = { | ||
213 | "C4", "C5", "D5", "E5", "F5", "G5", "A5", "B5", | ||
214 | "C6", "D6", "E6", "F6", "G6", "A6", "B6", "C7" | ||
215 | }; | ||
216 | |||
217 | static const struct soc_enum beep_pitch_enum = | ||
218 | SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 4, | ||
219 | ARRAY_SIZE(beep_pitch_text), beep_pitch_text); | ||
220 | |||
221 | static const char * const beep_ontime_text[] = { | ||
222 | "86 ms", "430 ms", "780 ms", "1.20 s", "1.50 s", | ||
223 | "1.80 s", "2.20 s", "2.50 s", "2.80 s", "3.20 s", | ||
224 | "3.50 s", "3.80 s", "4.20 s", "4.50 s", "4.80 s", "5.20 s" | ||
225 | }; | ||
226 | |||
227 | static const struct soc_enum beep_ontime_enum = | ||
228 | SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_ONTIME, 0, | ||
229 | ARRAY_SIZE(beep_ontime_text), beep_ontime_text); | ||
230 | |||
231 | static const char * const beep_offtime_text[] = { | ||
232 | "1.23 s", "2.58 s", "3.90 s", "5.20 s", | ||
233 | "6.60 s", "8.05 s", "9.35 s", "10.80 s" | ||
234 | }; | ||
235 | |||
236 | static const struct soc_enum beep_offtime_enum = | ||
237 | SOC_ENUM_SINGLE(CS42L56_BEEP_FREQ_OFFTIME, 5, | ||
238 | ARRAY_SIZE(beep_offtime_text), beep_offtime_text); | ||
239 | |||
240 | static const char * const beep_treble_text[] = { | ||
241 | "5kHz", "7kHz", "10kHz", "15kHz" | ||
242 | }; | ||
243 | |||
244 | static const struct soc_enum beep_treble_enum = | ||
245 | SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 3, | ||
246 | ARRAY_SIZE(beep_treble_text), beep_treble_text); | ||
247 | |||
248 | static const char * const beep_bass_text[] = { | ||
249 | "50Hz", "100Hz", "200Hz", "250Hz" | ||
250 | }; | ||
251 | |||
252 | static const struct soc_enum beep_bass_enum = | ||
253 | SOC_ENUM_SINGLE(CS42L56_BEEP_TONE_CFG, 1, | ||
254 | ARRAY_SIZE(beep_bass_text), beep_bass_text); | ||
255 | |||
256 | static const char * const adc_swap_text[] = { | ||
257 | "None", "A+B/2", "A-B/2", "Swap" | ||
258 | }; | ||
259 | |||
260 | static const struct soc_enum adc_swap_enum = | ||
261 | SOC_ENUM_SINGLE(CS42L56_MISC_ADC_CTL, 3, | ||
262 | ARRAY_SIZE(adc_swap_text), adc_swap_text); | ||
263 | |||
264 | static const char * const pgaa_mux_text[] = { | ||
265 | "AIN1A", "AIN2A", "AIN3A"}; | ||
266 | |||
267 | static const struct soc_enum pgaa_mux_enum = | ||
268 | SOC_ENUM_SINGLE(CS42L56_PGAA_MUX_VOLUME, 0, | ||
269 | ARRAY_SIZE(pgaa_mux_text), | ||
270 | pgaa_mux_text); | ||
271 | |||
272 | static const struct snd_kcontrol_new pgaa_mux = | ||
273 | SOC_DAPM_ENUM("Route", pgaa_mux_enum); | ||
274 | |||
275 | static const char * const pgab_mux_text[] = { | ||
276 | "AIN1B", "AIN2B", "AIN3B"}; | ||
277 | |||
278 | static const struct soc_enum pgab_mux_enum = | ||
279 | SOC_ENUM_SINGLE(CS42L56_PGAB_MUX_VOLUME, 0, | ||
280 | ARRAY_SIZE(pgab_mux_text), | ||
281 | pgab_mux_text); | ||
282 | |||
283 | static const struct snd_kcontrol_new pgab_mux = | ||
284 | SOC_DAPM_ENUM("Route", pgab_mux_enum); | ||
285 | |||
286 | static const char * const adca_mux_text[] = { | ||
287 | "PGAA", "AIN1A", "AIN2A", "AIN3A"}; | ||
288 | |||
289 | static const struct soc_enum adca_mux_enum = | ||
290 | SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 0, | ||
291 | ARRAY_SIZE(adca_mux_text), | ||
292 | adca_mux_text); | ||
293 | |||
294 | static const struct snd_kcontrol_new adca_mux = | ||
295 | SOC_DAPM_ENUM("Route", adca_mux_enum); | ||
296 | |||
297 | static const char * const adcb_mux_text[] = { | ||
298 | "PGAB", "AIN1B", "AIN2B", "AIN3B"}; | ||
299 | |||
300 | static const struct soc_enum adcb_mux_enum = | ||
301 | SOC_ENUM_SINGLE(CS42L56_AIN_REFCFG_ADC_MUX, 2, | ||
302 | ARRAY_SIZE(adcb_mux_text), | ||
303 | adcb_mux_text); | ||
304 | |||
305 | static const struct snd_kcontrol_new adcb_mux = | ||
306 | SOC_DAPM_ENUM("Route", adcb_mux_enum); | ||
307 | |||
308 | static const char * const left_swap_text[] = { | ||
309 | "Left", "LR 2", "Right"}; | ||
310 | |||
311 | static const char * const right_swap_text[] = { | ||
312 | "Right", "LR 2", "Left"}; | ||
313 | |||
314 | static const unsigned int swap_values[] = { 0, 1, 3 }; | ||
315 | |||
316 | static const struct soc_enum adca_swap_enum = | ||
317 | SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 0, 3, | ||
318 | ARRAY_SIZE(left_swap_text), | ||
319 | left_swap_text, | ||
320 | swap_values); | ||
321 | |||
322 | static const struct soc_enum pcma_swap_enum = | ||
323 | SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 4, 3, | ||
324 | ARRAY_SIZE(left_swap_text), | ||
325 | left_swap_text, | ||
326 | swap_values); | ||
327 | |||
328 | static const struct soc_enum adcb_swap_enum = | ||
329 | SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 2, 3, | ||
330 | ARRAY_SIZE(right_swap_text), | ||
331 | right_swap_text, | ||
332 | swap_values); | ||
333 | |||
334 | static const struct soc_enum pcmb_swap_enum = | ||
335 | SOC_VALUE_ENUM_SINGLE(CS42L56_CHAN_MIX_SWAP, 6, 3, | ||
336 | ARRAY_SIZE(right_swap_text), | ||
337 | right_swap_text, | ||
338 | swap_values); | ||
339 | |||
340 | static const struct snd_kcontrol_new hpa_switch = | ||
341 | SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 6, 1, 1); | ||
342 | |||
343 | static const struct snd_kcontrol_new hpb_switch = | ||
344 | SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 4, 1, 1); | ||
345 | |||
346 | static const struct snd_kcontrol_new loa_switch = | ||
347 | SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 2, 1, 1); | ||
348 | |||
349 | static const struct snd_kcontrol_new lob_switch = | ||
350 | SOC_DAPM_SINGLE("Switch", CS42L56_PWRCTL_2, 0, 1, 1); | ||
351 | |||
352 | static const char * const hploa_input_text[] = { | ||
353 | "DACA", "PGAA"}; | ||
354 | |||
355 | static const struct soc_enum lineouta_input_enum = | ||
356 | SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 2, | ||
357 | ARRAY_SIZE(hploa_input_text), | ||
358 | hploa_input_text); | ||
359 | |||
360 | static const struct snd_kcontrol_new lineouta_input = | ||
361 | SOC_DAPM_ENUM("Route", lineouta_input_enum); | ||
362 | |||
363 | static const struct soc_enum hpa_input_enum = | ||
364 | SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 0, | ||
365 | ARRAY_SIZE(hploa_input_text), | ||
366 | hploa_input_text); | ||
367 | |||
368 | static const struct snd_kcontrol_new hpa_input = | ||
369 | SOC_DAPM_ENUM("Route", hpa_input_enum); | ||
370 | |||
371 | static const char * const hplob_input_text[] = { | ||
372 | "DACB", "PGAB"}; | ||
373 | |||
374 | static const struct soc_enum lineoutb_input_enum = | ||
375 | SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 3, | ||
376 | ARRAY_SIZE(hplob_input_text), | ||
377 | hplob_input_text); | ||
378 | |||
379 | static const struct snd_kcontrol_new lineoutb_input = | ||
380 | SOC_DAPM_ENUM("Route", lineoutb_input_enum); | ||
381 | |||
382 | static const struct soc_enum hpb_input_enum = | ||
383 | SOC_ENUM_SINGLE(CS42L56_AMUTE_HPLO_MUX, 1, | ||
384 | ARRAY_SIZE(hplob_input_text), | ||
385 | hplob_input_text); | ||
386 | |||
387 | static const struct snd_kcontrol_new hpb_input = | ||
388 | SOC_DAPM_ENUM("Route", hpb_input_enum); | ||
389 | |||
390 | static const char * const dig_mux_text[] = { | ||
391 | "ADC", "DSP"}; | ||
392 | |||
393 | static const struct soc_enum dig_mux_enum = | ||
394 | SOC_ENUM_SINGLE(CS42L56_MISC_CTL, 7, | ||
395 | ARRAY_SIZE(dig_mux_text), | ||
396 | dig_mux_text); | ||
397 | |||
398 | static const struct snd_kcontrol_new dig_mux = | ||
399 | SOC_DAPM_ENUM("Route", dig_mux_enum); | ||
400 | |||
401 | static const char * const hpf_freq_text[] = { | ||
402 | "1.8Hz", "119Hz", "236Hz", "464Hz" | ||
403 | }; | ||
404 | |||
405 | static const struct soc_enum hpfa_freq_enum = | ||
406 | SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 0, | ||
407 | ARRAY_SIZE(hpf_freq_text), hpf_freq_text); | ||
408 | |||
409 | static const struct soc_enum hpfb_freq_enum = | ||
410 | SOC_ENUM_SINGLE(CS42L56_HPF_CTL, 2, | ||
411 | ARRAY_SIZE(hpf_freq_text), hpf_freq_text); | ||
412 | |||
413 | static const char * const ng_delay_text[] = { | ||
414 | "50ms", "100ms", "150ms", "200ms" | ||
415 | }; | ||
416 | |||
417 | static const struct soc_enum ng_delay_enum = | ||
418 | SOC_ENUM_SINGLE(CS42L56_NOISE_GATE_CTL, 0, | ||
419 | ARRAY_SIZE(ng_delay_text), ng_delay_text); | ||
420 | |||
421 | static const struct snd_kcontrol_new cs42l56_snd_controls[] = { | ||
422 | |||
423 | SOC_DOUBLE_R_SX_TLV("Master Volume", CS42L56_MASTER_A_VOLUME, | ||
424 | CS42L56_MASTER_B_VOLUME, 0, 0x34, 0xfd, adv_tlv), | ||
425 | SOC_DOUBLE("Master Mute Switch", CS42L56_DSP_MUTE_CTL, 0, 1, 1, 1), | ||
426 | |||
427 | SOC_DOUBLE_R_SX_TLV("ADC Mixer Volume", CS42L56_ADCA_MIX_VOLUME, | ||
428 | CS42L56_ADCB_MIX_VOLUME, 0, 0x88, 0xa9, hl_tlv), | ||
429 | SOC_DOUBLE("ADC Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 6, 7, 1, 1), | ||
430 | |||
431 | SOC_DOUBLE_R_SX_TLV("PCM Mixer Volume", CS42L56_PCMA_MIX_VOLUME, | ||
432 | CS42L56_PCMB_MIX_VOLUME, 0, 0x88, 0xa9, hl_tlv), | ||
433 | SOC_DOUBLE("PCM Mixer Mute Switch", CS42L56_DSP_MUTE_CTL, 4, 5, 1, 1), | ||
434 | |||
435 | SOC_SINGLE_TLV("Analog Advisory Volume", | ||
436 | CS42L56_ANAINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv), | ||
437 | SOC_SINGLE_TLV("Digital Advisory Volume", | ||
438 | CS42L56_DIGINPUT_ADV_VOLUME, 0, 0x00, 1, adv_tlv), | ||
439 | |||
440 | SOC_DOUBLE_R_SX_TLV("PGA Volume", CS42L56_PGAA_MUX_VOLUME, | ||
441 | CS42L56_PGAB_MUX_VOLUME, 0, 0x34, 0xfd, pga_tlv), | ||
442 | SOC_DOUBLE_R_TLV("ADC Volume", CS42L56_ADCA_ATTENUATOR, | ||
443 | CS42L56_ADCB_ATTENUATOR, 0, 0x00, 1, adc_tlv), | ||
444 | SOC_DOUBLE("ADC Mute Switch", CS42L56_MISC_ADC_CTL, 2, 3, 1, 1), | ||
445 | SOC_DOUBLE("ADC Boost Switch", CS42L56_GAIN_BIAS_CTL, 3, 2, 1, 1), | ||
446 | |||
447 | SOC_DOUBLE_R_SX_TLV("Headphone Volume", CS42L56_HPA_VOLUME, | ||
448 | CS42L56_HPA_VOLUME, 0, 0x44, 0x55, hl_tlv), | ||
449 | SOC_DOUBLE_R_SX_TLV("LineOut Volume", CS42L56_LOA_VOLUME, | ||
450 | CS42L56_LOA_VOLUME, 0, 0x44, 0x55, hl_tlv), | ||
451 | |||
452 | SOC_SINGLE_TLV("Bass Shelving Volume", CS42L56_TONE_CTL, | ||
453 | 0, 0x00, 1, tone_tlv), | ||
454 | SOC_SINGLE_TLV("Treble Shelving Volume", CS42L56_TONE_CTL, | ||
455 | 4, 0x00, 1, tone_tlv), | ||
456 | |||
457 | SOC_DOUBLE_TLV("PGA Preamp Volume", CS42L56_GAIN_BIAS_CTL, | ||
458 | 4, 6, 0x02, 1, preamp_tlv), | ||
459 | |||
460 | SOC_SINGLE("DSP Switch", CS42L56_PLAYBACK_CTL, 7, 1, 1), | ||
461 | SOC_SINGLE("Gang Playback Switch", CS42L56_PLAYBACK_CTL, 4, 1, 1), | ||
462 | SOC_SINGLE("Gang ADC Switch", CS42L56_MISC_ADC_CTL, 7, 1, 1), | ||
463 | SOC_SINGLE("Gang PGA Switch", CS42L56_MISC_ADC_CTL, 6, 1, 1), | ||
464 | |||
465 | SOC_SINGLE("PCMA Invert", CS42L56_PLAYBACK_CTL, 2, 1, 1), | ||
466 | SOC_SINGLE("PCMB Invert", CS42L56_PLAYBACK_CTL, 3, 1, 1), | ||
467 | SOC_SINGLE("ADCA Invert", CS42L56_MISC_ADC_CTL, 2, 1, 1), | ||
468 | SOC_SINGLE("ADCB Invert", CS42L56_MISC_ADC_CTL, 3, 1, 1), | ||
469 | |||
470 | SOC_ENUM("PCMA Swap", pcma_swap_enum), | ||
471 | SOC_ENUM("PCMB Swap", pcmb_swap_enum), | ||
472 | SOC_ENUM("ADCA Swap", adca_swap_enum), | ||
473 | SOC_ENUM("ADCB Swap", adcb_swap_enum), | ||
474 | |||
475 | SOC_DOUBLE("HPF Switch", CS42L56_HPF_CTL, 5, 7, 1, 1), | ||
476 | SOC_DOUBLE("HPF Freeze Switch", CS42L56_HPF_CTL, 4, 6, 1, 1), | ||
477 | SOC_ENUM("HPFA Corner Freq", hpfa_freq_enum), | ||
478 | SOC_ENUM("HPFB Corner Freq", hpfb_freq_enum), | ||
479 | |||
480 | SOC_SINGLE("Analog Soft Ramp", CS42L56_MISC_CTL, 4, 1, 1), | ||
481 | SOC_DOUBLE("Analog Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC, | ||
482 | 7, 5, 1, 1), | ||
483 | SOC_SINGLE("Analog Zero Cross", CS42L56_MISC_CTL, 3, 1, 1), | ||
484 | SOC_DOUBLE("Analog Zero Cross Disable", CS42L56_ALC_LIM_SFT_ZC, | ||
485 | 6, 4, 1, 1), | ||
486 | SOC_SINGLE("Digital Soft Ramp", CS42L56_MISC_CTL, 2, 1, 1), | ||
487 | SOC_SINGLE("Digital Soft Ramp Disable", CS42L56_ALC_LIM_SFT_ZC, | ||
488 | 3, 1, 1), | ||
489 | |||
490 | SOC_SINGLE("HL Deemphasis", CS42L56_PLAYBACK_CTL, 6, 1, 1), | ||
491 | |||
492 | SOC_SINGLE("ALC Switch", CS42L56_ALC_EN_ATTACK_RATE, 6, 1, 1), | ||
493 | SOC_SINGLE("ALC Limit All Switch", CS42L56_ALC_RELEASE_RATE, 7, 1, 1), | ||
494 | SOC_SINGLE_RANGE("ALC Attack", CS42L56_ALC_EN_ATTACK_RATE, | ||
495 | 0, 0, 0x3f, 0), | ||
496 | SOC_SINGLE_RANGE("ALC Release", CS42L56_ALC_RELEASE_RATE, | ||
497 | 0, 0x3f, 0, 0), | ||
498 | SOC_SINGLE_TLV("ALC MAX", CS42L56_ALC_THRESHOLD, | ||
499 | 5, 0x07, 1, alc_tlv), | ||
500 | SOC_SINGLE_TLV("ALC MIN", CS42L56_ALC_THRESHOLD, | ||
501 | 2, 0x07, 1, alc_tlv), | ||
502 | |||
503 | SOC_SINGLE("Limiter Switch", CS42L56_LIM_CTL_RELEASE_RATE, 7, 1, 1), | ||
504 | SOC_SINGLE("Limit All Switch", CS42L56_LIM_CTL_RELEASE_RATE, 6, 1, 1), | ||
505 | SOC_SINGLE_RANGE("Limiter Attack", CS42L56_LIM_ATTACK_RATE, | ||
506 | 0, 0, 0x3f, 0), | ||
507 | SOC_SINGLE_RANGE("Limiter Release", CS42L56_LIM_CTL_RELEASE_RATE, | ||
508 | 0, 0x3f, 0, 0), | ||
509 | SOC_SINGLE_TLV("Limiter MAX", CS42L56_LIM_THRESHOLD_CTL, | ||
510 | 5, 0x07, 1, alc_tlv), | ||
511 | SOC_SINGLE_TLV("Limiter Cushion", CS42L56_ALC_THRESHOLD, | ||
512 | 2, 0x07, 1, alc_tlv), | ||
513 | |||
514 | SOC_SINGLE("NG Switch", CS42L56_NOISE_GATE_CTL, 6, 1, 1), | ||
515 | SOC_SINGLE("NG All Switch", CS42L56_NOISE_GATE_CTL, 7, 1, 1), | ||
516 | SOC_SINGLE("NG Boost Switch", CS42L56_NOISE_GATE_CTL, 5, 1, 1), | ||
517 | SOC_SINGLE_TLV("NG Unboost Threshold", CS42L56_NOISE_GATE_CTL, | ||
518 | 2, 0x07, 1, ngnb_tlv), | ||
519 | SOC_SINGLE_TLV("NG Boost Threshold", CS42L56_NOISE_GATE_CTL, | ||
520 | 2, 0x07, 1, ngb_tlv), | ||
521 | SOC_ENUM("NG Delay", ng_delay_enum), | ||
522 | |||
523 | SOC_ENUM("Beep Config", beep_config_enum), | ||
524 | SOC_ENUM("Beep Pitch", beep_pitch_enum), | ||
525 | SOC_ENUM("Beep on Time", beep_ontime_enum), | ||
526 | SOC_ENUM("Beep off Time", beep_offtime_enum), | ||
527 | SOC_SINGLE_SX_TLV("Beep Volume", CS42L56_BEEP_FREQ_OFFTIME, | ||
528 | 0, 0x07, 0x23, beep_tlv), | ||
529 | SOC_SINGLE("Beep Tone Ctl Switch", CS42L56_BEEP_TONE_CFG, 0, 1, 1), | ||
530 | SOC_ENUM("Beep Treble Corner Freq", beep_treble_enum), | ||
531 | SOC_ENUM("Beep Bass Corner Freq", beep_bass_enum), | ||
532 | |||
533 | }; | ||
534 | |||
535 | static const struct snd_soc_dapm_widget cs42l56_dapm_widgets[] = { | ||
536 | |||
537 | SND_SOC_DAPM_SIGGEN("Beep"), | ||
538 | SND_SOC_DAPM_SUPPLY("VBUF", CS42L56_PWRCTL_1, 5, 1, NULL, 0), | ||
539 | SND_SOC_DAPM_MICBIAS("MIC1 Bias", CS42L56_PWRCTL_1, 4, 1), | ||
540 | SND_SOC_DAPM_SUPPLY("Charge Pump", CS42L56_PWRCTL_1, 3, 1, NULL, 0), | ||
541 | |||
542 | SND_SOC_DAPM_INPUT("AIN1A"), | ||
543 | SND_SOC_DAPM_INPUT("AIN2A"), | ||
544 | SND_SOC_DAPM_INPUT("AIN1B"), | ||
545 | SND_SOC_DAPM_INPUT("AIN2B"), | ||
546 | SND_SOC_DAPM_INPUT("AIN3A"), | ||
547 | SND_SOC_DAPM_INPUT("AIN3B"), | ||
548 | |||
549 | SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, | ||
550 | SND_SOC_NOPM, 0, 0), | ||
551 | |||
552 | SND_SOC_DAPM_AIF_IN("SDIN", NULL, 0, | ||
553 | SND_SOC_NOPM, 0, 0), | ||
554 | |||
555 | SND_SOC_DAPM_MUX("Digital Output Mux", SND_SOC_NOPM, | ||
556 | 0, 0, &dig_mux), | ||
557 | |||
558 | SND_SOC_DAPM_PGA("PGAA", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
559 | SND_SOC_DAPM_PGA("PGAB", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
560 | SND_SOC_DAPM_MUX("PGAA Input Mux", | ||
561 | SND_SOC_NOPM, 0, 0, &pgaa_mux), | ||
562 | SND_SOC_DAPM_MUX("PGAB Input Mux", | ||
563 | SND_SOC_NOPM, 0, 0, &pgab_mux), | ||
564 | |||
565 | SND_SOC_DAPM_MUX("ADCA Mux", SND_SOC_NOPM, | ||
566 | 0, 0, &adca_mux), | ||
567 | SND_SOC_DAPM_MUX("ADCB Mux", SND_SOC_NOPM, | ||
568 | 0, 0, &adcb_mux), | ||
569 | |||
570 | SND_SOC_DAPM_ADC("ADCA", NULL, CS42L56_PWRCTL_1, 1, 1), | ||
571 | SND_SOC_DAPM_ADC("ADCB", NULL, CS42L56_PWRCTL_1, 2, 1), | ||
572 | |||
573 | SND_SOC_DAPM_DAC("DACA", NULL, SND_SOC_NOPM, 0, 0), | ||
574 | SND_SOC_DAPM_DAC("DACB", NULL, SND_SOC_NOPM, 0, 0), | ||
575 | |||
576 | SND_SOC_DAPM_OUTPUT("HPA"), | ||
577 | SND_SOC_DAPM_OUTPUT("LOA"), | ||
578 | SND_SOC_DAPM_OUTPUT("HPB"), | ||
579 | SND_SOC_DAPM_OUTPUT("LOB"), | ||
580 | |||
581 | SND_SOC_DAPM_SWITCH("Headphone Right", | ||
582 | CS42L56_PWRCTL_2, 4, 1, &hpb_switch), | ||
583 | SND_SOC_DAPM_SWITCH("Headphone Left", | ||
584 | CS42L56_PWRCTL_2, 6, 1, &hpa_switch), | ||
585 | |||
586 | SND_SOC_DAPM_SWITCH("Lineout Right", | ||
587 | CS42L56_PWRCTL_2, 0, 1, &lob_switch), | ||
588 | SND_SOC_DAPM_SWITCH("Lineout Left", | ||
589 | CS42L56_PWRCTL_2, 2, 1, &loa_switch), | ||
590 | |||
591 | SND_SOC_DAPM_MUX("LINEOUTA Input Mux", SND_SOC_NOPM, | ||
592 | 0, 0, &lineouta_input), | ||
593 | SND_SOC_DAPM_MUX("LINEOUTB Input Mux", SND_SOC_NOPM, | ||
594 | 0, 0, &lineoutb_input), | ||
595 | SND_SOC_DAPM_MUX("HPA Input Mux", SND_SOC_NOPM, | ||
596 | 0, 0, &hpa_input), | ||
597 | SND_SOC_DAPM_MUX("HPB Input Mux", SND_SOC_NOPM, | ||
598 | 0, 0, &hpb_input), | ||
599 | |||
600 | }; | ||
601 | |||
602 | static const struct snd_soc_dapm_route cs42l56_audio_map[] = { | ||
603 | |||
604 | {"HiFi Capture", "DSP", "Digital Output Mux"}, | ||
605 | {"HiFi Capture", "ADC", "Digital Output Mux"}, | ||
606 | |||
607 | {"Digital Output Mux", NULL, "ADCA"}, | ||
608 | {"Digital Output Mux", NULL, "ADCB"}, | ||
609 | |||
610 | {"ADCB", NULL, "ADCB Mux"}, | ||
611 | {"ADCA", NULL, "ADCA Mux"}, | ||
612 | |||
613 | {"ADCA Mux", NULL, "AIN3A"}, | ||
614 | {"ADCA Mux", NULL, "AIN2A"}, | ||
615 | {"ADCA Mux", NULL, "AIN1A"}, | ||
616 | {"ADCA Mux", NULL, "PGAA"}, | ||
617 | {"ADCB Mux", NULL, "AIN3B"}, | ||
618 | {"ADCB Mux", NULL, "AIN2B"}, | ||
619 | {"ADCB Mux", NULL, "AIN1B"}, | ||
620 | {"ADCB Mux", NULL, "PGAB"}, | ||
621 | |||
622 | {"PGAA", "AIN1A", "PGAA Input Mux"}, | ||
623 | {"PGAA", "AIN2A", "PGAA Input Mux"}, | ||
624 | {"PGAA", "AIN3A", "PGAA Input Mux"}, | ||
625 | {"PGAB", "AIN1B", "PGAB Input Mux"}, | ||
626 | {"PGAB", "AIN2B", "PGAB Input Mux"}, | ||
627 | {"PGAB", "AIN3B", "PGAB Input Mux"}, | ||
628 | |||
629 | {"PGAA Input Mux", NULL, "AIN1A"}, | ||
630 | {"PGAA Input Mux", NULL, "AIN2A"}, | ||
631 | {"PGAA Input Mux", NULL, "AIN3A"}, | ||
632 | {"PGAB Input Mux", NULL, "AIN1B"}, | ||
633 | {"PGAB Input Mux", NULL, "AIN2B"}, | ||
634 | {"PGAB Input Mux", NULL, "AIN3B"}, | ||
635 | |||
636 | {"LOB", NULL, "Lineout Right"}, | ||
637 | {"LOA", NULL, "Lineout Left"}, | ||
638 | |||
639 | {"Lineout Right", "Switch", "LINEOUTB Input Mux"}, | ||
640 | {"Lineout Left", "Switch", "LINEOUTA Input Mux"}, | ||
641 | |||
642 | {"LINEOUTA Input Mux", "PGAA", "PGAA"}, | ||
643 | {"LINEOUTB Input Mux", "PGAB", "PGAB"}, | ||
644 | {"LINEOUTA Input Mux", "DACA", "DACA"}, | ||
645 | {"LINEOUTB Input Mux", "DACB", "DACB"}, | ||
646 | |||
647 | {"HPA", NULL, "Headphone Left"}, | ||
648 | {"HPB", NULL, "Headphone Right"}, | ||
649 | |||
650 | {"Headphone Right", "Switch", "HPB Input Mux"}, | ||
651 | {"Headphone Left", "Switch", "HPA Input Mux"}, | ||
652 | |||
653 | {"HPA Input Mux", "PGAA", "PGAA"}, | ||
654 | {"HPB Input Mux", "PGAB", "PGAB"}, | ||
655 | {"HPA Input Mux", "DACA", "DACA"}, | ||
656 | {"HPB Input Mux", "DACB", "DACB"}, | ||
657 | |||
658 | {"DACB", NULL, "HiFi Playback"}, | ||
659 | {"DACA", NULL, "HiFi Playback"}, | ||
660 | |||
661 | }; | ||
662 | |||
663 | struct cs42l56_clk_para { | ||
664 | u32 mclk; | ||
665 | u32 srate; | ||
666 | u8 ratio; | ||
667 | }; | ||
668 | |||
669 | static const struct cs42l56_clk_para clk_ratio_table[] = { | ||
670 | /* 8k */ | ||
671 | { 6000000, 8000, CS42L56_MCLK_LRCLK_768 }, | ||
672 | { 6144000, 8000, CS42L56_MCLK_LRCLK_750 }, | ||
673 | { 12000000, 8000, CS42L56_MCLK_LRCLK_768 }, | ||
674 | { 12288000, 8000, CS42L56_MCLK_LRCLK_750 }, | ||
675 | { 24000000, 8000, CS42L56_MCLK_LRCLK_768 }, | ||
676 | { 24576000, 8000, CS42L56_MCLK_LRCLK_750 }, | ||
677 | /* 11.025k */ | ||
678 | { 5644800, 11025, CS42L56_MCLK_LRCLK_512}, | ||
679 | { 11289600, 11025, CS42L56_MCLK_LRCLK_512}, | ||
680 | { 22579200, 11025, CS42L56_MCLK_LRCLK_512 }, | ||
681 | /* 11.0294k */ | ||
682 | { 6000000, 110294, CS42L56_MCLK_LRCLK_544 }, | ||
683 | { 12000000, 110294, CS42L56_MCLK_LRCLK_544 }, | ||
684 | { 24000000, 110294, CS42L56_MCLK_LRCLK_544 }, | ||
685 | /* 12k */ | ||
686 | { 6000000, 12000, CS42L56_MCLK_LRCLK_500 }, | ||
687 | { 6144000, 12000, CS42L56_MCLK_LRCLK_512 }, | ||
688 | { 12000000, 12000, CS42L56_MCLK_LRCLK_500 }, | ||
689 | { 12288000, 12000, CS42L56_MCLK_LRCLK_512 }, | ||
690 | { 24000000, 12000, CS42L56_MCLK_LRCLK_500 }, | ||
691 | { 24576000, 12000, CS42L56_MCLK_LRCLK_512 }, | ||
692 | /* 16k */ | ||
693 | { 6000000, 16000, CS42L56_MCLK_LRCLK_375 }, | ||
694 | { 6144000, 16000, CS42L56_MCLK_LRCLK_384 }, | ||
695 | { 12000000, 16000, CS42L56_MCLK_LRCLK_375 }, | ||
696 | { 12288000, 16000, CS42L56_MCLK_LRCLK_384 }, | ||
697 | { 24000000, 16000, CS42L56_MCLK_LRCLK_375 }, | ||
698 | { 24576000, 16000, CS42L56_MCLK_LRCLK_384 }, | ||
699 | /* 22.050k */ | ||
700 | { 5644800, 22050, CS42L56_MCLK_LRCLK_256 }, | ||
701 | { 11289600, 22050, CS42L56_MCLK_LRCLK_256 }, | ||
702 | { 22579200, 22050, CS42L56_MCLK_LRCLK_256 }, | ||
703 | /* 22.0588k */ | ||
704 | { 6000000, 220588, CS42L56_MCLK_LRCLK_272 }, | ||
705 | { 12000000, 220588, CS42L56_MCLK_LRCLK_272 }, | ||
706 | { 24000000, 220588, CS42L56_MCLK_LRCLK_272 }, | ||
707 | /* 24k */ | ||
708 | { 6000000, 24000, CS42L56_MCLK_LRCLK_250 }, | ||
709 | { 6144000, 24000, CS42L56_MCLK_LRCLK_256 }, | ||
710 | { 12000000, 24000, CS42L56_MCLK_LRCLK_250 }, | ||
711 | { 12288000, 24000, CS42L56_MCLK_LRCLK_256 }, | ||
712 | { 24000000, 24000, CS42L56_MCLK_LRCLK_250 }, | ||
713 | { 24576000, 24000, CS42L56_MCLK_LRCLK_256 }, | ||
714 | /* 32k */ | ||
715 | { 6000000, 32000, CS42L56_MCLK_LRCLK_187P5 }, | ||
716 | { 6144000, 32000, CS42L56_MCLK_LRCLK_192 }, | ||
717 | { 12000000, 32000, CS42L56_MCLK_LRCLK_187P5 }, | ||
718 | { 12288000, 32000, CS42L56_MCLK_LRCLK_192 }, | ||
719 | { 24000000, 32000, CS42L56_MCLK_LRCLK_187P5 }, | ||
720 | { 24576000, 32000, CS42L56_MCLK_LRCLK_192 }, | ||
721 | /* 44.118k */ | ||
722 | { 6000000, 44118, CS42L56_MCLK_LRCLK_136 }, | ||
723 | { 12000000, 44118, CS42L56_MCLK_LRCLK_136 }, | ||
724 | { 24000000, 44118, CS42L56_MCLK_LRCLK_136 }, | ||
725 | /* 44.1k */ | ||
726 | { 5644800, 44100, CS42L56_MCLK_LRCLK_128 }, | ||
727 | { 11289600, 44100, CS42L56_MCLK_LRCLK_128 }, | ||
728 | { 22579200, 44100, CS42L56_MCLK_LRCLK_128 }, | ||
729 | /* 48k */ | ||
730 | { 6000000, 48000, CS42L56_MCLK_LRCLK_125 }, | ||
731 | { 6144000, 48000, CS42L56_MCLK_LRCLK_128 }, | ||
732 | { 12000000, 48000, CS42L56_MCLK_LRCLK_125 }, | ||
733 | { 12288000, 48000, CS42L56_MCLK_LRCLK_128 }, | ||
734 | { 24000000, 48000, CS42L56_MCLK_LRCLK_125 }, | ||
735 | { 24576000, 48000, CS42L56_MCLK_LRCLK_128 }, | ||
736 | }; | ||
737 | |||
738 | static int cs42l56_get_mclk_ratio(int mclk, int rate) | ||
739 | { | ||
740 | int i; | ||
741 | |||
742 | for (i = 0; i < ARRAY_SIZE(clk_ratio_table); i++) { | ||
743 | if (clk_ratio_table[i].mclk == mclk && | ||
744 | clk_ratio_table[i].srate == rate) | ||
745 | return clk_ratio_table[i].ratio; | ||
746 | } | ||
747 | return -EINVAL; | ||
748 | } | ||
749 | |||
750 | static int cs42l56_set_sysclk(struct snd_soc_dai *codec_dai, | ||
751 | int clk_id, unsigned int freq, int dir) | ||
752 | { | ||
753 | struct snd_soc_codec *codec = codec_dai->codec; | ||
754 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
755 | |||
756 | switch (freq) { | ||
757 | case CS42L56_MCLK_5P6448MHZ: | ||
758 | case CS42L56_MCLK_6MHZ: | ||
759 | case CS42L56_MCLK_6P144MHZ: | ||
760 | cs42l56->mclk_div2 = 0; | ||
761 | cs42l56->mclk_prediv = 0; | ||
762 | break; | ||
763 | case CS42L56_MCLK_11P2896MHZ: | ||
764 | case CS42L56_MCLK_12MHZ: | ||
765 | case CS42L56_MCLK_12P288MHZ: | ||
766 | cs42l56->mclk_div2 = 1; | ||
767 | cs42l56->mclk_prediv = 0; | ||
768 | break; | ||
769 | case CS42L56_MCLK_22P5792MHZ: | ||
770 | case CS42L56_MCLK_24MHZ: | ||
771 | case CS42L56_MCLK_24P576MHZ: | ||
772 | cs42l56->mclk_div2 = 1; | ||
773 | cs42l56->mclk_prediv = 1; | ||
774 | break; | ||
775 | default: | ||
776 | return -EINVAL; | ||
777 | } | ||
778 | cs42l56->mclk = freq; | ||
779 | |||
780 | snd_soc_update_bits(codec, CS42L56_CLKCTL_1, | ||
781 | CS42L56_MCLK_PREDIV_MASK, | ||
782 | cs42l56->mclk_prediv); | ||
783 | snd_soc_update_bits(codec, CS42L56_CLKCTL_1, | ||
784 | CS42L56_MCLK_DIV2_MASK, | ||
785 | cs42l56->mclk_div2); | ||
786 | |||
787 | return 0; | ||
788 | } | ||
789 | |||
790 | static int cs42l56_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) | ||
791 | { | ||
792 | struct snd_soc_codec *codec = codec_dai->codec; | ||
793 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
794 | |||
795 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
796 | case SND_SOC_DAIFMT_CBM_CFM: | ||
797 | cs42l56->iface = CS42L56_MASTER_MODE; | ||
798 | break; | ||
799 | case SND_SOC_DAIFMT_CBS_CFS: | ||
800 | cs42l56->iface = CS42L56_SLAVE_MODE; | ||
801 | break; | ||
802 | default: | ||
803 | return -EINVAL; | ||
804 | } | ||
805 | |||
806 | /* interface format */ | ||
807 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
808 | case SND_SOC_DAIFMT_I2S: | ||
809 | cs42l56->iface_fmt = CS42L56_DIG_FMT_I2S; | ||
810 | break; | ||
811 | case SND_SOC_DAIFMT_LEFT_J: | ||
812 | cs42l56->iface_fmt = CS42L56_DIG_FMT_LEFT_J; | ||
813 | break; | ||
814 | default: | ||
815 | return -EINVAL; | ||
816 | } | ||
817 | |||
818 | /* sclk inversion */ | ||
819 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
820 | case SND_SOC_DAIFMT_NB_NF: | ||
821 | cs42l56->iface_inv = 0; | ||
822 | break; | ||
823 | case SND_SOC_DAIFMT_IB_NF: | ||
824 | cs42l56->iface_inv = CS42L56_SCLK_INV; | ||
825 | break; | ||
826 | default: | ||
827 | return -EINVAL; | ||
828 | } | ||
829 | |||
830 | snd_soc_update_bits(codec, CS42L56_CLKCTL_1, | ||
831 | CS42L56_MS_MODE_MASK, cs42l56->iface); | ||
832 | snd_soc_update_bits(codec, CS42L56_SERIAL_FMT, | ||
833 | CS42L56_DIG_FMT_MASK, cs42l56->iface_fmt); | ||
834 | snd_soc_update_bits(codec, CS42L56_CLKCTL_1, | ||
835 | CS42L56_SCLK_INV_MASK, cs42l56->iface_inv); | ||
836 | return 0; | ||
837 | } | ||
838 | |||
839 | static int cs42l56_digital_mute(struct snd_soc_dai *dai, int mute) | ||
840 | { | ||
841 | struct snd_soc_codec *codec = dai->codec; | ||
842 | |||
843 | if (mute) { | ||
844 | /* Hit the DSP Mixer first */ | ||
845 | snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL, | ||
846 | CS42L56_ADCAMIX_MUTE_MASK | | ||
847 | CS42L56_ADCBMIX_MUTE_MASK | | ||
848 | CS42L56_PCMAMIX_MUTE_MASK | | ||
849 | CS42L56_PCMBMIX_MUTE_MASK | | ||
850 | CS42L56_MSTB_MUTE_MASK | | ||
851 | CS42L56_MSTA_MUTE_MASK, | ||
852 | CS42L56_MUTE); | ||
853 | /* Mute ADC's */ | ||
854 | snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL, | ||
855 | CS42L56_ADCA_MUTE_MASK | | ||
856 | CS42L56_ADCB_MUTE_MASK, | ||
857 | CS42L56_MUTE); | ||
858 | /* HP And LO */ | ||
859 | snd_soc_update_bits(codec, CS42L56_HPA_VOLUME, | ||
860 | CS42L56_HP_MUTE_MASK, | ||
861 | CS42L56_MUTE); | ||
862 | snd_soc_update_bits(codec, CS42L56_HPB_VOLUME, | ||
863 | CS42L56_HP_MUTE_MASK, | ||
864 | CS42L56_MUTE); | ||
865 | snd_soc_update_bits(codec, CS42L56_LOA_VOLUME, | ||
866 | CS42L56_LO_MUTE_MASK, | ||
867 | CS42L56_MUTE); | ||
868 | snd_soc_update_bits(codec, CS42L56_LOB_VOLUME, | ||
869 | CS42L56_LO_MUTE_MASK, | ||
870 | CS42L56_MUTE); | ||
871 | |||
872 | |||
873 | } else { | ||
874 | snd_soc_update_bits(codec, CS42L56_DSP_MUTE_CTL, | ||
875 | CS42L56_ADCAMIX_MUTE_MASK | | ||
876 | CS42L56_ADCBMIX_MUTE_MASK | | ||
877 | CS42L56_PCMAMIX_MUTE_MASK | | ||
878 | CS42L56_PCMBMIX_MUTE_MASK | | ||
879 | CS42L56_MSTB_MUTE_MASK | | ||
880 | CS42L56_MSTA_MUTE_MASK, | ||
881 | CS42L56_UNMUTE); | ||
882 | snd_soc_update_bits(codec, CS42L56_MISC_ADC_CTL, | ||
883 | CS42L56_ADCA_MUTE_MASK | | ||
884 | CS42L56_ADCB_MUTE_MASK, | ||
885 | CS42L56_UNMUTE); | ||
886 | snd_soc_update_bits(codec, CS42L56_HPA_VOLUME, | ||
887 | CS42L56_HP_MUTE_MASK, | ||
888 | CS42L56_UNMUTE); | ||
889 | snd_soc_update_bits(codec, CS42L56_HPB_VOLUME, | ||
890 | CS42L56_HP_MUTE_MASK, | ||
891 | CS42L56_UNMUTE); | ||
892 | snd_soc_update_bits(codec, CS42L56_LOA_VOLUME, | ||
893 | CS42L56_LO_MUTE_MASK, | ||
894 | CS42L56_UNMUTE); | ||
895 | snd_soc_update_bits(codec, CS42L56_LOB_VOLUME, | ||
896 | CS42L56_LO_MUTE_MASK, | ||
897 | CS42L56_UNMUTE); | ||
898 | } | ||
899 | return 0; | ||
900 | } | ||
901 | |||
902 | static int cs42l56_pcm_hw_params(struct snd_pcm_substream *substream, | ||
903 | struct snd_pcm_hw_params *params, | ||
904 | struct snd_soc_dai *dai) | ||
905 | { | ||
906 | struct snd_soc_codec *codec = dai->codec; | ||
907 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
908 | int ratio; | ||
909 | |||
910 | ratio = cs42l56_get_mclk_ratio(cs42l56->mclk, params_rate(params)); | ||
911 | if (ratio >= 0) { | ||
912 | snd_soc_update_bits(codec, CS42L56_CLKCTL_2, | ||
913 | CS42L56_CLK_RATIO_MASK, ratio); | ||
914 | } else { | ||
915 | dev_err(codec->dev, "unsupported mclk/sclk/lrclk ratio\n"); | ||
916 | return -EINVAL; | ||
917 | } | ||
918 | |||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | static int cs42l56_set_bias_level(struct snd_soc_codec *codec, | ||
923 | enum snd_soc_bias_level level) | ||
924 | { | ||
925 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
926 | int ret; | ||
927 | |||
928 | switch (level) { | ||
929 | case SND_SOC_BIAS_ON: | ||
930 | break; | ||
931 | case SND_SOC_BIAS_PREPARE: | ||
932 | snd_soc_update_bits(codec, CS42L56_CLKCTL_1, | ||
933 | CS42L56_MCLK_DIS_MASK, 0); | ||
934 | snd_soc_update_bits(codec, CS42L56_PWRCTL_1, | ||
935 | CS42L56_PDN_ALL_MASK, 0); | ||
936 | break; | ||
937 | case SND_SOC_BIAS_STANDBY: | ||
938 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
939 | regcache_cache_only(cs42l56->regmap, false); | ||
940 | regcache_sync(cs42l56->regmap); | ||
941 | ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), | ||
942 | cs42l56->supplies); | ||
943 | if (ret != 0) { | ||
944 | dev_err(cs42l56->dev, | ||
945 | "Failed to enable regulators: %d\n", | ||
946 | ret); | ||
947 | return ret; | ||
948 | } | ||
949 | } | ||
950 | snd_soc_update_bits(codec, CS42L56_PWRCTL_1, | ||
951 | CS42L56_PDN_ALL_MASK, 1); | ||
952 | break; | ||
953 | case SND_SOC_BIAS_OFF: | ||
954 | snd_soc_update_bits(codec, CS42L56_PWRCTL_1, | ||
955 | CS42L56_PDN_ALL_MASK, 1); | ||
956 | snd_soc_update_bits(codec, CS42L56_CLKCTL_1, | ||
957 | CS42L56_MCLK_DIS_MASK, 1); | ||
958 | regcache_cache_only(cs42l56->regmap, true); | ||
959 | regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), | ||
960 | cs42l56->supplies); | ||
961 | break; | ||
962 | } | ||
963 | codec->dapm.bias_level = level; | ||
964 | |||
965 | return 0; | ||
966 | } | ||
967 | |||
968 | #define CS42L56_RATES (SNDRV_PCM_RATE_8000_48000) | ||
969 | |||
970 | #define CS42L56_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \ | ||
971 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
972 | SNDRV_PCM_FMTBIT_S32_LE) | ||
973 | |||
974 | |||
975 | static struct snd_soc_dai_ops cs42l56_ops = { | ||
976 | .hw_params = cs42l56_pcm_hw_params, | ||
977 | .digital_mute = cs42l56_digital_mute, | ||
978 | .set_fmt = cs42l56_set_dai_fmt, | ||
979 | .set_sysclk = cs42l56_set_sysclk, | ||
980 | }; | ||
981 | |||
982 | static struct snd_soc_dai_driver cs42l56_dai = { | ||
983 | .name = "cs42l56", | ||
984 | .playback = { | ||
985 | .stream_name = "HiFi Playback", | ||
986 | .channels_min = 1, | ||
987 | .channels_max = 2, | ||
988 | .rates = CS42L56_RATES, | ||
989 | .formats = CS42L56_FORMATS, | ||
990 | }, | ||
991 | .capture = { | ||
992 | .stream_name = "HiFi Capture", | ||
993 | .channels_min = 1, | ||
994 | .channels_max = 2, | ||
995 | .rates = CS42L56_RATES, | ||
996 | .formats = CS42L56_FORMATS, | ||
997 | }, | ||
998 | .ops = &cs42l56_ops, | ||
999 | }; | ||
1000 | |||
1001 | static int cs42l56_suspend(struct snd_soc_codec *codec) | ||
1002 | { | ||
1003 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1004 | |||
1005 | return 0; | ||
1006 | } | ||
1007 | |||
1008 | static int cs42l56_resume(struct snd_soc_codec *codec) | ||
1009 | { | ||
1010 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1011 | |||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | static int beep_freq[] = { | ||
1016 | 261, 522, 585, 667, 706, 774, 889, 1000, | ||
1017 | 1043, 1200, 1333, 1412, 1600, 1714, 2000, 2182 | ||
1018 | }; | ||
1019 | |||
1020 | static void cs42l56_beep_work(struct work_struct *work) | ||
1021 | { | ||
1022 | struct cs42l56_private *cs42l56 = | ||
1023 | container_of(work, struct cs42l56_private, beep_work); | ||
1024 | struct snd_soc_codec *codec = cs42l56->codec; | ||
1025 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
1026 | int i; | ||
1027 | int val = 0; | ||
1028 | int best = 0; | ||
1029 | |||
1030 | if (cs42l56->beep_rate) { | ||
1031 | for (i = 0; i < ARRAY_SIZE(beep_freq); i++) { | ||
1032 | if (abs(cs42l56->beep_rate - beep_freq[i]) < | ||
1033 | abs(cs42l56->beep_rate - beep_freq[best])) | ||
1034 | best = i; | ||
1035 | } | ||
1036 | |||
1037 | dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n", | ||
1038 | beep_freq[best], cs42l56->beep_rate); | ||
1039 | |||
1040 | val = (best << CS42L56_BEEP_RATE_SHIFT); | ||
1041 | |||
1042 | snd_soc_dapm_enable_pin(dapm, "Beep"); | ||
1043 | } else { | ||
1044 | dev_dbg(codec->dev, "Disabling beep\n"); | ||
1045 | snd_soc_dapm_disable_pin(dapm, "Beep"); | ||
1046 | } | ||
1047 | |||
1048 | snd_soc_update_bits(codec, CS42L56_BEEP_FREQ_ONTIME, | ||
1049 | CS42L56_BEEP_FREQ_MASK, val); | ||
1050 | |||
1051 | snd_soc_dapm_sync(dapm); | ||
1052 | } | ||
1053 | |||
1054 | /* For usability define a way of injecting beep events for the device - | ||
1055 | * many systems will not have a keyboard. | ||
1056 | */ | ||
1057 | static int cs42l56_beep_event(struct input_dev *dev, unsigned int type, | ||
1058 | unsigned int code, int hz) | ||
1059 | { | ||
1060 | struct snd_soc_codec *codec = input_get_drvdata(dev); | ||
1061 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
1062 | |||
1063 | dev_dbg(codec->dev, "Beep event %x %x\n", code, hz); | ||
1064 | |||
1065 | switch (code) { | ||
1066 | case SND_BELL: | ||
1067 | if (hz) | ||
1068 | hz = 261; | ||
1069 | case SND_TONE: | ||
1070 | break; | ||
1071 | default: | ||
1072 | return -1; | ||
1073 | } | ||
1074 | |||
1075 | /* Kick the beep from a workqueue */ | ||
1076 | cs42l56->beep_rate = hz; | ||
1077 | schedule_work(&cs42l56->beep_work); | ||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | static ssize_t cs42l56_beep_set(struct device *dev, | ||
1082 | struct device_attribute *attr, | ||
1083 | const char *buf, size_t count) | ||
1084 | { | ||
1085 | struct cs42l56_private *cs42l56 = dev_get_drvdata(dev); | ||
1086 | long int time; | ||
1087 | int ret; | ||
1088 | |||
1089 | ret = kstrtol(buf, 10, &time); | ||
1090 | if (ret != 0) | ||
1091 | return ret; | ||
1092 | |||
1093 | input_event(cs42l56->beep, EV_SND, SND_TONE, time); | ||
1094 | |||
1095 | return count; | ||
1096 | } | ||
1097 | |||
1098 | static DEVICE_ATTR(beep, 0200, NULL, cs42l56_beep_set); | ||
1099 | |||
1100 | static void cs42l56_init_beep(struct snd_soc_codec *codec) | ||
1101 | { | ||
1102 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
1103 | int ret; | ||
1104 | |||
1105 | cs42l56->beep = devm_input_allocate_device(codec->dev); | ||
1106 | if (!cs42l56->beep) { | ||
1107 | dev_err(codec->dev, "Failed to allocate beep device\n"); | ||
1108 | return; | ||
1109 | } | ||
1110 | |||
1111 | INIT_WORK(&cs42l56->beep_work, cs42l56_beep_work); | ||
1112 | cs42l56->beep_rate = 0; | ||
1113 | |||
1114 | cs42l56->beep->name = "CS42L56 Beep Generator"; | ||
1115 | cs42l56->beep->phys = dev_name(codec->dev); | ||
1116 | cs42l56->beep->id.bustype = BUS_I2C; | ||
1117 | |||
1118 | cs42l56->beep->evbit[0] = BIT_MASK(EV_SND); | ||
1119 | cs42l56->beep->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); | ||
1120 | cs42l56->beep->event = cs42l56_beep_event; | ||
1121 | cs42l56->beep->dev.parent = codec->dev; | ||
1122 | input_set_drvdata(cs42l56->beep, codec); | ||
1123 | |||
1124 | ret = input_register_device(cs42l56->beep); | ||
1125 | if (ret != 0) { | ||
1126 | cs42l56->beep = NULL; | ||
1127 | dev_err(codec->dev, "Failed to register beep device\n"); | ||
1128 | } | ||
1129 | |||
1130 | ret = device_create_file(codec->dev, &dev_attr_beep); | ||
1131 | if (ret != 0) { | ||
1132 | dev_err(codec->dev, "Failed to create keyclick file: %d\n", | ||
1133 | ret); | ||
1134 | } | ||
1135 | } | ||
1136 | |||
1137 | static void cs42l56_free_beep(struct snd_soc_codec *codec) | ||
1138 | { | ||
1139 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
1140 | |||
1141 | device_remove_file(codec->dev, &dev_attr_beep); | ||
1142 | cancel_work_sync(&cs42l56->beep_work); | ||
1143 | cs42l56->beep = NULL; | ||
1144 | |||
1145 | snd_soc_update_bits(codec, CS42L56_BEEP_TONE_CFG, | ||
1146 | CS42L56_BEEP_EN_MASK, 0); | ||
1147 | } | ||
1148 | |||
1149 | static int cs42l56_probe(struct snd_soc_codec *codec) | ||
1150 | { | ||
1151 | cs42l56_init_beep(codec); | ||
1152 | |||
1153 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1154 | |||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | static int cs42l56_remove(struct snd_soc_codec *codec) | ||
1159 | { | ||
1160 | struct cs42l56_private *cs42l56 = snd_soc_codec_get_drvdata(codec); | ||
1161 | |||
1162 | cs42l56_free_beep(codec); | ||
1163 | cs42l56_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1164 | regulator_bulk_free(ARRAY_SIZE(cs42l56->supplies), cs42l56->supplies); | ||
1165 | |||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | static struct snd_soc_codec_driver soc_codec_dev_cs42l56 = { | ||
1170 | .probe = cs42l56_probe, | ||
1171 | .remove = cs42l56_remove, | ||
1172 | .suspend = cs42l56_suspend, | ||
1173 | .resume = cs42l56_resume, | ||
1174 | .set_bias_level = cs42l56_set_bias_level, | ||
1175 | |||
1176 | .dapm_widgets = cs42l56_dapm_widgets, | ||
1177 | .num_dapm_widgets = ARRAY_SIZE(cs42l56_dapm_widgets), | ||
1178 | .dapm_routes = cs42l56_audio_map, | ||
1179 | .num_dapm_routes = ARRAY_SIZE(cs42l56_audio_map), | ||
1180 | |||
1181 | .controls = cs42l56_snd_controls, | ||
1182 | .num_controls = ARRAY_SIZE(cs42l56_snd_controls), | ||
1183 | }; | ||
1184 | |||
1185 | static struct regmap_config cs42l56_regmap = { | ||
1186 | .reg_bits = 8, | ||
1187 | .val_bits = 8, | ||
1188 | |||
1189 | .max_register = CS42L56_MAX_REGISTER, | ||
1190 | .reg_defaults = cs42l56_reg_defaults, | ||
1191 | .num_reg_defaults = ARRAY_SIZE(cs42l56_reg_defaults), | ||
1192 | .readable_reg = cs42l56_readable_register, | ||
1193 | .volatile_reg = cs42l56_volatile_register, | ||
1194 | .cache_type = REGCACHE_RBTREE, | ||
1195 | }; | ||
1196 | |||
1197 | static int cs42l56_handle_of_data(struct i2c_client *i2c_client, | ||
1198 | struct cs42l56_platform_data *pdata) | ||
1199 | { | ||
1200 | struct device_node *np = i2c_client->dev.of_node; | ||
1201 | u32 val32; | ||
1202 | |||
1203 | if (of_property_read_bool(np, "cirrus,ain1a-reference-cfg")) | ||
1204 | pdata->ain1a_ref_cfg = true; | ||
1205 | |||
1206 | if (of_property_read_bool(np, "cirrus,ain2a-reference-cfg")) | ||
1207 | pdata->ain2a_ref_cfg = true; | ||
1208 | |||
1209 | if (of_property_read_bool(np, "cirrus,ain1b-reference-cfg")) | ||
1210 | pdata->ain1b_ref_cfg = true; | ||
1211 | |||
1212 | if (of_property_read_bool(np, "cirrus,ain2b-reference-cfg")) | ||
1213 | pdata->ain2b_ref_cfg = true; | ||
1214 | |||
1215 | if (of_property_read_u32(np, "cirrus,micbias-lvl", &val32) >= 0) | ||
1216 | pdata->micbias_lvl = val32; | ||
1217 | |||
1218 | if (of_property_read_u32(np, "cirrus,chgfreq-divisor", &val32) >= 0) | ||
1219 | pdata->chgfreq = val32; | ||
1220 | |||
1221 | if (of_property_read_u32(np, "cirrus,adaptive-pwr-cfg", &val32) >= 0) | ||
1222 | pdata->adaptive_pwr = val32; | ||
1223 | |||
1224 | if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0) | ||
1225 | pdata->hpfa_freq = val32; | ||
1226 | |||
1227 | if (of_property_read_u32(np, "cirrus,hpf-left-freq", &val32) >= 0) | ||
1228 | pdata->hpfb_freq = val32; | ||
1229 | |||
1230 | pdata->gpio_nreset = of_get_named_gpio(np, "cirrus,gpio-nreset", 0); | ||
1231 | |||
1232 | return 0; | ||
1233 | } | ||
1234 | |||
1235 | static int cs42l56_i2c_probe(struct i2c_client *i2c_client, | ||
1236 | const struct i2c_device_id *id) | ||
1237 | { | ||
1238 | struct cs42l56_private *cs42l56; | ||
1239 | struct cs42l56_platform_data *pdata = | ||
1240 | dev_get_platdata(&i2c_client->dev); | ||
1241 | int ret, i; | ||
1242 | unsigned int devid = 0; | ||
1243 | unsigned int alpha_rev, metal_rev; | ||
1244 | unsigned int reg; | ||
1245 | |||
1246 | cs42l56 = devm_kzalloc(&i2c_client->dev, | ||
1247 | sizeof(struct cs42l56_private), | ||
1248 | GFP_KERNEL); | ||
1249 | if (cs42l56 == NULL) | ||
1250 | return -ENOMEM; | ||
1251 | cs42l56->dev = &i2c_client->dev; | ||
1252 | |||
1253 | cs42l56->regmap = devm_regmap_init_i2c(i2c_client, &cs42l56_regmap); | ||
1254 | if (IS_ERR(cs42l56->regmap)) { | ||
1255 | ret = PTR_ERR(cs42l56->regmap); | ||
1256 | dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); | ||
1257 | return ret; | ||
1258 | } | ||
1259 | |||
1260 | if (pdata) { | ||
1261 | cs42l56->pdata = *pdata; | ||
1262 | } else { | ||
1263 | pdata = devm_kzalloc(&i2c_client->dev, | ||
1264 | sizeof(struct cs42l56_platform_data), | ||
1265 | GFP_KERNEL); | ||
1266 | if (!pdata) { | ||
1267 | dev_err(&i2c_client->dev, | ||
1268 | "could not allocate pdata\n"); | ||
1269 | return -ENOMEM; | ||
1270 | } | ||
1271 | if (i2c_client->dev.of_node) { | ||
1272 | ret = cs42l56_handle_of_data(i2c_client, | ||
1273 | &cs42l56->pdata); | ||
1274 | if (ret != 0) | ||
1275 | return ret; | ||
1276 | } | ||
1277 | cs42l56->pdata = *pdata; | ||
1278 | } | ||
1279 | |||
1280 | if (cs42l56->pdata.gpio_nreset) { | ||
1281 | ret = gpio_request_one(cs42l56->pdata.gpio_nreset, | ||
1282 | GPIOF_OUT_INIT_HIGH, "CS42L56 /RST"); | ||
1283 | if (ret < 0) { | ||
1284 | dev_err(&i2c_client->dev, | ||
1285 | "Failed to request /RST %d: %d\n", | ||
1286 | cs42l56->pdata.gpio_nreset, ret); | ||
1287 | return ret; | ||
1288 | } | ||
1289 | gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 0); | ||
1290 | gpio_set_value_cansleep(cs42l56->pdata.gpio_nreset, 1); | ||
1291 | } | ||
1292 | |||
1293 | |||
1294 | i2c_set_clientdata(i2c_client, cs42l56); | ||
1295 | |||
1296 | for (i = 0; i < ARRAY_SIZE(cs42l56->supplies); i++) | ||
1297 | cs42l56->supplies[i].supply = cs42l56_supply_names[i]; | ||
1298 | |||
1299 | ret = devm_regulator_bulk_get(&i2c_client->dev, | ||
1300 | ARRAY_SIZE(cs42l56->supplies), | ||
1301 | cs42l56->supplies); | ||
1302 | if (ret != 0) { | ||
1303 | dev_err(&i2c_client->dev, | ||
1304 | "Failed to request supplies: %d\n", ret); | ||
1305 | return ret; | ||
1306 | } | ||
1307 | |||
1308 | ret = regulator_bulk_enable(ARRAY_SIZE(cs42l56->supplies), | ||
1309 | cs42l56->supplies); | ||
1310 | if (ret != 0) { | ||
1311 | dev_err(&i2c_client->dev, | ||
1312 | "Failed to enable supplies: %d\n", ret); | ||
1313 | return ret; | ||
1314 | } | ||
1315 | |||
1316 | regcache_cache_bypass(cs42l56->regmap, true); | ||
1317 | |||
1318 | ret = regmap_read(cs42l56->regmap, CS42L56_CHIP_ID_1, ®); | ||
1319 | devid = reg & CS42L56_CHIP_ID_MASK; | ||
1320 | if (devid != CS42L56_DEVID) { | ||
1321 | dev_err(&i2c_client->dev, | ||
1322 | "CS42L56 Device ID (%X). Expected %X\n", | ||
1323 | devid, CS42L56_DEVID); | ||
1324 | goto err_enable; | ||
1325 | } | ||
1326 | alpha_rev = reg & CS42L56_AREV_MASK; | ||
1327 | metal_rev = reg & CS42L56_MTLREV_MASK; | ||
1328 | |||
1329 | dev_info(&i2c_client->dev, "Cirrus Logic CS42L56 "); | ||
1330 | dev_info(&i2c_client->dev, "Alpha Rev %X Metal Rev %X\n", | ||
1331 | alpha_rev, metal_rev); | ||
1332 | |||
1333 | regcache_cache_bypass(cs42l56->regmap, false); | ||
1334 | |||
1335 | if (cs42l56->pdata.ain1a_ref_cfg) | ||
1336 | regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, | ||
1337 | CS42L56_AIN1A_REF_MASK, 1); | ||
1338 | |||
1339 | if (cs42l56->pdata.ain1b_ref_cfg) | ||
1340 | regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, | ||
1341 | CS42L56_AIN1B_REF_MASK, 1); | ||
1342 | |||
1343 | if (cs42l56->pdata.ain2a_ref_cfg) | ||
1344 | regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, | ||
1345 | CS42L56_AIN2A_REF_MASK, 1); | ||
1346 | |||
1347 | if (cs42l56->pdata.ain2b_ref_cfg) | ||
1348 | regmap_update_bits(cs42l56->regmap, CS42L56_AIN_REFCFG_ADC_MUX, | ||
1349 | CS42L56_AIN2B_REF_MASK, 1); | ||
1350 | |||
1351 | if (cs42l56->pdata.micbias_lvl) | ||
1352 | regmap_update_bits(cs42l56->regmap, CS42L56_GAIN_BIAS_CTL, | ||
1353 | CS42L56_MIC_BIAS_MASK, | ||
1354 | cs42l56->pdata.micbias_lvl); | ||
1355 | |||
1356 | if (cs42l56->pdata.chgfreq) | ||
1357 | regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL, | ||
1358 | CS42L56_CHRG_FREQ_MASK, | ||
1359 | cs42l56->pdata.chgfreq); | ||
1360 | |||
1361 | if (cs42l56->pdata.hpfb_freq) | ||
1362 | regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL, | ||
1363 | CS42L56_HPFB_FREQ_MASK, | ||
1364 | cs42l56->pdata.hpfb_freq); | ||
1365 | |||
1366 | if (cs42l56->pdata.hpfa_freq) | ||
1367 | regmap_update_bits(cs42l56->regmap, CS42L56_HPF_CTL, | ||
1368 | CS42L56_HPFA_FREQ_MASK, | ||
1369 | cs42l56->pdata.hpfa_freq); | ||
1370 | |||
1371 | if (cs42l56->pdata.adaptive_pwr) | ||
1372 | regmap_update_bits(cs42l56->regmap, CS42L56_CLASSH_CTL, | ||
1373 | CS42L56_ADAPT_PWR_MASK, | ||
1374 | cs42l56->pdata.adaptive_pwr); | ||
1375 | |||
1376 | ret = snd_soc_register_codec(&i2c_client->dev, | ||
1377 | &soc_codec_dev_cs42l56, &cs42l56_dai, 1); | ||
1378 | if (ret < 0) | ||
1379 | return ret; | ||
1380 | |||
1381 | return 0; | ||
1382 | |||
1383 | err_enable: | ||
1384 | regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), | ||
1385 | cs42l56->supplies); | ||
1386 | return ret; | ||
1387 | } | ||
1388 | |||
1389 | static int cs42l56_i2c_remove(struct i2c_client *client) | ||
1390 | { | ||
1391 | struct cs42l56_private *cs42l56 = i2c_get_clientdata(client); | ||
1392 | |||
1393 | snd_soc_unregister_codec(&client->dev); | ||
1394 | regulator_bulk_disable(ARRAY_SIZE(cs42l56->supplies), | ||
1395 | cs42l56->supplies); | ||
1396 | return 0; | ||
1397 | } | ||
1398 | |||
1399 | static const struct of_device_id cs42l56_of_match[] = { | ||
1400 | { .compatible = "cirrus,cs42l56", }, | ||
1401 | { } | ||
1402 | }; | ||
1403 | MODULE_DEVICE_TABLE(of, cs42l56_of_match); | ||
1404 | |||
1405 | |||
1406 | static const struct i2c_device_id cs42l56_id[] = { | ||
1407 | { "cs42l56", 0 }, | ||
1408 | { } | ||
1409 | }; | ||
1410 | MODULE_DEVICE_TABLE(i2c, cs42l56_id); | ||
1411 | |||
1412 | static struct i2c_driver cs42l56_i2c_driver = { | ||
1413 | .driver = { | ||
1414 | .name = "cs42l56", | ||
1415 | .owner = THIS_MODULE, | ||
1416 | .of_match_table = cs42l56_of_match, | ||
1417 | }, | ||
1418 | .id_table = cs42l56_id, | ||
1419 | .probe = cs42l56_i2c_probe, | ||
1420 | .remove = cs42l56_i2c_remove, | ||
1421 | }; | ||
1422 | |||
1423 | module_i2c_driver(cs42l56_i2c_driver); | ||
1424 | |||
1425 | MODULE_DESCRIPTION("ASoC CS42L56 driver"); | ||
1426 | MODULE_AUTHOR("Brian Austin, Cirrus Logic Inc, <brian.austin@cirrus.com>"); | ||
1427 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/cs42l56.h b/sound/soc/codecs/cs42l56.h new file mode 100644 index 000000000000..ad2b50a90b16 --- /dev/null +++ b/sound/soc/codecs/cs42l56.h | |||
@@ -0,0 +1,175 @@ | |||
1 | /* | ||
2 | * cs42l52.h -- CS42L56 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2014 CirrusLogic, Inc. | ||
5 | * | ||
6 | * Author: Brian Austin <brian.austin@cirrus.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | */ | ||
13 | |||
14 | #ifndef __CS42L56_H__ | ||
15 | #define __CS42L56_H__ | ||
16 | |||
17 | #define CS42L56_CHIP_ID_1 0x01 | ||
18 | #define CS42L56_CHIP_ID_2 0x02 | ||
19 | #define CS42L56_PWRCTL_1 0x03 | ||
20 | #define CS42L56_PWRCTL_2 0x04 | ||
21 | #define CS42L56_CLKCTL_1 0x05 | ||
22 | #define CS42L56_CLKCTL_2 0x06 | ||
23 | #define CS42L56_SERIAL_FMT 0x07 | ||
24 | #define CS42L56_CLASSH_CTL 0x08 | ||
25 | #define CS42L56_MISC_CTL 0x09 | ||
26 | #define CS42L56_INT_STATUS 0x0a | ||
27 | #define CS42L56_PLAYBACK_CTL 0x0b | ||
28 | #define CS42L56_DSP_MUTE_CTL 0x0c | ||
29 | #define CS42L56_ADCA_MIX_VOLUME 0x0d | ||
30 | #define CS42L56_ADCB_MIX_VOLUME 0x0e | ||
31 | #define CS42L56_PCMA_MIX_VOLUME 0x0f | ||
32 | #define CS42L56_PCMB_MIX_VOLUME 0x10 | ||
33 | #define CS42L56_ANAINPUT_ADV_VOLUME 0x11 | ||
34 | #define CS42L56_DIGINPUT_ADV_VOLUME 0x12 | ||
35 | #define CS42L56_MASTER_A_VOLUME 0x13 | ||
36 | #define CS42L56_MASTER_B_VOLUME 0x14 | ||
37 | #define CS42L56_BEEP_FREQ_ONTIME 0x15 | ||
38 | #define CS42L56_BEEP_FREQ_OFFTIME 0x16 | ||
39 | #define CS42L56_BEEP_TONE_CFG 0x17 | ||
40 | #define CS42L56_TONE_CTL 0x18 | ||
41 | #define CS42L56_CHAN_MIX_SWAP 0x19 | ||
42 | #define CS42L56_AIN_REFCFG_ADC_MUX 0x1a | ||
43 | #define CS42L56_HPF_CTL 0x1b | ||
44 | #define CS42L56_MISC_ADC_CTL 0x1c | ||
45 | #define CS42L56_GAIN_BIAS_CTL 0x1d | ||
46 | #define CS42L56_PGAA_MUX_VOLUME 0x1e | ||
47 | #define CS42L56_PGAB_MUX_VOLUME 0x1f | ||
48 | #define CS42L56_ADCA_ATTENUATOR 0x20 | ||
49 | #define CS42L56_ADCB_ATTENUATOR 0x21 | ||
50 | #define CS42L56_ALC_EN_ATTACK_RATE 0x22 | ||
51 | #define CS42L56_ALC_RELEASE_RATE 0x23 | ||
52 | #define CS42L56_ALC_THRESHOLD 0x24 | ||
53 | #define CS42L56_NOISE_GATE_CTL 0x25 | ||
54 | #define CS42L56_ALC_LIM_SFT_ZC 0x26 | ||
55 | #define CS42L56_AMUTE_HPLO_MUX 0x27 | ||
56 | #define CS42L56_HPA_VOLUME 0x28 | ||
57 | #define CS42L56_HPB_VOLUME 0x29 | ||
58 | #define CS42L56_LOA_VOLUME 0x2a | ||
59 | #define CS42L56_LOB_VOLUME 0x2b | ||
60 | #define CS42L56_LIM_THRESHOLD_CTL 0x2c | ||
61 | #define CS42L56_LIM_CTL_RELEASE_RATE 0x2d | ||
62 | #define CS42L56_LIM_ATTACK_RATE 0x2e | ||
63 | |||
64 | /* Device ID and Rev ID Masks */ | ||
65 | #define CS42L56_DEVID 0x56 | ||
66 | #define CS42L56_CHIP_ID_MASK 0xff | ||
67 | #define CS42L56_AREV_MASK 0x1c | ||
68 | #define CS42L56_MTLREV_MASK 0x03 | ||
69 | |||
70 | /* Power bit masks */ | ||
71 | #define CS42L56_PDN_ALL_MASK 0x01 | ||
72 | #define CS42L56_PDN_ADCA_MASK 0x02 | ||
73 | #define CS42L56_PDN_ADCB_MASK 0x04 | ||
74 | #define CS42L56_PDN_CHRG_MASK 0x08 | ||
75 | #define CS42L56_PDN_BIAS_MASK 0x10 | ||
76 | #define CS42L56_PDN_VBUF_MASK 0x20 | ||
77 | #define CS42L56_PDN_LOA_MASK 0x03 | ||
78 | #define CS42L56_PDN_LOB_MASK 0x0c | ||
79 | #define CS42L56_PDN_HPA_MASK 0x30 | ||
80 | #define CS42L56_PDN_HPB_MASK 0xc0 | ||
81 | |||
82 | /* serial port and clk masks */ | ||
83 | #define CS42L56_MASTER_MODE 1 | ||
84 | #define CS42L56_SLAVE_MODE 0 | ||
85 | #define CS42L56_MS_MODE_MASK 0x40 | ||
86 | #define CS42L56_SCLK_INV 1 | ||
87 | #define CS42L56_SCLK_INV_MASK 0x20 | ||
88 | #define CS42L56_SCLK_MCLK_MASK 0x18 | ||
89 | #define CS42L56_MCLK_PREDIV_MASK 0x04 | ||
90 | #define CS42L56_MCLK_DIV2_MASK 0x02 | ||
91 | #define CS42L56_MCLK_DIS_MASK 0x01 | ||
92 | #define CS42L56_CLK_AUTO_MASK 0x20 | ||
93 | #define CS42L56_CLK_RATIO_MASK 0x1f | ||
94 | #define CS42L56_DIG_FMT_I2S 0 | ||
95 | #define CS42L56_DIG_FMT_LEFT_J 1 | ||
96 | #define CS42L56_DIG_FMT_MASK 0x08 | ||
97 | |||
98 | /* Class H and misc ctl masks */ | ||
99 | #define CS42L56_ADAPT_PWR_MASK 0xc0 | ||
100 | #define CS42L56_CHRG_FREQ_MASK 0x0f | ||
101 | #define CS42L56_DIG_MUX_MASK 0x80 | ||
102 | #define CS42L56_ANLGSFT_MASK 0x10 | ||
103 | #define CS42L56_ANLGZC_MASK 0x08 | ||
104 | #define CS42L56_DIGSFT_MASK 0x04 | ||
105 | #define CS42L56_FREEZE_MASK 0x01 | ||
106 | #define CS42L56_MIC_BIAS_MASK 0x03 | ||
107 | #define CS42L56_HPFA_FREQ_MASK 0x03 | ||
108 | #define CS42L56_HPFB_FREQ_MASK 0xc0 | ||
109 | #define CS42L56_AIN1A_REF_MASK 0x10 | ||
110 | #define CS42L56_AIN2A_REF_MASK 0x40 | ||
111 | #define CS42L56_AIN1B_REF_MASK 0x20 | ||
112 | #define CS42L56_AIN2B_REF_MASK 0x80 | ||
113 | |||
114 | /* Playback Capture ctl masks */ | ||
115 | #define CS42L56_PDN_DSP_MASK 0x80 | ||
116 | #define CS42L56_DEEMPH_MASK 0x40 | ||
117 | #define CS42L56_PLYBCK_GANG_MASK 0x10 | ||
118 | #define CS42L56_PCM_INV_MASK 0x0c | ||
119 | #define CS42L56_MUTE 1 | ||
120 | #define CS42L56_UNMUTE 0 | ||
121 | #define CS42L56_ADCAMIX_MUTE_MASK 0x40 | ||
122 | #define CS42L56_ADCBMIX_MUTE_MASK 0x80 | ||
123 | #define CS42L56_PCMAMIX_MUTE_MASK 0x10 | ||
124 | #define CS42L56_PCMBMIX_MUTE_MASK 0x20 | ||
125 | #define CS42L56_MSTB_MUTE_MASK 0x02 | ||
126 | #define CS42L56_MSTA_MUTE_MASK 0x01 | ||
127 | #define CS42L56_ADCA_MUTE_MASK 0x01 | ||
128 | #define CS42L56_ADCB_MUTE_MASK 0x02 | ||
129 | #define CS42L56_HP_MUTE_MASK 0x80 | ||
130 | #define CS42L56_LO_MUTE_MASK 0x80 | ||
131 | |||
132 | /* Beep masks */ | ||
133 | #define CS42L56_BEEP_FREQ_MASK 0xf0 | ||
134 | #define CS42L56_BEEP_ONTIME_MASK 0x0f | ||
135 | #define CS42L56_BEEP_OFFTIME_MASK 0xe0 | ||
136 | #define CS42L56_BEEP_CFG_MASK 0xc0 | ||
137 | #define CS42L56_BEEP_TREBCF_MASK 0x18 | ||
138 | #define CS42L56_BEEP_BASSCF_MASK 0x06 | ||
139 | #define CS42L56_BEEP_TCEN_MASK 0x01 | ||
140 | #define CS42L56_BEEP_RATE_SHIFT 4 | ||
141 | #define CS42L56_BEEP_EN_MASK 0x3f | ||
142 | |||
143 | |||
144 | /* Supported MCLKS */ | ||
145 | #define CS42L56_MCLK_5P6448MHZ 5644800 | ||
146 | #define CS42L56_MCLK_6MHZ 6000000 | ||
147 | #define CS42L56_MCLK_6P144MHZ 6144000 | ||
148 | #define CS42L56_MCLK_11P2896MHZ 11289600 | ||
149 | #define CS42L56_MCLK_12MHZ 12000000 | ||
150 | #define CS42L56_MCLK_12P288MHZ 12288000 | ||
151 | #define CS42L56_MCLK_22P5792MHZ 22579200 | ||
152 | #define CS42L56_MCLK_24MHZ 24000000 | ||
153 | #define CS42L56_MCLK_24P576MHZ 24576000 | ||
154 | |||
155 | /* Clock ratios */ | ||
156 | #define CS42L56_MCLK_LRCLK_128 0x08 | ||
157 | #define CS42L56_MCLK_LRCLK_125 0x09 | ||
158 | #define CS42L56_MCLK_LRCLK_136 0x0b | ||
159 | #define CS42L56_MCLK_LRCLK_192 0x0c | ||
160 | #define CS42L56_MCLK_LRCLK_187P5 0x0d | ||
161 | #define CS42L56_MCLK_LRCLK_256 0x10 | ||
162 | #define CS42L56_MCLK_LRCLK_250 0x11 | ||
163 | #define CS42L56_MCLK_LRCLK_272 0x13 | ||
164 | #define CS42L56_MCLK_LRCLK_384 0x14 | ||
165 | #define CS42L56_MCLK_LRCLK_375 0x15 | ||
166 | #define CS42L56_MCLK_LRCLK_512 0x18 | ||
167 | #define CS42L56_MCLK_LRCLK_500 0x19 | ||
168 | #define CS42L56_MCLK_LRCLK_544 0x1b | ||
169 | #define CS42L56_MCLK_LRCLK_750 0x1c | ||
170 | #define CS42L56_MCLK_LRCLK_768 0x1d | ||
171 | |||
172 | |||
173 | #define CS42L56_MAX_REGISTER 0x34 | ||
174 | |||
175 | #endif | ||
diff --git a/sound/soc/codecs/cs42xx8.c b/sound/soc/codecs/cs42xx8.c index 85020322eee7..a25bc6061a30 100644 --- a/sound/soc/codecs/cs42xx8.c +++ b/sound/soc/codecs/cs42xx8.c | |||
@@ -248,8 +248,7 @@ static int cs42xx8_hw_params(struct snd_pcm_substream *substream, | |||
248 | struct snd_pcm_hw_params *params, | 248 | struct snd_pcm_hw_params *params, |
249 | struct snd_soc_dai *dai) | 249 | struct snd_soc_dai *dai) |
250 | { | 250 | { |
251 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 251 | struct snd_soc_codec *codec = dai->codec; |
252 | struct snd_soc_codec *codec = rtd->codec; | ||
253 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); | 252 | struct cs42xx8_priv *cs42xx8 = snd_soc_codec_get_drvdata(codec); |
254 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 253 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
255 | u32 ratio = cs42xx8->sysclk / params_rate(params); | 254 | u32 ratio = cs42xx8->sysclk / params_rate(params); |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 137e8ebc092c..21810e5f3321 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
@@ -335,7 +335,7 @@ static SOC_ENUM_SINGLE_DECL(da7210_hp_mode_sel, | |||
335 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, | 335 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, |
336 | struct snd_ctl_elem_value *ucontrol) | 336 | struct snd_ctl_elem_value *ucontrol) |
337 | { | 337 | { |
338 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 338 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
339 | 339 | ||
340 | if (ucontrol->value.integer.value[0]) { | 340 | if (ucontrol->value.integer.value[0]) { |
341 | /* Check if noise suppression is enabled */ | 341 | /* Check if noise suppression is enabled */ |
@@ -358,7 +358,7 @@ static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, | |||
358 | static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol, | 358 | static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol, |
359 | struct snd_ctl_elem_value *ucontrol) | 359 | struct snd_ctl_elem_value *ucontrol) |
360 | { | 360 | { |
361 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 361 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
362 | u8 val; | 362 | u8 val; |
363 | 363 | ||
364 | if (ucontrol->value.integer.value[0]) { | 364 | if (ucontrol->value.integer.value[0]) { |
diff --git a/sound/soc/codecs/da7213.c b/sound/soc/codecs/da7213.c index 738fa18a50d2..9ec577f0edb4 100644 --- a/sound/soc/codecs/da7213.c +++ b/sound/soc/codecs/da7213.c | |||
@@ -345,7 +345,7 @@ static void da7213_alc_calib(struct snd_soc_codec *codec) | |||
345 | static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, | 345 | static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, |
346 | struct snd_ctl_elem_value *ucontrol) | 346 | struct snd_ctl_elem_value *ucontrol) |
347 | { | 347 | { |
348 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 348 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
349 | struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); | 349 | struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); |
350 | int ret; | 350 | int ret; |
351 | 351 | ||
@@ -361,7 +361,7 @@ static int da7213_put_mixin_gain(struct snd_kcontrol *kcontrol, | |||
361 | static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol, | 361 | static int da7213_put_alc_sw(struct snd_kcontrol *kcontrol, |
362 | struct snd_ctl_elem_value *ucontrol) | 362 | struct snd_ctl_elem_value *ucontrol) |
363 | { | 363 | { |
364 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 364 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
365 | struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); | 365 | struct da7213_priv *da7213 = snd_soc_codec_get_drvdata(codec); |
366 | 366 | ||
367 | /* Force ALC offset calibration if enabling ALC */ | 367 | /* Force ALC offset calibration if enabling ALC */ |
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c index 48f3fef68484..2fae31cb0067 100644 --- a/sound/soc/codecs/da732x.c +++ b/sound/soc/codecs/da732x.c | |||
@@ -332,7 +332,7 @@ static SOC_ENUM_SINGLE_DECL(da732x_adc2_voice_filter_enum, | |||
332 | static int da732x_hpf_set(struct snd_kcontrol *kcontrol, | 332 | static int da732x_hpf_set(struct snd_kcontrol *kcontrol, |
333 | struct snd_ctl_elem_value *ucontrol) | 333 | struct snd_ctl_elem_value *ucontrol) |
334 | { | 334 | { |
335 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 335 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
336 | struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; | 336 | struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; |
337 | unsigned int reg = enum_ctrl->reg; | 337 | unsigned int reg = enum_ctrl->reg; |
338 | unsigned int sel = ucontrol->value.integer.value[0]; | 338 | unsigned int sel = ucontrol->value.integer.value[0]; |
@@ -360,7 +360,7 @@ static int da732x_hpf_set(struct snd_kcontrol *kcontrol, | |||
360 | static int da732x_hpf_get(struct snd_kcontrol *kcontrol, | 360 | static int da732x_hpf_get(struct snd_kcontrol *kcontrol, |
361 | struct snd_ctl_elem_value *ucontrol) | 361 | struct snd_ctl_elem_value *ucontrol) |
362 | { | 362 | { |
363 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 363 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
364 | struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; | 364 | struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value; |
365 | unsigned int reg = enum_ctrl->reg; | 365 | unsigned int reg = enum_ctrl->reg; |
366 | int val; | 366 | int val; |
diff --git a/sound/soc/codecs/da9055.c b/sound/soc/codecs/da9055.c index 4ff06b50fbba..ad19cc56702b 100644 --- a/sound/soc/codecs/da9055.c +++ b/sound/soc/codecs/da9055.c | |||
@@ -484,7 +484,7 @@ static int da9055_get_alc_data(struct snd_soc_codec *codec, u8 reg_val) | |||
484 | static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol, | 484 | static int da9055_put_alc_sw(struct snd_kcontrol *kcontrol, |
485 | struct snd_ctl_elem_value *ucontrol) | 485 | struct snd_ctl_elem_value *ucontrol) |
486 | { | 486 | { |
487 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 487 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
488 | u8 reg_val, adc_left, adc_right, mic_left, mic_right; | 488 | u8 reg_val, adc_left, adc_right, mic_left, mic_right; |
489 | int avg_left_data, avg_right_data, offset_l, offset_r; | 489 | int avg_left_data, avg_right_data, offset_l, offset_r; |
490 | 490 | ||
diff --git a/sound/soc/codecs/hdmi.c b/sound/soc/codecs/hdmi.c index 9cb1c7d3e1dc..1087fd5f9917 100644 --- a/sound/soc/codecs/hdmi.c +++ b/sound/soc/codecs/hdmi.c | |||
@@ -20,6 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <sound/soc.h> | 22 | #include <sound/soc.h> |
23 | #include <linux/of.h> | ||
23 | #include <linux/of_device.h> | 24 | #include <linux/of_device.h> |
24 | 25 | ||
25 | #define DRV_NAME "hdmi-audio-codec" | 26 | #define DRV_NAME "hdmi-audio-codec" |
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 4f048db9f55f..a924bb9d7886 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c | |||
@@ -49,7 +49,7 @@ static const struct reg_default lm4857_default_regs[] = { | |||
49 | static int lm4857_get_mode(struct snd_kcontrol *kcontrol, | 49 | static int lm4857_get_mode(struct snd_kcontrol *kcontrol, |
50 | struct snd_ctl_elem_value *ucontrol) | 50 | struct snd_ctl_elem_value *ucontrol) |
51 | { | 51 | { |
52 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 52 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
53 | struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); | 53 | struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); |
54 | 54 | ||
55 | ucontrol->value.integer.value[0] = lm4857->mode; | 55 | ucontrol->value.integer.value[0] = lm4857->mode; |
@@ -60,7 +60,7 @@ static int lm4857_get_mode(struct snd_kcontrol *kcontrol, | |||
60 | static int lm4857_set_mode(struct snd_kcontrol *kcontrol, | 60 | static int lm4857_set_mode(struct snd_kcontrol *kcontrol, |
61 | struct snd_ctl_elem_value *ucontrol) | 61 | struct snd_ctl_elem_value *ucontrol) |
62 | { | 62 | { |
63 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 63 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
64 | struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); | 64 | struct lm4857 *lm4857 = snd_soc_codec_get_drvdata(codec); |
65 | uint8_t value = ucontrol->value.integer.value[0]; | 65 | uint8_t value = ucontrol->value.integer.value[0]; |
66 | 66 | ||
diff --git a/sound/soc/codecs/max9768.c b/sound/soc/codecs/max9768.c index ec481fc428c7..e1c196a41930 100644 --- a/sound/soc/codecs/max9768.c +++ b/sound/soc/codecs/max9768.c | |||
@@ -43,7 +43,7 @@ static struct reg_default max9768_default_regs[] = { | |||
43 | static int max9768_get_gpio(struct snd_kcontrol *kcontrol, | 43 | static int max9768_get_gpio(struct snd_kcontrol *kcontrol, |
44 | struct snd_ctl_elem_value *ucontrol) | 44 | struct snd_ctl_elem_value *ucontrol) |
45 | { | 45 | { |
46 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 46 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
47 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); | 47 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); |
48 | int val = gpio_get_value_cansleep(max9768->mute_gpio); | 48 | int val = gpio_get_value_cansleep(max9768->mute_gpio); |
49 | 49 | ||
@@ -55,7 +55,7 @@ static int max9768_get_gpio(struct snd_kcontrol *kcontrol, | |||
55 | static int max9768_set_gpio(struct snd_kcontrol *kcontrol, | 55 | static int max9768_set_gpio(struct snd_kcontrol *kcontrol, |
56 | struct snd_ctl_elem_value *ucontrol) | 56 | struct snd_ctl_elem_value *ucontrol) |
57 | { | 57 | { |
58 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 58 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
59 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); | 59 | struct max9768 *max9768 = snd_soc_codec_get_drvdata(codec); |
60 | 60 | ||
61 | gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]); | 61 | gpio_set_value_cansleep(max9768->mute_gpio, !ucontrol->value.integer.value[0]); |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ef7cf89f5623..9134982807b5 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -635,7 +635,7 @@ static SOC_ENUM_SINGLE_DECL(max98088_dai1_adc_filter_enum, | |||
635 | static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, | 635 | static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, |
636 | struct snd_ctl_elem_value *ucontrol) | 636 | struct snd_ctl_elem_value *ucontrol) |
637 | { | 637 | { |
638 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 638 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
639 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 639 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
640 | unsigned int sel = ucontrol->value.integer.value[0]; | 640 | unsigned int sel = ucontrol->value.integer.value[0]; |
641 | 641 | ||
@@ -649,7 +649,7 @@ static int max98088_mic1pre_set(struct snd_kcontrol *kcontrol, | |||
649 | static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, | 649 | static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, |
650 | struct snd_ctl_elem_value *ucontrol) | 650 | struct snd_ctl_elem_value *ucontrol) |
651 | { | 651 | { |
652 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 652 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
653 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 653 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
654 | 654 | ||
655 | ucontrol->value.integer.value[0] = max98088->mic1pre; | 655 | ucontrol->value.integer.value[0] = max98088->mic1pre; |
@@ -659,7 +659,7 @@ static int max98088_mic1pre_get(struct snd_kcontrol *kcontrol, | |||
659 | static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, | 659 | static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, |
660 | struct snd_ctl_elem_value *ucontrol) | 660 | struct snd_ctl_elem_value *ucontrol) |
661 | { | 661 | { |
662 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 662 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
663 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 663 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
664 | unsigned int sel = ucontrol->value.integer.value[0]; | 664 | unsigned int sel = ucontrol->value.integer.value[0]; |
665 | 665 | ||
@@ -673,7 +673,7 @@ static int max98088_mic2pre_set(struct snd_kcontrol *kcontrol, | |||
673 | static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol, | 673 | static int max98088_mic2pre_get(struct snd_kcontrol *kcontrol, |
674 | struct snd_ctl_elem_value *ucontrol) | 674 | struct snd_ctl_elem_value *ucontrol) |
675 | { | 675 | { |
676 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 676 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
677 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 677 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
678 | 678 | ||
679 | ucontrol->value.integer.value[0] = max98088->mic2pre; | 679 | ucontrol->value.integer.value[0] = max98088->mic2pre; |
@@ -1750,7 +1750,7 @@ static void max98088_setup_eq2(struct snd_soc_codec *codec) | |||
1750 | static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, | 1750 | static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, |
1751 | struct snd_ctl_elem_value *ucontrol) | 1751 | struct snd_ctl_elem_value *ucontrol) |
1752 | { | 1752 | { |
1753 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1753 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1754 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 1754 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
1755 | struct max98088_pdata *pdata = max98088->pdata; | 1755 | struct max98088_pdata *pdata = max98088->pdata; |
1756 | int channel = max98088_get_channel(codec, kcontrol->id.name); | 1756 | int channel = max98088_get_channel(codec, kcontrol->id.name); |
@@ -1782,7 +1782,7 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, | |||
1782 | static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol, | 1782 | static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol, |
1783 | struct snd_ctl_elem_value *ucontrol) | 1783 | struct snd_ctl_elem_value *ucontrol) |
1784 | { | 1784 | { |
1785 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1785 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1786 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 1786 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
1787 | int channel = max98088_get_channel(codec, kcontrol->id.name); | 1787 | int channel = max98088_get_channel(codec, kcontrol->id.name); |
1788 | struct max98088_cdata *cdata; | 1788 | struct max98088_cdata *cdata; |
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c index f7b0b37aa858..9b76f5a45115 100644 --- a/sound/soc/codecs/max98090.c +++ b/sound/soc/codecs/max98090.c | |||
@@ -11,10 +11,12 @@ | |||
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/i2c.h> | 12 | #include <linux/i2c.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/of.h> | ||
14 | #include <linux/pm.h> | 15 | #include <linux/pm.h> |
15 | #include <linux/pm_runtime.h> | 16 | #include <linux/pm_runtime.h> |
16 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
19 | #include <linux/acpi.h> | ||
18 | #include <sound/jack.h> | 20 | #include <sound/jack.h> |
19 | #include <sound/pcm.h> | 21 | #include <sound/pcm.h> |
20 | #include <sound/pcm_params.h> | 22 | #include <sound/pcm_params.h> |
@@ -255,6 +257,7 @@ static struct reg_default max98090_reg[] = { | |||
255 | static bool max98090_volatile_register(struct device *dev, unsigned int reg) | 257 | static bool max98090_volatile_register(struct device *dev, unsigned int reg) |
256 | { | 258 | { |
257 | switch (reg) { | 259 | switch (reg) { |
260 | case M98090_REG_SOFTWARE_RESET: | ||
258 | case M98090_REG_DEVICE_STATUS: | 261 | case M98090_REG_DEVICE_STATUS: |
259 | case M98090_REG_JACK_STATUS: | 262 | case M98090_REG_JACK_STATUS: |
260 | case M98090_REG_REVISION_ID: | 263 | case M98090_REG_REVISION_ID: |
@@ -389,6 +392,7 @@ static const DECLARE_TLV_DB_SCALE(max98090_alc_tlv, -1500, 100, 0); | |||
389 | static const DECLARE_TLV_DB_SCALE(max98090_alcmakeup_tlv, 0, 100, 0); | 392 | static const DECLARE_TLV_DB_SCALE(max98090_alcmakeup_tlv, 0, 100, 0); |
390 | static const DECLARE_TLV_DB_SCALE(max98090_alccomp_tlv, -3100, 100, 0); | 393 | static const DECLARE_TLV_DB_SCALE(max98090_alccomp_tlv, -3100, 100, 0); |
391 | static const DECLARE_TLV_DB_SCALE(max98090_drcexp_tlv, -6600, 100, 0); | 394 | static const DECLARE_TLV_DB_SCALE(max98090_drcexp_tlv, -6600, 100, 0); |
395 | static const DECLARE_TLV_DB_SCALE(max98090_sdg_tlv, 50, 200, 0); | ||
392 | 396 | ||
393 | static const unsigned int max98090_mixout_tlv[] = { | 397 | static const unsigned int max98090_mixout_tlv[] = { |
394 | TLV_DB_RANGE_HEAD(2), | 398 | TLV_DB_RANGE_HEAD(2), |
@@ -426,7 +430,7 @@ static const unsigned int max98090_rcv_lout_tlv[] = { | |||
426 | static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, | 430 | static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, |
427 | struct snd_ctl_elem_value *ucontrol) | 431 | struct snd_ctl_elem_value *ucontrol) |
428 | { | 432 | { |
429 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 433 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
430 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | 434 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); |
431 | struct soc_mixer_control *mc = | 435 | struct soc_mixer_control *mc = |
432 | (struct soc_mixer_control *)kcontrol->private_value; | 436 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -466,7 +470,7 @@ static int max98090_get_enab_tlv(struct snd_kcontrol *kcontrol, | |||
466 | static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, | 470 | static int max98090_put_enab_tlv(struct snd_kcontrol *kcontrol, |
467 | struct snd_ctl_elem_value *ucontrol) | 471 | struct snd_ctl_elem_value *ucontrol) |
468 | { | 472 | { |
469 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 473 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
470 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); | 474 | struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec); |
471 | struct soc_mixer_control *mc = | 475 | struct soc_mixer_control *mc = |
472 | (struct soc_mixer_control *)kcontrol->private_value; | 476 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -665,7 +669,7 @@ static const struct snd_kcontrol_new max98090_snd_controls[] = { | |||
665 | SOC_SINGLE_EXT_TLV("Digital Sidetone Volume", | 669 | SOC_SINGLE_EXT_TLV("Digital Sidetone Volume", |
666 | M98090_REG_ADC_SIDETONE, M98090_DVST_SHIFT, | 670 | M98090_REG_ADC_SIDETONE, M98090_DVST_SHIFT, |
667 | M98090_DVST_NUM - 1, 1, max98090_get_enab_tlv, | 671 | M98090_DVST_NUM - 1, 1, max98090_get_enab_tlv, |
668 | max98090_put_enab_tlv, max98090_micboost_tlv), | 672 | max98090_put_enab_tlv, max98090_sdg_tlv), |
669 | SOC_SINGLE_TLV("Digital Coarse Volume", M98090_REG_DAI_PLAYBACK_LEVEL, | 673 | SOC_SINGLE_TLV("Digital Coarse Volume", M98090_REG_DAI_PLAYBACK_LEVEL, |
670 | M98090_DVG_SHIFT, M98090_DVG_NUM - 1, 0, | 674 | M98090_DVG_SHIFT, M98090_DVG_NUM - 1, 0, |
671 | max98090_dvg_tlv), | 675 | max98090_dvg_tlv), |
@@ -875,7 +879,7 @@ static const char *dmic_mux_text[] = { "ADC", "DMIC" }; | |||
875 | static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text); | 879 | static SOC_ENUM_SINGLE_VIRT_DECL(dmic_mux_enum, dmic_mux_text); |
876 | 880 | ||
877 | static const struct snd_kcontrol_new max98090_dmic_mux = | 881 | static const struct snd_kcontrol_new max98090_dmic_mux = |
878 | SOC_DAPM_ENUM_VIRT("DMIC Mux", dmic_mux_enum); | 882 | SOC_DAPM_ENUM("DMIC Mux", dmic_mux_enum); |
879 | 883 | ||
880 | static const char *max98090_micpre_text[] = { "Off", "On" }; | 884 | static const char *max98090_micpre_text[] = { "Off", "On" }; |
881 | 885 | ||
@@ -1175,8 +1179,7 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = { | |||
1175 | SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM, | 1179 | SND_SOC_DAPM_MUX("MIC2 Mux", SND_SOC_NOPM, |
1176 | 0, 0, &max98090_mic2_mux), | 1180 | 0, 0, &max98090_mic2_mux), |
1177 | 1181 | ||
1178 | SND_SOC_DAPM_VIRT_MUX("DMIC Mux", SND_SOC_NOPM, | 1182 | SND_SOC_DAPM_MUX("DMIC Mux", SND_SOC_NOPM, 0, 0, &max98090_dmic_mux), |
1179 | 0, 0, &max98090_dmic_mux), | ||
1180 | 1183 | ||
1181 | SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL, | 1184 | SND_SOC_DAPM_PGA_E("MIC1 Input", M98090_REG_MIC1_INPUT_LEVEL, |
1182 | M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event, | 1185 | M98090_MIC_PA1EN_SHIFT, 0, NULL, 0, max98090_micinput_event, |
@@ -1673,6 +1676,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
1673 | M98090_REG_CLOCK_RATIO_NI_LSB, 0x00); | 1676 | M98090_REG_CLOCK_RATIO_NI_LSB, 0x00); |
1674 | snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE, | 1677 | snd_soc_update_bits(codec, M98090_REG_CLOCK_MODE, |
1675 | M98090_USE_M1_MASK, 0); | 1678 | M98090_USE_M1_MASK, 0); |
1679 | max98090->master = false; | ||
1676 | break; | 1680 | break; |
1677 | case SND_SOC_DAIFMT_CBM_CFM: | 1681 | case SND_SOC_DAIFMT_CBM_CFM: |
1678 | /* Set to master mode */ | 1682 | /* Set to master mode */ |
@@ -1689,6 +1693,7 @@ static int max98090_dai_set_fmt(struct snd_soc_dai *codec_dai, | |||
1689 | regval |= M98090_MAS_MASK | | 1693 | regval |= M98090_MAS_MASK | |
1690 | M98090_BSEL_32; | 1694 | M98090_BSEL_32; |
1691 | } | 1695 | } |
1696 | max98090->master = true; | ||
1692 | break; | 1697 | break; |
1693 | case SND_SOC_DAIFMT_CBS_CFM: | 1698 | case SND_SOC_DAIFMT_CBS_CFM: |
1694 | case SND_SOC_DAIFMT_CBM_CFS: | 1699 | case SND_SOC_DAIFMT_CBM_CFS: |
@@ -1792,13 +1797,6 @@ static int max98090_set_bias_level(struct snd_soc_codec *codec, | |||
1792 | 1797 | ||
1793 | switch (level) { | 1798 | switch (level) { |
1794 | case SND_SOC_BIAS_ON: | 1799 | case SND_SOC_BIAS_ON: |
1795 | if (max98090->jack_state == M98090_JACK_STATE_HEADSET) { | ||
1796 | /* | ||
1797 | * Set to normal bias level. | ||
1798 | */ | ||
1799 | snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE, | ||
1800 | M98090_MBVSEL_MASK, M98090_MBVSEL_2V8); | ||
1801 | } | ||
1802 | break; | 1800 | break; |
1803 | 1801 | ||
1804 | case SND_SOC_BIAS_PREPARE: | 1802 | case SND_SOC_BIAS_PREPARE: |
@@ -1872,7 +1870,8 @@ static int max98090_dai_hw_params(struct snd_pcm_substream *substream, | |||
1872 | return -EINVAL; | 1870 | return -EINVAL; |
1873 | } | 1871 | } |
1874 | 1872 | ||
1875 | max98090_configure_bclk(codec); | 1873 | if (max98090->master) |
1874 | max98090_configure_bclk(codec); | ||
1876 | 1875 | ||
1877 | cdata->rate = max98090->lrclk; | 1876 | cdata->rate = max98090->lrclk; |
1878 | 1877 | ||
@@ -1951,8 +1950,6 @@ static int max98090_dai_set_sysclk(struct snd_soc_dai *dai, | |||
1951 | 1950 | ||
1952 | max98090->sysclk = freq; | 1951 | max98090->sysclk = freq; |
1953 | 1952 | ||
1954 | max98090_configure_bclk(codec); | ||
1955 | |||
1956 | return 0; | 1953 | return 0; |
1957 | } | 1954 | } |
1958 | 1955 | ||
@@ -2224,6 +2221,7 @@ static int max98090_probe(struct snd_soc_codec *codec) | |||
2224 | /* Initialize private data */ | 2221 | /* Initialize private data */ |
2225 | 2222 | ||
2226 | max98090->sysclk = (unsigned)-1; | 2223 | max98090->sysclk = (unsigned)-1; |
2224 | max98090->master = false; | ||
2227 | 2225 | ||
2228 | cdata = &max98090->dai[0]; | 2226 | cdata = &max98090->dai[0]; |
2229 | cdata->rate = (unsigned)-1; | 2227 | cdata->rate = (unsigned)-1; |
@@ -2293,6 +2291,9 @@ static int max98090_probe(struct snd_soc_codec *codec) | |||
2293 | snd_soc_write(codec, M98090_REG_BIAS_CONTROL, | 2291 | snd_soc_write(codec, M98090_REG_BIAS_CONTROL, |
2294 | M98090_VCM_MODE_MASK); | 2292 | M98090_VCM_MODE_MASK); |
2295 | 2293 | ||
2294 | snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE, | ||
2295 | M98090_MBVSEL_MASK, M98090_MBVSEL_2V8); | ||
2296 | |||
2296 | max98090_handle_pdata(codec); | 2297 | max98090_handle_pdata(codec); |
2297 | 2298 | ||
2298 | max98090_add_widgets(codec); | 2299 | max98090_add_widgets(codec); |
@@ -2329,9 +2330,11 @@ static const struct regmap_config max98090_regmap = { | |||
2329 | }; | 2330 | }; |
2330 | 2331 | ||
2331 | static int max98090_i2c_probe(struct i2c_client *i2c, | 2332 | static int max98090_i2c_probe(struct i2c_client *i2c, |
2332 | const struct i2c_device_id *id) | 2333 | const struct i2c_device_id *i2c_id) |
2333 | { | 2334 | { |
2334 | struct max98090_priv *max98090; | 2335 | struct max98090_priv *max98090; |
2336 | const struct acpi_device_id *acpi_id; | ||
2337 | kernel_ulong_t driver_data = 0; | ||
2335 | int ret; | 2338 | int ret; |
2336 | 2339 | ||
2337 | pr_debug("max98090_i2c_probe\n"); | 2340 | pr_debug("max98090_i2c_probe\n"); |
@@ -2341,7 +2344,19 @@ static int max98090_i2c_probe(struct i2c_client *i2c, | |||
2341 | if (max98090 == NULL) | 2344 | if (max98090 == NULL) |
2342 | return -ENOMEM; | 2345 | return -ENOMEM; |
2343 | 2346 | ||
2344 | max98090->devtype = id->driver_data; | 2347 | if (ACPI_HANDLE(&i2c->dev)) { |
2348 | acpi_id = acpi_match_device(i2c->dev.driver->acpi_match_table, | ||
2349 | &i2c->dev); | ||
2350 | if (!acpi_id) { | ||
2351 | dev_err(&i2c->dev, "No driver data\n"); | ||
2352 | return -EINVAL; | ||
2353 | } | ||
2354 | driver_data = acpi_id->driver_data; | ||
2355 | } else if (i2c_id) { | ||
2356 | driver_data = i2c_id->driver_data; | ||
2357 | } | ||
2358 | |||
2359 | max98090->devtype = driver_data; | ||
2345 | i2c_set_clientdata(i2c, max98090); | 2360 | i2c_set_clientdata(i2c, max98090); |
2346 | max98090->pdata = i2c->dev.platform_data; | 2361 | max98090->pdata = i2c->dev.platform_data; |
2347 | max98090->irq = i2c->irq; | 2362 | max98090->irq = i2c->irq; |
@@ -2373,6 +2388,8 @@ static int max98090_runtime_resume(struct device *dev) | |||
2373 | 2388 | ||
2374 | regcache_cache_only(max98090->regmap, false); | 2389 | regcache_cache_only(max98090->regmap, false); |
2375 | 2390 | ||
2391 | max98090_reset(max98090); | ||
2392 | |||
2376 | regcache_sync(max98090->regmap); | 2393 | regcache_sync(max98090->regmap); |
2377 | 2394 | ||
2378 | return 0; | 2395 | return 0; |
@@ -2388,9 +2405,34 @@ static int max98090_runtime_suspend(struct device *dev) | |||
2388 | } | 2405 | } |
2389 | #endif | 2406 | #endif |
2390 | 2407 | ||
2408 | #ifdef CONFIG_PM | ||
2409 | static int max98090_resume(struct device *dev) | ||
2410 | { | ||
2411 | struct max98090_priv *max98090 = dev_get_drvdata(dev); | ||
2412 | unsigned int status; | ||
2413 | |||
2414 | regcache_mark_dirty(max98090->regmap); | ||
2415 | |||
2416 | max98090_reset(max98090); | ||
2417 | |||
2418 | /* clear IRQ status */ | ||
2419 | regmap_read(max98090->regmap, M98090_REG_DEVICE_STATUS, &status); | ||
2420 | |||
2421 | regcache_sync(max98090->regmap); | ||
2422 | |||
2423 | return 0; | ||
2424 | } | ||
2425 | |||
2426 | static int max98090_suspend(struct device *dev) | ||
2427 | { | ||
2428 | return 0; | ||
2429 | } | ||
2430 | #endif | ||
2431 | |||
2391 | static const struct dev_pm_ops max98090_pm = { | 2432 | static const struct dev_pm_ops max98090_pm = { |
2392 | SET_RUNTIME_PM_OPS(max98090_runtime_suspend, | 2433 | SET_RUNTIME_PM_OPS(max98090_runtime_suspend, |
2393 | max98090_runtime_resume, NULL) | 2434 | max98090_runtime_resume, NULL) |
2435 | SET_SYSTEM_SLEEP_PM_OPS(max98090_suspend, max98090_resume) | ||
2394 | }; | 2436 | }; |
2395 | 2437 | ||
2396 | static const struct i2c_device_id max98090_i2c_id[] = { | 2438 | static const struct i2c_device_id max98090_i2c_id[] = { |
@@ -2405,12 +2447,21 @@ static const struct of_device_id max98090_of_match[] = { | |||
2405 | }; | 2447 | }; |
2406 | MODULE_DEVICE_TABLE(of, max98090_of_match); | 2448 | MODULE_DEVICE_TABLE(of, max98090_of_match); |
2407 | 2449 | ||
2450 | #ifdef CONFIG_ACPI | ||
2451 | static struct acpi_device_id max98090_acpi_match[] = { | ||
2452 | { "193C9890", MAX98090 }, | ||
2453 | { } | ||
2454 | }; | ||
2455 | MODULE_DEVICE_TABLE(acpi, max98090_acpi_match); | ||
2456 | #endif | ||
2457 | |||
2408 | static struct i2c_driver max98090_i2c_driver = { | 2458 | static struct i2c_driver max98090_i2c_driver = { |
2409 | .driver = { | 2459 | .driver = { |
2410 | .name = "max98090", | 2460 | .name = "max98090", |
2411 | .owner = THIS_MODULE, | 2461 | .owner = THIS_MODULE, |
2412 | .pm = &max98090_pm, | 2462 | .pm = &max98090_pm, |
2413 | .of_match_table = of_match_ptr(max98090_of_match), | 2463 | .of_match_table = of_match_ptr(max98090_of_match), |
2464 | .acpi_match_table = ACPI_PTR(max98090_acpi_match), | ||
2414 | }, | 2465 | }, |
2415 | .probe = max98090_i2c_probe, | 2466 | .probe = max98090_i2c_probe, |
2416 | .remove = max98090_i2c_remove, | 2467 | .remove = max98090_i2c_remove, |
diff --git a/sound/soc/codecs/max98090.h b/sound/soc/codecs/max98090.h index 1a4e2334a7b2..5a3c8d0613cb 100644 --- a/sound/soc/codecs/max98090.h +++ b/sound/soc/codecs/max98090.h | |||
@@ -1540,6 +1540,7 @@ struct max98090_priv { | |||
1540 | unsigned int pa2en; | 1540 | unsigned int pa2en; |
1541 | unsigned int extmic_mux; | 1541 | unsigned int extmic_mux; |
1542 | unsigned int sidetone; | 1542 | unsigned int sidetone; |
1543 | bool master; | ||
1543 | }; | 1544 | }; |
1544 | 1545 | ||
1545 | int max98090_mic_detect(struct snd_soc_codec *codec, | 1546 | int max98090_mic_detect(struct snd_soc_codec *codec, |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 03f0536e6f61..d6c1e4c19a5a 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
@@ -612,7 +612,7 @@ static SOC_ENUM_SINGLE_DECL(max98095_dai3_dac_filter_enum, | |||
612 | static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, | 612 | static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, |
613 | struct snd_ctl_elem_value *ucontrol) | 613 | struct snd_ctl_elem_value *ucontrol) |
614 | { | 614 | { |
615 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 615 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
616 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 616 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
617 | unsigned int sel = ucontrol->value.integer.value[0]; | 617 | unsigned int sel = ucontrol->value.integer.value[0]; |
618 | 618 | ||
@@ -626,7 +626,7 @@ static int max98095_mic1pre_set(struct snd_kcontrol *kcontrol, | |||
626 | static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, | 626 | static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, |
627 | struct snd_ctl_elem_value *ucontrol) | 627 | struct snd_ctl_elem_value *ucontrol) |
628 | { | 628 | { |
629 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 629 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
630 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 630 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
631 | 631 | ||
632 | ucontrol->value.integer.value[0] = max98095->mic1pre; | 632 | ucontrol->value.integer.value[0] = max98095->mic1pre; |
@@ -636,7 +636,7 @@ static int max98095_mic1pre_get(struct snd_kcontrol *kcontrol, | |||
636 | static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, | 636 | static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, |
637 | struct snd_ctl_elem_value *ucontrol) | 637 | struct snd_ctl_elem_value *ucontrol) |
638 | { | 638 | { |
639 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 639 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
640 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 640 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
641 | unsigned int sel = ucontrol->value.integer.value[0]; | 641 | unsigned int sel = ucontrol->value.integer.value[0]; |
642 | 642 | ||
@@ -650,7 +650,7 @@ static int max98095_mic2pre_set(struct snd_kcontrol *kcontrol, | |||
650 | static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol, | 650 | static int max98095_mic2pre_get(struct snd_kcontrol *kcontrol, |
651 | struct snd_ctl_elem_value *ucontrol) | 651 | struct snd_ctl_elem_value *ucontrol) |
652 | { | 652 | { |
653 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 653 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
654 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 654 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
655 | 655 | ||
656 | ucontrol->value.integer.value[0] = max98095->mic2pre; | 656 | ucontrol->value.integer.value[0] = max98095->mic2pre; |
@@ -1737,7 +1737,7 @@ static int max98095_get_eq_channel(const char *name) | |||
1737 | static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, | 1737 | static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, |
1738 | struct snd_ctl_elem_value *ucontrol) | 1738 | struct snd_ctl_elem_value *ucontrol) |
1739 | { | 1739 | { |
1740 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1740 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1741 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 1741 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
1742 | struct max98095_pdata *pdata = max98095->pdata; | 1742 | struct max98095_pdata *pdata = max98095->pdata; |
1743 | int channel = max98095_get_eq_channel(kcontrol->id.name); | 1743 | int channel = max98095_get_eq_channel(kcontrol->id.name); |
@@ -1801,7 +1801,7 @@ static int max98095_put_eq_enum(struct snd_kcontrol *kcontrol, | |||
1801 | static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol, | 1801 | static int max98095_get_eq_enum(struct snd_kcontrol *kcontrol, |
1802 | struct snd_ctl_elem_value *ucontrol) | 1802 | struct snd_ctl_elem_value *ucontrol) |
1803 | { | 1803 | { |
1804 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1804 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1805 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 1805 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
1806 | int channel = max98095_get_eq_channel(kcontrol->id.name); | 1806 | int channel = max98095_get_eq_channel(kcontrol->id.name); |
1807 | struct max98095_cdata *cdata; | 1807 | struct max98095_cdata *cdata; |
@@ -1891,7 +1891,7 @@ static int max98095_get_bq_channel(struct snd_soc_codec *codec, | |||
1891 | static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, | 1891 | static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, |
1892 | struct snd_ctl_elem_value *ucontrol) | 1892 | struct snd_ctl_elem_value *ucontrol) |
1893 | { | 1893 | { |
1894 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1894 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1895 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 1895 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
1896 | struct max98095_pdata *pdata = max98095->pdata; | 1896 | struct max98095_pdata *pdata = max98095->pdata; |
1897 | int channel = max98095_get_bq_channel(codec, kcontrol->id.name); | 1897 | int channel = max98095_get_bq_channel(codec, kcontrol->id.name); |
@@ -1952,7 +1952,7 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, | |||
1952 | static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol, | 1952 | static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol, |
1953 | struct snd_ctl_elem_value *ucontrol) | 1953 | struct snd_ctl_elem_value *ucontrol) |
1954 | { | 1954 | { |
1955 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1955 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1956 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 1956 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
1957 | int channel = max98095_get_bq_channel(codec, kcontrol->id.name); | 1957 | int channel = max98095_get_bq_channel(codec, kcontrol->id.name); |
1958 | struct max98095_cdata *cdata; | 1958 | struct max98095_cdata *cdata; |
@@ -2399,10 +2399,17 @@ static const struct i2c_device_id max98095_i2c_id[] = { | |||
2399 | }; | 2399 | }; |
2400 | MODULE_DEVICE_TABLE(i2c, max98095_i2c_id); | 2400 | MODULE_DEVICE_TABLE(i2c, max98095_i2c_id); |
2401 | 2401 | ||
2402 | static const struct of_device_id max98095_of_match[] = { | ||
2403 | { .compatible = "maxim,max98095", }, | ||
2404 | { } | ||
2405 | }; | ||
2406 | MODULE_DEVICE_TABLE(of, max98095_of_match); | ||
2407 | |||
2402 | static struct i2c_driver max98095_i2c_driver = { | 2408 | static struct i2c_driver max98095_i2c_driver = { |
2403 | .driver = { | 2409 | .driver = { |
2404 | .name = "max98095", | 2410 | .name = "max98095", |
2405 | .owner = THIS_MODULE, | 2411 | .owner = THIS_MODULE, |
2412 | .of_match_table = of_match_ptr(max98095_of_match), | ||
2406 | }, | 2413 | }, |
2407 | .probe = max98095_i2c_probe, | 2414 | .probe = max98095_i2c_probe, |
2408 | .remove = max98095_i2c_remove, | 2415 | .remove = max98095_i2c_remove, |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 2c59b1fb69dc..9965277b595a 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -22,6 +22,7 @@ | |||
22 | */ | 22 | */ |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/device.h> | 24 | #include <linux/device.h> |
25 | #include <linux/of.h> | ||
25 | #include <linux/mfd/mc13xxx.h> | 26 | #include <linux/mfd/mc13xxx.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
27 | #include <sound/core.h> | 28 | #include <sound/core.h> |
@@ -409,7 +410,7 @@ static const char * const adcl_enum_text[] = { | |||
409 | static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text); | 410 | static SOC_ENUM_SINGLE_VIRT_DECL(adcl_enum, adcl_enum_text); |
410 | 411 | ||
411 | static const struct snd_kcontrol_new left_input_mux = | 412 | static const struct snd_kcontrol_new left_input_mux = |
412 | SOC_DAPM_ENUM_VIRT("Route", adcl_enum); | 413 | SOC_DAPM_ENUM("Route", adcl_enum); |
413 | 414 | ||
414 | static const char * const adcr_enum_text[] = { | 415 | static const char * const adcr_enum_text[] = { |
415 | "MC1R", "MC2", "RXINR", "TXIN", | 416 | "MC1R", "MC2", "RXINR", "TXIN", |
@@ -418,7 +419,7 @@ static const char * const adcr_enum_text[] = { | |||
418 | static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text); | 419 | static SOC_ENUM_SINGLE_VIRT_DECL(adcr_enum, adcr_enum_text); |
419 | 420 | ||
420 | static const struct snd_kcontrol_new right_input_mux = | 421 | static const struct snd_kcontrol_new right_input_mux = |
421 | SOC_DAPM_ENUM_VIRT("Route", adcr_enum); | 422 | SOC_DAPM_ENUM("Route", adcr_enum); |
422 | 423 | ||
423 | static const struct snd_kcontrol_new samp_ctl = | 424 | static const struct snd_kcontrol_new samp_ctl = |
424 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0); | 425 | SOC_DAPM_SINGLE("Switch", MC13783_AUDIO_RX0, 3, 1, 0); |
@@ -478,9 +479,9 @@ static const struct snd_soc_dapm_widget mc13783_dapm_widgets[] = { | |||
478 | SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl), | 479 | SND_SOC_DAPM_SWITCH("MC2 Amp", MC13783_AUDIO_TX, 9, 0, &mc2_amp_ctl), |
479 | SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl), | 480 | SND_SOC_DAPM_SWITCH("TXIN Amp", MC13783_AUDIO_TX, 11, 0, &atx_amp_ctl), |
480 | 481 | ||
481 | SND_SOC_DAPM_VIRT_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, | 482 | SND_SOC_DAPM_MUX("PGA Left Input Mux", SND_SOC_NOPM, 0, 0, |
482 | &left_input_mux), | 483 | &left_input_mux), |
483 | SND_SOC_DAPM_VIRT_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, | 484 | SND_SOC_DAPM_MUX("PGA Right Input Mux", SND_SOC_NOPM, 0, 0, |
484 | &right_input_mux), | 485 | &right_input_mux), |
485 | 486 | ||
486 | SND_SOC_DAPM_MUX("Speaker Amp Source MUX", SND_SOC_NOPM, 0, 0, | 487 | SND_SOC_DAPM_MUX("Speaker Amp Source MUX", SND_SOC_NOPM, 0, 0, |
@@ -608,14 +609,6 @@ static struct snd_kcontrol_new mc13783_control_list[] = { | |||
608 | static int mc13783_probe(struct snd_soc_codec *codec) | 609 | static int mc13783_probe(struct snd_soc_codec *codec) |
609 | { | 610 | { |
610 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); | 611 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); |
611 | int ret; | ||
612 | |||
613 | ret = snd_soc_codec_set_cache_io(codec, | ||
614 | dev_get_regmap(codec->dev->parent, NULL)); | ||
615 | if (ret != 0) { | ||
616 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
617 | return ret; | ||
618 | } | ||
619 | 612 | ||
620 | /* these are the reset values */ | 613 | /* these are the reset values */ |
621 | mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); | 614 | mc13xxx_reg_write(priv->mc13xxx, MC13783_AUDIO_RX0, 0x25893); |
@@ -735,9 +728,15 @@ static struct snd_soc_dai_driver mc13783_dai_sync[] = { | |||
735 | } | 728 | } |
736 | }; | 729 | }; |
737 | 730 | ||
731 | static struct regmap *mc13783_get_regmap(struct device *dev) | ||
732 | { | ||
733 | return dev_get_regmap(dev->parent, NULL); | ||
734 | } | ||
735 | |||
738 | static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { | 736 | static struct snd_soc_codec_driver soc_codec_dev_mc13783 = { |
739 | .probe = mc13783_probe, | 737 | .probe = mc13783_probe, |
740 | .remove = mc13783_remove, | 738 | .remove = mc13783_remove, |
739 | .get_regmap = mc13783_get_regmap, | ||
741 | .controls = mc13783_control_list, | 740 | .controls = mc13783_control_list, |
742 | .num_controls = ARRAY_SIZE(mc13783_control_list), | 741 | .num_controls = ARRAY_SIZE(mc13783_control_list), |
743 | .dapm_widgets = mc13783_dapm_widgets, | 742 | .dapm_widgets = mc13783_dapm_widgets, |
@@ -750,6 +749,7 @@ static int __init mc13783_codec_probe(struct platform_device *pdev) | |||
750 | { | 749 | { |
751 | struct mc13783_priv *priv; | 750 | struct mc13783_priv *priv; |
752 | struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data; | 751 | struct mc13xxx_codec_platform_data *pdata = pdev->dev.platform_data; |
752 | struct device_node *np; | ||
753 | int ret; | 753 | int ret; |
754 | 754 | ||
755 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); | 755 | priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); |
@@ -760,7 +760,17 @@ static int __init mc13783_codec_probe(struct platform_device *pdev) | |||
760 | priv->adc_ssi_port = pdata->adc_ssi_port; | 760 | priv->adc_ssi_port = pdata->adc_ssi_port; |
761 | priv->dac_ssi_port = pdata->dac_ssi_port; | 761 | priv->dac_ssi_port = pdata->dac_ssi_port; |
762 | } else { | 762 | } else { |
763 | return -ENOSYS; | 763 | np = of_get_child_by_name(pdev->dev.parent->of_node, "codec"); |
764 | if (!np) | ||
765 | return -ENOSYS; | ||
766 | |||
767 | ret = of_property_read_u32(np, "adc-port", &priv->adc_ssi_port); | ||
768 | if (ret) | ||
769 | return ret; | ||
770 | |||
771 | ret = of_property_read_u32(np, "dac-port", &priv->dac_ssi_port); | ||
772 | if (ret) | ||
773 | return ret; | ||
764 | } | 774 | } |
765 | 775 | ||
766 | dev_set_drvdata(&pdev->dev, priv); | 776 | dev_set_drvdata(&pdev->dev, priv); |
diff --git a/sound/soc/codecs/pcm1681.c b/sound/soc/codecs/pcm1681.c index e427544183d7..a722a023c262 100644 --- a/sound/soc/codecs/pcm1681.c +++ b/sound/soc/codecs/pcm1681.c | |||
@@ -115,7 +115,7 @@ static int pcm1681_set_deemph(struct snd_soc_codec *codec) | |||
115 | static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, | 115 | static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, |
116 | struct snd_ctl_elem_value *ucontrol) | 116 | struct snd_ctl_elem_value *ucontrol) |
117 | { | 117 | { |
118 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 118 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
119 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); | 119 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); |
120 | 120 | ||
121 | ucontrol->value.enumerated.item[0] = priv->deemph; | 121 | ucontrol->value.enumerated.item[0] = priv->deemph; |
@@ -126,7 +126,7 @@ static int pcm1681_get_deemph(struct snd_kcontrol *kcontrol, | |||
126 | static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, | 126 | static int pcm1681_put_deemph(struct snd_kcontrol *kcontrol, |
127 | struct snd_ctl_elem_value *ucontrol) | 127 | struct snd_ctl_elem_value *ucontrol) |
128 | { | 128 | { |
129 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 129 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
130 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); | 130 | struct pcm1681_private *priv = snd_soc_codec_get_drvdata(codec); |
131 | 131 | ||
132 | priv->deemph = ucontrol->value.enumerated.item[0]; | 132 | priv->deemph = ucontrol->value.enumerated.item[0]; |
diff --git a/sound/soc/codecs/pcm512x.c b/sound/soc/codecs/pcm512x.c index 4b4c0c7bb918..163ec3855fd4 100644 --- a/sound/soc/codecs/pcm512x.c +++ b/sound/soc/codecs/pcm512x.c | |||
@@ -269,7 +269,7 @@ SOC_DOUBLE("Playback Digital Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT, | |||
269 | PCM512x_RQMR_SHIFT, 1, 1), | 269 | PCM512x_RQMR_SHIFT, 1, 1), |
270 | 270 | ||
271 | SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), | 271 | SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1), |
272 | SOC_VALUE_ENUM("DSP Program", pcm512x_dsp_program), | 272 | SOC_ENUM("DSP Program", pcm512x_dsp_program), |
273 | 273 | ||
274 | SOC_ENUM("Clock Missing Period", pcm512x_clk_missing), | 274 | SOC_ENUM("Clock Missing Period", pcm512x_clk_missing), |
275 | SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l), | 275 | SOC_ENUM("Auto Mute Time Left", pcm512x_autom_l), |
@@ -517,6 +517,7 @@ void pcm512x_remove(struct device *dev) | |||
517 | } | 517 | } |
518 | EXPORT_SYMBOL_GPL(pcm512x_remove); | 518 | EXPORT_SYMBOL_GPL(pcm512x_remove); |
519 | 519 | ||
520 | #ifdef CONFIG_PM_RUNTIME | ||
520 | static int pcm512x_suspend(struct device *dev) | 521 | static int pcm512x_suspend(struct device *dev) |
521 | { | 522 | { |
522 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); | 523 | struct pcm512x_priv *pcm512x = dev_get_drvdata(dev); |
@@ -578,6 +579,7 @@ static int pcm512x_resume(struct device *dev) | |||
578 | 579 | ||
579 | return 0; | 580 | return 0; |
580 | } | 581 | } |
582 | #endif | ||
581 | 583 | ||
582 | const struct dev_pm_ops pcm512x_pm_ops = { | 584 | const struct dev_pm_ops pcm512x_pm_ops = { |
583 | SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) | 585 | SET_RUNTIME_PM_OPS(pcm512x_suspend, pcm512x_resume, NULL) |
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index d4c229f0233f..30e234708579 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -188,7 +188,7 @@ static unsigned int mic_bst_tlv[] = { | |||
188 | static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, | 188 | static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, |
189 | struct snd_ctl_elem_value *ucontrol) | 189 | struct snd_ctl_elem_value *ucontrol) |
190 | { | 190 | { |
191 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 191 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
192 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | 192 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); |
193 | 193 | ||
194 | ucontrol->value.integer.value[0] = rt5631->dmic_used_flag; | 194 | ucontrol->value.integer.value[0] = rt5631->dmic_used_flag; |
@@ -199,7 +199,7 @@ static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, | |||
199 | static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, | 199 | static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, |
200 | struct snd_ctl_elem_value *ucontrol) | 200 | struct snd_ctl_elem_value *ucontrol) |
201 | { | 201 | { |
202 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 202 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
203 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | 203 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); |
204 | 204 | ||
205 | rt5631->dmic_used_flag = ucontrol->value.integer.value[0]; | 205 | rt5631->dmic_used_flag = ucontrol->value.integer.value[0]; |
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c index 68b4dd622b87..9e0d48f98927 100644 --- a/sound/soc/codecs/rt5640.c +++ b/sound/soc/codecs/rt5640.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * rt5640.c -- RT5640 ALSA SoC audio codec driver | 2 | * rt5640.c -- RT5640/RT5639 ALSA SoC audio codec driver |
3 | * | 3 | * |
4 | * Copyright 2011 Realtek Semiconductor Corp. | 4 | * Copyright 2011 Realtek Semiconductor Corp. |
5 | * Author: Johnny Hsu <johnnyhsu@realtek.com> | 5 | * Author: Johnny Hsu <johnnyhsu@realtek.com> |
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/gpio.h> | 18 | #include <linux/gpio.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
21 | #include <linux/of.h> | ||
21 | #include <linux/of_gpio.h> | 22 | #include <linux/of_gpio.h> |
22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
23 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
@@ -59,7 +60,7 @@ static struct reg_default init_list[] = { | |||
59 | }; | 60 | }; |
60 | #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) | 61 | #define RT5640_INIT_REG_LEN ARRAY_SIZE(init_list) |
61 | 62 | ||
62 | static const struct reg_default rt5640_reg[RT5640_VENDOR_ID2 + 1] = { | 63 | static const struct reg_default rt5640_reg[] = { |
63 | { 0x00, 0x000e }, | 64 | { 0x00, 0x000e }, |
64 | { 0x01, 0xc8c8 }, | 65 | { 0x01, 0xc8c8 }, |
65 | { 0x02, 0xc8c8 }, | 66 | { 0x02, 0xc8c8 }, |
@@ -398,18 +399,13 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { | |||
398 | RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), | 399 | RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), |
399 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT, | 400 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5640_OUTPUT, |
400 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), | 401 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), |
401 | /* MONO Output Control */ | 402 | |
402 | SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, | ||
403 | RT5640_L_MUTE_SFT, 1, 1), | ||
404 | /* DAC Digital Volume */ | 403 | /* DAC Digital Volume */ |
405 | SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL, | 404 | SOC_DOUBLE("DAC2 Playback Switch", RT5640_DAC2_CTRL, |
406 | RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1), | 405 | RT5640_M_DAC_L2_VOL_SFT, RT5640_M_DAC_R2_VOL_SFT, 1, 1), |
407 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, | 406 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5640_DAC1_DIG_VOL, |
408 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, | 407 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, |
409 | 175, 0, dac_vol_tlv), | 408 | 175, 0, dac_vol_tlv), |
410 | SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, | ||
411 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, | ||
412 | 175, 0, dac_vol_tlv), | ||
413 | /* IN1/IN2 Control */ | 409 | /* IN1/IN2 Control */ |
414 | SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, | 410 | SOC_SINGLE_TLV("IN1 Boost", RT5640_IN1_IN2, |
415 | RT5640_BST_SFT1, 8, 0, bst_tlv), | 411 | RT5640_BST_SFT1, 8, 0, bst_tlv), |
@@ -441,6 +437,15 @@ static const struct snd_kcontrol_new rt5640_snd_controls[] = { | |||
441 | SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum), | 437 | SOC_ENUM("DAC IF2 Data Switch", rt5640_if2_dac_enum), |
442 | }; | 438 | }; |
443 | 439 | ||
440 | static const struct snd_kcontrol_new rt5640_specific_snd_controls[] = { | ||
441 | /* MONO Output Control */ | ||
442 | SOC_SINGLE("Mono Playback Switch", RT5640_MONO_OUT, RT5640_L_MUTE_SFT, | ||
443 | 1, 1), | ||
444 | |||
445 | SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5640_DAC2_DIG_VOL, | ||
446 | RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 175, 0, dac_vol_tlv), | ||
447 | }; | ||
448 | |||
444 | /** | 449 | /** |
445 | * set_dmic_clk - Set parameter of dmic. | 450 | * set_dmic_clk - Set parameter of dmic. |
446 | * | 451 | * |
@@ -480,14 +485,14 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w, | |||
480 | return idx; | 485 | return idx; |
481 | } | 486 | } |
482 | 487 | ||
483 | static int check_sysclk1_source(struct snd_soc_dapm_widget *source, | 488 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
484 | struct snd_soc_dapm_widget *sink) | 489 | struct snd_soc_dapm_widget *sink) |
485 | { | 490 | { |
486 | unsigned int val; | 491 | unsigned int val; |
487 | 492 | ||
488 | val = snd_soc_read(source->codec, RT5640_GLB_CLK); | 493 | val = snd_soc_read(source->codec, RT5640_GLB_CLK); |
489 | val &= RT5640_SCLK_SRC_MASK; | 494 | val &= RT5640_SCLK_SRC_MASK; |
490 | if (val == RT5640_SCLK_SRC_PLL1 || val == RT5640_SCLK_SRC_PLL1T) | 495 | if (val == RT5640_SCLK_SRC_PLL1) |
491 | return 1; | 496 | return 1; |
492 | else | 497 | else |
493 | return 0; | 498 | return 0; |
@@ -554,6 +559,20 @@ static const struct snd_kcontrol_new rt5640_sto_dac_r_mix[] = { | |||
554 | RT5640_M_ANC_DAC_R_SFT, 1, 1), | 559 | RT5640_M_ANC_DAC_R_SFT, 1, 1), |
555 | }; | 560 | }; |
556 | 561 | ||
562 | static const struct snd_kcontrol_new rt5639_sto_dac_l_mix[] = { | ||
563 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_STO_DAC_MIXER, | ||
564 | RT5640_M_DAC_L1_SFT, 1, 1), | ||
565 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5640_STO_DAC_MIXER, | ||
566 | RT5640_M_DAC_L2_SFT, 1, 1), | ||
567 | }; | ||
568 | |||
569 | static const struct snd_kcontrol_new rt5639_sto_dac_r_mix[] = { | ||
570 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_STO_DAC_MIXER, | ||
571 | RT5640_M_DAC_R1_SFT, 1, 1), | ||
572 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5640_STO_DAC_MIXER, | ||
573 | RT5640_M_DAC_R2_SFT, 1, 1), | ||
574 | }; | ||
575 | |||
557 | static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = { | 576 | static const struct snd_kcontrol_new rt5640_mono_dac_l_mix[] = { |
558 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER, | 577 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_MONO_DAC_MIXER, |
559 | RT5640_M_DAC_L1_MONO_L_SFT, 1, 1), | 578 | RT5640_M_DAC_L1_MONO_L_SFT, 1, 1), |
@@ -676,6 +695,30 @@ static const struct snd_kcontrol_new rt5640_out_r_mix[] = { | |||
676 | RT5640_M_DAC_R1_OM_R_SFT, 1, 1), | 695 | RT5640_M_DAC_R1_OM_R_SFT, 1, 1), |
677 | }; | 696 | }; |
678 | 697 | ||
698 | static const struct snd_kcontrol_new rt5639_out_l_mix[] = { | ||
699 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_L3_MIXER, | ||
700 | RT5640_M_BST1_OM_L_SFT, 1, 1), | ||
701 | SOC_DAPM_SINGLE("INL Switch", RT5640_OUT_L3_MIXER, | ||
702 | RT5640_M_IN_L_OM_L_SFT, 1, 1), | ||
703 | SOC_DAPM_SINGLE("REC MIXL Switch", RT5640_OUT_L3_MIXER, | ||
704 | RT5640_M_RM_L_OM_L_SFT, 1, 1), | ||
705 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_OUT_L3_MIXER, | ||
706 | RT5640_M_DAC_L1_OM_L_SFT, 1, 1), | ||
707 | }; | ||
708 | |||
709 | static const struct snd_kcontrol_new rt5639_out_r_mix[] = { | ||
710 | SOC_DAPM_SINGLE("BST2 Switch", RT5640_OUT_R3_MIXER, | ||
711 | RT5640_M_BST4_OM_R_SFT, 1, 1), | ||
712 | SOC_DAPM_SINGLE("BST1 Switch", RT5640_OUT_R3_MIXER, | ||
713 | RT5640_M_BST1_OM_R_SFT, 1, 1), | ||
714 | SOC_DAPM_SINGLE("INR Switch", RT5640_OUT_R3_MIXER, | ||
715 | RT5640_M_IN_R_OM_R_SFT, 1, 1), | ||
716 | SOC_DAPM_SINGLE("REC MIXR Switch", RT5640_OUT_R3_MIXER, | ||
717 | RT5640_M_RM_R_OM_R_SFT, 1, 1), | ||
718 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_OUT_R3_MIXER, | ||
719 | RT5640_M_DAC_R1_OM_R_SFT, 1, 1), | ||
720 | }; | ||
721 | |||
679 | static const struct snd_kcontrol_new rt5640_spo_l_mix[] = { | 722 | static const struct snd_kcontrol_new rt5640_spo_l_mix[] = { |
680 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER, | 723 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5640_SPO_L_MIXER, |
681 | RT5640_M_DAC_R1_SPM_L_SFT, 1, 1), | 724 | RT5640_M_DAC_R1_SPM_L_SFT, 1, 1), |
@@ -707,6 +750,13 @@ static const struct snd_kcontrol_new rt5640_hpo_mix[] = { | |||
707 | RT5640_M_HPVOL_HM_SFT, 1, 1), | 750 | RT5640_M_HPVOL_HM_SFT, 1, 1), |
708 | }; | 751 | }; |
709 | 752 | ||
753 | static const struct snd_kcontrol_new rt5639_hpo_mix[] = { | ||
754 | SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5640_HPO_MIXER, | ||
755 | RT5640_M_DAC1_HM_SFT, 1, 1), | ||
756 | SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5640_HPO_MIXER, | ||
757 | RT5640_M_HPVOL_HM_SFT, 1, 1), | ||
758 | }; | ||
759 | |||
710 | static const struct snd_kcontrol_new rt5640_lout_mix[] = { | 760 | static const struct snd_kcontrol_new rt5640_lout_mix[] = { |
711 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER, | 761 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5640_LOUT_MIXER, |
712 | RT5640_M_DAC_L1_LM_SFT, 1, 1), | 762 | RT5640_M_DAC_L1_LM_SFT, 1, 1), |
@@ -824,7 +874,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dac_l2_enum, | |||
824 | 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); | 874 | 0x3, rt5640_dac_l2_src, rt5640_dac_l2_values); |
825 | 875 | ||
826 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = | 876 | static const struct snd_kcontrol_new rt5640_dac_l2_mux = |
827 | SOC_DAPM_VALUE_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); | 877 | SOC_DAPM_ENUM("DAC2 left channel source", rt5640_dac_l2_enum); |
828 | 878 | ||
829 | static const char * const rt5640_dac_r2_src[] = { | 879 | static const char * const rt5640_dac_r2_src[] = { |
830 | "IF2", | 880 | "IF2", |
@@ -859,7 +909,7 @@ static SOC_VALUE_ENUM_SINGLE_DECL(rt5640_dai_iis_map_enum, | |||
859 | rt5640_dai_iis_map_values); | 909 | rt5640_dai_iis_map_values); |
860 | 910 | ||
861 | static const struct snd_kcontrol_new rt5640_dai_mux = | 911 | static const struct snd_kcontrol_new rt5640_dai_mux = |
862 | SOC_DAPM_VALUE_ENUM("DAI select", rt5640_dai_iis_map_enum); | 912 | SOC_DAPM_ENUM("DAI select", rt5640_dai_iis_map_enum); |
863 | 913 | ||
864 | /* SDI select */ | 914 | /* SDI select */ |
865 | static const char * const rt5640_sdi_sel[] = { | 915 | static const char * const rt5640_sdi_sel[] = { |
@@ -872,54 +922,6 @@ static SOC_ENUM_SINGLE_DECL(rt5640_sdi_sel_enum, RT5640_I2S2_SDP, | |||
872 | static const struct snd_kcontrol_new rt5640_sdi_mux = | 922 | static const struct snd_kcontrol_new rt5640_sdi_mux = |
873 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); | 923 | SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); |
874 | 924 | ||
875 | static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, | ||
876 | struct snd_kcontrol *kcontrol, int event) | ||
877 | { | ||
878 | struct snd_soc_codec *codec = w->codec; | ||
879 | |||
880 | switch (event) { | ||
881 | case SND_SOC_DAPM_PRE_PMU: | ||
882 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
883 | RT5640_GP2_PIN_MASK | RT5640_GP3_PIN_MASK, | ||
884 | RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP3_PIN_DMIC1_SDA); | ||
885 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
886 | RT5640_DMIC_1L_LH_MASK | RT5640_DMIC_1R_LH_MASK | | ||
887 | RT5640_DMIC_1_DP_MASK, | ||
888 | RT5640_DMIC_1L_LH_FALLING | RT5640_DMIC_1R_LH_RISING | | ||
889 | RT5640_DMIC_1_DP_IN1P); | ||
890 | break; | ||
891 | |||
892 | default: | ||
893 | return 0; | ||
894 | } | ||
895 | |||
896 | return 0; | ||
897 | } | ||
898 | |||
899 | static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w, | ||
900 | struct snd_kcontrol *kcontrol, int event) | ||
901 | { | ||
902 | struct snd_soc_codec *codec = w->codec; | ||
903 | |||
904 | switch (event) { | ||
905 | case SND_SOC_DAPM_PRE_PMU: | ||
906 | snd_soc_update_bits(codec, RT5640_GPIO_CTRL1, | ||
907 | RT5640_GP2_PIN_MASK | RT5640_GP4_PIN_MASK, | ||
908 | RT5640_GP2_PIN_DMIC1_SCL | RT5640_GP4_PIN_DMIC2_SDA); | ||
909 | snd_soc_update_bits(codec, RT5640_DMIC, | ||
910 | RT5640_DMIC_2L_LH_MASK | RT5640_DMIC_2R_LH_MASK | | ||
911 | RT5640_DMIC_2_DP_MASK, | ||
912 | RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING | | ||
913 | RT5640_DMIC_2_DP_IN1N); | ||
914 | break; | ||
915 | |||
916 | default: | ||
917 | return 0; | ||
918 | } | ||
919 | |||
920 | return 0; | ||
921 | } | ||
922 | |||
923 | static void hp_amp_power_on(struct snd_soc_codec *codec) | 925 | static void hp_amp_power_on(struct snd_soc_codec *codec) |
924 | { | 926 | { |
925 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | 927 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); |
@@ -1054,12 +1056,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { | |||
1054 | 1056 | ||
1055 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | 1057 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, |
1056 | set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | 1058 | set_dmic_clk, SND_SOC_DAPM_PRE_PMU), |
1057 | SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, | 1059 | SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5640_DMIC, RT5640_DMIC_1_EN_SFT, 0, |
1058 | RT5640_DMIC_1_EN_SFT, 0, rt5640_set_dmic1_event, | 1060 | NULL, 0), |
1059 | SND_SOC_DAPM_PRE_PMU), | 1061 | SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, RT5640_DMIC_2_EN_SFT, 0, |
1060 | SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5640_DMIC, | 1062 | NULL, 0), |
1061 | RT5640_DMIC_2_EN_SFT, 0, rt5640_set_dmic2_event, | ||
1062 | SND_SOC_DAPM_PRE_PMU), | ||
1063 | /* Boost */ | 1063 | /* Boost */ |
1064 | SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2, | 1064 | SND_SOC_DAPM_PGA("BST1", RT5640_PWR_ANLG2, |
1065 | RT5640_PWR_BST1_BIT, 0, NULL, 0), | 1065 | RT5640_PWR_BST1_BIT, 0, NULL, 0), |
@@ -1146,26 +1146,15 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { | |||
1146 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | 1146 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), |
1147 | SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | 1147 | SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), |
1148 | SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | 1148 | SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), |
1149 | /* Audio DSP */ | 1149 | |
1150 | SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1151 | /* ANC */ | ||
1152 | SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1153 | /* Output Side */ | 1150 | /* Output Side */ |
1154 | /* DAC mixer before sound effect */ | 1151 | /* DAC mixer before sound effect */ |
1155 | SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, | 1152 | SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, |
1156 | rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)), | 1153 | rt5640_dac_l_mix, ARRAY_SIZE(rt5640_dac_l_mix)), |
1157 | SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, | 1154 | SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, |
1158 | rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)), | 1155 | rt5640_dac_r_mix, ARRAY_SIZE(rt5640_dac_r_mix)), |
1159 | /* DAC2 channel Mux */ | 1156 | |
1160 | SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
1161 | &rt5640_dac_l2_mux), | ||
1162 | SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1163 | &rt5640_dac_r2_mux), | ||
1164 | /* DAC Mixer */ | 1157 | /* DAC Mixer */ |
1165 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1166 | rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), | ||
1167 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1168 | rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), | ||
1169 | SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, | 1158 | SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, |
1170 | rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)), | 1159 | rt5640_mono_dac_l_mix, ARRAY_SIZE(rt5640_mono_dac_l_mix)), |
1171 | SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, | 1160 | SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, |
@@ -1177,21 +1166,14 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { | |||
1177 | /* DACs */ | 1166 | /* DACs */ |
1178 | SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1, | 1167 | SND_SOC_DAPM_DAC("DAC L1", NULL, RT5640_PWR_DIG1, |
1179 | RT5640_PWR_DAC_L1_BIT, 0), | 1168 | RT5640_PWR_DAC_L1_BIT, 0), |
1180 | SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, | ||
1181 | RT5640_PWR_DAC_L2_BIT, 0), | ||
1182 | SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1, | 1169 | SND_SOC_DAPM_DAC("DAC R1", NULL, RT5640_PWR_DIG1, |
1183 | RT5640_PWR_DAC_R1_BIT, 0), | 1170 | RT5640_PWR_DAC_R1_BIT, 0), |
1184 | SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, | 1171 | |
1185 | RT5640_PWR_DAC_R2_BIT, 0), | ||
1186 | /* SPK/OUT Mixer */ | 1172 | /* SPK/OUT Mixer */ |
1187 | SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT, | 1173 | SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT, |
1188 | 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)), | 1174 | 0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)), |
1189 | SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT, | 1175 | SND_SOC_DAPM_MIXER("SPK MIXR", RT5640_PWR_MIXER, RT5640_PWR_SM_R_BIT, |
1190 | 0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)), | 1176 | 0, rt5640_spk_r_mix, ARRAY_SIZE(rt5640_spk_r_mix)), |
1191 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, | ||
1192 | 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), | ||
1193 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, | ||
1194 | 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), | ||
1195 | /* Ouput Volume */ | 1177 | /* Ouput Volume */ |
1196 | SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL, | 1178 | SND_SOC_DAPM_PGA("SPKVOL L", RT5640_PWR_VOL, |
1197 | RT5640_PWR_SV_L_BIT, 0, NULL, 0), | 1179 | RT5640_PWR_SV_L_BIT, 0, NULL, 0), |
@@ -1210,16 +1192,8 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { | |||
1210 | 0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)), | 1192 | 0, rt5640_spo_l_mix, ARRAY_SIZE(rt5640_spo_l_mix)), |
1211 | SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, | 1193 | SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, |
1212 | 0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)), | 1194 | 0, rt5640_spo_r_mix, ARRAY_SIZE(rt5640_spo_r_mix)), |
1213 | SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, | ||
1214 | rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), | ||
1215 | SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, | ||
1216 | rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), | ||
1217 | SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0, | 1195 | SND_SOC_DAPM_MIXER("LOUT MIX", RT5640_PWR_ANLG1, RT5640_PWR_LM_BIT, 0, |
1218 | rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)), | 1196 | rt5640_lout_mix, ARRAY_SIZE(rt5640_lout_mix)), |
1219 | SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, | ||
1220 | rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), | ||
1221 | SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, | ||
1222 | RT5640_PWR_MA_BIT, 0, NULL, 0), | ||
1223 | SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, | 1197 | SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, |
1224 | 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU), | 1198 | 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU), |
1225 | SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, | 1199 | SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, |
@@ -1251,10 +1225,69 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { | |||
1251 | SND_SOC_DAPM_OUTPUT("HPOR"), | 1225 | SND_SOC_DAPM_OUTPUT("HPOR"), |
1252 | SND_SOC_DAPM_OUTPUT("LOUTL"), | 1226 | SND_SOC_DAPM_OUTPUT("LOUTL"), |
1253 | SND_SOC_DAPM_OUTPUT("LOUTR"), | 1227 | SND_SOC_DAPM_OUTPUT("LOUTR"), |
1228 | }; | ||
1229 | |||
1230 | static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = { | ||
1231 | /* Audio DSP */ | ||
1232 | SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1233 | /* ANC */ | ||
1234 | SND_SOC_DAPM_PGA("ANC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1235 | |||
1236 | /* DAC2 channel Mux */ | ||
1237 | SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_l2_mux), | ||
1238 | SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5640_dac_r2_mux), | ||
1239 | |||
1240 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1241 | rt5640_sto_dac_l_mix, ARRAY_SIZE(rt5640_sto_dac_l_mix)), | ||
1242 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1243 | rt5640_sto_dac_r_mix, ARRAY_SIZE(rt5640_sto_dac_r_mix)), | ||
1244 | |||
1245 | SND_SOC_DAPM_DAC("DAC R2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_R2_BIT, | ||
1246 | 0), | ||
1247 | SND_SOC_DAPM_DAC("DAC L2", NULL, RT5640_PWR_DIG1, RT5640_PWR_DAC_L2_BIT, | ||
1248 | 0), | ||
1249 | |||
1250 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, | ||
1251 | 0, rt5640_out_l_mix, ARRAY_SIZE(rt5640_out_l_mix)), | ||
1252 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, | ||
1253 | 0, rt5640_out_r_mix, ARRAY_SIZE(rt5640_out_r_mix)), | ||
1254 | |||
1255 | SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, | ||
1256 | rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), | ||
1257 | SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, | ||
1258 | rt5640_hpo_mix, ARRAY_SIZE(rt5640_hpo_mix)), | ||
1259 | |||
1260 | SND_SOC_DAPM_MIXER("Mono MIX", RT5640_PWR_ANLG1, RT5640_PWR_MM_BIT, 0, | ||
1261 | rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), | ||
1262 | SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, | ||
1263 | RT5640_PWR_MA_BIT, 0, NULL, 0), | ||
1264 | |||
1254 | SND_SOC_DAPM_OUTPUT("MONOP"), | 1265 | SND_SOC_DAPM_OUTPUT("MONOP"), |
1255 | SND_SOC_DAPM_OUTPUT("MONON"), | 1266 | SND_SOC_DAPM_OUTPUT("MONON"), |
1256 | }; | 1267 | }; |
1257 | 1268 | ||
1269 | static const struct snd_soc_dapm_widget rt5639_specific_dapm_widgets[] = { | ||
1270 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1271 | rt5639_sto_dac_l_mix, ARRAY_SIZE(rt5639_sto_dac_l_mix)), | ||
1272 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1273 | rt5639_sto_dac_r_mix, ARRAY_SIZE(rt5639_sto_dac_r_mix)), | ||
1274 | |||
1275 | SND_SOC_DAPM_SUPPLY("DAC L2 Filter", RT5640_PWR_DIG1, | ||
1276 | RT5640_PWR_DAC_L2_BIT, 0, NULL, 0), | ||
1277 | SND_SOC_DAPM_SUPPLY("DAC R2 Filter", RT5640_PWR_DIG1, | ||
1278 | RT5640_PWR_DAC_R2_BIT, 0, NULL, 0), | ||
1279 | |||
1280 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5640_PWR_MIXER, RT5640_PWR_OM_L_BIT, | ||
1281 | 0, rt5639_out_l_mix, ARRAY_SIZE(rt5639_out_l_mix)), | ||
1282 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5640_PWR_MIXER, RT5640_PWR_OM_R_BIT, | ||
1283 | 0, rt5639_out_r_mix, ARRAY_SIZE(rt5639_out_r_mix)), | ||
1284 | |||
1285 | SND_SOC_DAPM_MIXER("HPO MIX L", SND_SOC_NOPM, 0, 0, | ||
1286 | rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)), | ||
1287 | SND_SOC_DAPM_MIXER("HPO MIX R", SND_SOC_NOPM, 0, 0, | ||
1288 | rt5639_hpo_mix, ARRAY_SIZE(rt5639_hpo_mix)), | ||
1289 | }; | ||
1290 | |||
1258 | static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | 1291 | static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { |
1259 | {"IN1P", NULL, "LDO2"}, | 1292 | {"IN1P", NULL, "LDO2"}, |
1260 | {"IN2P", NULL, "LDO2"}, | 1293 | {"IN2P", NULL, "LDO2"}, |
@@ -1323,22 +1356,22 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | |||
1323 | {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, | 1356 | {"Stereo ADC MIXL", "ADC1 Switch", "Stereo ADC L1 Mux"}, |
1324 | {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, | 1357 | {"Stereo ADC MIXL", "ADC2 Switch", "Stereo ADC L2 Mux"}, |
1325 | {"Stereo ADC MIXL", NULL, "Stereo Filter"}, | 1358 | {"Stereo ADC MIXL", NULL, "Stereo Filter"}, |
1326 | {"Stereo Filter", NULL, "PLL1", check_sysclk1_source}, | 1359 | {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll}, |
1327 | 1360 | ||
1328 | {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, | 1361 | {"Stereo ADC MIXR", "ADC1 Switch", "Stereo ADC R1 Mux"}, |
1329 | {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, | 1362 | {"Stereo ADC MIXR", "ADC2 Switch", "Stereo ADC R2 Mux"}, |
1330 | {"Stereo ADC MIXR", NULL, "Stereo Filter"}, | 1363 | {"Stereo ADC MIXR", NULL, "Stereo Filter"}, |
1331 | {"Stereo Filter", NULL, "PLL1", check_sysclk1_source}, | 1364 | {"Stereo Filter", NULL, "PLL1", is_sys_clk_from_pll}, |
1332 | 1365 | ||
1333 | {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, | 1366 | {"Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux"}, |
1334 | {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, | 1367 | {"Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux"}, |
1335 | {"Mono ADC MIXL", NULL, "Mono Left Filter"}, | 1368 | {"Mono ADC MIXL", NULL, "Mono Left Filter"}, |
1336 | {"Mono Left Filter", NULL, "PLL1", check_sysclk1_source}, | 1369 | {"Mono Left Filter", NULL, "PLL1", is_sys_clk_from_pll}, |
1337 | 1370 | ||
1338 | {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, | 1371 | {"Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux"}, |
1339 | {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, | 1372 | {"Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux"}, |
1340 | {"Mono ADC MIXR", NULL, "Mono Right Filter"}, | 1373 | {"Mono ADC MIXR", NULL, "Mono Right Filter"}, |
1341 | {"Mono Right Filter", NULL, "PLL1", check_sysclk1_source}, | 1374 | {"Mono Right Filter", NULL, "PLL1", is_sys_clk_from_pll}, |
1342 | 1375 | ||
1343 | {"IF2 ADC L", NULL, "Mono ADC MIXL"}, | 1376 | {"IF2 ADC L", NULL, "Mono ADC MIXL"}, |
1344 | {"IF2 ADC R", NULL, "Mono ADC MIXR"}, | 1377 | {"IF2 ADC R", NULL, "Mono ADC MIXR"}, |
@@ -1396,71 +1429,38 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | |||
1396 | {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"}, | 1429 | {"DAC MIXR", "Stereo ADC Switch", "Stereo ADC MIXR"}, |
1397 | {"DAC MIXR", "INF1 Switch", "IF1 DAC R"}, | 1430 | {"DAC MIXR", "INF1 Switch", "IF1 DAC R"}, |
1398 | 1431 | ||
1399 | {"ANC", NULL, "Stereo ADC MIXL"}, | ||
1400 | {"ANC", NULL, "Stereo ADC MIXR"}, | ||
1401 | |||
1402 | {"Audio DSP", NULL, "DAC MIXL"}, | ||
1403 | {"Audio DSP", NULL, "DAC MIXR"}, | ||
1404 | |||
1405 | {"DAC L2 Mux", "IF2", "IF2 DAC L"}, | ||
1406 | {"DAC L2 Mux", "Base L/R", "Audio DSP"}, | ||
1407 | |||
1408 | {"DAC R2 Mux", "IF2", "IF2 DAC R"}, | ||
1409 | |||
1410 | {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, | 1432 | {"Stereo DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, |
1411 | {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1412 | {"Stereo DAC MIXL", "ANC Switch", "ANC"}, | ||
1413 | {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, | 1433 | {"Stereo DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, |
1414 | {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1415 | {"Stereo DAC MIXR", "ANC Switch", "ANC"}, | ||
1416 | 1434 | ||
1417 | {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, | 1435 | {"Mono DAC MIXL", "DAC L1 Switch", "DAC MIXL"}, |
1418 | {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1419 | {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1420 | {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, | 1436 | {"Mono DAC MIXR", "DAC R1 Switch", "DAC MIXR"}, |
1421 | {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1422 | {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1423 | 1437 | ||
1424 | {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"}, | 1438 | {"DIG MIXL", "DAC L1 Switch", "DAC MIXL"}, |
1425 | {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1426 | {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, | 1439 | {"DIG MIXR", "DAC R1 Switch", "DAC MIXR"}, |
1427 | {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1428 | 1440 | ||
1429 | {"DAC L1", NULL, "Stereo DAC MIXL"}, | 1441 | {"DAC L1", NULL, "Stereo DAC MIXL"}, |
1430 | {"DAC L1", NULL, "PLL1", check_sysclk1_source}, | 1442 | {"DAC L1", NULL, "PLL1", is_sys_clk_from_pll}, |
1431 | {"DAC R1", NULL, "Stereo DAC MIXR"}, | 1443 | {"DAC R1", NULL, "Stereo DAC MIXR"}, |
1432 | {"DAC R1", NULL, "PLL1", check_sysclk1_source}, | 1444 | {"DAC R1", NULL, "PLL1", is_sys_clk_from_pll}, |
1433 | {"DAC L2", NULL, "Mono DAC MIXL"}, | ||
1434 | {"DAC L2", NULL, "PLL1", check_sysclk1_source}, | ||
1435 | {"DAC R2", NULL, "Mono DAC MIXR"}, | ||
1436 | {"DAC R2", NULL, "PLL1", check_sysclk1_source}, | ||
1437 | 1445 | ||
1438 | {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, | 1446 | {"SPK MIXL", "REC MIXL Switch", "RECMIXL"}, |
1439 | {"SPK MIXL", "INL Switch", "INL VOL"}, | 1447 | {"SPK MIXL", "INL Switch", "INL VOL"}, |
1440 | {"SPK MIXL", "DAC L1 Switch", "DAC L1"}, | 1448 | {"SPK MIXL", "DAC L1 Switch", "DAC L1"}, |
1441 | {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, | ||
1442 | {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"}, | 1449 | {"SPK MIXL", "OUT MIXL Switch", "OUT MIXL"}, |
1443 | {"SPK MIXR", "REC MIXR Switch", "RECMIXR"}, | 1450 | {"SPK MIXR", "REC MIXR Switch", "RECMIXR"}, |
1444 | {"SPK MIXR", "INR Switch", "INR VOL"}, | 1451 | {"SPK MIXR", "INR Switch", "INR VOL"}, |
1445 | {"SPK MIXR", "DAC R1 Switch", "DAC R1"}, | 1452 | {"SPK MIXR", "DAC R1 Switch", "DAC R1"}, |
1446 | {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, | ||
1447 | {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"}, | 1453 | {"SPK MIXR", "OUT MIXR Switch", "OUT MIXR"}, |
1448 | 1454 | ||
1449 | {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, | ||
1450 | {"OUT MIXL", "BST1 Switch", "BST1"}, | 1455 | {"OUT MIXL", "BST1 Switch", "BST1"}, |
1451 | {"OUT MIXL", "INL Switch", "INL VOL"}, | 1456 | {"OUT MIXL", "INL Switch", "INL VOL"}, |
1452 | {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, | 1457 | {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, |
1453 | {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, | ||
1454 | {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, | ||
1455 | {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, | 1458 | {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, |
1456 | 1459 | ||
1457 | {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, | ||
1458 | {"OUT MIXR", "BST2 Switch", "BST2"}, | 1460 | {"OUT MIXR", "BST2 Switch", "BST2"}, |
1459 | {"OUT MIXR", "BST1 Switch", "BST1"}, | 1461 | {"OUT MIXR", "BST1 Switch", "BST1"}, |
1460 | {"OUT MIXR", "INR Switch", "INR VOL"}, | 1462 | {"OUT MIXR", "INR Switch", "INR VOL"}, |
1461 | {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, | 1463 | {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, |
1462 | {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, | ||
1463 | {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, | ||
1464 | {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, | 1464 | {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, |
1465 | 1465 | ||
1466 | {"SPKVOL L", NULL, "SPK MIXL"}, | 1466 | {"SPKVOL L", NULL, "SPK MIXL"}, |
@@ -1479,11 +1479,9 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | |||
1479 | {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"}, | 1479 | {"SPOR MIX", "SPKVOL R Switch", "SPKVOL R"}, |
1480 | {"SPOR MIX", "BST1 Switch", "BST1"}, | 1480 | {"SPOR MIX", "BST1 Switch", "BST1"}, |
1481 | 1481 | ||
1482 | {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, | ||
1483 | {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, | 1482 | {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, |
1484 | {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, | 1483 | {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, |
1485 | {"HPO MIX L", NULL, "HP L Amp"}, | 1484 | {"HPO MIX L", NULL, "HP L Amp"}, |
1486 | {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, | ||
1487 | {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, | 1485 | {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, |
1488 | {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, | 1486 | {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, |
1489 | {"HPO MIX R", NULL, "HP R Amp"}, | 1487 | {"HPO MIX R", NULL, "HP R Amp"}, |
@@ -1493,12 +1491,6 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | |||
1493 | {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, | 1491 | {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, |
1494 | {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, | 1492 | {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, |
1495 | 1493 | ||
1496 | {"Mono MIX", "DAC R2 Switch", "DAC R2"}, | ||
1497 | {"Mono MIX", "DAC L2 Switch", "DAC L2"}, | ||
1498 | {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, | ||
1499 | {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, | ||
1500 | {"Mono MIX", "BST1 Switch", "BST1"}, | ||
1501 | |||
1502 | {"HP Amp", NULL, "HPO MIX L"}, | 1494 | {"HP Amp", NULL, "HPO MIX L"}, |
1503 | {"HP Amp", NULL, "HPO MIX R"}, | 1495 | {"HP Amp", NULL, "HPO MIX R"}, |
1504 | 1496 | ||
@@ -1523,11 +1515,82 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = { | |||
1523 | {"HPOR", NULL, "HP R Playback"}, | 1515 | {"HPOR", NULL, "HP R Playback"}, |
1524 | {"LOUTL", NULL, "LOUT MIX"}, | 1516 | {"LOUTL", NULL, "LOUT MIX"}, |
1525 | {"LOUTR", NULL, "LOUT MIX"}, | 1517 | {"LOUTR", NULL, "LOUT MIX"}, |
1518 | }; | ||
1519 | |||
1520 | static const struct snd_soc_dapm_route rt5640_specific_dapm_routes[] = { | ||
1521 | {"ANC", NULL, "Stereo ADC MIXL"}, | ||
1522 | {"ANC", NULL, "Stereo ADC MIXR"}, | ||
1523 | |||
1524 | {"Audio DSP", NULL, "DAC MIXL"}, | ||
1525 | {"Audio DSP", NULL, "DAC MIXR"}, | ||
1526 | |||
1527 | {"DAC L2 Mux", "IF2", "IF2 DAC L"}, | ||
1528 | {"DAC L2 Mux", "Base L/R", "Audio DSP"}, | ||
1529 | |||
1530 | {"DAC R2 Mux", "IF2", "IF2 DAC R"}, | ||
1531 | |||
1532 | {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1533 | {"Stereo DAC MIXL", "ANC Switch", "ANC"}, | ||
1534 | {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1535 | {"Stereo DAC MIXR", "ANC Switch", "ANC"}, | ||
1536 | |||
1537 | {"Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1538 | {"Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1539 | |||
1540 | {"Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1541 | {"Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1542 | |||
1543 | {"DIG MIXR", "DAC R2 Switch", "DAC R2 Mux"}, | ||
1544 | {"DIG MIXL", "DAC L2 Switch", "DAC L2 Mux"}, | ||
1545 | |||
1546 | {"DAC L2", NULL, "Mono DAC MIXL"}, | ||
1547 | {"DAC L2", NULL, "PLL1", is_sys_clk_from_pll}, | ||
1548 | {"DAC R2", NULL, "Mono DAC MIXR"}, | ||
1549 | {"DAC R2", NULL, "PLL1", is_sys_clk_from_pll}, | ||
1550 | |||
1551 | {"SPK MIXL", "DAC L2 Switch", "DAC L2"}, | ||
1552 | {"SPK MIXR", "DAC R2 Switch", "DAC R2"}, | ||
1553 | |||
1554 | {"OUT MIXL", "SPK MIXL Switch", "SPK MIXL"}, | ||
1555 | {"OUT MIXR", "SPK MIXR Switch", "SPK MIXR"}, | ||
1556 | |||
1557 | {"OUT MIXL", "DAC R2 Switch", "DAC R2"}, | ||
1558 | {"OUT MIXL", "DAC L2 Switch", "DAC L2"}, | ||
1559 | |||
1560 | {"OUT MIXR", "DAC L2 Switch", "DAC L2"}, | ||
1561 | {"OUT MIXR", "DAC R2 Switch", "DAC R2"}, | ||
1562 | |||
1563 | {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, | ||
1564 | {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, | ||
1565 | |||
1566 | {"Mono MIX", "DAC R2 Switch", "DAC R2"}, | ||
1567 | {"Mono MIX", "DAC L2 Switch", "DAC L2"}, | ||
1568 | {"Mono MIX", "OUTVOL R Switch", "OUTVOL R"}, | ||
1569 | {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, | ||
1570 | {"Mono MIX", "BST1 Switch", "BST1"}, | ||
1571 | |||
1526 | {"MONOP", NULL, "Mono MIX"}, | 1572 | {"MONOP", NULL, "Mono MIX"}, |
1527 | {"MONON", NULL, "Mono MIX"}, | 1573 | {"MONON", NULL, "Mono MIX"}, |
1528 | {"MONOP", NULL, "Improve MONO Amp Drv"}, | 1574 | {"MONOP", NULL, "Improve MONO Amp Drv"}, |
1529 | }; | 1575 | }; |
1530 | 1576 | ||
1577 | static const struct snd_soc_dapm_route rt5639_specific_dapm_routes[] = { | ||
1578 | {"Stereo DAC MIXL", "DAC L2 Switch", "IF2 DAC L"}, | ||
1579 | {"Stereo DAC MIXR", "DAC R2 Switch", "IF2 DAC R"}, | ||
1580 | |||
1581 | {"Mono DAC MIXL", "DAC L2 Switch", "IF2 DAC L"}, | ||
1582 | {"Mono DAC MIXL", "DAC R2 Switch", "IF2 DAC R"}, | ||
1583 | |||
1584 | {"Mono DAC MIXR", "DAC R2 Switch", "IF2 DAC R"}, | ||
1585 | {"Mono DAC MIXR", "DAC L2 Switch", "IF2 DAC L"}, | ||
1586 | |||
1587 | {"DIG MIXL", "DAC L2 Switch", "IF2 DAC L"}, | ||
1588 | {"DIG MIXR", "DAC R2 Switch", "IF2 DAC R"}, | ||
1589 | |||
1590 | {"IF2 DAC L", NULL, "DAC L2 Filter"}, | ||
1591 | {"IF2 DAC R", NULL, "DAC R2 Filter"}, | ||
1592 | }; | ||
1593 | |||
1531 | static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) | 1594 | static int get_sdp_info(struct snd_soc_codec *codec, int dai_id) |
1532 | { | 1595 | { |
1533 | int ret = 0, val; | 1596 | int ret = 0, val; |
@@ -1622,16 +1685,16 @@ static int rt5640_hw_params(struct snd_pcm_substream *substream, | |||
1622 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | 1685 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", |
1623 | bclk_ms, pre_div, dai->id); | 1686 | bclk_ms, pre_div, dai->id); |
1624 | 1687 | ||
1625 | switch (params_format(params)) { | 1688 | switch (params_width(params)) { |
1626 | case SNDRV_PCM_FORMAT_S16_LE: | 1689 | case 16: |
1627 | break; | 1690 | break; |
1628 | case SNDRV_PCM_FORMAT_S20_3LE: | 1691 | case 20: |
1629 | val_len |= RT5640_I2S_DL_20; | 1692 | val_len |= RT5640_I2S_DL_20; |
1630 | break; | 1693 | break; |
1631 | case SNDRV_PCM_FORMAT_S24_LE: | 1694 | case 24: |
1632 | val_len |= RT5640_I2S_DL_24; | 1695 | val_len |= RT5640_I2S_DL_24; |
1633 | break; | 1696 | break; |
1634 | case SNDRV_PCM_FORMAT_S8: | 1697 | case 8: |
1635 | val_len |= RT5640_I2S_DL_8; | 1698 | val_len |= RT5640_I2S_DL_8; |
1636 | break; | 1699 | break; |
1637 | default: | 1700 | default: |
@@ -1744,12 +1807,6 @@ static int rt5640_set_dai_sysclk(struct snd_soc_dai *dai, | |||
1744 | case RT5640_SCLK_S_PLL1: | 1807 | case RT5640_SCLK_S_PLL1: |
1745 | reg_val |= RT5640_SCLK_SRC_PLL1; | 1808 | reg_val |= RT5640_SCLK_SRC_PLL1; |
1746 | break; | 1809 | break; |
1747 | case RT5640_SCLK_S_PLL1_TK: | ||
1748 | reg_val |= RT5640_SCLK_SRC_PLL1T; | ||
1749 | break; | ||
1750 | case RT5640_SCLK_S_RCCLK: | ||
1751 | reg_val |= RT5640_SCLK_SRC_RCCLK; | ||
1752 | break; | ||
1753 | default: | 1810 | default: |
1754 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | 1811 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); |
1755 | return -EINVAL; | 1812 | return -EINVAL; |
@@ -1890,11 +1947,9 @@ static int rt5640_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | |||
1890 | static int rt5640_set_bias_level(struct snd_soc_codec *codec, | 1947 | static int rt5640_set_bias_level(struct snd_soc_codec *codec, |
1891 | enum snd_soc_bias_level level) | 1948 | enum snd_soc_bias_level level) |
1892 | { | 1949 | { |
1893 | struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); | ||
1894 | switch (level) { | 1950 | switch (level) { |
1895 | case SND_SOC_BIAS_STANDBY: | 1951 | case SND_SOC_BIAS_STANDBY: |
1896 | if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { | 1952 | if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { |
1897 | regcache_cache_only(rt5640->regmap, false); | ||
1898 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | 1953 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, |
1899 | RT5640_PWR_VREF1 | RT5640_PWR_MB | | 1954 | RT5640_PWR_VREF1 | RT5640_PWR_MB | |
1900 | RT5640_PWR_BG | RT5640_PWR_VREF2, | 1955 | RT5640_PWR_BG | RT5640_PWR_VREF2, |
@@ -1904,7 +1959,6 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec, | |||
1904 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, | 1959 | snd_soc_update_bits(codec, RT5640_PWR_ANLG1, |
1905 | RT5640_PWR_FV1 | RT5640_PWR_FV2, | 1960 | RT5640_PWR_FV1 | RT5640_PWR_FV2, |
1906 | RT5640_PWR_FV1 | RT5640_PWR_FV2); | 1961 | RT5640_PWR_FV1 | RT5640_PWR_FV2); |
1907 | regcache_sync(rt5640->regmap); | ||
1908 | snd_soc_update_bits(codec, RT5640_DUMMY1, | 1962 | snd_soc_update_bits(codec, RT5640_DUMMY1, |
1909 | 0x0301, 0x0301); | 1963 | 0x0301, 0x0301); |
1910 | snd_soc_update_bits(codec, RT5640_MICBIAS, | 1964 | snd_soc_update_bits(codec, RT5640_MICBIAS, |
@@ -1938,13 +1992,39 @@ static int rt5640_probe(struct snd_soc_codec *codec) | |||
1938 | 1992 | ||
1939 | rt5640->codec = codec; | 1993 | rt5640->codec = codec; |
1940 | 1994 | ||
1941 | codec->dapm.idle_bias_off = 1; | ||
1942 | rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1995 | rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1943 | 1996 | ||
1944 | snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); | 1997 | snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); |
1945 | snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); | 1998 | snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); |
1946 | snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); | 1999 | snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); |
1947 | 2000 | ||
2001 | switch (snd_soc_read(codec, RT5640_RESET) & RT5640_ID_MASK) { | ||
2002 | case RT5640_ID_5640: | ||
2003 | case RT5640_ID_5642: | ||
2004 | snd_soc_add_codec_controls(codec, | ||
2005 | rt5640_specific_snd_controls, | ||
2006 | ARRAY_SIZE(rt5640_specific_snd_controls)); | ||
2007 | snd_soc_dapm_new_controls(&codec->dapm, | ||
2008 | rt5640_specific_dapm_widgets, | ||
2009 | ARRAY_SIZE(rt5640_specific_dapm_widgets)); | ||
2010 | snd_soc_dapm_add_routes(&codec->dapm, | ||
2011 | rt5640_specific_dapm_routes, | ||
2012 | ARRAY_SIZE(rt5640_specific_dapm_routes)); | ||
2013 | break; | ||
2014 | case RT5640_ID_5639: | ||
2015 | snd_soc_dapm_new_controls(&codec->dapm, | ||
2016 | rt5639_specific_dapm_widgets, | ||
2017 | ARRAY_SIZE(rt5639_specific_dapm_widgets)); | ||
2018 | snd_soc_dapm_add_routes(&codec->dapm, | ||
2019 | rt5639_specific_dapm_routes, | ||
2020 | ARRAY_SIZE(rt5639_specific_dapm_routes)); | ||
2021 | break; | ||
2022 | default: | ||
2023 | dev_err(codec->dev, | ||
2024 | "The driver is for RT5639 RT5640 or RT5642 only\n"); | ||
2025 | return -ENODEV; | ||
2026 | } | ||
2027 | |||
1948 | return 0; | 2028 | return 0; |
1949 | } | 2029 | } |
1950 | 2030 | ||
@@ -1979,6 +2059,9 @@ static int rt5640_resume(struct snd_soc_codec *codec) | |||
1979 | msleep(400); | 2059 | msleep(400); |
1980 | } | 2060 | } |
1981 | 2061 | ||
2062 | regcache_cache_only(rt5640->regmap, false); | ||
2063 | regcache_sync(rt5640->regmap); | ||
2064 | |||
1982 | return 0; | 2065 | return 0; |
1983 | } | 2066 | } |
1984 | #else | 2067 | #else |
@@ -2044,6 +2127,7 @@ static struct snd_soc_codec_driver soc_codec_dev_rt5640 = { | |||
2044 | .suspend = rt5640_suspend, | 2127 | .suspend = rt5640_suspend, |
2045 | .resume = rt5640_resume, | 2128 | .resume = rt5640_resume, |
2046 | .set_bias_level = rt5640_set_bias_level, | 2129 | .set_bias_level = rt5640_set_bias_level, |
2130 | .idle_bias_off = true, | ||
2047 | .controls = rt5640_snd_controls, | 2131 | .controls = rt5640_snd_controls, |
2048 | .num_controls = ARRAY_SIZE(rt5640_snd_controls), | 2132 | .num_controls = ARRAY_SIZE(rt5640_snd_controls), |
2049 | .dapm_widgets = rt5640_dapm_widgets, | 2133 | .dapm_widgets = rt5640_dapm_widgets, |
@@ -2070,12 +2154,15 @@ static const struct regmap_config rt5640_regmap = { | |||
2070 | 2154 | ||
2071 | static const struct i2c_device_id rt5640_i2c_id[] = { | 2155 | static const struct i2c_device_id rt5640_i2c_id[] = { |
2072 | { "rt5640", 0 }, | 2156 | { "rt5640", 0 }, |
2157 | { "rt5639", 0 }, | ||
2158 | { "rt5642", 0 }, | ||
2073 | { } | 2159 | { } |
2074 | }; | 2160 | }; |
2075 | MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); | 2161 | MODULE_DEVICE_TABLE(i2c, rt5640_i2c_id); |
2076 | 2162 | ||
2077 | #if defined(CONFIG_OF) | 2163 | #if defined(CONFIG_OF) |
2078 | static const struct of_device_id rt5640_of_match[] = { | 2164 | static const struct of_device_id rt5640_of_match[] = { |
2165 | { .compatible = "realtek,rt5639", }, | ||
2079 | { .compatible = "realtek,rt5640", }, | 2166 | { .compatible = "realtek,rt5640", }, |
2080 | {}, | 2167 | {}, |
2081 | }; | 2168 | }; |
@@ -2166,7 +2253,7 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, | |||
2166 | } | 2253 | } |
2167 | 2254 | ||
2168 | regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); | 2255 | regmap_read(rt5640->regmap, RT5640_VENDOR_ID2, &val); |
2169 | if ((val != RT5640_DEVICE_ID)) { | 2256 | if (val != RT5640_DEVICE_ID) { |
2170 | dev_err(&i2c->dev, | 2257 | dev_err(&i2c->dev, |
2171 | "Device with ID register %x is not rt5640/39\n", val); | 2258 | "Device with ID register %x is not rt5640/39\n", val); |
2172 | return -ENODEV; | 2259 | return -ENODEV; |
@@ -2187,6 +2274,25 @@ static int rt5640_i2c_probe(struct i2c_client *i2c, | |||
2187 | regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, | 2274 | regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, |
2188 | RT5640_IN_DF2, RT5640_IN_DF2); | 2275 | RT5640_IN_DF2, RT5640_IN_DF2); |
2189 | 2276 | ||
2277 | if (rt5640->pdata.dmic_en) { | ||
2278 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
2279 | RT5640_GP2_PIN_MASK, RT5640_GP2_PIN_DMIC1_SCL); | ||
2280 | |||
2281 | if (rt5640->pdata.dmic1_data_pin) { | ||
2282 | regmap_update_bits(rt5640->regmap, RT5640_DMIC, | ||
2283 | RT5640_DMIC_1_DP_MASK, RT5640_DMIC_1_DP_GPIO3); | ||
2284 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
2285 | RT5640_GP3_PIN_MASK, RT5640_GP3_PIN_DMIC1_SDA); | ||
2286 | } | ||
2287 | |||
2288 | if (rt5640->pdata.dmic2_data_pin) { | ||
2289 | regmap_update_bits(rt5640->regmap, RT5640_DMIC, | ||
2290 | RT5640_DMIC_2_DP_MASK, RT5640_DMIC_2_DP_GPIO4); | ||
2291 | regmap_update_bits(rt5640->regmap, RT5640_GPIO_CTRL1, | ||
2292 | RT5640_GP4_PIN_MASK, RT5640_GP4_PIN_DMIC2_SDA); | ||
2293 | } | ||
2294 | } | ||
2295 | |||
2190 | rt5640->hp_mute = 1; | 2296 | rt5640->hp_mute = 1; |
2191 | 2297 | ||
2192 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, | 2298 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, |
@@ -2219,6 +2325,6 @@ static struct i2c_driver rt5640_i2c_driver = { | |||
2219 | }; | 2325 | }; |
2220 | module_i2c_driver(rt5640_i2c_driver); | 2326 | module_i2c_driver(rt5640_i2c_driver); |
2221 | 2327 | ||
2222 | MODULE_DESCRIPTION("ASoC RT5640 driver"); | 2328 | MODULE_DESCRIPTION("ASoC RT5640/RT5639 driver"); |
2223 | MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>"); | 2329 | MODULE_AUTHOR("Johnny Hsu <johnnyhsu@realtek.com>"); |
2224 | MODULE_LICENSE("GPL v2"); | 2330 | MODULE_LICENSE("GPL v2"); |
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h index 5e8df25a13f3..895ca149db2e 100644 --- a/sound/soc/codecs/rt5640.h +++ b/sound/soc/codecs/rt5640.h | |||
@@ -192,6 +192,13 @@ | |||
192 | #define RT5640_R_VOL_MASK (0x3f) | 192 | #define RT5640_R_VOL_MASK (0x3f) |
193 | #define RT5640_R_VOL_SFT 0 | 193 | #define RT5640_R_VOL_SFT 0 |
194 | 194 | ||
195 | /* SW Reset & Device ID (0x00) */ | ||
196 | #define RT5640_ID_MASK (0x3 << 1) | ||
197 | #define RT5640_ID_5639 (0x0 << 1) | ||
198 | #define RT5640_ID_5640 (0x2 << 1) | ||
199 | #define RT5640_ID_5642 (0x3 << 1) | ||
200 | |||
201 | |||
195 | /* IN1 and IN2 Control (0x0d) */ | 202 | /* IN1 and IN2 Control (0x0d) */ |
196 | /* IN3 and IN4 Control (0x0e) */ | 203 | /* IN3 and IN4 Control (0x0e) */ |
197 | #define RT5640_BST_SFT1 12 | 204 | #define RT5640_BST_SFT1 12 |
@@ -976,8 +983,6 @@ | |||
976 | #define RT5640_SCLK_SRC_SFT 14 | 983 | #define RT5640_SCLK_SRC_SFT 14 |
977 | #define RT5640_SCLK_SRC_MCLK (0x0 << 14) | 984 | #define RT5640_SCLK_SRC_MCLK (0x0 << 14) |
978 | #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) | 985 | #define RT5640_SCLK_SRC_PLL1 (0x1 << 14) |
979 | #define RT5640_SCLK_SRC_PLL1T (0x2 << 14) | ||
980 | #define RT5640_SCLK_SRC_RCCLK (0x3 << 14) /* 15MHz */ | ||
981 | #define RT5640_PLL1_SRC_MASK (0x3 << 12) | 986 | #define RT5640_PLL1_SRC_MASK (0x3 << 12) |
982 | #define RT5640_PLL1_SRC_SFT 12 | 987 | #define RT5640_PLL1_SRC_SFT 12 |
983 | #define RT5640_PLL1_SRC_MCLK (0x0 << 12) | 988 | #define RT5640_PLL1_SRC_MCLK (0x0 << 12) |
@@ -2097,7 +2102,6 @@ struct rt5640_priv { | |||
2097 | int pll_in; | 2102 | int pll_in; |
2098 | int pll_out; | 2103 | int pll_out; |
2099 | 2104 | ||
2100 | int dmic_en; | ||
2101 | bool hp_mute; | 2105 | bool hp_mute; |
2102 | }; | 2106 | }; |
2103 | 2107 | ||
diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c new file mode 100644 index 000000000000..ab97d722e15d --- /dev/null +++ b/sound/soc/codecs/rt5645.c | |||
@@ -0,0 +1,2475 @@ | |||
1 | /* | ||
2 | * rt5645.c -- RT5645 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2013 Realtek Semiconductor Corp. | ||
5 | * Author: Bard Liao <bardliao@realtek.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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/spi/spi.h> | ||
20 | #include <sound/core.h> | ||
21 | #include <sound/pcm.h> | ||
22 | #include <sound/pcm_params.h> | ||
23 | #include <sound/jack.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <sound/soc-dapm.h> | ||
26 | #include <sound/initval.h> | ||
27 | #include <sound/tlv.h> | ||
28 | |||
29 | #include "rt5645.h" | ||
30 | |||
31 | #define RT5645_DEVICE_ID 0x6308 | ||
32 | |||
33 | #define RT5645_PR_RANGE_BASE (0xff + 1) | ||
34 | #define RT5645_PR_SPACING 0x100 | ||
35 | |||
36 | #define RT5645_PR_BASE (RT5645_PR_RANGE_BASE + (0 * RT5645_PR_SPACING)) | ||
37 | |||
38 | static const struct regmap_range_cfg rt5645_ranges[] = { | ||
39 | { | ||
40 | .name = "PR", | ||
41 | .range_min = RT5645_PR_BASE, | ||
42 | .range_max = RT5645_PR_BASE + 0xf8, | ||
43 | .selector_reg = RT5645_PRIV_INDEX, | ||
44 | .selector_mask = 0xff, | ||
45 | .selector_shift = 0x0, | ||
46 | .window_start = RT5645_PRIV_DATA, | ||
47 | .window_len = 0x1, | ||
48 | }, | ||
49 | }; | ||
50 | |||
51 | static const struct reg_default init_list[] = { | ||
52 | {RT5645_PR_BASE + 0x3d, 0x3600}, | ||
53 | {RT5645_PR_BASE + 0x1c, 0xfd20}, | ||
54 | {RT5645_PR_BASE + 0x20, 0x611f}, | ||
55 | {RT5645_PR_BASE + 0x21, 0x4040}, | ||
56 | {RT5645_PR_BASE + 0x23, 0x0004}, | ||
57 | }; | ||
58 | #define RT5645_INIT_REG_LEN ARRAY_SIZE(init_list) | ||
59 | |||
60 | static const struct reg_default rt5645_reg[] = { | ||
61 | { 0x00, 0x0000 }, | ||
62 | { 0x01, 0xc8c8 }, | ||
63 | { 0x02, 0xc8c8 }, | ||
64 | { 0x03, 0xc8c8 }, | ||
65 | { 0x0a, 0x0002 }, | ||
66 | { 0x0b, 0x2827 }, | ||
67 | { 0x0c, 0xe000 }, | ||
68 | { 0x0d, 0x0000 }, | ||
69 | { 0x0e, 0x0000 }, | ||
70 | { 0x0f, 0x0808 }, | ||
71 | { 0x14, 0x3333 }, | ||
72 | { 0x16, 0x4b00 }, | ||
73 | { 0x18, 0x018b }, | ||
74 | { 0x19, 0xafaf }, | ||
75 | { 0x1a, 0xafaf }, | ||
76 | { 0x1b, 0x0001 }, | ||
77 | { 0x1c, 0x2f2f }, | ||
78 | { 0x1d, 0x2f2f }, | ||
79 | { 0x1e, 0x0000 }, | ||
80 | { 0x20, 0x0000 }, | ||
81 | { 0x27, 0x7060 }, | ||
82 | { 0x28, 0x7070 }, | ||
83 | { 0x29, 0x8080 }, | ||
84 | { 0x2a, 0x5656 }, | ||
85 | { 0x2b, 0x5454 }, | ||
86 | { 0x2c, 0xaaa0 }, | ||
87 | { 0x2f, 0x1002 }, | ||
88 | { 0x31, 0x5000 }, | ||
89 | { 0x32, 0x0000 }, | ||
90 | { 0x33, 0x0000 }, | ||
91 | { 0x34, 0x0000 }, | ||
92 | { 0x35, 0x0000 }, | ||
93 | { 0x3b, 0x0000 }, | ||
94 | { 0x3c, 0x007f }, | ||
95 | { 0x3d, 0x0000 }, | ||
96 | { 0x3e, 0x007f }, | ||
97 | { 0x3f, 0x0000 }, | ||
98 | { 0x40, 0x001f }, | ||
99 | { 0x41, 0x0000 }, | ||
100 | { 0x42, 0x001f }, | ||
101 | { 0x45, 0x6000 }, | ||
102 | { 0x46, 0x003e }, | ||
103 | { 0x47, 0x003e }, | ||
104 | { 0x48, 0xf807 }, | ||
105 | { 0x4a, 0x0004 }, | ||
106 | { 0x4d, 0x0000 }, | ||
107 | { 0x4e, 0x0000 }, | ||
108 | { 0x4f, 0x01ff }, | ||
109 | { 0x50, 0x0000 }, | ||
110 | { 0x51, 0x0000 }, | ||
111 | { 0x52, 0x01ff }, | ||
112 | { 0x53, 0xf000 }, | ||
113 | { 0x56, 0x0111 }, | ||
114 | { 0x57, 0x0064 }, | ||
115 | { 0x58, 0xef0e }, | ||
116 | { 0x59, 0xf0f0 }, | ||
117 | { 0x5a, 0xef0e }, | ||
118 | { 0x5b, 0xf0f0 }, | ||
119 | { 0x5c, 0xef0e }, | ||
120 | { 0x5d, 0xf0f0 }, | ||
121 | { 0x5e, 0xf000 }, | ||
122 | { 0x5f, 0x0000 }, | ||
123 | { 0x61, 0x0300 }, | ||
124 | { 0x62, 0x0000 }, | ||
125 | { 0x63, 0x00c2 }, | ||
126 | { 0x64, 0x0000 }, | ||
127 | { 0x65, 0x0000 }, | ||
128 | { 0x66, 0x0000 }, | ||
129 | { 0x6a, 0x0000 }, | ||
130 | { 0x6c, 0x0aaa }, | ||
131 | { 0x70, 0x8000 }, | ||
132 | { 0x71, 0x8000 }, | ||
133 | { 0x72, 0x8000 }, | ||
134 | { 0x73, 0x7770 }, | ||
135 | { 0x74, 0x3e00 }, | ||
136 | { 0x75, 0x2409 }, | ||
137 | { 0x76, 0x000a }, | ||
138 | { 0x77, 0x0c00 }, | ||
139 | { 0x78, 0x0000 }, | ||
140 | { 0x80, 0x0000 }, | ||
141 | { 0x81, 0x0000 }, | ||
142 | { 0x82, 0x0000 }, | ||
143 | { 0x83, 0x0000 }, | ||
144 | { 0x84, 0x0000 }, | ||
145 | { 0x85, 0x0000 }, | ||
146 | { 0x8a, 0x0000 }, | ||
147 | { 0x8e, 0x0004 }, | ||
148 | { 0x8f, 0x1100 }, | ||
149 | { 0x90, 0x0646 }, | ||
150 | { 0x91, 0x0c06 }, | ||
151 | { 0x93, 0x0000 }, | ||
152 | { 0x94, 0x0200 }, | ||
153 | { 0x95, 0x0000 }, | ||
154 | { 0x9a, 0x2184 }, | ||
155 | { 0x9b, 0x010a }, | ||
156 | { 0x9c, 0x0aea }, | ||
157 | { 0x9d, 0x000c }, | ||
158 | { 0x9e, 0x0400 }, | ||
159 | { 0xa0, 0xa0a8 }, | ||
160 | { 0xa1, 0x0059 }, | ||
161 | { 0xa2, 0x0001 }, | ||
162 | { 0xae, 0x6000 }, | ||
163 | { 0xaf, 0x0000 }, | ||
164 | { 0xb0, 0x6000 }, | ||
165 | { 0xb1, 0x0000 }, | ||
166 | { 0xb2, 0x0000 }, | ||
167 | { 0xb3, 0x001f }, | ||
168 | { 0xb4, 0x020c }, | ||
169 | { 0xb5, 0x1f00 }, | ||
170 | { 0xb6, 0x0000 }, | ||
171 | { 0xbb, 0x0000 }, | ||
172 | { 0xbc, 0x0000 }, | ||
173 | { 0xbd, 0x0000 }, | ||
174 | { 0xbe, 0x0000 }, | ||
175 | { 0xbf, 0x3100 }, | ||
176 | { 0xc0, 0x0000 }, | ||
177 | { 0xc1, 0x0000 }, | ||
178 | { 0xc2, 0x0000 }, | ||
179 | { 0xc3, 0x2000 }, | ||
180 | { 0xcd, 0x0000 }, | ||
181 | { 0xce, 0x0000 }, | ||
182 | { 0xcf, 0x1813 }, | ||
183 | { 0xd0, 0x0690 }, | ||
184 | { 0xd1, 0x1c17 }, | ||
185 | { 0xd3, 0xb320 }, | ||
186 | { 0xd4, 0x0000 }, | ||
187 | { 0xd6, 0x0400 }, | ||
188 | { 0xd9, 0x0809 }, | ||
189 | { 0xda, 0x0000 }, | ||
190 | { 0xdb, 0x0003 }, | ||
191 | { 0xdc, 0x0049 }, | ||
192 | { 0xdd, 0x001b }, | ||
193 | { 0xe6, 0x8000 }, | ||
194 | { 0xe7, 0x0200 }, | ||
195 | { 0xec, 0xb300 }, | ||
196 | { 0xed, 0x0000 }, | ||
197 | { 0xf0, 0x001f }, | ||
198 | { 0xf1, 0x020c }, | ||
199 | { 0xf2, 0x1f00 }, | ||
200 | { 0xf3, 0x0000 }, | ||
201 | { 0xf4, 0x4000 }, | ||
202 | { 0xf8, 0x0000 }, | ||
203 | { 0xf9, 0x0000 }, | ||
204 | { 0xfa, 0x2060 }, | ||
205 | { 0xfb, 0x4040 }, | ||
206 | { 0xfc, 0x0000 }, | ||
207 | { 0xfd, 0x0002 }, | ||
208 | { 0xfe, 0x10ec }, | ||
209 | { 0xff, 0x6308 }, | ||
210 | }; | ||
211 | |||
212 | static int rt5645_reset(struct snd_soc_codec *codec) | ||
213 | { | ||
214 | return snd_soc_write(codec, RT5645_RESET, 0); | ||
215 | } | ||
216 | |||
217 | static bool rt5645_volatile_register(struct device *dev, unsigned int reg) | ||
218 | { | ||
219 | int i; | ||
220 | |||
221 | for (i = 0; i < ARRAY_SIZE(rt5645_ranges); i++) { | ||
222 | if (reg >= rt5645_ranges[i].range_min && | ||
223 | reg <= rt5645_ranges[i].range_max) { | ||
224 | return true; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | switch (reg) { | ||
229 | case RT5645_RESET: | ||
230 | case RT5645_PRIV_DATA: | ||
231 | case RT5645_IN1_CTRL1: | ||
232 | case RT5645_IN1_CTRL2: | ||
233 | case RT5645_IN1_CTRL3: | ||
234 | case RT5645_A_JD_CTRL1: | ||
235 | case RT5645_ADC_EQ_CTRL1: | ||
236 | case RT5645_EQ_CTRL1: | ||
237 | case RT5645_ALC_CTRL_1: | ||
238 | case RT5645_IRQ_CTRL2: | ||
239 | case RT5645_IRQ_CTRL3: | ||
240 | case RT5645_INT_IRQ_ST: | ||
241 | case RT5645_IL_CMD: | ||
242 | case RT5645_VENDOR_ID: | ||
243 | case RT5645_VENDOR_ID1: | ||
244 | case RT5645_VENDOR_ID2: | ||
245 | return true; | ||
246 | default: | ||
247 | return false; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | static bool rt5645_readable_register(struct device *dev, unsigned int reg) | ||
252 | { | ||
253 | int i; | ||
254 | |||
255 | for (i = 0; i < ARRAY_SIZE(rt5645_ranges); i++) { | ||
256 | if (reg >= rt5645_ranges[i].range_min && | ||
257 | reg <= rt5645_ranges[i].range_max) { | ||
258 | return true; | ||
259 | } | ||
260 | } | ||
261 | |||
262 | switch (reg) { | ||
263 | case RT5645_RESET: | ||
264 | case RT5645_SPK_VOL: | ||
265 | case RT5645_HP_VOL: | ||
266 | case RT5645_LOUT1: | ||
267 | case RT5645_IN1_CTRL1: | ||
268 | case RT5645_IN1_CTRL2: | ||
269 | case RT5645_IN1_CTRL3: | ||
270 | case RT5645_IN2_CTRL: | ||
271 | case RT5645_INL1_INR1_VOL: | ||
272 | case RT5645_SPK_FUNC_LIM: | ||
273 | case RT5645_ADJ_HPF_CTRL: | ||
274 | case RT5645_DAC1_DIG_VOL: | ||
275 | case RT5645_DAC2_DIG_VOL: | ||
276 | case RT5645_DAC_CTRL: | ||
277 | case RT5645_STO1_ADC_DIG_VOL: | ||
278 | case RT5645_MONO_ADC_DIG_VOL: | ||
279 | case RT5645_ADC_BST_VOL1: | ||
280 | case RT5645_ADC_BST_VOL2: | ||
281 | case RT5645_STO1_ADC_MIXER: | ||
282 | case RT5645_MONO_ADC_MIXER: | ||
283 | case RT5645_AD_DA_MIXER: | ||
284 | case RT5645_STO_DAC_MIXER: | ||
285 | case RT5645_MONO_DAC_MIXER: | ||
286 | case RT5645_DIG_MIXER: | ||
287 | case RT5645_DIG_INF1_DATA: | ||
288 | case RT5645_PDM_OUT_CTRL: | ||
289 | case RT5645_REC_L1_MIXER: | ||
290 | case RT5645_REC_L2_MIXER: | ||
291 | case RT5645_REC_R1_MIXER: | ||
292 | case RT5645_REC_R2_MIXER: | ||
293 | case RT5645_HPMIXL_CTRL: | ||
294 | case RT5645_HPOMIXL_CTRL: | ||
295 | case RT5645_HPMIXR_CTRL: | ||
296 | case RT5645_HPOMIXR_CTRL: | ||
297 | case RT5645_HPO_MIXER: | ||
298 | case RT5645_SPK_L_MIXER: | ||
299 | case RT5645_SPK_R_MIXER: | ||
300 | case RT5645_SPO_MIXER: | ||
301 | case RT5645_SPO_CLSD_RATIO: | ||
302 | case RT5645_OUT_L1_MIXER: | ||
303 | case RT5645_OUT_R1_MIXER: | ||
304 | case RT5645_OUT_L_GAIN1: | ||
305 | case RT5645_OUT_L_GAIN2: | ||
306 | case RT5645_OUT_R_GAIN1: | ||
307 | case RT5645_OUT_R_GAIN2: | ||
308 | case RT5645_LOUT_MIXER: | ||
309 | case RT5645_HAPTIC_CTRL1: | ||
310 | case RT5645_HAPTIC_CTRL2: | ||
311 | case RT5645_HAPTIC_CTRL3: | ||
312 | case RT5645_HAPTIC_CTRL4: | ||
313 | case RT5645_HAPTIC_CTRL5: | ||
314 | case RT5645_HAPTIC_CTRL6: | ||
315 | case RT5645_HAPTIC_CTRL7: | ||
316 | case RT5645_HAPTIC_CTRL8: | ||
317 | case RT5645_HAPTIC_CTRL9: | ||
318 | case RT5645_HAPTIC_CTRL10: | ||
319 | case RT5645_PWR_DIG1: | ||
320 | case RT5645_PWR_DIG2: | ||
321 | case RT5645_PWR_ANLG1: | ||
322 | case RT5645_PWR_ANLG2: | ||
323 | case RT5645_PWR_MIXER: | ||
324 | case RT5645_PWR_VOL: | ||
325 | case RT5645_PRIV_INDEX: | ||
326 | case RT5645_PRIV_DATA: | ||
327 | case RT5645_I2S1_SDP: | ||
328 | case RT5645_I2S2_SDP: | ||
329 | case RT5645_ADDA_CLK1: | ||
330 | case RT5645_ADDA_CLK2: | ||
331 | case RT5645_DMIC_CTRL1: | ||
332 | case RT5645_DMIC_CTRL2: | ||
333 | case RT5645_TDM_CTRL_1: | ||
334 | case RT5645_TDM_CTRL_2: | ||
335 | case RT5645_GLB_CLK: | ||
336 | case RT5645_PLL_CTRL1: | ||
337 | case RT5645_PLL_CTRL2: | ||
338 | case RT5645_ASRC_1: | ||
339 | case RT5645_ASRC_2: | ||
340 | case RT5645_ASRC_3: | ||
341 | case RT5645_ASRC_4: | ||
342 | case RT5645_DEPOP_M1: | ||
343 | case RT5645_DEPOP_M2: | ||
344 | case RT5645_DEPOP_M3: | ||
345 | case RT5645_MICBIAS: | ||
346 | case RT5645_A_JD_CTRL1: | ||
347 | case RT5645_VAD_CTRL4: | ||
348 | case RT5645_CLSD_OUT_CTRL: | ||
349 | case RT5645_ADC_EQ_CTRL1: | ||
350 | case RT5645_ADC_EQ_CTRL2: | ||
351 | case RT5645_EQ_CTRL1: | ||
352 | case RT5645_EQ_CTRL2: | ||
353 | case RT5645_ALC_CTRL_1: | ||
354 | case RT5645_ALC_CTRL_2: | ||
355 | case RT5645_ALC_CTRL_3: | ||
356 | case RT5645_ALC_CTRL_4: | ||
357 | case RT5645_ALC_CTRL_5: | ||
358 | case RT5645_JD_CTRL: | ||
359 | case RT5645_IRQ_CTRL1: | ||
360 | case RT5645_IRQ_CTRL2: | ||
361 | case RT5645_IRQ_CTRL3: | ||
362 | case RT5645_INT_IRQ_ST: | ||
363 | case RT5645_GPIO_CTRL1: | ||
364 | case RT5645_GPIO_CTRL2: | ||
365 | case RT5645_GPIO_CTRL3: | ||
366 | case RT5645_BASS_BACK: | ||
367 | case RT5645_MP3_PLUS1: | ||
368 | case RT5645_MP3_PLUS2: | ||
369 | case RT5645_ADJ_HPF1: | ||
370 | case RT5645_ADJ_HPF2: | ||
371 | case RT5645_HP_CALIB_AMP_DET: | ||
372 | case RT5645_SV_ZCD1: | ||
373 | case RT5645_SV_ZCD2: | ||
374 | case RT5645_IL_CMD: | ||
375 | case RT5645_IL_CMD2: | ||
376 | case RT5645_IL_CMD3: | ||
377 | case RT5645_DRC1_HL_CTRL1: | ||
378 | case RT5645_DRC2_HL_CTRL1: | ||
379 | case RT5645_ADC_MONO_HP_CTRL1: | ||
380 | case RT5645_ADC_MONO_HP_CTRL2: | ||
381 | case RT5645_DRC2_CTRL1: | ||
382 | case RT5645_DRC2_CTRL2: | ||
383 | case RT5645_DRC2_CTRL3: | ||
384 | case RT5645_DRC2_CTRL4: | ||
385 | case RT5645_DRC2_CTRL5: | ||
386 | case RT5645_JD_CTRL3: | ||
387 | case RT5645_JD_CTRL4: | ||
388 | case RT5645_GEN_CTRL1: | ||
389 | case RT5645_GEN_CTRL2: | ||
390 | case RT5645_GEN_CTRL3: | ||
391 | case RT5645_VENDOR_ID: | ||
392 | case RT5645_VENDOR_ID1: | ||
393 | case RT5645_VENDOR_ID2: | ||
394 | return true; | ||
395 | default: | ||
396 | return false; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); | ||
401 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); | ||
402 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | ||
403 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | ||
404 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | ||
405 | |||
406 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | ||
407 | static unsigned int bst_tlv[] = { | ||
408 | TLV_DB_RANGE_HEAD(7), | ||
409 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
410 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | ||
411 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | ||
412 | 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), | ||
413 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | ||
414 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | ||
415 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), | ||
416 | }; | ||
417 | |||
418 | static const char * const rt5645_tdm_data_swap_select[] = { | ||
419 | "L/R", "R/L", "L/L", "R/R" | ||
420 | }; | ||
421 | |||
422 | static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot0_1_enum, | ||
423 | RT5645_TDM_CTRL_1, 6, rt5645_tdm_data_swap_select); | ||
424 | |||
425 | static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot2_3_enum, | ||
426 | RT5645_TDM_CTRL_1, 4, rt5645_tdm_data_swap_select); | ||
427 | |||
428 | static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot4_5_enum, | ||
429 | RT5645_TDM_CTRL_1, 2, rt5645_tdm_data_swap_select); | ||
430 | |||
431 | static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_slot6_7_enum, | ||
432 | RT5645_TDM_CTRL_1, 0, rt5645_tdm_data_swap_select); | ||
433 | |||
434 | static const char * const rt5645_tdm_adc_data_select[] = { | ||
435 | "1/2/R", "2/1/R", "R/1/2", "R/2/1" | ||
436 | }; | ||
437 | |||
438 | static SOC_ENUM_SINGLE_DECL(rt5645_tdm_adc_sel_enum, | ||
439 | RT5645_TDM_CTRL_1, 8, | ||
440 | rt5645_tdm_adc_data_select); | ||
441 | |||
442 | static const struct snd_kcontrol_new rt5645_snd_controls[] = { | ||
443 | /* Speaker Output Volume */ | ||
444 | SOC_DOUBLE("Speaker Channel Switch", RT5645_SPK_VOL, | ||
445 | RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), | ||
446 | SOC_DOUBLE_TLV("Speaker Playback Volume", RT5645_SPK_VOL, | ||
447 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), | ||
448 | |||
449 | /* Headphone Output Volume */ | ||
450 | SOC_DOUBLE("HP Channel Switch", RT5645_HP_VOL, | ||
451 | RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), | ||
452 | SOC_DOUBLE_TLV("HP Playback Volume", RT5645_HP_VOL, | ||
453 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), | ||
454 | |||
455 | /* OUTPUT Control */ | ||
456 | SOC_DOUBLE("OUT Playback Switch", RT5645_LOUT1, | ||
457 | RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1), | ||
458 | SOC_DOUBLE("OUT Channel Switch", RT5645_LOUT1, | ||
459 | RT5645_VOL_L_SFT, RT5645_VOL_R_SFT, 1, 1), | ||
460 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5645_LOUT1, | ||
461 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 39, 1, out_vol_tlv), | ||
462 | |||
463 | /* DAC Digital Volume */ | ||
464 | SOC_DOUBLE("DAC2 Playback Switch", RT5645_DAC_CTRL, | ||
465 | RT5645_M_DAC_L2_VOL_SFT, RT5645_M_DAC_R2_VOL_SFT, 1, 1), | ||
466 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5645_DAC1_DIG_VOL, | ||
467 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 175, 0, dac_vol_tlv), | ||
468 | SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5645_DAC2_DIG_VOL, | ||
469 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 175, 0, dac_vol_tlv), | ||
470 | |||
471 | /* IN1/IN2 Control */ | ||
472 | SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1, | ||
473 | RT5645_BST_SFT1, 8, 0, bst_tlv), | ||
474 | SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL, | ||
475 | RT5645_BST_SFT2, 8, 0, bst_tlv), | ||
476 | |||
477 | /* INL/INR Volume Control */ | ||
478 | SOC_DOUBLE_TLV("IN Capture Volume", RT5645_INL1_INR1_VOL, | ||
479 | RT5645_INL_VOL_SFT, RT5645_INR_VOL_SFT, 31, 1, in_vol_tlv), | ||
480 | |||
481 | /* ADC Digital Volume Control */ | ||
482 | SOC_DOUBLE("ADC Capture Switch", RT5645_STO1_ADC_DIG_VOL, | ||
483 | RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1), | ||
484 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5645_STO1_ADC_DIG_VOL, | ||
485 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 127, 0, adc_vol_tlv), | ||
486 | SOC_DOUBLE("Mono ADC Capture Switch", RT5645_MONO_ADC_DIG_VOL, | ||
487 | RT5645_L_MUTE_SFT, RT5645_R_MUTE_SFT, 1, 1), | ||
488 | SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5645_MONO_ADC_DIG_VOL, | ||
489 | RT5645_L_VOL_SFT, RT5645_R_VOL_SFT, 127, 0, adc_vol_tlv), | ||
490 | |||
491 | /* ADC Boost Volume Control */ | ||
492 | SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5645_ADC_BST_VOL1, | ||
493 | RT5645_STO1_ADC_L_BST_SFT, RT5645_STO1_ADC_R_BST_SFT, 3, 0, | ||
494 | adc_bst_tlv), | ||
495 | SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5645_ADC_BST_VOL1, | ||
496 | RT5645_STO2_ADC_L_BST_SFT, RT5645_STO2_ADC_R_BST_SFT, 3, 0, | ||
497 | adc_bst_tlv), | ||
498 | |||
499 | /* I2S2 function select */ | ||
500 | SOC_SINGLE("I2S2 Func Switch", RT5645_GPIO_CTRL1, RT5645_I2S2_SEL_SFT, | ||
501 | 1, 1), | ||
502 | |||
503 | /* TDM */ | ||
504 | SOC_ENUM("TDM Adc Slot0 1 Data", rt5645_tdm_adc_slot0_1_enum), | ||
505 | SOC_ENUM("TDM Adc Slot2 3 Data", rt5645_tdm_adc_slot2_3_enum), | ||
506 | SOC_ENUM("TDM Adc Slot4 5 Data", rt5645_tdm_adc_slot4_5_enum), | ||
507 | SOC_ENUM("TDM Adc Slot6 7 Data", rt5645_tdm_adc_slot6_7_enum), | ||
508 | SOC_ENUM("TDM IF1 ADC DATA Sel", rt5645_tdm_adc_sel_enum), | ||
509 | SOC_SINGLE("TDM IF1_DAC1_L Sel", RT5645_TDM_CTRL_3, 12, 7, 0), | ||
510 | SOC_SINGLE("TDM IF1_DAC1_R Sel", RT5645_TDM_CTRL_3, 8, 7, 0), | ||
511 | SOC_SINGLE("TDM IF1_DAC2_L Sel", RT5645_TDM_CTRL_3, 4, 7, 0), | ||
512 | SOC_SINGLE("TDM IF1_DAC2_R Sel", RT5645_TDM_CTRL_3, 0, 7, 0), | ||
513 | }; | ||
514 | |||
515 | /** | ||
516 | * set_dmic_clk - Set parameter of dmic. | ||
517 | * | ||
518 | * @w: DAPM widget. | ||
519 | * @kcontrol: The kcontrol of this widget. | ||
520 | * @event: Event id. | ||
521 | * | ||
522 | * Choose dmic clock between 1MHz and 3MHz. | ||
523 | * It is better for clock to approximate 3MHz. | ||
524 | */ | ||
525 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | ||
526 | struct snd_kcontrol *kcontrol, int event) | ||
527 | { | ||
528 | struct snd_soc_codec *codec = w->codec; | ||
529 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
530 | int div[] = {2, 3, 4, 6, 8, 12}; | ||
531 | int idx = -EINVAL, i; | ||
532 | int rate, red, bound, temp; | ||
533 | |||
534 | rate = rt5645->sysclk; | ||
535 | red = 3000000 * 12; | ||
536 | for (i = 0; i < ARRAY_SIZE(div); i++) { | ||
537 | bound = div[i] * 3000000; | ||
538 | if (rate > bound) | ||
539 | continue; | ||
540 | temp = bound - rate; | ||
541 | if (temp < red) { | ||
542 | red = temp; | ||
543 | idx = i; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | if (idx < 0) | ||
548 | dev_err(codec->dev, "Failed to set DMIC clock\n"); | ||
549 | else | ||
550 | snd_soc_update_bits(codec, RT5645_DMIC_CTRL1, | ||
551 | RT5645_DMIC_CLK_MASK, idx << RT5645_DMIC_CLK_SFT); | ||
552 | return idx; | ||
553 | } | ||
554 | |||
555 | static int is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, | ||
556 | struct snd_soc_dapm_widget *sink) | ||
557 | { | ||
558 | unsigned int val; | ||
559 | |||
560 | val = snd_soc_read(source->codec, RT5645_GLB_CLK); | ||
561 | val &= RT5645_SCLK_SRC_MASK; | ||
562 | if (val == RT5645_SCLK_SRC_PLL1) | ||
563 | return 1; | ||
564 | else | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | /* Digital Mixer */ | ||
569 | static const struct snd_kcontrol_new rt5645_sto1_adc_l_mix[] = { | ||
570 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, | ||
571 | RT5645_M_ADC_L1_SFT, 1, 1), | ||
572 | SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER, | ||
573 | RT5645_M_ADC_L2_SFT, 1, 1), | ||
574 | }; | ||
575 | |||
576 | static const struct snd_kcontrol_new rt5645_sto1_adc_r_mix[] = { | ||
577 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_STO1_ADC_MIXER, | ||
578 | RT5645_M_ADC_R1_SFT, 1, 1), | ||
579 | SOC_DAPM_SINGLE("ADC2 Switch", RT5645_STO1_ADC_MIXER, | ||
580 | RT5645_M_ADC_R2_SFT, 1, 1), | ||
581 | }; | ||
582 | |||
583 | static const struct snd_kcontrol_new rt5645_mono_adc_l_mix[] = { | ||
584 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_MONO_ADC_MIXER, | ||
585 | RT5645_M_MONO_ADC_L1_SFT, 1, 1), | ||
586 | SOC_DAPM_SINGLE("ADC2 Switch", RT5645_MONO_ADC_MIXER, | ||
587 | RT5645_M_MONO_ADC_L2_SFT, 1, 1), | ||
588 | }; | ||
589 | |||
590 | static const struct snd_kcontrol_new rt5645_mono_adc_r_mix[] = { | ||
591 | SOC_DAPM_SINGLE("ADC1 Switch", RT5645_MONO_ADC_MIXER, | ||
592 | RT5645_M_MONO_ADC_R1_SFT, 1, 1), | ||
593 | SOC_DAPM_SINGLE("ADC2 Switch", RT5645_MONO_ADC_MIXER, | ||
594 | RT5645_M_MONO_ADC_R2_SFT, 1, 1), | ||
595 | }; | ||
596 | |||
597 | static const struct snd_kcontrol_new rt5645_dac_l_mix[] = { | ||
598 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER, | ||
599 | RT5645_M_ADCMIX_L_SFT, 1, 1), | ||
600 | SOC_DAPM_SINGLE("DAC1 Switch", RT5645_AD_DA_MIXER, | ||
601 | RT5645_M_DAC1_L_SFT, 1, 1), | ||
602 | }; | ||
603 | |||
604 | static const struct snd_kcontrol_new rt5645_dac_r_mix[] = { | ||
605 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5645_AD_DA_MIXER, | ||
606 | RT5645_M_ADCMIX_R_SFT, 1, 1), | ||
607 | SOC_DAPM_SINGLE("DAC1 Switch", RT5645_AD_DA_MIXER, | ||
608 | RT5645_M_DAC1_R_SFT, 1, 1), | ||
609 | }; | ||
610 | |||
611 | static const struct snd_kcontrol_new rt5645_sto_dac_l_mix[] = { | ||
612 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_STO_DAC_MIXER, | ||
613 | RT5645_M_DAC_L1_SFT, 1, 1), | ||
614 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_STO_DAC_MIXER, | ||
615 | RT5645_M_DAC_L2_SFT, 1, 1), | ||
616 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_STO_DAC_MIXER, | ||
617 | RT5645_M_DAC_R1_STO_L_SFT, 1, 1), | ||
618 | }; | ||
619 | |||
620 | static const struct snd_kcontrol_new rt5645_sto_dac_r_mix[] = { | ||
621 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_STO_DAC_MIXER, | ||
622 | RT5645_M_DAC_R1_SFT, 1, 1), | ||
623 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_STO_DAC_MIXER, | ||
624 | RT5645_M_DAC_R2_SFT, 1, 1), | ||
625 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_STO_DAC_MIXER, | ||
626 | RT5645_M_DAC_L1_STO_R_SFT, 1, 1), | ||
627 | }; | ||
628 | |||
629 | static const struct snd_kcontrol_new rt5645_mono_dac_l_mix[] = { | ||
630 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_MONO_DAC_MIXER, | ||
631 | RT5645_M_DAC_L1_MONO_L_SFT, 1, 1), | ||
632 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_MONO_DAC_MIXER, | ||
633 | RT5645_M_DAC_L2_MONO_L_SFT, 1, 1), | ||
634 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_MONO_DAC_MIXER, | ||
635 | RT5645_M_DAC_R2_MONO_L_SFT, 1, 1), | ||
636 | }; | ||
637 | |||
638 | static const struct snd_kcontrol_new rt5645_mono_dac_r_mix[] = { | ||
639 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_MONO_DAC_MIXER, | ||
640 | RT5645_M_DAC_R1_MONO_R_SFT, 1, 1), | ||
641 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_MONO_DAC_MIXER, | ||
642 | RT5645_M_DAC_R2_MONO_R_SFT, 1, 1), | ||
643 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_MONO_DAC_MIXER, | ||
644 | RT5645_M_DAC_L2_MONO_R_SFT, 1, 1), | ||
645 | }; | ||
646 | |||
647 | static const struct snd_kcontrol_new rt5645_dig_l_mix[] = { | ||
648 | SOC_DAPM_SINGLE("Sto DAC Mix L Switch", RT5645_DIG_MIXER, | ||
649 | RT5645_M_STO_L_DAC_L_SFT, 1, 1), | ||
650 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_DIG_MIXER, | ||
651 | RT5645_M_DAC_L2_DAC_L_SFT, 1, 1), | ||
652 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_DIG_MIXER, | ||
653 | RT5645_M_DAC_R2_DAC_L_SFT, 1, 1), | ||
654 | }; | ||
655 | |||
656 | static const struct snd_kcontrol_new rt5645_dig_r_mix[] = { | ||
657 | SOC_DAPM_SINGLE("Sto DAC Mix R Switch", RT5645_DIG_MIXER, | ||
658 | RT5645_M_STO_R_DAC_R_SFT, 1, 1), | ||
659 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_DIG_MIXER, | ||
660 | RT5645_M_DAC_R2_DAC_R_SFT, 1, 1), | ||
661 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_DIG_MIXER, | ||
662 | RT5645_M_DAC_L2_DAC_R_SFT, 1, 1), | ||
663 | }; | ||
664 | |||
665 | /* Analog Input Mixer */ | ||
666 | static const struct snd_kcontrol_new rt5645_rec_l_mix[] = { | ||
667 | SOC_DAPM_SINGLE("HPOL Switch", RT5645_REC_L2_MIXER, | ||
668 | RT5645_M_HP_L_RM_L_SFT, 1, 1), | ||
669 | SOC_DAPM_SINGLE("INL Switch", RT5645_REC_L2_MIXER, | ||
670 | RT5645_M_IN_L_RM_L_SFT, 1, 1), | ||
671 | SOC_DAPM_SINGLE("BST2 Switch", RT5645_REC_L2_MIXER, | ||
672 | RT5645_M_BST2_RM_L_SFT, 1, 1), | ||
673 | SOC_DAPM_SINGLE("BST1 Switch", RT5645_REC_L2_MIXER, | ||
674 | RT5645_M_BST1_RM_L_SFT, 1, 1), | ||
675 | SOC_DAPM_SINGLE("OUT MIXL Switch", RT5645_REC_L2_MIXER, | ||
676 | RT5645_M_OM_L_RM_L_SFT, 1, 1), | ||
677 | }; | ||
678 | |||
679 | static const struct snd_kcontrol_new rt5645_rec_r_mix[] = { | ||
680 | SOC_DAPM_SINGLE("HPOR Switch", RT5645_REC_R2_MIXER, | ||
681 | RT5645_M_HP_R_RM_R_SFT, 1, 1), | ||
682 | SOC_DAPM_SINGLE("INR Switch", RT5645_REC_R2_MIXER, | ||
683 | RT5645_M_IN_R_RM_R_SFT, 1, 1), | ||
684 | SOC_DAPM_SINGLE("BST2 Switch", RT5645_REC_R2_MIXER, | ||
685 | RT5645_M_BST2_RM_R_SFT, 1, 1), | ||
686 | SOC_DAPM_SINGLE("BST1 Switch", RT5645_REC_R2_MIXER, | ||
687 | RT5645_M_BST1_RM_R_SFT, 1, 1), | ||
688 | SOC_DAPM_SINGLE("OUT MIXR Switch", RT5645_REC_R2_MIXER, | ||
689 | RT5645_M_OM_R_RM_R_SFT, 1, 1), | ||
690 | }; | ||
691 | |||
692 | static const struct snd_kcontrol_new rt5645_spk_l_mix[] = { | ||
693 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_SPK_L_MIXER, | ||
694 | RT5645_M_DAC_L1_SM_L_SFT, 1, 1), | ||
695 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_SPK_L_MIXER, | ||
696 | RT5645_M_DAC_L2_SM_L_SFT, 1, 1), | ||
697 | SOC_DAPM_SINGLE("INL Switch", RT5645_SPK_L_MIXER, | ||
698 | RT5645_M_IN_L_SM_L_SFT, 1, 1), | ||
699 | SOC_DAPM_SINGLE("BST1 Switch", RT5645_SPK_L_MIXER, | ||
700 | RT5645_M_BST1_L_SM_L_SFT, 1, 1), | ||
701 | }; | ||
702 | |||
703 | static const struct snd_kcontrol_new rt5645_spk_r_mix[] = { | ||
704 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_SPK_R_MIXER, | ||
705 | RT5645_M_DAC_R1_SM_R_SFT, 1, 1), | ||
706 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_SPK_R_MIXER, | ||
707 | RT5645_M_DAC_R2_SM_R_SFT, 1, 1), | ||
708 | SOC_DAPM_SINGLE("INR Switch", RT5645_SPK_R_MIXER, | ||
709 | RT5645_M_IN_R_SM_R_SFT, 1, 1), | ||
710 | SOC_DAPM_SINGLE("BST2 Switch", RT5645_SPK_R_MIXER, | ||
711 | RT5645_M_BST2_R_SM_R_SFT, 1, 1), | ||
712 | }; | ||
713 | |||
714 | static const struct snd_kcontrol_new rt5645_out_l_mix[] = { | ||
715 | SOC_DAPM_SINGLE("BST1 Switch", RT5645_OUT_L1_MIXER, | ||
716 | RT5645_M_BST1_OM_L_SFT, 1, 1), | ||
717 | SOC_DAPM_SINGLE("INL Switch", RT5645_OUT_L1_MIXER, | ||
718 | RT5645_M_IN_L_OM_L_SFT, 1, 1), | ||
719 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5645_OUT_L1_MIXER, | ||
720 | RT5645_M_DAC_L2_OM_L_SFT, 1, 1), | ||
721 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_OUT_L1_MIXER, | ||
722 | RT5645_M_DAC_L1_OM_L_SFT, 1, 1), | ||
723 | }; | ||
724 | |||
725 | static const struct snd_kcontrol_new rt5645_out_r_mix[] = { | ||
726 | SOC_DAPM_SINGLE("BST2 Switch", RT5645_OUT_R1_MIXER, | ||
727 | RT5645_M_BST2_OM_R_SFT, 1, 1), | ||
728 | SOC_DAPM_SINGLE("INR Switch", RT5645_OUT_R1_MIXER, | ||
729 | RT5645_M_IN_R_OM_R_SFT, 1, 1), | ||
730 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5645_OUT_R1_MIXER, | ||
731 | RT5645_M_DAC_R2_OM_R_SFT, 1, 1), | ||
732 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_OUT_R1_MIXER, | ||
733 | RT5645_M_DAC_R1_OM_R_SFT, 1, 1), | ||
734 | }; | ||
735 | |||
736 | static const struct snd_kcontrol_new rt5645_spo_l_mix[] = { | ||
737 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_SPO_MIXER, | ||
738 | RT5645_M_DAC_R1_SPM_L_SFT, 1, 1), | ||
739 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_SPO_MIXER, | ||
740 | RT5645_M_DAC_L1_SPM_L_SFT, 1, 1), | ||
741 | SOC_DAPM_SINGLE("SPKVOL R Switch", RT5645_SPO_MIXER, | ||
742 | RT5645_M_SV_R_SPM_L_SFT, 1, 1), | ||
743 | SOC_DAPM_SINGLE("SPKVOL L Switch", RT5645_SPO_MIXER, | ||
744 | RT5645_M_SV_L_SPM_L_SFT, 1, 1), | ||
745 | }; | ||
746 | |||
747 | static const struct snd_kcontrol_new rt5645_spo_r_mix[] = { | ||
748 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_SPO_MIXER, | ||
749 | RT5645_M_DAC_R1_SPM_R_SFT, 1, 1), | ||
750 | SOC_DAPM_SINGLE("SPKVOL R Switch", RT5645_SPO_MIXER, | ||
751 | RT5645_M_SV_R_SPM_R_SFT, 1, 1), | ||
752 | }; | ||
753 | |||
754 | static const struct snd_kcontrol_new rt5645_hpo_mix[] = { | ||
755 | SOC_DAPM_SINGLE("DAC1 Switch", RT5645_HPO_MIXER, | ||
756 | RT5645_M_DAC1_HM_SFT, 1, 1), | ||
757 | SOC_DAPM_SINGLE("HPVOL Switch", RT5645_HPO_MIXER, | ||
758 | RT5645_M_HPVOL_HM_SFT, 1, 1), | ||
759 | }; | ||
760 | |||
761 | static const struct snd_kcontrol_new rt5645_hpvoll_mix[] = { | ||
762 | SOC_DAPM_SINGLE("DAC1 Switch", RT5645_HPOMIXL_CTRL, | ||
763 | RT5645_M_DAC1_HV_SFT, 1, 1), | ||
764 | SOC_DAPM_SINGLE("DAC2 Switch", RT5645_HPOMIXL_CTRL, | ||
765 | RT5645_M_DAC2_HV_SFT, 1, 1), | ||
766 | SOC_DAPM_SINGLE("INL Switch", RT5645_HPOMIXL_CTRL, | ||
767 | RT5645_M_IN_HV_SFT, 1, 1), | ||
768 | SOC_DAPM_SINGLE("BST1 Switch", RT5645_HPOMIXL_CTRL, | ||
769 | RT5645_M_BST1_HV_SFT, 1, 1), | ||
770 | }; | ||
771 | |||
772 | static const struct snd_kcontrol_new rt5645_hpvolr_mix[] = { | ||
773 | SOC_DAPM_SINGLE("DAC1 Switch", RT5645_HPOMIXR_CTRL, | ||
774 | RT5645_M_DAC1_HV_SFT, 1, 1), | ||
775 | SOC_DAPM_SINGLE("DAC2 Switch", RT5645_HPOMIXR_CTRL, | ||
776 | RT5645_M_DAC2_HV_SFT, 1, 1), | ||
777 | SOC_DAPM_SINGLE("INR Switch", RT5645_HPOMIXR_CTRL, | ||
778 | RT5645_M_IN_HV_SFT, 1, 1), | ||
779 | SOC_DAPM_SINGLE("BST2 Switch", RT5645_HPOMIXR_CTRL, | ||
780 | RT5645_M_BST2_HV_SFT, 1, 1), | ||
781 | }; | ||
782 | |||
783 | static const struct snd_kcontrol_new rt5645_lout_mix[] = { | ||
784 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5645_LOUT_MIXER, | ||
785 | RT5645_M_DAC_L1_LM_SFT, 1, 1), | ||
786 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5645_LOUT_MIXER, | ||
787 | RT5645_M_DAC_R1_LM_SFT, 1, 1), | ||
788 | SOC_DAPM_SINGLE("OUTMIX L Switch", RT5645_LOUT_MIXER, | ||
789 | RT5645_M_OV_L_LM_SFT, 1, 1), | ||
790 | SOC_DAPM_SINGLE("OUTMIX R Switch", RT5645_LOUT_MIXER, | ||
791 | RT5645_M_OV_R_LM_SFT, 1, 1), | ||
792 | }; | ||
793 | |||
794 | /*DAC1 L/R source*/ /* MX-29 [9:8] [11:10] */ | ||
795 | static const char * const rt5645_dac1_src[] = { | ||
796 | "IF1 DAC", "IF2 DAC", "IF3 DAC" | ||
797 | }; | ||
798 | |||
799 | static SOC_ENUM_SINGLE_DECL( | ||
800 | rt5645_dac1l_enum, RT5645_AD_DA_MIXER, | ||
801 | RT5645_DAC1_L_SEL_SFT, rt5645_dac1_src); | ||
802 | |||
803 | static const struct snd_kcontrol_new rt5645_dac1l_mux = | ||
804 | SOC_DAPM_ENUM("DAC1 L source", rt5645_dac1l_enum); | ||
805 | |||
806 | static SOC_ENUM_SINGLE_DECL( | ||
807 | rt5645_dac1r_enum, RT5645_AD_DA_MIXER, | ||
808 | RT5645_DAC1_R_SEL_SFT, rt5645_dac1_src); | ||
809 | |||
810 | static const struct snd_kcontrol_new rt5645_dac1r_mux = | ||
811 | SOC_DAPM_ENUM("DAC1 R source", rt5645_dac1r_enum); | ||
812 | |||
813 | /*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */ | ||
814 | static const char * const rt5645_dac12_src[] = { | ||
815 | "IF1 DAC", "IF2 DAC", "IF3 DAC", "Mono ADC", "VAD_ADC" | ||
816 | }; | ||
817 | |||
818 | static SOC_ENUM_SINGLE_DECL( | ||
819 | rt5645_dac2l_enum, RT5645_DAC_CTRL, | ||
820 | RT5645_DAC2_L_SEL_SFT, rt5645_dac12_src); | ||
821 | |||
822 | static const struct snd_kcontrol_new rt5645_dac_l2_mux = | ||
823 | SOC_DAPM_ENUM("DAC2 L source", rt5645_dac2l_enum); | ||
824 | |||
825 | static const char * const rt5645_dacr2_src[] = { | ||
826 | "IF1 DAC", "IF2 DAC", "IF3 DAC", "Mono ADC", "Haptic" | ||
827 | }; | ||
828 | |||
829 | static SOC_ENUM_SINGLE_DECL( | ||
830 | rt5645_dac2r_enum, RT5645_DAC_CTRL, | ||
831 | RT5645_DAC2_R_SEL_SFT, rt5645_dacr2_src); | ||
832 | |||
833 | static const struct snd_kcontrol_new rt5645_dac_r2_mux = | ||
834 | SOC_DAPM_ENUM("DAC2 R source", rt5645_dac2r_enum); | ||
835 | |||
836 | |||
837 | /* INL/R source */ | ||
838 | static const char * const rt5645_inl_src[] = { | ||
839 | "IN2P", "MonoP" | ||
840 | }; | ||
841 | |||
842 | static SOC_ENUM_SINGLE_DECL( | ||
843 | rt5645_inl_enum, RT5645_INL1_INR1_VOL, | ||
844 | RT5645_INL_SEL_SFT, rt5645_inl_src); | ||
845 | |||
846 | static const struct snd_kcontrol_new rt5645_inl_mux = | ||
847 | SOC_DAPM_ENUM("INL source", rt5645_inl_enum); | ||
848 | |||
849 | static const char * const rt5645_inr_src[] = { | ||
850 | "IN2N", "MonoN" | ||
851 | }; | ||
852 | |||
853 | static SOC_ENUM_SINGLE_DECL( | ||
854 | rt5645_inr_enum, RT5645_INL1_INR1_VOL, | ||
855 | RT5645_INR_SEL_SFT, rt5645_inr_src); | ||
856 | |||
857 | static const struct snd_kcontrol_new rt5645_inr_mux = | ||
858 | SOC_DAPM_ENUM("INR source", rt5645_inr_enum); | ||
859 | |||
860 | /* Stereo1 ADC source */ | ||
861 | /* MX-27 [12] */ | ||
862 | static const char * const rt5645_stereo_adc1_src[] = { | ||
863 | "DAC MIX", "ADC" | ||
864 | }; | ||
865 | |||
866 | static SOC_ENUM_SINGLE_DECL( | ||
867 | rt5645_stereo1_adc1_enum, RT5645_STO1_ADC_MIXER, | ||
868 | RT5645_ADC_1_SRC_SFT, rt5645_stereo_adc1_src); | ||
869 | |||
870 | static const struct snd_kcontrol_new rt5645_sto_adc1_mux = | ||
871 | SOC_DAPM_ENUM("Stereo1 ADC1 Mux", rt5645_stereo1_adc1_enum); | ||
872 | |||
873 | /* MX-27 [11] */ | ||
874 | static const char * const rt5645_stereo_adc2_src[] = { | ||
875 | "DAC MIX", "DMIC" | ||
876 | }; | ||
877 | |||
878 | static SOC_ENUM_SINGLE_DECL( | ||
879 | rt5645_stereo1_adc2_enum, RT5645_STO1_ADC_MIXER, | ||
880 | RT5645_ADC_2_SRC_SFT, rt5645_stereo_adc2_src); | ||
881 | |||
882 | static const struct snd_kcontrol_new rt5645_sto_adc2_mux = | ||
883 | SOC_DAPM_ENUM("Stereo1 ADC2 Mux", rt5645_stereo1_adc2_enum); | ||
884 | |||
885 | /* MX-27 [8] */ | ||
886 | static const char * const rt5645_stereo_dmic_src[] = { | ||
887 | "DMIC1", "DMIC2" | ||
888 | }; | ||
889 | |||
890 | static SOC_ENUM_SINGLE_DECL( | ||
891 | rt5645_stereo1_dmic_enum, RT5645_STO1_ADC_MIXER, | ||
892 | RT5645_DMIC_SRC_SFT, rt5645_stereo_dmic_src); | ||
893 | |||
894 | static const struct snd_kcontrol_new rt5645_sto1_dmic_mux = | ||
895 | SOC_DAPM_ENUM("Stereo1 DMIC source", rt5645_stereo1_dmic_enum); | ||
896 | |||
897 | /* Mono ADC source */ | ||
898 | /* MX-28 [12] */ | ||
899 | static const char * const rt5645_mono_adc_l1_src[] = { | ||
900 | "Mono DAC MIXL", "ADC" | ||
901 | }; | ||
902 | |||
903 | static SOC_ENUM_SINGLE_DECL( | ||
904 | rt5645_mono_adc_l1_enum, RT5645_MONO_ADC_MIXER, | ||
905 | RT5645_MONO_ADC_L1_SRC_SFT, rt5645_mono_adc_l1_src); | ||
906 | |||
907 | static const struct snd_kcontrol_new rt5645_mono_adc_l1_mux = | ||
908 | SOC_DAPM_ENUM("Mono ADC1 left source", rt5645_mono_adc_l1_enum); | ||
909 | /* MX-28 [11] */ | ||
910 | static const char * const rt5645_mono_adc_l2_src[] = { | ||
911 | "Mono DAC MIXL", "DMIC" | ||
912 | }; | ||
913 | |||
914 | static SOC_ENUM_SINGLE_DECL( | ||
915 | rt5645_mono_adc_l2_enum, RT5645_MONO_ADC_MIXER, | ||
916 | RT5645_MONO_ADC_L2_SRC_SFT, rt5645_mono_adc_l2_src); | ||
917 | |||
918 | static const struct snd_kcontrol_new rt5645_mono_adc_l2_mux = | ||
919 | SOC_DAPM_ENUM("Mono ADC2 left source", rt5645_mono_adc_l2_enum); | ||
920 | |||
921 | /* MX-28 [8] */ | ||
922 | static const char * const rt5645_mono_dmic_src[] = { | ||
923 | "DMIC1", "DMIC2" | ||
924 | }; | ||
925 | |||
926 | static SOC_ENUM_SINGLE_DECL( | ||
927 | rt5645_mono_dmic_l_enum, RT5645_MONO_ADC_MIXER, | ||
928 | RT5645_MONO_DMIC_L_SRC_SFT, rt5645_mono_dmic_src); | ||
929 | |||
930 | static const struct snd_kcontrol_new rt5645_mono_dmic_l_mux = | ||
931 | SOC_DAPM_ENUM("Mono DMIC left source", rt5645_mono_dmic_l_enum); | ||
932 | /* MX-28 [1:0] */ | ||
933 | static SOC_ENUM_SINGLE_DECL( | ||
934 | rt5645_mono_dmic_r_enum, RT5645_MONO_ADC_MIXER, | ||
935 | RT5645_MONO_DMIC_R_SRC_SFT, rt5645_mono_dmic_src); | ||
936 | |||
937 | static const struct snd_kcontrol_new rt5645_mono_dmic_r_mux = | ||
938 | SOC_DAPM_ENUM("Mono DMIC Right source", rt5645_mono_dmic_r_enum); | ||
939 | /* MX-28 [4] */ | ||
940 | static const char * const rt5645_mono_adc_r1_src[] = { | ||
941 | "Mono DAC MIXR", "ADC" | ||
942 | }; | ||
943 | |||
944 | static SOC_ENUM_SINGLE_DECL( | ||
945 | rt5645_mono_adc_r1_enum, RT5645_MONO_ADC_MIXER, | ||
946 | RT5645_MONO_ADC_R1_SRC_SFT, rt5645_mono_adc_r1_src); | ||
947 | |||
948 | static const struct snd_kcontrol_new rt5645_mono_adc_r1_mux = | ||
949 | SOC_DAPM_ENUM("Mono ADC1 right source", rt5645_mono_adc_r1_enum); | ||
950 | /* MX-28 [3] */ | ||
951 | static const char * const rt5645_mono_adc_r2_src[] = { | ||
952 | "Mono DAC MIXR", "DMIC" | ||
953 | }; | ||
954 | |||
955 | static SOC_ENUM_SINGLE_DECL( | ||
956 | rt5645_mono_adc_r2_enum, RT5645_MONO_ADC_MIXER, | ||
957 | RT5645_MONO_ADC_R2_SRC_SFT, rt5645_mono_adc_r2_src); | ||
958 | |||
959 | static const struct snd_kcontrol_new rt5645_mono_adc_r2_mux = | ||
960 | SOC_DAPM_ENUM("Mono ADC2 right source", rt5645_mono_adc_r2_enum); | ||
961 | |||
962 | /* MX-77 [9:8] */ | ||
963 | static const char * const rt5645_if1_adc_in_src[] = { | ||
964 | "IF_ADC1", "IF_ADC2", "VAD_ADC" | ||
965 | }; | ||
966 | |||
967 | static SOC_ENUM_SINGLE_DECL( | ||
968 | rt5645_if1_adc_in_enum, RT5645_TDM_CTRL_1, | ||
969 | RT5645_IF1_ADC_IN_SFT, rt5645_if1_adc_in_src); | ||
970 | |||
971 | static const struct snd_kcontrol_new rt5645_if1_adc_in_mux = | ||
972 | SOC_DAPM_ENUM("IF1 ADC IN source", rt5645_if1_adc_in_enum); | ||
973 | |||
974 | /* MX-2F [13:12] */ | ||
975 | static const char * const rt5645_if2_adc_in_src[] = { | ||
976 | "IF_ADC1", "IF_ADC2", "VAD_ADC" | ||
977 | }; | ||
978 | |||
979 | static SOC_ENUM_SINGLE_DECL( | ||
980 | rt5645_if2_adc_in_enum, RT5645_DIG_INF1_DATA, | ||
981 | RT5645_IF2_ADC_IN_SFT, rt5645_if2_adc_in_src); | ||
982 | |||
983 | static const struct snd_kcontrol_new rt5645_if2_adc_in_mux = | ||
984 | SOC_DAPM_ENUM("IF2 ADC IN source", rt5645_if2_adc_in_enum); | ||
985 | |||
986 | /* MX-2F [1:0] */ | ||
987 | static const char * const rt5645_if3_adc_in_src[] = { | ||
988 | "IF_ADC1", "IF_ADC2", "VAD_ADC" | ||
989 | }; | ||
990 | |||
991 | static SOC_ENUM_SINGLE_DECL( | ||
992 | rt5645_if3_adc_in_enum, RT5645_DIG_INF1_DATA, | ||
993 | RT5645_IF3_ADC_IN_SFT, rt5645_if3_adc_in_src); | ||
994 | |||
995 | static const struct snd_kcontrol_new rt5645_if3_adc_in_mux = | ||
996 | SOC_DAPM_ENUM("IF3 ADC IN source", rt5645_if3_adc_in_enum); | ||
997 | |||
998 | /* MX-31 [15] [13] [11] [9] */ | ||
999 | static const char * const rt5645_pdm_src[] = { | ||
1000 | "Mono DAC", "Stereo DAC" | ||
1001 | }; | ||
1002 | |||
1003 | static SOC_ENUM_SINGLE_DECL( | ||
1004 | rt5645_pdm1_l_enum, RT5645_PDM_OUT_CTRL, | ||
1005 | RT5645_PDM1_L_SFT, rt5645_pdm_src); | ||
1006 | |||
1007 | static const struct snd_kcontrol_new rt5645_pdm1_l_mux = | ||
1008 | SOC_DAPM_ENUM("PDM1 L source", rt5645_pdm1_l_enum); | ||
1009 | |||
1010 | static SOC_ENUM_SINGLE_DECL( | ||
1011 | rt5645_pdm1_r_enum, RT5645_PDM_OUT_CTRL, | ||
1012 | RT5645_PDM1_R_SFT, rt5645_pdm_src); | ||
1013 | |||
1014 | static const struct snd_kcontrol_new rt5645_pdm1_r_mux = | ||
1015 | SOC_DAPM_ENUM("PDM1 R source", rt5645_pdm1_r_enum); | ||
1016 | |||
1017 | /* MX-9D [9:8] */ | ||
1018 | static const char * const rt5645_vad_adc_src[] = { | ||
1019 | "Sto1 ADC L", "Mono ADC L", "Mono ADC R" | ||
1020 | }; | ||
1021 | |||
1022 | static SOC_ENUM_SINGLE_DECL( | ||
1023 | rt5645_vad_adc_enum, RT5645_VAD_CTRL4, | ||
1024 | RT5645_VAD_SEL_SFT, rt5645_vad_adc_src); | ||
1025 | |||
1026 | static const struct snd_kcontrol_new rt5645_vad_adc_mux = | ||
1027 | SOC_DAPM_ENUM("VAD ADC source", rt5645_vad_adc_enum); | ||
1028 | |||
1029 | static const struct snd_kcontrol_new spk_l_vol_control = | ||
1030 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_SPK_VOL, | ||
1031 | RT5645_L_MUTE_SFT, 1, 1); | ||
1032 | |||
1033 | static const struct snd_kcontrol_new spk_r_vol_control = | ||
1034 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_SPK_VOL, | ||
1035 | RT5645_R_MUTE_SFT, 1, 1); | ||
1036 | |||
1037 | static const struct snd_kcontrol_new hp_l_vol_control = | ||
1038 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_HP_VOL, | ||
1039 | RT5645_L_MUTE_SFT, 1, 1); | ||
1040 | |||
1041 | static const struct snd_kcontrol_new hp_r_vol_control = | ||
1042 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_HP_VOL, | ||
1043 | RT5645_R_MUTE_SFT, 1, 1); | ||
1044 | |||
1045 | static const struct snd_kcontrol_new pdm1_l_vol_control = | ||
1046 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_PDM_OUT_CTRL, | ||
1047 | RT5645_M_PDM1_L, 1, 1); | ||
1048 | |||
1049 | static const struct snd_kcontrol_new pdm1_r_vol_control = | ||
1050 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5645_PDM_OUT_CTRL, | ||
1051 | RT5645_M_PDM1_R, 1, 1); | ||
1052 | |||
1053 | static void hp_amp_power(struct snd_soc_codec *codec, int on) | ||
1054 | { | ||
1055 | static int hp_amp_power_count; | ||
1056 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
1057 | |||
1058 | if (on) { | ||
1059 | if (hp_amp_power_count <= 0) { | ||
1060 | /* depop parameters */ | ||
1061 | snd_soc_update_bits(codec, RT5645_DEPOP_M2, | ||
1062 | RT5645_DEPOP_MASK, RT5645_DEPOP_MAN); | ||
1063 | snd_soc_write(codec, RT5645_DEPOP_M1, 0x000d); | ||
1064 | regmap_write(rt5645->regmap, RT5645_PR_BASE + | ||
1065 | RT5645_HP_DCC_INT1, 0x9f01); | ||
1066 | mdelay(150); | ||
1067 | /* headphone amp power on */ | ||
1068 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
1069 | RT5645_PWR_FV1 | RT5645_PWR_FV2 , 0); | ||
1070 | snd_soc_update_bits(codec, RT5645_PWR_VOL, | ||
1071 | RT5645_PWR_HV_L | RT5645_PWR_HV_R, | ||
1072 | RT5645_PWR_HV_L | RT5645_PWR_HV_R); | ||
1073 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
1074 | RT5645_PWR_HP_L | RT5645_PWR_HP_R | | ||
1075 | RT5645_PWR_HA, | ||
1076 | RT5645_PWR_HP_L | RT5645_PWR_HP_R | | ||
1077 | RT5645_PWR_HA); | ||
1078 | mdelay(5); | ||
1079 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
1080 | RT5645_PWR_FV1 | RT5645_PWR_FV2, | ||
1081 | RT5645_PWR_FV1 | RT5645_PWR_FV2); | ||
1082 | |||
1083 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1084 | RT5645_HP_CO_MASK | RT5645_HP_SG_MASK, | ||
1085 | RT5645_HP_CO_EN | RT5645_HP_SG_EN); | ||
1086 | regmap_write(rt5645->regmap, RT5645_PR_BASE + | ||
1087 | 0x14, 0x1aaa); | ||
1088 | regmap_write(rt5645->regmap, RT5645_PR_BASE + | ||
1089 | 0x24, 0x0430); | ||
1090 | } | ||
1091 | hp_amp_power_count++; | ||
1092 | } else { | ||
1093 | hp_amp_power_count--; | ||
1094 | if (hp_amp_power_count <= 0) { | ||
1095 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1096 | RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK | | ||
1097 | RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS | | ||
1098 | RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS); | ||
1099 | /* headphone amp power down */ | ||
1100 | snd_soc_write(codec, RT5645_DEPOP_M1, 0x0000); | ||
1101 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
1102 | RT5645_PWR_HP_L | RT5645_PWR_HP_R | | ||
1103 | RT5645_PWR_HA, 0); | ||
1104 | } | ||
1105 | } | ||
1106 | } | ||
1107 | |||
1108 | static int rt5645_hp_event(struct snd_soc_dapm_widget *w, | ||
1109 | struct snd_kcontrol *kcontrol, int event) | ||
1110 | { | ||
1111 | struct snd_soc_codec *codec = w->codec; | ||
1112 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
1113 | |||
1114 | switch (event) { | ||
1115 | case SND_SOC_DAPM_POST_PMU: | ||
1116 | hp_amp_power(codec, 1); | ||
1117 | /* headphone unmute sequence */ | ||
1118 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, RT5645_CP_FQ1_MASK | | ||
1119 | RT5645_CP_FQ2_MASK | RT5645_CP_FQ3_MASK, | ||
1120 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ1_SFT) | | ||
1121 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | ||
1122 | (RT5645_CP_FQ_192_KHZ << RT5645_CP_FQ3_SFT)); | ||
1123 | regmap_write(rt5645->regmap, | ||
1124 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); | ||
1125 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1126 | RT5645_SMT_TRIG_MASK, RT5645_SMT_TRIG_EN); | ||
1127 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1128 | RT5645_RSTN_MASK, RT5645_RSTN_EN); | ||
1129 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1130 | RT5645_RSTN_MASK | RT5645_HP_L_SMT_MASK | | ||
1131 | RT5645_HP_R_SMT_MASK, RT5645_RSTN_DIS | | ||
1132 | RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN); | ||
1133 | msleep(40); | ||
1134 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1135 | RT5645_HP_SG_MASK | RT5645_HP_L_SMT_MASK | | ||
1136 | RT5645_HP_R_SMT_MASK, RT5645_HP_SG_DIS | | ||
1137 | RT5645_HP_L_SMT_DIS | RT5645_HP_R_SMT_DIS); | ||
1138 | break; | ||
1139 | |||
1140 | case SND_SOC_DAPM_PRE_PMD: | ||
1141 | /* headphone mute sequence */ | ||
1142 | snd_soc_update_bits(codec, RT5645_DEPOP_M3, | ||
1143 | RT5645_CP_FQ1_MASK | RT5645_CP_FQ2_MASK | | ||
1144 | RT5645_CP_FQ3_MASK, | ||
1145 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ1_SFT) | | ||
1146 | (RT5645_CP_FQ_12_KHZ << RT5645_CP_FQ2_SFT) | | ||
1147 | (RT5645_CP_FQ_96_KHZ << RT5645_CP_FQ3_SFT)); | ||
1148 | regmap_write(rt5645->regmap, | ||
1149 | RT5645_PR_BASE + RT5645_MAMP_INT_REG2, 0xfc00); | ||
1150 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1151 | RT5645_HP_SG_MASK, RT5645_HP_SG_EN); | ||
1152 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1153 | RT5645_RSTP_MASK, RT5645_RSTP_EN); | ||
1154 | snd_soc_update_bits(codec, RT5645_DEPOP_M1, | ||
1155 | RT5645_RSTP_MASK | RT5645_HP_L_SMT_MASK | | ||
1156 | RT5645_HP_R_SMT_MASK, RT5645_RSTP_DIS | | ||
1157 | RT5645_HP_L_SMT_EN | RT5645_HP_R_SMT_EN); | ||
1158 | msleep(30); | ||
1159 | hp_amp_power(codec, 0); | ||
1160 | break; | ||
1161 | |||
1162 | default: | ||
1163 | return 0; | ||
1164 | } | ||
1165 | |||
1166 | return 0; | ||
1167 | } | ||
1168 | |||
1169 | static int rt5645_spk_event(struct snd_soc_dapm_widget *w, | ||
1170 | struct snd_kcontrol *kcontrol, int event) | ||
1171 | { | ||
1172 | struct snd_soc_codec *codec = w->codec; | ||
1173 | |||
1174 | switch (event) { | ||
1175 | case SND_SOC_DAPM_POST_PMU: | ||
1176 | snd_soc_update_bits(codec, RT5645_PWR_DIG1, | ||
1177 | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | | ||
1178 | RT5645_PWR_CLS_D_L, | ||
1179 | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | | ||
1180 | RT5645_PWR_CLS_D_L); | ||
1181 | break; | ||
1182 | |||
1183 | case SND_SOC_DAPM_PRE_PMD: | ||
1184 | snd_soc_update_bits(codec, RT5645_PWR_DIG1, | ||
1185 | RT5645_PWR_CLS_D | RT5645_PWR_CLS_D_R | | ||
1186 | RT5645_PWR_CLS_D_L, 0); | ||
1187 | break; | ||
1188 | |||
1189 | default: | ||
1190 | return 0; | ||
1191 | } | ||
1192 | |||
1193 | return 0; | ||
1194 | } | ||
1195 | |||
1196 | static int rt5645_lout_event(struct snd_soc_dapm_widget *w, | ||
1197 | struct snd_kcontrol *kcontrol, int event) | ||
1198 | { | ||
1199 | struct snd_soc_codec *codec = w->codec; | ||
1200 | |||
1201 | switch (event) { | ||
1202 | case SND_SOC_DAPM_POST_PMU: | ||
1203 | hp_amp_power(codec, 1); | ||
1204 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
1205 | RT5645_PWR_LM, RT5645_PWR_LM); | ||
1206 | snd_soc_update_bits(codec, RT5645_LOUT1, | ||
1207 | RT5645_L_MUTE | RT5645_R_MUTE, 0); | ||
1208 | break; | ||
1209 | |||
1210 | case SND_SOC_DAPM_PRE_PMD: | ||
1211 | snd_soc_update_bits(codec, RT5645_LOUT1, | ||
1212 | RT5645_L_MUTE | RT5645_R_MUTE, | ||
1213 | RT5645_L_MUTE | RT5645_R_MUTE); | ||
1214 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
1215 | RT5645_PWR_LM, 0); | ||
1216 | hp_amp_power(codec, 0); | ||
1217 | break; | ||
1218 | |||
1219 | default: | ||
1220 | return 0; | ||
1221 | } | ||
1222 | |||
1223 | return 0; | ||
1224 | } | ||
1225 | |||
1226 | static int rt5645_bst2_event(struct snd_soc_dapm_widget *w, | ||
1227 | struct snd_kcontrol *kcontrol, int event) | ||
1228 | { | ||
1229 | struct snd_soc_codec *codec = w->codec; | ||
1230 | |||
1231 | switch (event) { | ||
1232 | case SND_SOC_DAPM_POST_PMU: | ||
1233 | snd_soc_update_bits(codec, RT5645_PWR_ANLG2, | ||
1234 | RT5645_PWR_BST2_P, RT5645_PWR_BST2_P); | ||
1235 | break; | ||
1236 | |||
1237 | case SND_SOC_DAPM_PRE_PMD: | ||
1238 | snd_soc_update_bits(codec, RT5645_PWR_ANLG2, | ||
1239 | RT5645_PWR_BST2_P, 0); | ||
1240 | break; | ||
1241 | |||
1242 | default: | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | return 0; | ||
1247 | } | ||
1248 | |||
1249 | static const struct snd_soc_dapm_widget rt5645_dapm_widgets[] = { | ||
1250 | SND_SOC_DAPM_SUPPLY("LDO2", RT5645_PWR_MIXER, | ||
1251 | RT5645_PWR_LDO2_BIT, 0, NULL, 0), | ||
1252 | SND_SOC_DAPM_SUPPLY("PLL1", RT5645_PWR_ANLG2, | ||
1253 | RT5645_PWR_PLL_BIT, 0, NULL, 0), | ||
1254 | |||
1255 | SND_SOC_DAPM_SUPPLY("JD Power", RT5645_PWR_ANLG2, | ||
1256 | RT5645_PWR_JD1_BIT, 0, NULL, 0), | ||
1257 | SND_SOC_DAPM_SUPPLY("Mic Det Power", RT5645_PWR_VOL, | ||
1258 | RT5645_PWR_MIC_DET_BIT, 0, NULL, 0), | ||
1259 | |||
1260 | /* Input Side */ | ||
1261 | /* micbias */ | ||
1262 | SND_SOC_DAPM_MICBIAS("micbias1", RT5645_PWR_ANLG2, | ||
1263 | RT5645_PWR_MB1_BIT, 0), | ||
1264 | SND_SOC_DAPM_MICBIAS("micbias2", RT5645_PWR_ANLG2, | ||
1265 | RT5645_PWR_MB2_BIT, 0), | ||
1266 | /* Input Lines */ | ||
1267 | SND_SOC_DAPM_INPUT("DMIC L1"), | ||
1268 | SND_SOC_DAPM_INPUT("DMIC R1"), | ||
1269 | SND_SOC_DAPM_INPUT("DMIC L2"), | ||
1270 | SND_SOC_DAPM_INPUT("DMIC R2"), | ||
1271 | |||
1272 | SND_SOC_DAPM_INPUT("IN1P"), | ||
1273 | SND_SOC_DAPM_INPUT("IN1N"), | ||
1274 | SND_SOC_DAPM_INPUT("IN2P"), | ||
1275 | SND_SOC_DAPM_INPUT("IN2N"), | ||
1276 | |||
1277 | SND_SOC_DAPM_INPUT("Haptic Generator"), | ||
1278 | |||
1279 | SND_SOC_DAPM_PGA("DMIC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1280 | SND_SOC_DAPM_PGA("DMIC2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1281 | SND_SOC_DAPM_SUPPLY("DMIC CLK", SND_SOC_NOPM, 0, 0, | ||
1282 | set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | ||
1283 | SND_SOC_DAPM_SUPPLY("DMIC1 Power", RT5645_DMIC_CTRL1, | ||
1284 | RT5645_DMIC_1_EN_SFT, 0, NULL, 0), | ||
1285 | SND_SOC_DAPM_SUPPLY("DMIC2 Power", RT5645_DMIC_CTRL1, | ||
1286 | RT5645_DMIC_2_EN_SFT, 0, NULL, 0), | ||
1287 | /* Boost */ | ||
1288 | SND_SOC_DAPM_PGA("BST1", RT5645_PWR_ANLG2, | ||
1289 | RT5645_PWR_BST1_BIT, 0, NULL, 0), | ||
1290 | SND_SOC_DAPM_PGA_E("BST2", RT5645_PWR_ANLG2, | ||
1291 | RT5645_PWR_BST2_BIT, 0, NULL, 0, rt5645_bst2_event, | ||
1292 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1293 | /* Input Volume */ | ||
1294 | SND_SOC_DAPM_PGA("INL VOL", RT5645_PWR_VOL, | ||
1295 | RT5645_PWR_IN_L_BIT, 0, NULL, 0), | ||
1296 | SND_SOC_DAPM_PGA("INR VOL", RT5645_PWR_VOL, | ||
1297 | RT5645_PWR_IN_R_BIT, 0, NULL, 0), | ||
1298 | /* REC Mixer */ | ||
1299 | SND_SOC_DAPM_MIXER("RECMIXL", RT5645_PWR_MIXER, RT5645_PWR_RM_L_BIT, | ||
1300 | 0, rt5645_rec_l_mix, ARRAY_SIZE(rt5645_rec_l_mix)), | ||
1301 | SND_SOC_DAPM_MIXER("RECMIXR", RT5645_PWR_MIXER, RT5645_PWR_RM_R_BIT, | ||
1302 | 0, rt5645_rec_r_mix, ARRAY_SIZE(rt5645_rec_r_mix)), | ||
1303 | /* ADCs */ | ||
1304 | SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), | ||
1305 | SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), | ||
1306 | |||
1307 | SND_SOC_DAPM_SUPPLY("ADC L power", RT5645_PWR_DIG1, | ||
1308 | RT5645_PWR_ADC_L_BIT, 0, NULL, 0), | ||
1309 | SND_SOC_DAPM_SUPPLY("ADC R power", RT5645_PWR_DIG1, | ||
1310 | RT5645_PWR_ADC_R_BIT, 0, NULL, 0), | ||
1311 | |||
1312 | /* ADC Mux */ | ||
1313 | SND_SOC_DAPM_MUX("Stereo1 DMIC Mux", SND_SOC_NOPM, 0, 0, | ||
1314 | &rt5645_sto1_dmic_mux), | ||
1315 | SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
1316 | &rt5645_sto_adc2_mux), | ||
1317 | SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1318 | &rt5645_sto_adc2_mux), | ||
1319 | SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, | ||
1320 | &rt5645_sto_adc1_mux), | ||
1321 | SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, | ||
1322 | &rt5645_sto_adc1_mux), | ||
1323 | SND_SOC_DAPM_MUX("Mono DMIC L Mux", SND_SOC_NOPM, 0, 0, | ||
1324 | &rt5645_mono_dmic_l_mux), | ||
1325 | SND_SOC_DAPM_MUX("Mono DMIC R Mux", SND_SOC_NOPM, 0, 0, | ||
1326 | &rt5645_mono_dmic_r_mux), | ||
1327 | SND_SOC_DAPM_MUX("Mono ADC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
1328 | &rt5645_mono_adc_l2_mux), | ||
1329 | SND_SOC_DAPM_MUX("Mono ADC L1 Mux", SND_SOC_NOPM, 0, 0, | ||
1330 | &rt5645_mono_adc_l1_mux), | ||
1331 | SND_SOC_DAPM_MUX("Mono ADC R1 Mux", SND_SOC_NOPM, 0, 0, | ||
1332 | &rt5645_mono_adc_r1_mux), | ||
1333 | SND_SOC_DAPM_MUX("Mono ADC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1334 | &rt5645_mono_adc_r2_mux), | ||
1335 | /* ADC Mixer */ | ||
1336 | |||
1337 | SND_SOC_DAPM_SUPPLY_S("adc stereo1 filter", 1, RT5645_PWR_DIG2, | ||
1338 | RT5645_PWR_ADC_S1F_BIT, 0, NULL, 0), | ||
1339 | SND_SOC_DAPM_SUPPLY_S("adc stereo2 filter", 1, RT5645_PWR_DIG2, | ||
1340 | RT5645_PWR_ADC_S2F_BIT, 0, NULL, 0), | ||
1341 | SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
1342 | rt5645_sto1_adc_l_mix, ARRAY_SIZE(rt5645_sto1_adc_l_mix), | ||
1343 | NULL, 0), | ||
1344 | SND_SOC_DAPM_MIXER_E("Sto1 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
1345 | rt5645_sto1_adc_r_mix, ARRAY_SIZE(rt5645_sto1_adc_r_mix), | ||
1346 | NULL, 0), | ||
1347 | SND_SOC_DAPM_SUPPLY_S("adc mono left filter", 1, RT5645_PWR_DIG2, | ||
1348 | RT5645_PWR_ADC_MF_L_BIT, 0, NULL, 0), | ||
1349 | SND_SOC_DAPM_MIXER_E("Mono ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
1350 | rt5645_mono_adc_l_mix, ARRAY_SIZE(rt5645_mono_adc_l_mix), | ||
1351 | NULL, 0), | ||
1352 | SND_SOC_DAPM_SUPPLY_S("adc mono right filter", 1, RT5645_PWR_DIG2, | ||
1353 | RT5645_PWR_ADC_MF_R_BIT, 0, NULL, 0), | ||
1354 | SND_SOC_DAPM_MIXER_E("Mono ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
1355 | rt5645_mono_adc_r_mix, ARRAY_SIZE(rt5645_mono_adc_r_mix), | ||
1356 | NULL, 0), | ||
1357 | |||
1358 | /* ADC PGA */ | ||
1359 | SND_SOC_DAPM_PGA("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1360 | SND_SOC_DAPM_PGA("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1361 | SND_SOC_DAPM_PGA("Sto2 ADC LR MIX", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1362 | SND_SOC_DAPM_PGA("VAD_ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1363 | SND_SOC_DAPM_PGA("IF_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1364 | SND_SOC_DAPM_PGA("IF_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1365 | SND_SOC_DAPM_PGA("IF1_ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1366 | SND_SOC_DAPM_PGA("IF1_ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1367 | SND_SOC_DAPM_PGA("IF1_ADC3", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1368 | SND_SOC_DAPM_PGA("IF1_ADC4", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1369 | |||
1370 | /* IF1 2 Mux */ | ||
1371 | SND_SOC_DAPM_MUX("IF1 ADC Mux", SND_SOC_NOPM, | ||
1372 | 0, 0, &rt5645_if1_adc_in_mux), | ||
1373 | SND_SOC_DAPM_MUX("IF2 ADC Mux", SND_SOC_NOPM, | ||
1374 | 0, 0, &rt5645_if2_adc_in_mux), | ||
1375 | |||
1376 | /* Digital Interface */ | ||
1377 | SND_SOC_DAPM_SUPPLY("I2S1", RT5645_PWR_DIG1, | ||
1378 | RT5645_PWR_I2S1_BIT, 0, NULL, 0), | ||
1379 | SND_SOC_DAPM_PGA("IF1 DAC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1380 | SND_SOC_DAPM_PGA("IF1 DAC2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1381 | SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1382 | SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1383 | SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1384 | SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1385 | SND_SOC_DAPM_PGA("IF1 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1386 | SND_SOC_DAPM_PGA("IF1 ADC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1387 | SND_SOC_DAPM_PGA("IF1 ADC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1388 | SND_SOC_DAPM_SUPPLY("I2S2", RT5645_PWR_DIG1, | ||
1389 | RT5645_PWR_I2S2_BIT, 0, NULL, 0), | ||
1390 | SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1391 | SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1392 | SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1393 | SND_SOC_DAPM_PGA("IF2 ADC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1394 | |||
1395 | /* Digital Interface Select */ | ||
1396 | SND_SOC_DAPM_MUX("VAD ADC Mux", SND_SOC_NOPM, | ||
1397 | 0, 0, &rt5645_vad_adc_mux), | ||
1398 | |||
1399 | /* Audio Interface */ | ||
1400 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1401 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1402 | SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1403 | SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1404 | |||
1405 | /* Output Side */ | ||
1406 | /* DAC mixer before sound effect */ | ||
1407 | SND_SOC_DAPM_MIXER("DAC1 MIXL", SND_SOC_NOPM, 0, 0, | ||
1408 | rt5645_dac_l_mix, ARRAY_SIZE(rt5645_dac_l_mix)), | ||
1409 | SND_SOC_DAPM_MIXER("DAC1 MIXR", SND_SOC_NOPM, 0, 0, | ||
1410 | rt5645_dac_r_mix, ARRAY_SIZE(rt5645_dac_r_mix)), | ||
1411 | |||
1412 | /* DAC2 channel Mux */ | ||
1413 | SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac_l2_mux), | ||
1414 | SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac_r2_mux), | ||
1415 | SND_SOC_DAPM_PGA("DAC L2 Volume", RT5645_PWR_DIG1, | ||
1416 | RT5645_PWR_DAC_L2_BIT, 0, NULL, 0), | ||
1417 | SND_SOC_DAPM_PGA("DAC R2 Volume", RT5645_PWR_DIG1, | ||
1418 | RT5645_PWR_DAC_R2_BIT, 0, NULL, 0), | ||
1419 | |||
1420 | SND_SOC_DAPM_MUX("DAC1 L Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac1l_mux), | ||
1421 | SND_SOC_DAPM_MUX("DAC1 R Mux", SND_SOC_NOPM, 0, 0, &rt5645_dac1r_mux), | ||
1422 | |||
1423 | /* DAC Mixer */ | ||
1424 | SND_SOC_DAPM_SUPPLY_S("dac stereo1 filter", 1, RT5645_PWR_DIG2, | ||
1425 | RT5645_PWR_DAC_S1F_BIT, 0, NULL, 0), | ||
1426 | SND_SOC_DAPM_SUPPLY_S("dac mono left filter", 1, RT5645_PWR_DIG2, | ||
1427 | RT5645_PWR_DAC_MF_L_BIT, 0, NULL, 0), | ||
1428 | SND_SOC_DAPM_SUPPLY_S("dac mono right filter", 1, RT5645_PWR_DIG2, | ||
1429 | RT5645_PWR_DAC_MF_R_BIT, 0, NULL, 0), | ||
1430 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1431 | rt5645_sto_dac_l_mix, ARRAY_SIZE(rt5645_sto_dac_l_mix)), | ||
1432 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1433 | rt5645_sto_dac_r_mix, ARRAY_SIZE(rt5645_sto_dac_r_mix)), | ||
1434 | SND_SOC_DAPM_MIXER("Mono DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1435 | rt5645_mono_dac_l_mix, ARRAY_SIZE(rt5645_mono_dac_l_mix)), | ||
1436 | SND_SOC_DAPM_MIXER("Mono DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1437 | rt5645_mono_dac_r_mix, ARRAY_SIZE(rt5645_mono_dac_r_mix)), | ||
1438 | SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1439 | rt5645_dig_l_mix, ARRAY_SIZE(rt5645_dig_l_mix)), | ||
1440 | SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1441 | rt5645_dig_r_mix, ARRAY_SIZE(rt5645_dig_r_mix)), | ||
1442 | |||
1443 | /* DACs */ | ||
1444 | SND_SOC_DAPM_DAC("DAC L1", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_L1_BIT, | ||
1445 | 0), | ||
1446 | SND_SOC_DAPM_DAC("DAC L2", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_L2_BIT, | ||
1447 | 0), | ||
1448 | SND_SOC_DAPM_DAC("DAC R1", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_R1_BIT, | ||
1449 | 0), | ||
1450 | SND_SOC_DAPM_DAC("DAC R2", NULL, RT5645_PWR_DIG1, RT5645_PWR_DAC_R2_BIT, | ||
1451 | 0), | ||
1452 | /* OUT Mixer */ | ||
1453 | SND_SOC_DAPM_MIXER("SPK MIXL", RT5645_PWR_MIXER, RT5645_PWR_SM_L_BIT, | ||
1454 | 0, rt5645_spk_l_mix, ARRAY_SIZE(rt5645_spk_l_mix)), | ||
1455 | SND_SOC_DAPM_MIXER("SPK MIXR", RT5645_PWR_MIXER, RT5645_PWR_SM_R_BIT, | ||
1456 | 0, rt5645_spk_r_mix, ARRAY_SIZE(rt5645_spk_r_mix)), | ||
1457 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5645_PWR_MIXER, RT5645_PWR_OM_L_BIT, | ||
1458 | 0, rt5645_out_l_mix, ARRAY_SIZE(rt5645_out_l_mix)), | ||
1459 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5645_PWR_MIXER, RT5645_PWR_OM_R_BIT, | ||
1460 | 0, rt5645_out_r_mix, ARRAY_SIZE(rt5645_out_r_mix)), | ||
1461 | /* Ouput Volume */ | ||
1462 | SND_SOC_DAPM_SWITCH("SPKVOL L", RT5645_PWR_VOL, RT5645_PWR_SV_L_BIT, 0, | ||
1463 | &spk_l_vol_control), | ||
1464 | SND_SOC_DAPM_SWITCH("SPKVOL R", RT5645_PWR_VOL, RT5645_PWR_SV_R_BIT, 0, | ||
1465 | &spk_r_vol_control), | ||
1466 | SND_SOC_DAPM_MIXER("HPOVOL MIXL", RT5645_PWR_VOL, RT5645_PWR_HV_L_BIT, | ||
1467 | 0, rt5645_hpvoll_mix, ARRAY_SIZE(rt5645_hpvoll_mix)), | ||
1468 | SND_SOC_DAPM_MIXER("HPOVOL MIXR", RT5645_PWR_VOL, RT5645_PWR_HV_R_BIT, | ||
1469 | 0, rt5645_hpvolr_mix, ARRAY_SIZE(rt5645_hpvolr_mix)), | ||
1470 | SND_SOC_DAPM_SUPPLY("HPOVOL MIXL Power", RT5645_PWR_MIXER, | ||
1471 | RT5645_PWR_HM_L_BIT, 0, NULL, 0), | ||
1472 | SND_SOC_DAPM_SUPPLY("HPOVOL MIXR Power", RT5645_PWR_MIXER, | ||
1473 | RT5645_PWR_HM_R_BIT, 0, NULL, 0), | ||
1474 | SND_SOC_DAPM_PGA("DAC 1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1475 | SND_SOC_DAPM_PGA("DAC 2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1476 | SND_SOC_DAPM_PGA("HPOVOL", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1477 | SND_SOC_DAPM_SWITCH("HPOVOL L", SND_SOC_NOPM, 0, 0, &hp_l_vol_control), | ||
1478 | SND_SOC_DAPM_SWITCH("HPOVOL R", SND_SOC_NOPM, 0, 0, &hp_r_vol_control), | ||
1479 | |||
1480 | /* HPO/LOUT/Mono Mixer */ | ||
1481 | SND_SOC_DAPM_MIXER("SPOL MIX", SND_SOC_NOPM, 0, 0, rt5645_spo_l_mix, | ||
1482 | ARRAY_SIZE(rt5645_spo_l_mix)), | ||
1483 | SND_SOC_DAPM_MIXER("SPOR MIX", SND_SOC_NOPM, 0, 0, rt5645_spo_r_mix, | ||
1484 | ARRAY_SIZE(rt5645_spo_r_mix)), | ||
1485 | SND_SOC_DAPM_MIXER("HPO MIX", SND_SOC_NOPM, 0, 0, rt5645_hpo_mix, | ||
1486 | ARRAY_SIZE(rt5645_hpo_mix)), | ||
1487 | SND_SOC_DAPM_MIXER("LOUT MIX", SND_SOC_NOPM, 0, 0, rt5645_lout_mix, | ||
1488 | ARRAY_SIZE(rt5645_lout_mix)), | ||
1489 | |||
1490 | SND_SOC_DAPM_PGA_S("HP amp", 1, SND_SOC_NOPM, 0, 0, rt5645_hp_event, | ||
1491 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1492 | SND_SOC_DAPM_PGA_S("LOUT amp", 1, SND_SOC_NOPM, 0, 0, rt5645_lout_event, | ||
1493 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1494 | SND_SOC_DAPM_PGA_S("SPK amp", 2, SND_SOC_NOPM, 0, 0, rt5645_spk_event, | ||
1495 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1496 | |||
1497 | /* PDM */ | ||
1498 | SND_SOC_DAPM_SUPPLY("PDM1 Power", RT5645_PWR_DIG2, RT5645_PWR_PDM1_BIT, | ||
1499 | 0, NULL, 0), | ||
1500 | SND_SOC_DAPM_MUX("PDM1 L Mux", SND_SOC_NOPM, 0, 0, &rt5645_pdm1_l_mux), | ||
1501 | SND_SOC_DAPM_MUX("PDM1 R Mux", SND_SOC_NOPM, 0, 0, &rt5645_pdm1_r_mux), | ||
1502 | |||
1503 | SND_SOC_DAPM_SWITCH("PDM1 L", SND_SOC_NOPM, 0, 0, &pdm1_l_vol_control), | ||
1504 | SND_SOC_DAPM_SWITCH("PDM1 R", SND_SOC_NOPM, 0, 0, &pdm1_r_vol_control), | ||
1505 | |||
1506 | /* Output Lines */ | ||
1507 | SND_SOC_DAPM_OUTPUT("HPOL"), | ||
1508 | SND_SOC_DAPM_OUTPUT("HPOR"), | ||
1509 | SND_SOC_DAPM_OUTPUT("LOUTL"), | ||
1510 | SND_SOC_DAPM_OUTPUT("LOUTR"), | ||
1511 | SND_SOC_DAPM_OUTPUT("PDM1L"), | ||
1512 | SND_SOC_DAPM_OUTPUT("PDM1R"), | ||
1513 | SND_SOC_DAPM_OUTPUT("SPOL"), | ||
1514 | SND_SOC_DAPM_OUTPUT("SPOR"), | ||
1515 | }; | ||
1516 | |||
1517 | static const struct snd_soc_dapm_route rt5645_dapm_routes[] = { | ||
1518 | { "IN1P", NULL, "LDO2" }, | ||
1519 | { "IN2P", NULL, "LDO2" }, | ||
1520 | |||
1521 | { "DMIC1", NULL, "DMIC L1" }, | ||
1522 | { "DMIC1", NULL, "DMIC R1" }, | ||
1523 | { "DMIC2", NULL, "DMIC L2" }, | ||
1524 | { "DMIC2", NULL, "DMIC R2" }, | ||
1525 | |||
1526 | { "BST1", NULL, "IN1P" }, | ||
1527 | { "BST1", NULL, "IN1N" }, | ||
1528 | { "BST1", NULL, "JD Power" }, | ||
1529 | { "BST1", NULL, "Mic Det Power" }, | ||
1530 | { "BST2", NULL, "IN2P" }, | ||
1531 | { "BST2", NULL, "IN2N" }, | ||
1532 | |||
1533 | { "INL VOL", NULL, "IN2P" }, | ||
1534 | { "INR VOL", NULL, "IN2N" }, | ||
1535 | |||
1536 | { "RECMIXL", "HPOL Switch", "HPOL" }, | ||
1537 | { "RECMIXL", "INL Switch", "INL VOL" }, | ||
1538 | { "RECMIXL", "BST2 Switch", "BST2" }, | ||
1539 | { "RECMIXL", "BST1 Switch", "BST1" }, | ||
1540 | { "RECMIXL", "OUT MIXL Switch", "OUT MIXL" }, | ||
1541 | |||
1542 | { "RECMIXR", "HPOR Switch", "HPOR" }, | ||
1543 | { "RECMIXR", "INR Switch", "INR VOL" }, | ||
1544 | { "RECMIXR", "BST2 Switch", "BST2" }, | ||
1545 | { "RECMIXR", "BST1 Switch", "BST1" }, | ||
1546 | { "RECMIXR", "OUT MIXR Switch", "OUT MIXR" }, | ||
1547 | |||
1548 | { "ADC L", NULL, "RECMIXL" }, | ||
1549 | { "ADC L", NULL, "ADC L power" }, | ||
1550 | { "ADC R", NULL, "RECMIXR" }, | ||
1551 | { "ADC R", NULL, "ADC R power" }, | ||
1552 | |||
1553 | {"DMIC L1", NULL, "DMIC CLK"}, | ||
1554 | {"DMIC L1", NULL, "DMIC1 Power"}, | ||
1555 | {"DMIC R1", NULL, "DMIC CLK"}, | ||
1556 | {"DMIC R1", NULL, "DMIC1 Power"}, | ||
1557 | {"DMIC L2", NULL, "DMIC CLK"}, | ||
1558 | {"DMIC L2", NULL, "DMIC2 Power"}, | ||
1559 | {"DMIC R2", NULL, "DMIC CLK"}, | ||
1560 | {"DMIC R2", NULL, "DMIC2 Power"}, | ||
1561 | |||
1562 | { "Stereo1 DMIC Mux", "DMIC1", "DMIC1" }, | ||
1563 | { "Stereo1 DMIC Mux", "DMIC2", "DMIC2" }, | ||
1564 | |||
1565 | { "Mono DMIC L Mux", "DMIC1", "DMIC L1" }, | ||
1566 | { "Mono DMIC L Mux", "DMIC2", "DMIC L2" }, | ||
1567 | |||
1568 | { "Mono DMIC R Mux", "DMIC1", "DMIC R1" }, | ||
1569 | { "Mono DMIC R Mux", "DMIC2", "DMIC R2" }, | ||
1570 | |||
1571 | { "Stereo1 ADC L2 Mux", "DMIC", "Stereo1 DMIC Mux" }, | ||
1572 | { "Stereo1 ADC L2 Mux", "DAC MIX", "DAC MIXL" }, | ||
1573 | { "Stereo1 ADC L1 Mux", "ADC", "ADC L" }, | ||
1574 | { "Stereo1 ADC L1 Mux", "DAC MIX", "DAC MIXL" }, | ||
1575 | |||
1576 | { "Stereo1 ADC R1 Mux", "ADC", "ADC R" }, | ||
1577 | { "Stereo1 ADC R1 Mux", "DAC MIX", "DAC MIXR" }, | ||
1578 | { "Stereo1 ADC R2 Mux", "DMIC", "Stereo1 DMIC Mux" }, | ||
1579 | { "Stereo1 ADC R2 Mux", "DAC MIX", "DAC MIXR" }, | ||
1580 | |||
1581 | { "Mono ADC L2 Mux", "DMIC", "Mono DMIC L Mux" }, | ||
1582 | { "Mono ADC L2 Mux", "Mono DAC MIXL", "Mono DAC MIXL" }, | ||
1583 | { "Mono ADC L1 Mux", "Mono DAC MIXL", "Mono DAC MIXL" }, | ||
1584 | { "Mono ADC L1 Mux", "ADC", "ADC L" }, | ||
1585 | |||
1586 | { "Mono ADC R1 Mux", "Mono DAC MIXR", "Mono DAC MIXR" }, | ||
1587 | { "Mono ADC R1 Mux", "ADC", "ADC R" }, | ||
1588 | { "Mono ADC R2 Mux", "DMIC", "Mono DMIC R Mux" }, | ||
1589 | { "Mono ADC R2 Mux", "Mono DAC MIXR", "Mono DAC MIXR" }, | ||
1590 | |||
1591 | { "Sto1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux" }, | ||
1592 | { "Sto1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux" }, | ||
1593 | { "Sto1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux" }, | ||
1594 | { "Sto1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux" }, | ||
1595 | |||
1596 | { "Stereo1 ADC MIXL", NULL, "Sto1 ADC MIXL" }, | ||
1597 | { "Stereo1 ADC MIXL", NULL, "adc stereo1 filter" }, | ||
1598 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1599 | |||
1600 | { "Stereo1 ADC MIXR", NULL, "Sto1 ADC MIXR" }, | ||
1601 | { "Stereo1 ADC MIXR", NULL, "adc stereo1 filter" }, | ||
1602 | { "adc stereo1 filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1603 | |||
1604 | { "Mono ADC MIXL", "ADC1 Switch", "Mono ADC L1 Mux" }, | ||
1605 | { "Mono ADC MIXL", "ADC2 Switch", "Mono ADC L2 Mux" }, | ||
1606 | { "Mono ADC MIXL", NULL, "adc mono left filter" }, | ||
1607 | { "adc mono left filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1608 | |||
1609 | { "Mono ADC MIXR", "ADC1 Switch", "Mono ADC R1 Mux" }, | ||
1610 | { "Mono ADC MIXR", "ADC2 Switch", "Mono ADC R2 Mux" }, | ||
1611 | { "Mono ADC MIXR", NULL, "adc mono right filter" }, | ||
1612 | { "adc mono right filter", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1613 | |||
1614 | { "VAD ADC Mux", "Sto1 ADC L", "Stereo1 ADC MIXL" }, | ||
1615 | { "VAD ADC Mux", "Mono ADC L", "Mono ADC MIXL" }, | ||
1616 | { "VAD ADC Mux", "Mono ADC R", "Mono ADC MIXR" }, | ||
1617 | |||
1618 | { "IF_ADC1", NULL, "Stereo1 ADC MIXL" }, | ||
1619 | { "IF_ADC1", NULL, "Stereo1 ADC MIXR" }, | ||
1620 | { "IF_ADC2", NULL, "Mono ADC MIXL" }, | ||
1621 | { "IF_ADC2", NULL, "Mono ADC MIXR" }, | ||
1622 | { "VAD_ADC", NULL, "VAD ADC Mux" }, | ||
1623 | |||
1624 | { "IF1 ADC Mux", "IF_ADC1", "IF_ADC1" }, | ||
1625 | { "IF1 ADC Mux", "IF_ADC2", "IF_ADC2" }, | ||
1626 | { "IF1 ADC Mux", "VAD_ADC", "VAD_ADC" }, | ||
1627 | |||
1628 | { "IF2 ADC Mux", "IF_ADC1", "IF_ADC1" }, | ||
1629 | { "IF2 ADC Mux", "IF_ADC2", "IF_ADC2" }, | ||
1630 | { "IF2 ADC Mux", "VAD_ADC", "VAD_ADC" }, | ||
1631 | |||
1632 | { "IF1 ADC", NULL, "I2S1" }, | ||
1633 | { "IF1 ADC", NULL, "IF1 ADC Mux" }, | ||
1634 | { "IF2 ADC", NULL, "I2S2" }, | ||
1635 | { "IF2 ADC", NULL, "IF2 ADC Mux" }, | ||
1636 | |||
1637 | { "AIF1TX", NULL, "IF1 ADC" }, | ||
1638 | { "AIF1TX", NULL, "IF2 ADC" }, | ||
1639 | { "AIF2TX", NULL, "IF2 ADC" }, | ||
1640 | |||
1641 | { "IF1 DAC1", NULL, "AIF1RX" }, | ||
1642 | { "IF1 DAC2", NULL, "AIF1RX" }, | ||
1643 | { "IF2 DAC", NULL, "AIF2RX" }, | ||
1644 | |||
1645 | { "IF1 DAC1", NULL, "I2S1" }, | ||
1646 | { "IF1 DAC2", NULL, "I2S1" }, | ||
1647 | { "IF2 DAC", NULL, "I2S2" }, | ||
1648 | |||
1649 | { "IF1 DAC2 L", NULL, "IF1 DAC2" }, | ||
1650 | { "IF1 DAC2 R", NULL, "IF1 DAC2" }, | ||
1651 | { "IF1 DAC1 L", NULL, "IF1 DAC1" }, | ||
1652 | { "IF1 DAC1 R", NULL, "IF1 DAC1" }, | ||
1653 | { "IF2 DAC L", NULL, "IF2 DAC" }, | ||
1654 | { "IF2 DAC R", NULL, "IF2 DAC" }, | ||
1655 | |||
1656 | { "DAC1 L Mux", "IF1 DAC", "IF1 DAC1 L" }, | ||
1657 | { "DAC1 L Mux", "IF2 DAC", "IF2 DAC L" }, | ||
1658 | |||
1659 | { "DAC1 R Mux", "IF1 DAC", "IF1 DAC1 R" }, | ||
1660 | { "DAC1 R Mux", "IF2 DAC", "IF2 DAC R" }, | ||
1661 | |||
1662 | { "DAC1 MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL" }, | ||
1663 | { "DAC1 MIXL", "DAC1 Switch", "DAC1 L Mux" }, | ||
1664 | { "DAC1 MIXL", NULL, "dac stereo1 filter" }, | ||
1665 | { "DAC1 MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR" }, | ||
1666 | { "DAC1 MIXR", "DAC1 Switch", "DAC1 R Mux" }, | ||
1667 | { "DAC1 MIXR", NULL, "dac stereo1 filter" }, | ||
1668 | |||
1669 | { "DAC L2 Mux", "IF1 DAC", "IF1 DAC2 L" }, | ||
1670 | { "DAC L2 Mux", "IF2 DAC", "IF2 DAC L" }, | ||
1671 | { "DAC L2 Mux", "Mono ADC", "Mono ADC MIXL" }, | ||
1672 | { "DAC L2 Mux", "VAD_ADC", "VAD_ADC" }, | ||
1673 | { "DAC L2 Volume", NULL, "DAC L2 Mux" }, | ||
1674 | { "DAC L2 Volume", NULL, "dac mono left filter" }, | ||
1675 | |||
1676 | { "DAC R2 Mux", "IF1 DAC", "IF1 DAC2 R" }, | ||
1677 | { "DAC R2 Mux", "IF2 DAC", "IF2 DAC R" }, | ||
1678 | { "DAC R2 Mux", "Mono ADC", "Mono ADC MIXR" }, | ||
1679 | { "DAC R2 Mux", "Haptic", "Haptic Generator" }, | ||
1680 | { "DAC R2 Volume", NULL, "DAC R2 Mux" }, | ||
1681 | { "DAC R2 Volume", NULL, "dac mono right filter" }, | ||
1682 | |||
1683 | { "Stereo DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" }, | ||
1684 | { "Stereo DAC MIXL", "DAC R1 Switch", "DAC1 MIXR" }, | ||
1685 | { "Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" }, | ||
1686 | { "Stereo DAC MIXL", NULL, "dac stereo1 filter" }, | ||
1687 | { "Stereo DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" }, | ||
1688 | { "Stereo DAC MIXR", "DAC L1 Switch", "DAC1 MIXL" }, | ||
1689 | { "Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, | ||
1690 | { "Stereo DAC MIXR", NULL, "dac stereo1 filter" }, | ||
1691 | |||
1692 | { "Mono DAC MIXL", "DAC L1 Switch", "DAC1 MIXL" }, | ||
1693 | { "Mono DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" }, | ||
1694 | { "Mono DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" }, | ||
1695 | { "Mono DAC MIXL", NULL, "dac mono left filter" }, | ||
1696 | { "Mono DAC MIXR", "DAC R1 Switch", "DAC1 MIXR" }, | ||
1697 | { "Mono DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, | ||
1698 | { "Mono DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, | ||
1699 | { "Mono DAC MIXR", NULL, "dac mono right filter" }, | ||
1700 | |||
1701 | { "DAC MIXL", "Sto DAC Mix L Switch", "Stereo DAC MIXL" }, | ||
1702 | { "DAC MIXL", "DAC L2 Switch", "DAC L2 Volume" }, | ||
1703 | { "DAC MIXL", "DAC R2 Switch", "DAC R2 Volume" }, | ||
1704 | { "DAC MIXR", "Sto DAC Mix R Switch", "Stereo DAC MIXR" }, | ||
1705 | { "DAC MIXR", "DAC R2 Switch", "DAC R2 Volume" }, | ||
1706 | { "DAC MIXR", "DAC L2 Switch", "DAC L2 Volume" }, | ||
1707 | |||
1708 | { "DAC L1", NULL, "Stereo DAC MIXL" }, | ||
1709 | { "DAC L1", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1710 | { "DAC R1", NULL, "Stereo DAC MIXR" }, | ||
1711 | { "DAC R1", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1712 | { "DAC L2", NULL, "Mono DAC MIXL" }, | ||
1713 | { "DAC L2", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1714 | { "DAC R2", NULL, "Mono DAC MIXR" }, | ||
1715 | { "DAC R2", NULL, "PLL1", is_sys_clk_from_pll }, | ||
1716 | |||
1717 | { "SPK MIXL", "BST1 Switch", "BST1" }, | ||
1718 | { "SPK MIXL", "INL Switch", "INL VOL" }, | ||
1719 | { "SPK MIXL", "DAC L1 Switch", "DAC L1" }, | ||
1720 | { "SPK MIXL", "DAC L2 Switch", "DAC L2" }, | ||
1721 | { "SPK MIXR", "BST2 Switch", "BST2" }, | ||
1722 | { "SPK MIXR", "INR Switch", "INR VOL" }, | ||
1723 | { "SPK MIXR", "DAC R1 Switch", "DAC R1" }, | ||
1724 | { "SPK MIXR", "DAC R2 Switch", "DAC R2" }, | ||
1725 | |||
1726 | { "OUT MIXL", "BST1 Switch", "BST1" }, | ||
1727 | { "OUT MIXL", "INL Switch", "INL VOL" }, | ||
1728 | { "OUT MIXL", "DAC L2 Switch", "DAC L2" }, | ||
1729 | { "OUT MIXL", "DAC L1 Switch", "DAC L1" }, | ||
1730 | |||
1731 | { "OUT MIXR", "BST2 Switch", "BST2" }, | ||
1732 | { "OUT MIXR", "INR Switch", "INR VOL" }, | ||
1733 | { "OUT MIXR", "DAC R2 Switch", "DAC R2" }, | ||
1734 | { "OUT MIXR", "DAC R1 Switch", "DAC R1" }, | ||
1735 | |||
1736 | { "HPOVOL MIXL", "DAC1 Switch", "DAC L1" }, | ||
1737 | { "HPOVOL MIXL", "DAC2 Switch", "DAC L2" }, | ||
1738 | { "HPOVOL MIXL", "INL Switch", "INL VOL" }, | ||
1739 | { "HPOVOL MIXL", "BST1 Switch", "BST1" }, | ||
1740 | { "HPOVOL MIXL", NULL, "HPOVOL MIXL Power" }, | ||
1741 | { "HPOVOL MIXR", "DAC1 Switch", "DAC R1" }, | ||
1742 | { "HPOVOL MIXR", "DAC2 Switch", "DAC R2" }, | ||
1743 | { "HPOVOL MIXR", "INR Switch", "INR VOL" }, | ||
1744 | { "HPOVOL MIXR", "BST2 Switch", "BST2" }, | ||
1745 | { "HPOVOL MIXR", NULL, "HPOVOL MIXR Power" }, | ||
1746 | |||
1747 | { "DAC 2", NULL, "DAC L2" }, | ||
1748 | { "DAC 2", NULL, "DAC R2" }, | ||
1749 | { "DAC 1", NULL, "DAC L1" }, | ||
1750 | { "DAC 1", NULL, "DAC R1" }, | ||
1751 | { "HPOVOL L", "Switch", "HPOVOL MIXL" }, | ||
1752 | { "HPOVOL R", "Switch", "HPOVOL MIXR" }, | ||
1753 | { "HPOVOL", NULL, "HPOVOL L" }, | ||
1754 | { "HPOVOL", NULL, "HPOVOL R" }, | ||
1755 | { "HPO MIX", "DAC1 Switch", "DAC 1" }, | ||
1756 | { "HPO MIX", "HPVOL Switch", "HPOVOL" }, | ||
1757 | |||
1758 | { "SPKVOL L", "Switch", "SPK MIXL" }, | ||
1759 | { "SPKVOL R", "Switch", "SPK MIXR" }, | ||
1760 | |||
1761 | { "SPOL MIX", "DAC R1 Switch", "DAC R1" }, | ||
1762 | { "SPOL MIX", "DAC L1 Switch", "DAC L1" }, | ||
1763 | { "SPOL MIX", "SPKVOL R Switch", "SPKVOL R" }, | ||
1764 | { "SPOL MIX", "SPKVOL L Switch", "SPKVOL L" }, | ||
1765 | { "SPOR MIX", "DAC R1 Switch", "DAC R1" }, | ||
1766 | { "SPOR MIX", "SPKVOL R Switch", "SPKVOL R" }, | ||
1767 | |||
1768 | { "LOUT MIX", "DAC L1 Switch", "DAC L1" }, | ||
1769 | { "LOUT MIX", "DAC R1 Switch", "DAC R1" }, | ||
1770 | { "LOUT MIX", "OUTMIX L Switch", "OUT MIXL" }, | ||
1771 | { "LOUT MIX", "OUTMIX R Switch", "OUT MIXR" }, | ||
1772 | |||
1773 | { "PDM1 L Mux", "Stereo DAC", "Stereo DAC MIXL" }, | ||
1774 | { "PDM1 L Mux", "Mono DAC", "Mono DAC MIXL" }, | ||
1775 | { "PDM1 L Mux", NULL, "PDM1 Power" }, | ||
1776 | { "PDM1 R Mux", "Stereo DAC", "Stereo DAC MIXR" }, | ||
1777 | { "PDM1 R Mux", "Mono DAC", "Mono DAC MIXR" }, | ||
1778 | { "PDM1 R Mux", NULL, "PDM1 Power" }, | ||
1779 | |||
1780 | { "HP amp", NULL, "HPO MIX" }, | ||
1781 | { "HP amp", NULL, "JD Power" }, | ||
1782 | { "HP amp", NULL, "Mic Det Power" }, | ||
1783 | { "HP amp", NULL, "LDO2" }, | ||
1784 | { "HPOL", NULL, "HP amp" }, | ||
1785 | { "HPOR", NULL, "HP amp" }, | ||
1786 | |||
1787 | { "LOUT amp", NULL, "LOUT MIX" }, | ||
1788 | { "LOUTL", NULL, "LOUT amp" }, | ||
1789 | { "LOUTR", NULL, "LOUT amp" }, | ||
1790 | |||
1791 | { "PDM1 L", "Switch", "PDM1 L Mux" }, | ||
1792 | { "PDM1 R", "Switch", "PDM1 R Mux" }, | ||
1793 | |||
1794 | { "PDM1L", NULL, "PDM1 L" }, | ||
1795 | { "PDM1R", NULL, "PDM1 R" }, | ||
1796 | |||
1797 | { "SPK amp", NULL, "SPOL MIX" }, | ||
1798 | { "SPK amp", NULL, "SPOR MIX" }, | ||
1799 | { "SPOL", NULL, "SPK amp" }, | ||
1800 | { "SPOR", NULL, "SPK amp" }, | ||
1801 | }; | ||
1802 | |||
1803 | static int get_clk_info(int sclk, int rate) | ||
1804 | { | ||
1805 | int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | ||
1806 | |||
1807 | if (sclk <= 0 || rate <= 0) | ||
1808 | return -EINVAL; | ||
1809 | |||
1810 | rate = rate << 8; | ||
1811 | for (i = 0; i < ARRAY_SIZE(pd); i++) | ||
1812 | if (sclk == rate * pd[i]) | ||
1813 | return i; | ||
1814 | |||
1815 | return -EINVAL; | ||
1816 | } | ||
1817 | |||
1818 | static int rt5645_hw_params(struct snd_pcm_substream *substream, | ||
1819 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
1820 | { | ||
1821 | struct snd_soc_codec *codec = dai->codec; | ||
1822 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
1823 | unsigned int val_len = 0, val_clk, mask_clk; | ||
1824 | int pre_div, bclk_ms, frame_size; | ||
1825 | |||
1826 | rt5645->lrck[dai->id] = params_rate(params); | ||
1827 | pre_div = get_clk_info(rt5645->sysclk, rt5645->lrck[dai->id]); | ||
1828 | if (pre_div < 0) { | ||
1829 | dev_err(codec->dev, "Unsupported clock setting\n"); | ||
1830 | return -EINVAL; | ||
1831 | } | ||
1832 | frame_size = snd_soc_params_to_frame_size(params); | ||
1833 | if (frame_size < 0) { | ||
1834 | dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); | ||
1835 | return -EINVAL; | ||
1836 | } | ||
1837 | bclk_ms = frame_size > 32; | ||
1838 | rt5645->bclk[dai->id] = rt5645->lrck[dai->id] * (32 << bclk_ms); | ||
1839 | |||
1840 | dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", | ||
1841 | rt5645->bclk[dai->id], rt5645->lrck[dai->id]); | ||
1842 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | ||
1843 | bclk_ms, pre_div, dai->id); | ||
1844 | |||
1845 | switch (params_width(params)) { | ||
1846 | case 16: | ||
1847 | break; | ||
1848 | case 20: | ||
1849 | val_len |= RT5645_I2S_DL_20; | ||
1850 | break; | ||
1851 | case 24: | ||
1852 | val_len |= RT5645_I2S_DL_24; | ||
1853 | break; | ||
1854 | case 8: | ||
1855 | val_len |= RT5645_I2S_DL_8; | ||
1856 | break; | ||
1857 | default: | ||
1858 | return -EINVAL; | ||
1859 | } | ||
1860 | |||
1861 | switch (dai->id) { | ||
1862 | case RT5645_AIF1: | ||
1863 | mask_clk = RT5645_I2S_BCLK_MS1_MASK | RT5645_I2S_PD1_MASK; | ||
1864 | val_clk = bclk_ms << RT5645_I2S_BCLK_MS1_SFT | | ||
1865 | pre_div << RT5645_I2S_PD1_SFT; | ||
1866 | snd_soc_update_bits(codec, RT5645_I2S1_SDP, | ||
1867 | RT5645_I2S_DL_MASK, val_len); | ||
1868 | snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); | ||
1869 | break; | ||
1870 | case RT5645_AIF2: | ||
1871 | mask_clk = RT5645_I2S_BCLK_MS2_MASK | RT5645_I2S_PD2_MASK; | ||
1872 | val_clk = bclk_ms << RT5645_I2S_BCLK_MS2_SFT | | ||
1873 | pre_div << RT5645_I2S_PD2_SFT; | ||
1874 | snd_soc_update_bits(codec, RT5645_I2S2_SDP, | ||
1875 | RT5645_I2S_DL_MASK, val_len); | ||
1876 | snd_soc_update_bits(codec, RT5645_ADDA_CLK1, mask_clk, val_clk); | ||
1877 | break; | ||
1878 | default: | ||
1879 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
1880 | return -EINVAL; | ||
1881 | } | ||
1882 | |||
1883 | return 0; | ||
1884 | } | ||
1885 | |||
1886 | static int rt5645_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
1887 | { | ||
1888 | struct snd_soc_codec *codec = dai->codec; | ||
1889 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
1890 | unsigned int reg_val = 0; | ||
1891 | |||
1892 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1893 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1894 | rt5645->master[dai->id] = 1; | ||
1895 | break; | ||
1896 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1897 | reg_val |= RT5645_I2S_MS_S; | ||
1898 | rt5645->master[dai->id] = 0; | ||
1899 | break; | ||
1900 | default: | ||
1901 | return -EINVAL; | ||
1902 | } | ||
1903 | |||
1904 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1905 | case SND_SOC_DAIFMT_NB_NF: | ||
1906 | break; | ||
1907 | case SND_SOC_DAIFMT_IB_NF: | ||
1908 | reg_val |= RT5645_I2S_BP_INV; | ||
1909 | break; | ||
1910 | default: | ||
1911 | return -EINVAL; | ||
1912 | } | ||
1913 | |||
1914 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1915 | case SND_SOC_DAIFMT_I2S: | ||
1916 | break; | ||
1917 | case SND_SOC_DAIFMT_LEFT_J: | ||
1918 | reg_val |= RT5645_I2S_DF_LEFT; | ||
1919 | break; | ||
1920 | case SND_SOC_DAIFMT_DSP_A: | ||
1921 | reg_val |= RT5645_I2S_DF_PCM_A; | ||
1922 | break; | ||
1923 | case SND_SOC_DAIFMT_DSP_B: | ||
1924 | reg_val |= RT5645_I2S_DF_PCM_B; | ||
1925 | break; | ||
1926 | default: | ||
1927 | return -EINVAL; | ||
1928 | } | ||
1929 | switch (dai->id) { | ||
1930 | case RT5645_AIF1: | ||
1931 | snd_soc_update_bits(codec, RT5645_I2S1_SDP, | ||
1932 | RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | | ||
1933 | RT5645_I2S_DF_MASK, reg_val); | ||
1934 | break; | ||
1935 | case RT5645_AIF2: | ||
1936 | snd_soc_update_bits(codec, RT5645_I2S2_SDP, | ||
1937 | RT5645_I2S_MS_MASK | RT5645_I2S_BP_MASK | | ||
1938 | RT5645_I2S_DF_MASK, reg_val); | ||
1939 | break; | ||
1940 | default: | ||
1941 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
1942 | return -EINVAL; | ||
1943 | } | ||
1944 | return 0; | ||
1945 | } | ||
1946 | |||
1947 | static int rt5645_set_dai_sysclk(struct snd_soc_dai *dai, | ||
1948 | int clk_id, unsigned int freq, int dir) | ||
1949 | { | ||
1950 | struct snd_soc_codec *codec = dai->codec; | ||
1951 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
1952 | unsigned int reg_val = 0; | ||
1953 | |||
1954 | if (freq == rt5645->sysclk && clk_id == rt5645->sysclk_src) | ||
1955 | return 0; | ||
1956 | |||
1957 | switch (clk_id) { | ||
1958 | case RT5645_SCLK_S_MCLK: | ||
1959 | reg_val |= RT5645_SCLK_SRC_MCLK; | ||
1960 | break; | ||
1961 | case RT5645_SCLK_S_PLL1: | ||
1962 | reg_val |= RT5645_SCLK_SRC_PLL1; | ||
1963 | break; | ||
1964 | case RT5645_SCLK_S_RCCLK: | ||
1965 | reg_val |= RT5645_SCLK_SRC_RCCLK; | ||
1966 | break; | ||
1967 | default: | ||
1968 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
1969 | return -EINVAL; | ||
1970 | } | ||
1971 | snd_soc_update_bits(codec, RT5645_GLB_CLK, | ||
1972 | RT5645_SCLK_SRC_MASK, reg_val); | ||
1973 | rt5645->sysclk = freq; | ||
1974 | rt5645->sysclk_src = clk_id; | ||
1975 | |||
1976 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | ||
1977 | |||
1978 | return 0; | ||
1979 | } | ||
1980 | |||
1981 | /** | ||
1982 | * rt5645_pll_calc - Calcualte PLL M/N/K code. | ||
1983 | * @freq_in: external clock provided to codec. | ||
1984 | * @freq_out: target clock which codec works on. | ||
1985 | * @pll_code: Pointer to structure with M, N, K and bypass flag. | ||
1986 | * | ||
1987 | * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2 | ||
1988 | * which make calculation more efficiently. | ||
1989 | * | ||
1990 | * Returns 0 for success or negative error code. | ||
1991 | */ | ||
1992 | static int rt5645_pll_calc(const unsigned int freq_in, | ||
1993 | const unsigned int freq_out, struct rt5645_pll_code *pll_code) | ||
1994 | { | ||
1995 | int max_n = RT5645_PLL_N_MAX, max_m = RT5645_PLL_M_MAX; | ||
1996 | int k, n = 0, m = 0, red, n_t, m_t, pll_out, in_t, out_t; | ||
1997 | int red_t = abs(freq_out - freq_in); | ||
1998 | bool bypass = false; | ||
1999 | |||
2000 | if (RT5645_PLL_INP_MAX < freq_in || RT5645_PLL_INP_MIN > freq_in) | ||
2001 | return -EINVAL; | ||
2002 | |||
2003 | k = 100000000 / freq_out - 2; | ||
2004 | if (k > RT5645_PLL_K_MAX) | ||
2005 | k = RT5645_PLL_K_MAX; | ||
2006 | for (n_t = 0; n_t <= max_n; n_t++) { | ||
2007 | in_t = freq_in / (k + 2); | ||
2008 | pll_out = freq_out / (n_t + 2); | ||
2009 | if (in_t < 0) | ||
2010 | continue; | ||
2011 | if (in_t == pll_out) { | ||
2012 | bypass = true; | ||
2013 | n = n_t; | ||
2014 | goto code_find; | ||
2015 | } | ||
2016 | red = abs(in_t - pll_out); | ||
2017 | if (red < red_t) { | ||
2018 | bypass = true; | ||
2019 | n = n_t; | ||
2020 | m = m_t; | ||
2021 | if (red == 0) | ||
2022 | goto code_find; | ||
2023 | red_t = red; | ||
2024 | } | ||
2025 | for (m_t = 0; m_t <= max_m; m_t++) { | ||
2026 | out_t = in_t / (m_t + 2); | ||
2027 | red = abs(out_t - pll_out); | ||
2028 | if (red < red_t) { | ||
2029 | bypass = false; | ||
2030 | n = n_t; | ||
2031 | m = m_t; | ||
2032 | if (red == 0) | ||
2033 | goto code_find; | ||
2034 | red_t = red; | ||
2035 | } | ||
2036 | } | ||
2037 | } | ||
2038 | pr_debug("Only get approximation about PLL\n"); | ||
2039 | |||
2040 | code_find: | ||
2041 | |||
2042 | pll_code->m_bp = bypass; | ||
2043 | pll_code->m_code = m; | ||
2044 | pll_code->n_code = n; | ||
2045 | pll_code->k_code = k; | ||
2046 | return 0; | ||
2047 | } | ||
2048 | |||
2049 | static int rt5645_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
2050 | unsigned int freq_in, unsigned int freq_out) | ||
2051 | { | ||
2052 | struct snd_soc_codec *codec = dai->codec; | ||
2053 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
2054 | struct rt5645_pll_code pll_code; | ||
2055 | int ret; | ||
2056 | |||
2057 | if (source == rt5645->pll_src && freq_in == rt5645->pll_in && | ||
2058 | freq_out == rt5645->pll_out) | ||
2059 | return 0; | ||
2060 | |||
2061 | if (!freq_in || !freq_out) { | ||
2062 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
2063 | |||
2064 | rt5645->pll_in = 0; | ||
2065 | rt5645->pll_out = 0; | ||
2066 | snd_soc_update_bits(codec, RT5645_GLB_CLK, | ||
2067 | RT5645_SCLK_SRC_MASK, RT5645_SCLK_SRC_MCLK); | ||
2068 | return 0; | ||
2069 | } | ||
2070 | |||
2071 | switch (source) { | ||
2072 | case RT5645_PLL1_S_MCLK: | ||
2073 | snd_soc_update_bits(codec, RT5645_GLB_CLK, | ||
2074 | RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_MCLK); | ||
2075 | break; | ||
2076 | case RT5645_PLL1_S_BCLK1: | ||
2077 | case RT5645_PLL1_S_BCLK2: | ||
2078 | switch (dai->id) { | ||
2079 | case RT5645_AIF1: | ||
2080 | snd_soc_update_bits(codec, RT5645_GLB_CLK, | ||
2081 | RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK1); | ||
2082 | break; | ||
2083 | case RT5645_AIF2: | ||
2084 | snd_soc_update_bits(codec, RT5645_GLB_CLK, | ||
2085 | RT5645_PLL1_SRC_MASK, RT5645_PLL1_SRC_BCLK2); | ||
2086 | break; | ||
2087 | default: | ||
2088 | dev_err(codec->dev, "Invalid dai->id: %d\n", dai->id); | ||
2089 | return -EINVAL; | ||
2090 | } | ||
2091 | break; | ||
2092 | default: | ||
2093 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
2094 | return -EINVAL; | ||
2095 | } | ||
2096 | |||
2097 | ret = rt5645_pll_calc(freq_in, freq_out, &pll_code); | ||
2098 | if (ret < 0) { | ||
2099 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
2100 | return ret; | ||
2101 | } | ||
2102 | |||
2103 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=%d\n", | ||
2104 | pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), | ||
2105 | pll_code.n_code, pll_code.k_code); | ||
2106 | |||
2107 | snd_soc_write(codec, RT5645_PLL_CTRL1, | ||
2108 | pll_code.n_code << RT5645_PLL_N_SFT | pll_code.k_code); | ||
2109 | snd_soc_write(codec, RT5645_PLL_CTRL2, | ||
2110 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5645_PLL_M_SFT | | ||
2111 | pll_code.m_bp << RT5645_PLL_M_BP_SFT); | ||
2112 | |||
2113 | rt5645->pll_in = freq_in; | ||
2114 | rt5645->pll_out = freq_out; | ||
2115 | rt5645->pll_src = source; | ||
2116 | |||
2117 | return 0; | ||
2118 | } | ||
2119 | |||
2120 | static int rt5645_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, | ||
2121 | unsigned int rx_mask, int slots, int slot_width) | ||
2122 | { | ||
2123 | struct snd_soc_codec *codec = dai->codec; | ||
2124 | unsigned int val = 0; | ||
2125 | |||
2126 | if (rx_mask || tx_mask) | ||
2127 | val |= (1 << 14); | ||
2128 | |||
2129 | switch (slots) { | ||
2130 | case 4: | ||
2131 | val |= (1 << 12); | ||
2132 | break; | ||
2133 | case 6: | ||
2134 | val |= (2 << 12); | ||
2135 | break; | ||
2136 | case 8: | ||
2137 | val |= (3 << 12); | ||
2138 | break; | ||
2139 | case 2: | ||
2140 | default: | ||
2141 | break; | ||
2142 | } | ||
2143 | |||
2144 | switch (slot_width) { | ||
2145 | case 20: | ||
2146 | val |= (1 << 10); | ||
2147 | break; | ||
2148 | case 24: | ||
2149 | val |= (2 << 10); | ||
2150 | break; | ||
2151 | case 32: | ||
2152 | val |= (3 << 10); | ||
2153 | break; | ||
2154 | case 16: | ||
2155 | default: | ||
2156 | break; | ||
2157 | } | ||
2158 | |||
2159 | snd_soc_update_bits(codec, RT5645_TDM_CTRL_1, 0x7c00, val); | ||
2160 | |||
2161 | return 0; | ||
2162 | } | ||
2163 | |||
2164 | static int rt5645_set_bias_level(struct snd_soc_codec *codec, | ||
2165 | enum snd_soc_bias_level level) | ||
2166 | { | ||
2167 | switch (level) { | ||
2168 | case SND_SOC_BIAS_STANDBY: | ||
2169 | if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) { | ||
2170 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
2171 | RT5645_PWR_VREF1 | RT5645_PWR_MB | | ||
2172 | RT5645_PWR_BG | RT5645_PWR_VREF2, | ||
2173 | RT5645_PWR_VREF1 | RT5645_PWR_MB | | ||
2174 | RT5645_PWR_BG | RT5645_PWR_VREF2); | ||
2175 | mdelay(10); | ||
2176 | snd_soc_update_bits(codec, RT5645_PWR_ANLG1, | ||
2177 | RT5645_PWR_FV1 | RT5645_PWR_FV2, | ||
2178 | RT5645_PWR_FV1 | RT5645_PWR_FV2); | ||
2179 | snd_soc_update_bits(codec, RT5645_GEN_CTRL1, | ||
2180 | RT5645_DIG_GATE_CTRL, RT5645_DIG_GATE_CTRL); | ||
2181 | } | ||
2182 | break; | ||
2183 | |||
2184 | case SND_SOC_BIAS_OFF: | ||
2185 | snd_soc_write(codec, RT5645_DEPOP_M2, 0x1100); | ||
2186 | snd_soc_write(codec, RT5645_GEN_CTRL1, 0x0128); | ||
2187 | snd_soc_write(codec, RT5645_PWR_DIG1, 0x0000); | ||
2188 | snd_soc_write(codec, RT5645_PWR_DIG2, 0x0000); | ||
2189 | snd_soc_write(codec, RT5645_PWR_VOL, 0x0000); | ||
2190 | snd_soc_write(codec, RT5645_PWR_MIXER, 0x0000); | ||
2191 | snd_soc_write(codec, RT5645_PWR_ANLG1, 0x0000); | ||
2192 | snd_soc_write(codec, RT5645_PWR_ANLG2, 0x0000); | ||
2193 | break; | ||
2194 | |||
2195 | default: | ||
2196 | break; | ||
2197 | } | ||
2198 | codec->dapm.bias_level = level; | ||
2199 | |||
2200 | return 0; | ||
2201 | } | ||
2202 | |||
2203 | static int rt5645_probe(struct snd_soc_codec *codec) | ||
2204 | { | ||
2205 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
2206 | |||
2207 | rt5645->codec = codec; | ||
2208 | |||
2209 | rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
2210 | |||
2211 | snd_soc_update_bits(codec, RT5645_CHARGE_PUMP, 0x0300, 0x0200); | ||
2212 | |||
2213 | return 0; | ||
2214 | } | ||
2215 | |||
2216 | static int rt5645_remove(struct snd_soc_codec *codec) | ||
2217 | { | ||
2218 | rt5645_reset(codec); | ||
2219 | return 0; | ||
2220 | } | ||
2221 | |||
2222 | #ifdef CONFIG_PM | ||
2223 | static int rt5645_suspend(struct snd_soc_codec *codec) | ||
2224 | { | ||
2225 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
2226 | |||
2227 | regcache_cache_only(rt5645->regmap, true); | ||
2228 | regcache_mark_dirty(rt5645->regmap); | ||
2229 | |||
2230 | return 0; | ||
2231 | } | ||
2232 | |||
2233 | static int rt5645_resume(struct snd_soc_codec *codec) | ||
2234 | { | ||
2235 | struct rt5645_priv *rt5645 = snd_soc_codec_get_drvdata(codec); | ||
2236 | |||
2237 | regcache_cache_only(rt5645->regmap, false); | ||
2238 | regcache_sync(rt5645->regmap); | ||
2239 | |||
2240 | return 0; | ||
2241 | } | ||
2242 | #else | ||
2243 | #define rt5645_suspend NULL | ||
2244 | #define rt5645_resume NULL | ||
2245 | #endif | ||
2246 | |||
2247 | #define RT5645_STEREO_RATES SNDRV_PCM_RATE_8000_96000 | ||
2248 | #define RT5645_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
2249 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
2250 | |||
2251 | static struct snd_soc_dai_ops rt5645_aif_dai_ops = { | ||
2252 | .hw_params = rt5645_hw_params, | ||
2253 | .set_fmt = rt5645_set_dai_fmt, | ||
2254 | .set_sysclk = rt5645_set_dai_sysclk, | ||
2255 | .set_tdm_slot = rt5645_set_tdm_slot, | ||
2256 | .set_pll = rt5645_set_dai_pll, | ||
2257 | }; | ||
2258 | |||
2259 | static struct snd_soc_dai_driver rt5645_dai[] = { | ||
2260 | { | ||
2261 | .name = "rt5645-aif1", | ||
2262 | .id = RT5645_AIF1, | ||
2263 | .playback = { | ||
2264 | .stream_name = "AIF1 Playback", | ||
2265 | .channels_min = 1, | ||
2266 | .channels_max = 2, | ||
2267 | .rates = RT5645_STEREO_RATES, | ||
2268 | .formats = RT5645_FORMATS, | ||
2269 | }, | ||
2270 | .capture = { | ||
2271 | .stream_name = "AIF1 Capture", | ||
2272 | .channels_min = 1, | ||
2273 | .channels_max = 2, | ||
2274 | .rates = RT5645_STEREO_RATES, | ||
2275 | .formats = RT5645_FORMATS, | ||
2276 | }, | ||
2277 | .ops = &rt5645_aif_dai_ops, | ||
2278 | }, | ||
2279 | { | ||
2280 | .name = "rt5645-aif2", | ||
2281 | .id = RT5645_AIF2, | ||
2282 | .playback = { | ||
2283 | .stream_name = "AIF2 Playback", | ||
2284 | .channels_min = 1, | ||
2285 | .channels_max = 2, | ||
2286 | .rates = RT5645_STEREO_RATES, | ||
2287 | .formats = RT5645_FORMATS, | ||
2288 | }, | ||
2289 | .capture = { | ||
2290 | .stream_name = "AIF2 Capture", | ||
2291 | .channels_min = 1, | ||
2292 | .channels_max = 2, | ||
2293 | .rates = RT5645_STEREO_RATES, | ||
2294 | .formats = RT5645_FORMATS, | ||
2295 | }, | ||
2296 | .ops = &rt5645_aif_dai_ops, | ||
2297 | }, | ||
2298 | }; | ||
2299 | |||
2300 | static struct snd_soc_codec_driver soc_codec_dev_rt5645 = { | ||
2301 | .probe = rt5645_probe, | ||
2302 | .remove = rt5645_remove, | ||
2303 | .suspend = rt5645_suspend, | ||
2304 | .resume = rt5645_resume, | ||
2305 | .set_bias_level = rt5645_set_bias_level, | ||
2306 | .idle_bias_off = true, | ||
2307 | .controls = rt5645_snd_controls, | ||
2308 | .num_controls = ARRAY_SIZE(rt5645_snd_controls), | ||
2309 | .dapm_widgets = rt5645_dapm_widgets, | ||
2310 | .num_dapm_widgets = ARRAY_SIZE(rt5645_dapm_widgets), | ||
2311 | .dapm_routes = rt5645_dapm_routes, | ||
2312 | .num_dapm_routes = ARRAY_SIZE(rt5645_dapm_routes), | ||
2313 | }; | ||
2314 | |||
2315 | static const struct regmap_config rt5645_regmap = { | ||
2316 | .reg_bits = 8, | ||
2317 | .val_bits = 16, | ||
2318 | |||
2319 | .max_register = RT5645_VENDOR_ID2 + 1 + (ARRAY_SIZE(rt5645_ranges) * | ||
2320 | RT5645_PR_SPACING), | ||
2321 | .volatile_reg = rt5645_volatile_register, | ||
2322 | .readable_reg = rt5645_readable_register, | ||
2323 | |||
2324 | .cache_type = REGCACHE_RBTREE, | ||
2325 | .reg_defaults = rt5645_reg, | ||
2326 | .num_reg_defaults = ARRAY_SIZE(rt5645_reg), | ||
2327 | .ranges = rt5645_ranges, | ||
2328 | .num_ranges = ARRAY_SIZE(rt5645_ranges), | ||
2329 | }; | ||
2330 | |||
2331 | static const struct i2c_device_id rt5645_i2c_id[] = { | ||
2332 | { "rt5645", 0 }, | ||
2333 | { } | ||
2334 | }; | ||
2335 | MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id); | ||
2336 | |||
2337 | static int rt5645_i2c_probe(struct i2c_client *i2c, | ||
2338 | const struct i2c_device_id *id) | ||
2339 | { | ||
2340 | struct rt5645_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
2341 | struct rt5645_priv *rt5645; | ||
2342 | int ret; | ||
2343 | unsigned int val; | ||
2344 | |||
2345 | rt5645 = devm_kzalloc(&i2c->dev, sizeof(struct rt5645_priv), | ||
2346 | GFP_KERNEL); | ||
2347 | if (rt5645 == NULL) | ||
2348 | return -ENOMEM; | ||
2349 | |||
2350 | i2c_set_clientdata(i2c, rt5645); | ||
2351 | |||
2352 | if (pdata) | ||
2353 | rt5645->pdata = *pdata; | ||
2354 | |||
2355 | rt5645->regmap = devm_regmap_init_i2c(i2c, &rt5645_regmap); | ||
2356 | if (IS_ERR(rt5645->regmap)) { | ||
2357 | ret = PTR_ERR(rt5645->regmap); | ||
2358 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
2359 | ret); | ||
2360 | return ret; | ||
2361 | } | ||
2362 | |||
2363 | regmap_read(rt5645->regmap, RT5645_VENDOR_ID2, &val); | ||
2364 | if (val != RT5645_DEVICE_ID) { | ||
2365 | dev_err(&i2c->dev, | ||
2366 | "Device with ID register %x is not rt5645\n", val); | ||
2367 | return -ENODEV; | ||
2368 | } | ||
2369 | |||
2370 | regmap_write(rt5645->regmap, RT5645_RESET, 0); | ||
2371 | |||
2372 | ret = regmap_register_patch(rt5645->regmap, init_list, | ||
2373 | ARRAY_SIZE(init_list)); | ||
2374 | if (ret != 0) | ||
2375 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | ||
2376 | |||
2377 | if (rt5645->pdata.in2_diff) | ||
2378 | regmap_update_bits(rt5645->regmap, RT5645_IN2_CTRL, | ||
2379 | RT5645_IN_DF2, RT5645_IN_DF2); | ||
2380 | |||
2381 | if (rt5645->pdata.dmic_en) { | ||
2382 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2383 | RT5645_GP2_PIN_MASK, RT5645_GP2_PIN_DMIC1_SCL); | ||
2384 | |||
2385 | switch (rt5645->pdata.dmic1_data_pin) { | ||
2386 | case RT5645_DMIC_DATA_IN2N: | ||
2387 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2388 | RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_IN2N); | ||
2389 | break; | ||
2390 | |||
2391 | case RT5645_DMIC_DATA_GPIO5: | ||
2392 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2393 | RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO5); | ||
2394 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2395 | RT5645_GP5_PIN_MASK, RT5645_GP5_PIN_DMIC1_SDA); | ||
2396 | break; | ||
2397 | |||
2398 | case RT5645_DMIC_DATA_GPIO11: | ||
2399 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2400 | RT5645_DMIC_1_DP_MASK, RT5645_DMIC_1_DP_GPIO11); | ||
2401 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2402 | RT5645_GP11_PIN_MASK, | ||
2403 | RT5645_GP11_PIN_DMIC1_SDA); | ||
2404 | break; | ||
2405 | |||
2406 | default: | ||
2407 | break; | ||
2408 | } | ||
2409 | |||
2410 | switch (rt5645->pdata.dmic2_data_pin) { | ||
2411 | case RT5645_DMIC_DATA_IN2P: | ||
2412 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2413 | RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_IN2P); | ||
2414 | break; | ||
2415 | |||
2416 | case RT5645_DMIC_DATA_GPIO6: | ||
2417 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2418 | RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO6); | ||
2419 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2420 | RT5645_GP6_PIN_MASK, RT5645_GP6_PIN_DMIC2_SDA); | ||
2421 | break; | ||
2422 | |||
2423 | case RT5645_DMIC_DATA_GPIO10: | ||
2424 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2425 | RT5645_DMIC_2_DP_MASK, RT5645_DMIC_2_DP_GPIO10); | ||
2426 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2427 | RT5645_GP10_PIN_MASK, | ||
2428 | RT5645_GP10_PIN_DMIC2_SDA); | ||
2429 | break; | ||
2430 | |||
2431 | case RT5645_DMIC_DATA_GPIO12: | ||
2432 | regmap_update_bits(rt5645->regmap, RT5645_DMIC_CTRL1, | ||
2433 | RT5645_DMIC_1_DP_MASK, RT5645_DMIC_2_DP_GPIO12); | ||
2434 | regmap_update_bits(rt5645->regmap, RT5645_GPIO_CTRL1, | ||
2435 | RT5645_GP12_PIN_MASK, | ||
2436 | RT5645_GP12_PIN_DMIC2_SDA); | ||
2437 | break; | ||
2438 | |||
2439 | default: | ||
2440 | break; | ||
2441 | } | ||
2442 | |||
2443 | } | ||
2444 | |||
2445 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5645, | ||
2446 | rt5645_dai, ARRAY_SIZE(rt5645_dai)); | ||
2447 | if (ret < 0) | ||
2448 | goto err; | ||
2449 | |||
2450 | return 0; | ||
2451 | err: | ||
2452 | return ret; | ||
2453 | } | ||
2454 | |||
2455 | static int rt5645_i2c_remove(struct i2c_client *i2c) | ||
2456 | { | ||
2457 | snd_soc_unregister_codec(&i2c->dev); | ||
2458 | |||
2459 | return 0; | ||
2460 | } | ||
2461 | |||
2462 | static struct i2c_driver rt5645_i2c_driver = { | ||
2463 | .driver = { | ||
2464 | .name = "rt5645", | ||
2465 | .owner = THIS_MODULE, | ||
2466 | }, | ||
2467 | .probe = rt5645_i2c_probe, | ||
2468 | .remove = rt5645_i2c_remove, | ||
2469 | .id_table = rt5645_i2c_id, | ||
2470 | }; | ||
2471 | module_i2c_driver(rt5645_i2c_driver); | ||
2472 | |||
2473 | MODULE_DESCRIPTION("ASoC RT5645 driver"); | ||
2474 | MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); | ||
2475 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rt5645.h b/sound/soc/codecs/rt5645.h new file mode 100644 index 000000000000..345aa3f5d14f --- /dev/null +++ b/sound/soc/codecs/rt5645.h | |||
@@ -0,0 +1,2188 @@ | |||
1 | /* | ||
2 | * rt5645.h -- RT5645 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2013 Realtek Microelectronics | ||
5 | * Author: Bard Liao <bardliao@realtek.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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __RT5645_H__ | ||
13 | #define __RT5645_H__ | ||
14 | |||
15 | #include <sound/rt5645.h> | ||
16 | |||
17 | /* Info */ | ||
18 | #define RT5645_RESET 0x00 | ||
19 | #define RT5645_VENDOR_ID 0xfd | ||
20 | #define RT5645_VENDOR_ID1 0xfe | ||
21 | #define RT5645_VENDOR_ID2 0xff | ||
22 | /* I/O - Output */ | ||
23 | #define RT5645_SPK_VOL 0x01 | ||
24 | #define RT5645_HP_VOL 0x02 | ||
25 | #define RT5645_LOUT1 0x03 | ||
26 | #define RT5645_LOUT_CTRL 0x05 | ||
27 | /* I/O - Input */ | ||
28 | #define RT5645_IN1_CTRL1 0x0a | ||
29 | #define RT5645_IN1_CTRL2 0x0b | ||
30 | #define RT5645_IN1_CTRL3 0x0c | ||
31 | #define RT5645_IN2_CTRL 0x0d | ||
32 | #define RT5645_INL1_INR1_VOL 0x0f | ||
33 | #define RT5645_SPK_FUNC_LIM 0x14 | ||
34 | #define RT5645_ADJ_HPF_CTRL 0x16 | ||
35 | /* I/O - ADC/DAC/DMIC */ | ||
36 | #define RT5645_DAC1_DIG_VOL 0x19 | ||
37 | #define RT5645_DAC2_DIG_VOL 0x1a | ||
38 | #define RT5645_DAC_CTRL 0x1b | ||
39 | #define RT5645_STO1_ADC_DIG_VOL 0x1c | ||
40 | #define RT5645_MONO_ADC_DIG_VOL 0x1d | ||
41 | #define RT5645_ADC_BST_VOL1 0x1e | ||
42 | /* Mixer - D-D */ | ||
43 | #define RT5645_ADC_BST_VOL2 0x20 | ||
44 | #define RT5645_STO1_ADC_MIXER 0x27 | ||
45 | #define RT5645_MONO_ADC_MIXER 0x28 | ||
46 | #define RT5645_AD_DA_MIXER 0x29 | ||
47 | #define RT5645_STO_DAC_MIXER 0x2a | ||
48 | #define RT5645_MONO_DAC_MIXER 0x2b | ||
49 | #define RT5645_DIG_MIXER 0x2c | ||
50 | #define RT5645_DIG_INF1_DATA 0x2f | ||
51 | /* Mixer - PDM */ | ||
52 | #define RT5645_PDM_OUT_CTRL 0x31 | ||
53 | /* Mixer - ADC */ | ||
54 | #define RT5645_REC_L1_MIXER 0x3b | ||
55 | #define RT5645_REC_L2_MIXER 0x3c | ||
56 | #define RT5645_REC_R1_MIXER 0x3d | ||
57 | #define RT5645_REC_R2_MIXER 0x3e | ||
58 | /* Mixer - DAC */ | ||
59 | #define RT5645_HPMIXL_CTRL 0x3f | ||
60 | #define RT5645_HPOMIXL_CTRL 0x40 | ||
61 | #define RT5645_HPMIXR_CTRL 0x41 | ||
62 | #define RT5645_HPOMIXR_CTRL 0x42 | ||
63 | #define RT5645_HPO_MIXER 0x45 | ||
64 | #define RT5645_SPK_L_MIXER 0x46 | ||
65 | #define RT5645_SPK_R_MIXER 0x47 | ||
66 | #define RT5645_SPO_MIXER 0x48 | ||
67 | #define RT5645_SPO_CLSD_RATIO 0x4a | ||
68 | #define RT5645_OUT_L_GAIN1 0x4d | ||
69 | #define RT5645_OUT_L_GAIN2 0x4e | ||
70 | #define RT5645_OUT_L1_MIXER 0x4f | ||
71 | #define RT5645_OUT_R_GAIN1 0x50 | ||
72 | #define RT5645_OUT_R_GAIN2 0x51 | ||
73 | #define RT5645_OUT_R1_MIXER 0x52 | ||
74 | #define RT5645_LOUT_MIXER 0x53 | ||
75 | /* Haptic */ | ||
76 | #define RT5645_HAPTIC_CTRL1 0x56 | ||
77 | #define RT5645_HAPTIC_CTRL2 0x57 | ||
78 | #define RT5645_HAPTIC_CTRL3 0x58 | ||
79 | #define RT5645_HAPTIC_CTRL4 0x59 | ||
80 | #define RT5645_HAPTIC_CTRL5 0x5a | ||
81 | #define RT5645_HAPTIC_CTRL6 0x5b | ||
82 | #define RT5645_HAPTIC_CTRL7 0x5c | ||
83 | #define RT5645_HAPTIC_CTRL8 0x5d | ||
84 | #define RT5645_HAPTIC_CTRL9 0x5e | ||
85 | #define RT5645_HAPTIC_CTRL10 0x5f | ||
86 | /* Power */ | ||
87 | #define RT5645_PWR_DIG1 0x61 | ||
88 | #define RT5645_PWR_DIG2 0x62 | ||
89 | #define RT5645_PWR_ANLG1 0x63 | ||
90 | #define RT5645_PWR_ANLG2 0x64 | ||
91 | #define RT5645_PWR_MIXER 0x65 | ||
92 | #define RT5645_PWR_VOL 0x66 | ||
93 | /* Private Register Control */ | ||
94 | #define RT5645_PRIV_INDEX 0x6a | ||
95 | #define RT5645_PRIV_DATA 0x6c | ||
96 | /* Format - ADC/DAC */ | ||
97 | #define RT5645_I2S1_SDP 0x70 | ||
98 | #define RT5645_I2S2_SDP 0x71 | ||
99 | #define RT5645_ADDA_CLK1 0x73 | ||
100 | #define RT5645_ADDA_CLK2 0x74 | ||
101 | #define RT5645_DMIC_CTRL1 0x75 | ||
102 | #define RT5645_DMIC_CTRL2 0x76 | ||
103 | /* Format - TDM Control */ | ||
104 | #define RT5645_TDM_CTRL_1 0x77 | ||
105 | #define RT5645_TDM_CTRL_2 0x78 | ||
106 | #define RT5645_TDM_CTRL_3 0x79 | ||
107 | |||
108 | /* Function - Analog */ | ||
109 | #define RT5645_GLB_CLK 0x80 | ||
110 | #define RT5645_PLL_CTRL1 0x81 | ||
111 | #define RT5645_PLL_CTRL2 0x82 | ||
112 | #define RT5645_ASRC_1 0x83 | ||
113 | #define RT5645_ASRC_2 0x84 | ||
114 | #define RT5645_ASRC_3 0x85 | ||
115 | #define RT5645_ASRC_4 0x8a | ||
116 | #define RT5645_DEPOP_M1 0x8e | ||
117 | #define RT5645_DEPOP_M2 0x8f | ||
118 | #define RT5645_DEPOP_M3 0x90 | ||
119 | #define RT5645_CHARGE_PUMP 0x91 | ||
120 | #define RT5645_MICBIAS 0x93 | ||
121 | #define RT5645_A_JD_CTRL1 0x94 | ||
122 | #define RT5645_VAD_CTRL4 0x9d | ||
123 | #define RT5645_CLSD_OUT_CTRL 0xa0 | ||
124 | /* Function - Digital */ | ||
125 | #define RT5645_ADC_EQ_CTRL1 0xae | ||
126 | #define RT5645_ADC_EQ_CTRL2 0xaf | ||
127 | #define RT5645_EQ_CTRL1 0xb0 | ||
128 | #define RT5645_EQ_CTRL2 0xb1 | ||
129 | #define RT5645_ALC_CTRL_1 0xb3 | ||
130 | #define RT5645_ALC_CTRL_2 0xb4 | ||
131 | #define RT5645_ALC_CTRL_3 0xb5 | ||
132 | #define RT5645_ALC_CTRL_4 0xb6 | ||
133 | #define RT5645_ALC_CTRL_5 0xb7 | ||
134 | #define RT5645_JD_CTRL 0xbb | ||
135 | #define RT5645_IRQ_CTRL1 0xbc | ||
136 | #define RT5645_IRQ_CTRL2 0xbd | ||
137 | #define RT5645_IRQ_CTRL3 0xbe | ||
138 | #define RT5645_INT_IRQ_ST 0xbf | ||
139 | #define RT5645_GPIO_CTRL1 0xc0 | ||
140 | #define RT5645_GPIO_CTRL2 0xc1 | ||
141 | #define RT5645_GPIO_CTRL3 0xc2 | ||
142 | #define RT5645_BASS_BACK 0xcf | ||
143 | #define RT5645_MP3_PLUS1 0xd0 | ||
144 | #define RT5645_MP3_PLUS2 0xd1 | ||
145 | #define RT5645_ADJ_HPF1 0xd3 | ||
146 | #define RT5645_ADJ_HPF2 0xd4 | ||
147 | #define RT5645_HP_CALIB_AMP_DET 0xd6 | ||
148 | #define RT5645_SV_ZCD1 0xd9 | ||
149 | #define RT5645_SV_ZCD2 0xda | ||
150 | #define RT5645_IL_CMD 0xdb | ||
151 | #define RT5645_IL_CMD2 0xdc | ||
152 | #define RT5645_IL_CMD3 0xdd | ||
153 | #define RT5645_DRC1_HL_CTRL1 0xe7 | ||
154 | #define RT5645_DRC2_HL_CTRL1 0xe9 | ||
155 | #define RT5645_MUTI_DRC_CTRL1 0xea | ||
156 | #define RT5645_ADC_MONO_HP_CTRL1 0xec | ||
157 | #define RT5645_ADC_MONO_HP_CTRL2 0xed | ||
158 | #define RT5645_DRC2_CTRL1 0xf0 | ||
159 | #define RT5645_DRC2_CTRL2 0xf1 | ||
160 | #define RT5645_DRC2_CTRL3 0xf2 | ||
161 | #define RT5645_DRC2_CTRL4 0xf3 | ||
162 | #define RT5645_DRC2_CTRL5 0xf4 | ||
163 | #define RT5645_JD_CTRL3 0xf8 | ||
164 | #define RT5645_JD_CTRL4 0xf9 | ||
165 | /* General Control */ | ||
166 | #define RT5645_GEN_CTRL1 0xfa | ||
167 | #define RT5645_GEN_CTRL2 0xfb | ||
168 | #define RT5645_GEN_CTRL3 0xfc | ||
169 | |||
170 | |||
171 | /* Index of Codec Private Register definition */ | ||
172 | #define RT5645_DIG_VOL 0x00 | ||
173 | #define RT5645_PR_ALC_CTRL_1 0x01 | ||
174 | #define RT5645_PR_ALC_CTRL_2 0x02 | ||
175 | #define RT5645_PR_ALC_CTRL_3 0x03 | ||
176 | #define RT5645_PR_ALC_CTRL_4 0x04 | ||
177 | #define RT5645_PR_ALC_CTRL_5 0x05 | ||
178 | #define RT5645_PR_ALC_CTRL_6 0x06 | ||
179 | #define RT5645_BIAS_CUR1 0x12 | ||
180 | #define RT5645_BIAS_CUR3 0x14 | ||
181 | #define RT5645_CLSD_INT_REG1 0x1c | ||
182 | #define RT5645_MAMP_INT_REG2 0x37 | ||
183 | #define RT5645_CHOP_DAC_ADC 0x3d | ||
184 | #define RT5645_MIXER_INT_REG 0x3f | ||
185 | #define RT5645_3D_SPK 0x63 | ||
186 | #define RT5645_WND_1 0x6c | ||
187 | #define RT5645_WND_2 0x6d | ||
188 | #define RT5645_WND_3 0x6e | ||
189 | #define RT5645_WND_4 0x6f | ||
190 | #define RT5645_WND_5 0x70 | ||
191 | #define RT5645_WND_8 0x73 | ||
192 | #define RT5645_DIP_SPK_INF 0x75 | ||
193 | #define RT5645_HP_DCC_INT1 0x77 | ||
194 | #define RT5645_EQ_BW_LOP 0xa0 | ||
195 | #define RT5645_EQ_GN_LOP 0xa1 | ||
196 | #define RT5645_EQ_FC_BP1 0xa2 | ||
197 | #define RT5645_EQ_BW_BP1 0xa3 | ||
198 | #define RT5645_EQ_GN_BP1 0xa4 | ||
199 | #define RT5645_EQ_FC_BP2 0xa5 | ||
200 | #define RT5645_EQ_BW_BP2 0xa6 | ||
201 | #define RT5645_EQ_GN_BP2 0xa7 | ||
202 | #define RT5645_EQ_FC_BP3 0xa8 | ||
203 | #define RT5645_EQ_BW_BP3 0xa9 | ||
204 | #define RT5645_EQ_GN_BP3 0xaa | ||
205 | #define RT5645_EQ_FC_BP4 0xab | ||
206 | #define RT5645_EQ_BW_BP4 0xac | ||
207 | #define RT5645_EQ_GN_BP4 0xad | ||
208 | #define RT5645_EQ_FC_HIP1 0xae | ||
209 | #define RT5645_EQ_GN_HIP1 0xaf | ||
210 | #define RT5645_EQ_FC_HIP2 0xb0 | ||
211 | #define RT5645_EQ_BW_HIP2 0xb1 | ||
212 | #define RT5645_EQ_GN_HIP2 0xb2 | ||
213 | #define RT5645_EQ_PRE_VOL 0xb3 | ||
214 | #define RT5645_EQ_PST_VOL 0xb4 | ||
215 | |||
216 | |||
217 | /* global definition */ | ||
218 | #define RT5645_L_MUTE (0x1 << 15) | ||
219 | #define RT5645_L_MUTE_SFT 15 | ||
220 | #define RT5645_VOL_L_MUTE (0x1 << 14) | ||
221 | #define RT5645_VOL_L_SFT 14 | ||
222 | #define RT5645_R_MUTE (0x1 << 7) | ||
223 | #define RT5645_R_MUTE_SFT 7 | ||
224 | #define RT5645_VOL_R_MUTE (0x1 << 6) | ||
225 | #define RT5645_VOL_R_SFT 6 | ||
226 | #define RT5645_L_VOL_MASK (0x3f << 8) | ||
227 | #define RT5645_L_VOL_SFT 8 | ||
228 | #define RT5645_R_VOL_MASK (0x3f) | ||
229 | #define RT5645_R_VOL_SFT 0 | ||
230 | |||
231 | /* IN1 Control 1 (0x0a) */ | ||
232 | #define RT5645_CBJ_BST1_MASK (0xf << 12) | ||
233 | #define RT5645_CBJ_BST1_SFT (12) | ||
234 | #define RT5645_CBJ_JD_HP_EN (0x1 << 9) | ||
235 | #define RT5645_CBJ_JD_MIC_EN (0x1 << 8) | ||
236 | #define RT5645_CBJ_JD_MIC_SW_EN (0x1 << 7) | ||
237 | #define RT5645_CBJ_MIC_SEL_R (0x1 << 6) | ||
238 | #define RT5645_CBJ_MIC_SEL_L (0x1 << 5) | ||
239 | #define RT5645_CBJ_MIC_SW (0x1 << 4) | ||
240 | #define RT5645_CBJ_BST1_EN (0x1 << 2) | ||
241 | |||
242 | /* IN1 Control 2 (0x0b) */ | ||
243 | #define RT5645_CBJ_MN_JD (0x1 << 12) | ||
244 | #define RT5645_CAPLESS_EN (0x1 << 11) | ||
245 | #define RT5645_CBJ_DET_MODE (0x1 << 7) | ||
246 | |||
247 | /* IN1 Control 3 (0x0c) */ | ||
248 | #define RT5645_CBJ_TIE_G_L (0x1 << 15) | ||
249 | #define RT5645_CBJ_TIE_G_R (0x1 << 14) | ||
250 | |||
251 | /* IN2 Control (0x0d) */ | ||
252 | #define RT5645_BST_MASK1 (0xf<<12) | ||
253 | #define RT5645_BST_SFT1 12 | ||
254 | #define RT5645_BST_MASK2 (0xf<<8) | ||
255 | #define RT5645_BST_SFT2 8 | ||
256 | #define RT5645_IN_DF2 (0x1 << 6) | ||
257 | #define RT5645_IN_SFT2 6 | ||
258 | |||
259 | /* INL and INR Volume Control (0x0f) */ | ||
260 | #define RT5645_INL_SEL_MASK (0x1 << 15) | ||
261 | #define RT5645_INL_SEL_SFT 15 | ||
262 | #define RT5645_INL_SEL_IN4P (0x0 << 15) | ||
263 | #define RT5645_INL_SEL_MONOP (0x1 << 15) | ||
264 | #define RT5645_INL_VOL_MASK (0x1f << 8) | ||
265 | #define RT5645_INL_VOL_SFT 8 | ||
266 | #define RT5645_INR_SEL_MASK (0x1 << 7) | ||
267 | #define RT5645_INR_SEL_SFT 7 | ||
268 | #define RT5645_INR_SEL_IN4N (0x0 << 7) | ||
269 | #define RT5645_INR_SEL_MONON (0x1 << 7) | ||
270 | #define RT5645_INR_VOL_MASK (0x1f) | ||
271 | #define RT5645_INR_VOL_SFT 0 | ||
272 | |||
273 | /* DAC1 Digital Volume (0x19) */ | ||
274 | #define RT5645_DAC_L1_VOL_MASK (0xff << 8) | ||
275 | #define RT5645_DAC_L1_VOL_SFT 8 | ||
276 | #define RT5645_DAC_R1_VOL_MASK (0xff) | ||
277 | #define RT5645_DAC_R1_VOL_SFT 0 | ||
278 | |||
279 | /* DAC2 Digital Volume (0x1a) */ | ||
280 | #define RT5645_DAC_L2_VOL_MASK (0xff << 8) | ||
281 | #define RT5645_DAC_L2_VOL_SFT 8 | ||
282 | #define RT5645_DAC_R2_VOL_MASK (0xff) | ||
283 | #define RT5645_DAC_R2_VOL_SFT 0 | ||
284 | |||
285 | /* DAC2 Control (0x1b) */ | ||
286 | #define RT5645_M_DAC_L2_VOL (0x1 << 13) | ||
287 | #define RT5645_M_DAC_L2_VOL_SFT 13 | ||
288 | #define RT5645_M_DAC_R2_VOL (0x1 << 12) | ||
289 | #define RT5645_M_DAC_R2_VOL_SFT 12 | ||
290 | #define RT5645_DAC2_L_SEL_MASK (0x7 << 4) | ||
291 | #define RT5645_DAC2_L_SEL_SFT 4 | ||
292 | #define RT5645_DAC2_R_SEL_MASK (0x7 << 0) | ||
293 | #define RT5645_DAC2_R_SEL_SFT 0 | ||
294 | |||
295 | /* ADC Digital Volume Control (0x1c) */ | ||
296 | #define RT5645_ADC_L_VOL_MASK (0x7f << 8) | ||
297 | #define RT5645_ADC_L_VOL_SFT 8 | ||
298 | #define RT5645_ADC_R_VOL_MASK (0x7f) | ||
299 | #define RT5645_ADC_R_VOL_SFT 0 | ||
300 | |||
301 | /* Mono ADC Digital Volume Control (0x1d) */ | ||
302 | #define RT5645_MONO_ADC_L_VOL_MASK (0x7f << 8) | ||
303 | #define RT5645_MONO_ADC_L_VOL_SFT 8 | ||
304 | #define RT5645_MONO_ADC_R_VOL_MASK (0x7f) | ||
305 | #define RT5645_MONO_ADC_R_VOL_SFT 0 | ||
306 | |||
307 | /* ADC Boost Volume Control (0x1e) */ | ||
308 | #define RT5645_STO1_ADC_L_BST_MASK (0x3 << 14) | ||
309 | #define RT5645_STO1_ADC_L_BST_SFT 14 | ||
310 | #define RT5645_STO1_ADC_R_BST_MASK (0x3 << 12) | ||
311 | #define RT5645_STO1_ADC_R_BST_SFT 12 | ||
312 | #define RT5645_STO1_ADC_COMP_MASK (0x3 << 10) | ||
313 | #define RT5645_STO1_ADC_COMP_SFT 10 | ||
314 | #define RT5645_STO2_ADC_L_BST_MASK (0x3 << 8) | ||
315 | #define RT5645_STO2_ADC_L_BST_SFT 8 | ||
316 | #define RT5645_STO2_ADC_R_BST_MASK (0x3 << 6) | ||
317 | #define RT5645_STO2_ADC_R_BST_SFT 6 | ||
318 | #define RT5645_STO2_ADC_COMP_MASK (0x3 << 4) | ||
319 | #define RT5645_STO2_ADC_COMP_SFT 4 | ||
320 | |||
321 | /* Stereo2 ADC Mixer Control (0x26) */ | ||
322 | #define RT5645_STO2_ADC_SRC_MASK (0x1 << 15) | ||
323 | #define RT5645_STO2_ADC_SRC_SFT 15 | ||
324 | |||
325 | /* Stereo ADC Mixer Control (0x27) */ | ||
326 | #define RT5645_M_ADC_L1 (0x1 << 14) | ||
327 | #define RT5645_M_ADC_L1_SFT 14 | ||
328 | #define RT5645_M_ADC_L2 (0x1 << 13) | ||
329 | #define RT5645_M_ADC_L2_SFT 13 | ||
330 | #define RT5645_ADC_1_SRC_MASK (0x1 << 12) | ||
331 | #define RT5645_ADC_1_SRC_SFT 12 | ||
332 | #define RT5645_ADC_1_SRC_ADC (0x1 << 12) | ||
333 | #define RT5645_ADC_1_SRC_DACMIX (0x0 << 12) | ||
334 | #define RT5645_ADC_2_SRC_MASK (0x1 << 11) | ||
335 | #define RT5645_ADC_2_SRC_SFT 11 | ||
336 | #define RT5645_DMIC_SRC_MASK (0x1 << 8) | ||
337 | #define RT5645_DMIC_SRC_SFT 8 | ||
338 | #define RT5645_M_ADC_R1 (0x1 << 6) | ||
339 | #define RT5645_M_ADC_R1_SFT 6 | ||
340 | #define RT5645_M_ADC_R2 (0x1 << 5) | ||
341 | #define RT5645_M_ADC_R2_SFT 5 | ||
342 | #define RT5645_DMIC3_SRC_MASK (0x1 << 1) | ||
343 | #define RT5645_DMIC3_SRC_SFT 0 | ||
344 | |||
345 | /* Mono ADC Mixer Control (0x28) */ | ||
346 | #define RT5645_M_MONO_ADC_L1 (0x1 << 14) | ||
347 | #define RT5645_M_MONO_ADC_L1_SFT 14 | ||
348 | #define RT5645_M_MONO_ADC_L2 (0x1 << 13) | ||
349 | #define RT5645_M_MONO_ADC_L2_SFT 13 | ||
350 | #define RT5645_MONO_ADC_L1_SRC_MASK (0x1 << 12) | ||
351 | #define RT5645_MONO_ADC_L1_SRC_SFT 12 | ||
352 | #define RT5645_MONO_ADC_L1_SRC_DACMIXL (0x0 << 12) | ||
353 | #define RT5645_MONO_ADC_L1_SRC_ADCL (0x1 << 12) | ||
354 | #define RT5645_MONO_ADC_L2_SRC_MASK (0x1 << 11) | ||
355 | #define RT5645_MONO_ADC_L2_SRC_SFT 11 | ||
356 | #define RT5645_MONO_DMIC_L_SRC_MASK (0x1 << 8) | ||
357 | #define RT5645_MONO_DMIC_L_SRC_SFT 8 | ||
358 | #define RT5645_M_MONO_ADC_R1 (0x1 << 6) | ||
359 | #define RT5645_M_MONO_ADC_R1_SFT 6 | ||
360 | #define RT5645_M_MONO_ADC_R2 (0x1 << 5) | ||
361 | #define RT5645_M_MONO_ADC_R2_SFT 5 | ||
362 | #define RT5645_MONO_ADC_R1_SRC_MASK (0x1 << 4) | ||
363 | #define RT5645_MONO_ADC_R1_SRC_SFT 4 | ||
364 | #define RT5645_MONO_ADC_R1_SRC_ADCR (0x1 << 4) | ||
365 | #define RT5645_MONO_ADC_R1_SRC_DACMIXR (0x0 << 4) | ||
366 | #define RT5645_MONO_ADC_R2_SRC_MASK (0x1 << 3) | ||
367 | #define RT5645_MONO_ADC_R2_SRC_SFT 3 | ||
368 | #define RT5645_MONO_DMIC_R_SRC_MASK (0x3) | ||
369 | #define RT5645_MONO_DMIC_R_SRC_SFT 0 | ||
370 | |||
371 | /* ADC Mixer to DAC Mixer Control (0x29) */ | ||
372 | #define RT5645_M_ADCMIX_L (0x1 << 15) | ||
373 | #define RT5645_M_ADCMIX_L_SFT 15 | ||
374 | #define RT5645_M_DAC1_L (0x1 << 14) | ||
375 | #define RT5645_M_DAC1_L_SFT 14 | ||
376 | #define RT5645_DAC1_R_SEL_MASK (0x3 << 10) | ||
377 | #define RT5645_DAC1_R_SEL_SFT 10 | ||
378 | #define RT5645_DAC1_R_SEL_IF1 (0x0 << 10) | ||
379 | #define RT5645_DAC1_R_SEL_IF2 (0x1 << 10) | ||
380 | #define RT5645_DAC1_R_SEL_IF3 (0x2 << 10) | ||
381 | #define RT5645_DAC1_R_SEL_IF4 (0x3 << 10) | ||
382 | #define RT5645_DAC1_L_SEL_MASK (0x3 << 8) | ||
383 | #define RT5645_DAC1_L_SEL_SFT 8 | ||
384 | #define RT5645_DAC1_L_SEL_IF1 (0x0 << 8) | ||
385 | #define RT5645_DAC1_L_SEL_IF2 (0x1 << 8) | ||
386 | #define RT5645_DAC1_L_SEL_IF3 (0x2 << 8) | ||
387 | #define RT5645_DAC1_L_SEL_IF4 (0x3 << 8) | ||
388 | #define RT5645_M_ADCMIX_R (0x1 << 7) | ||
389 | #define RT5645_M_ADCMIX_R_SFT 7 | ||
390 | #define RT5645_M_DAC1_R (0x1 << 6) | ||
391 | #define RT5645_M_DAC1_R_SFT 6 | ||
392 | |||
393 | /* Stereo DAC Mixer Control (0x2a) */ | ||
394 | #define RT5645_M_DAC_L1 (0x1 << 14) | ||
395 | #define RT5645_M_DAC_L1_SFT 14 | ||
396 | #define RT5645_DAC_L1_STO_L_VOL_MASK (0x1 << 13) | ||
397 | #define RT5645_DAC_L1_STO_L_VOL_SFT 13 | ||
398 | #define RT5645_M_DAC_L2 (0x1 << 12) | ||
399 | #define RT5645_M_DAC_L2_SFT 12 | ||
400 | #define RT5645_DAC_L2_STO_L_VOL_MASK (0x1 << 11) | ||
401 | #define RT5645_DAC_L2_STO_L_VOL_SFT 11 | ||
402 | #define RT5645_M_ANC_DAC_L (0x1 << 10) | ||
403 | #define RT5645_M_ANC_DAC_L_SFT 10 | ||
404 | #define RT5645_M_DAC_R1_STO_L (0x1 << 9) | ||
405 | #define RT5645_M_DAC_R1_STO_L_SFT 9 | ||
406 | #define RT5645_DAC_R1_STO_L_VOL_MASK (0x1 << 8) | ||
407 | #define RT5645_DAC_R1_STO_L_VOL_SFT 8 | ||
408 | #define RT5645_M_DAC_R1 (0x1 << 6) | ||
409 | #define RT5645_M_DAC_R1_SFT 6 | ||
410 | #define RT5645_DAC_R1_STO_R_VOL_MASK (0x1 << 5) | ||
411 | #define RT5645_DAC_R1_STO_R_VOL_SFT 5 | ||
412 | #define RT5645_M_DAC_R2 (0x1 << 4) | ||
413 | #define RT5645_M_DAC_R2_SFT 4 | ||
414 | #define RT5645_DAC_R2_STO_R_VOL_MASK (0x1 << 3) | ||
415 | #define RT5645_DAC_R2_STO_R_VOL_SFT 3 | ||
416 | #define RT5645_M_ANC_DAC_R (0x1 << 2) | ||
417 | #define RT5645_M_ANC_DAC_R_SFT 2 | ||
418 | #define RT5645_M_DAC_L1_STO_R (0x1 << 1) | ||
419 | #define RT5645_M_DAC_L1_STO_R_SFT 1 | ||
420 | #define RT5645_DAC_L1_STO_R_VOL_MASK (0x1) | ||
421 | #define RT5645_DAC_L1_STO_R_VOL_SFT 0 | ||
422 | |||
423 | /* Mono DAC Mixer Control (0x2b) */ | ||
424 | #define RT5645_M_DAC_L1_MONO_L (0x1 << 14) | ||
425 | #define RT5645_M_DAC_L1_MONO_L_SFT 14 | ||
426 | #define RT5645_DAC_L1_MONO_L_VOL_MASK (0x1 << 13) | ||
427 | #define RT5645_DAC_L1_MONO_L_VOL_SFT 13 | ||
428 | #define RT5645_M_DAC_L2_MONO_L (0x1 << 12) | ||
429 | #define RT5645_M_DAC_L2_MONO_L_SFT 12 | ||
430 | #define RT5645_DAC_L2_MONO_L_VOL_MASK (0x1 << 11) | ||
431 | #define RT5645_DAC_L2_MONO_L_VOL_SFT 11 | ||
432 | #define RT5645_M_DAC_R2_MONO_L (0x1 << 10) | ||
433 | #define RT5645_M_DAC_R2_MONO_L_SFT 10 | ||
434 | #define RT5645_DAC_R2_MONO_L_VOL_MASK (0x1 << 9) | ||
435 | #define RT5645_DAC_R2_MONO_L_VOL_SFT 9 | ||
436 | #define RT5645_M_DAC_R1_MONO_R (0x1 << 6) | ||
437 | #define RT5645_M_DAC_R1_MONO_R_SFT 6 | ||
438 | #define RT5645_DAC_R1_MONO_R_VOL_MASK (0x1 << 5) | ||
439 | #define RT5645_DAC_R1_MONO_R_VOL_SFT 5 | ||
440 | #define RT5645_M_DAC_R2_MONO_R (0x1 << 4) | ||
441 | #define RT5645_M_DAC_R2_MONO_R_SFT 4 | ||
442 | #define RT5645_DAC_R2_MONO_R_VOL_MASK (0x1 << 3) | ||
443 | #define RT5645_DAC_R2_MONO_R_VOL_SFT 3 | ||
444 | #define RT5645_M_DAC_L2_MONO_R (0x1 << 2) | ||
445 | #define RT5645_M_DAC_L2_MONO_R_SFT 2 | ||
446 | #define RT5645_DAC_L2_MONO_R_VOL_MASK (0x1 << 1) | ||
447 | #define RT5645_DAC_L2_MONO_R_VOL_SFT 1 | ||
448 | |||
449 | /* Digital Mixer Control (0x2c) */ | ||
450 | #define RT5645_M_STO_L_DAC_L (0x1 << 15) | ||
451 | #define RT5645_M_STO_L_DAC_L_SFT 15 | ||
452 | #define RT5645_STO_L_DAC_L_VOL_MASK (0x1 << 14) | ||
453 | #define RT5645_STO_L_DAC_L_VOL_SFT 14 | ||
454 | #define RT5645_M_DAC_L2_DAC_L (0x1 << 13) | ||
455 | #define RT5645_M_DAC_L2_DAC_L_SFT 13 | ||
456 | #define RT5645_DAC_L2_DAC_L_VOL_MASK (0x1 << 12) | ||
457 | #define RT5645_DAC_L2_DAC_L_VOL_SFT 12 | ||
458 | #define RT5645_M_STO_R_DAC_R (0x1 << 11) | ||
459 | #define RT5645_M_STO_R_DAC_R_SFT 11 | ||
460 | #define RT5645_STO_R_DAC_R_VOL_MASK (0x1 << 10) | ||
461 | #define RT5645_STO_R_DAC_R_VOL_SFT 10 | ||
462 | #define RT5645_M_DAC_R2_DAC_R (0x1 << 9) | ||
463 | #define RT5645_M_DAC_R2_DAC_R_SFT 9 | ||
464 | #define RT5645_DAC_R2_DAC_R_VOL_MASK (0x1 << 8) | ||
465 | #define RT5645_DAC_R2_DAC_R_VOL_SFT 8 | ||
466 | #define RT5645_M_DAC_R2_DAC_L (0x1 << 7) | ||
467 | #define RT5645_M_DAC_R2_DAC_L_SFT 7 | ||
468 | #define RT5645_DAC_R2_DAC_L_VOL_MASK (0x1 << 6) | ||
469 | #define RT5645_DAC_R2_DAC_L_VOL_SFT 6 | ||
470 | #define RT5645_M_DAC_L2_DAC_R (0x1 << 5) | ||
471 | #define RT5645_M_DAC_L2_DAC_R_SFT 5 | ||
472 | #define RT5645_DAC_L2_DAC_R_VOL_MASK (0x1 << 4) | ||
473 | #define RT5645_DAC_L2_DAC_R_VOL_SFT 4 | ||
474 | |||
475 | /* Digital Interface Data Control (0x2f) */ | ||
476 | #define RT5645_IF1_ADC2_IN_SEL (0x1 << 15) | ||
477 | #define RT5645_IF1_ADC2_IN_SFT 15 | ||
478 | #define RT5645_IF2_ADC_IN_MASK (0x7 << 12) | ||
479 | #define RT5645_IF2_ADC_IN_SFT 12 | ||
480 | #define RT5645_IF2_DAC_SEL_MASK (0x3 << 10) | ||
481 | #define RT5645_IF2_DAC_SEL_SFT 10 | ||
482 | #define RT5645_IF2_ADC_SEL_MASK (0x3 << 8) | ||
483 | #define RT5645_IF2_ADC_SEL_SFT 8 | ||
484 | #define RT5645_IF3_DAC_SEL_MASK (0x3 << 6) | ||
485 | #define RT5645_IF3_DAC_SEL_SFT 6 | ||
486 | #define RT5645_IF3_ADC_SEL_MASK (0x3 << 4) | ||
487 | #define RT5645_IF3_ADC_SEL_SFT 4 | ||
488 | #define RT5645_IF3_ADC_IN_MASK (0x7) | ||
489 | #define RT5645_IF3_ADC_IN_SFT 0 | ||
490 | |||
491 | /* PDM Output Control (0x31) */ | ||
492 | #define RT5645_PDM1_L_MASK (0x1 << 15) | ||
493 | #define RT5645_PDM1_L_SFT 15 | ||
494 | #define RT5645_M_PDM1_L (0x1 << 14) | ||
495 | #define RT5645_M_PDM1_L_SFT 14 | ||
496 | #define RT5645_PDM1_R_MASK (0x1 << 13) | ||
497 | #define RT5645_PDM1_R_SFT 13 | ||
498 | #define RT5645_M_PDM1_R (0x1 << 12) | ||
499 | #define RT5645_M_PDM1_R_SFT 12 | ||
500 | #define RT5645_PDM2_L_MASK (0x1 << 11) | ||
501 | #define RT5645_PDM2_L_SFT 11 | ||
502 | #define RT5645_M_PDM2_L (0x1 << 10) | ||
503 | #define RT5645_M_PDM2_L_SFT 10 | ||
504 | #define RT5645_PDM2_R_MASK (0x1 << 9) | ||
505 | #define RT5645_PDM2_R_SFT 9 | ||
506 | #define RT5645_M_PDM2_R (0x1 << 8) | ||
507 | #define RT5645_M_PDM2_R_SFT 8 | ||
508 | #define RT5645_PDM2_BUSY (0x1 << 7) | ||
509 | #define RT5645_PDM1_BUSY (0x1 << 6) | ||
510 | #define RT5645_PDM_PATTERN (0x1 << 5) | ||
511 | #define RT5645_PDM_GAIN (0x1 << 4) | ||
512 | #define RT5645_PDM_DIV_MASK (0x3) | ||
513 | |||
514 | /* REC Left Mixer Control 1 (0x3b) */ | ||
515 | #define RT5645_G_HP_L_RM_L_MASK (0x7 << 13) | ||
516 | #define RT5645_G_HP_L_RM_L_SFT 13 | ||
517 | #define RT5645_G_IN_L_RM_L_MASK (0x7 << 10) | ||
518 | #define RT5645_G_IN_L_RM_L_SFT 10 | ||
519 | #define RT5645_G_BST4_RM_L_MASK (0x7 << 7) | ||
520 | #define RT5645_G_BST4_RM_L_SFT 7 | ||
521 | #define RT5645_G_BST3_RM_L_MASK (0x7 << 4) | ||
522 | #define RT5645_G_BST3_RM_L_SFT 4 | ||
523 | #define RT5645_G_BST2_RM_L_MASK (0x7 << 1) | ||
524 | #define RT5645_G_BST2_RM_L_SFT 1 | ||
525 | |||
526 | /* REC Left Mixer Control 2 (0x3c) */ | ||
527 | #define RT5645_G_BST1_RM_L_MASK (0x7 << 13) | ||
528 | #define RT5645_G_BST1_RM_L_SFT 13 | ||
529 | #define RT5645_G_OM_L_RM_L_MASK (0x7 << 10) | ||
530 | #define RT5645_G_OM_L_RM_L_SFT 10 | ||
531 | #define RT5645_M_MM_L_RM_L (0x1 << 6) | ||
532 | #define RT5645_M_MM_L_RM_L_SFT 6 | ||
533 | #define RT5645_M_IN_L_RM_L (0x1 << 5) | ||
534 | #define RT5645_M_IN_L_RM_L_SFT 5 | ||
535 | #define RT5645_M_HP_L_RM_L (0x1 << 4) | ||
536 | #define RT5645_M_HP_L_RM_L_SFT 4 | ||
537 | #define RT5645_M_BST3_RM_L (0x1 << 3) | ||
538 | #define RT5645_M_BST3_RM_L_SFT 3 | ||
539 | #define RT5645_M_BST2_RM_L (0x1 << 2) | ||
540 | #define RT5645_M_BST2_RM_L_SFT 2 | ||
541 | #define RT5645_M_BST1_RM_L (0x1 << 1) | ||
542 | #define RT5645_M_BST1_RM_L_SFT 1 | ||
543 | #define RT5645_M_OM_L_RM_L (0x1) | ||
544 | #define RT5645_M_OM_L_RM_L_SFT 0 | ||
545 | |||
546 | /* REC Right Mixer Control 1 (0x3d) */ | ||
547 | #define RT5645_G_HP_R_RM_R_MASK (0x7 << 13) | ||
548 | #define RT5645_G_HP_R_RM_R_SFT 13 | ||
549 | #define RT5645_G_IN_R_RM_R_MASK (0x7 << 10) | ||
550 | #define RT5645_G_IN_R_RM_R_SFT 10 | ||
551 | #define RT5645_G_BST4_RM_R_MASK (0x7 << 7) | ||
552 | #define RT5645_G_BST4_RM_R_SFT 7 | ||
553 | #define RT5645_G_BST3_RM_R_MASK (0x7 << 4) | ||
554 | #define RT5645_G_BST3_RM_R_SFT 4 | ||
555 | #define RT5645_G_BST2_RM_R_MASK (0x7 << 1) | ||
556 | #define RT5645_G_BST2_RM_R_SFT 1 | ||
557 | |||
558 | /* REC Right Mixer Control 2 (0x3e) */ | ||
559 | #define RT5645_G_BST1_RM_R_MASK (0x7 << 13) | ||
560 | #define RT5645_G_BST1_RM_R_SFT 13 | ||
561 | #define RT5645_G_OM_R_RM_R_MASK (0x7 << 10) | ||
562 | #define RT5645_G_OM_R_RM_R_SFT 10 | ||
563 | #define RT5645_M_MM_R_RM_R (0x1 << 6) | ||
564 | #define RT5645_M_MM_R_RM_R_SFT 6 | ||
565 | #define RT5645_M_IN_R_RM_R (0x1 << 5) | ||
566 | #define RT5645_M_IN_R_RM_R_SFT 5 | ||
567 | #define RT5645_M_HP_R_RM_R (0x1 << 4) | ||
568 | #define RT5645_M_HP_R_RM_R_SFT 4 | ||
569 | #define RT5645_M_BST3_RM_R (0x1 << 3) | ||
570 | #define RT5645_M_BST3_RM_R_SFT 3 | ||
571 | #define RT5645_M_BST2_RM_R (0x1 << 2) | ||
572 | #define RT5645_M_BST2_RM_R_SFT 2 | ||
573 | #define RT5645_M_BST1_RM_R (0x1 << 1) | ||
574 | #define RT5645_M_BST1_RM_R_SFT 1 | ||
575 | #define RT5645_M_OM_R_RM_R (0x1) | ||
576 | #define RT5645_M_OM_R_RM_R_SFT 0 | ||
577 | |||
578 | /* HPOMIX Control (0x40) (0x42) */ | ||
579 | #define RT5645_M_BST1_HV (0x1 << 4) | ||
580 | #define RT5645_M_BST1_HV_SFT 4 | ||
581 | #define RT5645_M_BST2_HV (0x1 << 4) | ||
582 | #define RT5645_M_BST2_HV_SFT 4 | ||
583 | #define RT5645_M_BST3_HV (0x1 << 3) | ||
584 | #define RT5645_M_BST3_HV_SFT 3 | ||
585 | #define RT5645_M_IN_HV (0x1 << 2) | ||
586 | #define RT5645_M_IN_HV_SFT 2 | ||
587 | #define RT5645_M_DAC2_HV (0x1 << 1) | ||
588 | #define RT5645_M_DAC2_HV_SFT 1 | ||
589 | #define RT5645_M_DAC1_HV (0x1 << 0) | ||
590 | #define RT5645_M_DAC1_HV_SFT 0 | ||
591 | |||
592 | /* HPMIX Control (0x45) */ | ||
593 | #define RT5645_M_DAC1_HM (0x1 << 14) | ||
594 | #define RT5645_M_DAC1_HM_SFT 14 | ||
595 | #define RT5645_M_HPVOL_HM (0x1 << 13) | ||
596 | #define RT5645_M_HPVOL_HM_SFT 13 | ||
597 | |||
598 | /* SPK Left Mixer Control (0x46) */ | ||
599 | #define RT5645_G_RM_L_SM_L_MASK (0x3 << 14) | ||
600 | #define RT5645_G_RM_L_SM_L_SFT 14 | ||
601 | #define RT5645_G_IN_L_SM_L_MASK (0x3 << 12) | ||
602 | #define RT5645_G_IN_L_SM_L_SFT 12 | ||
603 | #define RT5645_G_DAC_L1_SM_L_MASK (0x3 << 10) | ||
604 | #define RT5645_G_DAC_L1_SM_L_SFT 10 | ||
605 | #define RT5645_G_DAC_L2_SM_L_MASK (0x3 << 8) | ||
606 | #define RT5645_G_DAC_L2_SM_L_SFT 8 | ||
607 | #define RT5645_G_OM_L_SM_L_MASK (0x3 << 6) | ||
608 | #define RT5645_G_OM_L_SM_L_SFT 6 | ||
609 | #define RT5645_M_BST1_L_SM_L (0x1 << 5) | ||
610 | #define RT5645_M_BST1_L_SM_L_SFT 5 | ||
611 | #define RT5645_M_IN_L_SM_L (0x1 << 3) | ||
612 | #define RT5645_M_IN_L_SM_L_SFT 3 | ||
613 | #define RT5645_M_DAC_L1_SM_L (0x1 << 1) | ||
614 | #define RT5645_M_DAC_L1_SM_L_SFT 1 | ||
615 | #define RT5645_M_DAC_L2_SM_L (0x1 << 2) | ||
616 | #define RT5645_M_DAC_L2_SM_L_SFT 2 | ||
617 | #define RT5645_M_BST3_L_SM_L (0x1 << 4) | ||
618 | #define RT5645_M_BST3_L_SM_L_SFT 4 | ||
619 | |||
620 | /* SPK Right Mixer Control (0x47) */ | ||
621 | #define RT5645_G_RM_R_SM_R_MASK (0x3 << 14) | ||
622 | #define RT5645_G_RM_R_SM_R_SFT 14 | ||
623 | #define RT5645_G_IN_R_SM_R_MASK (0x3 << 12) | ||
624 | #define RT5645_G_IN_R_SM_R_SFT 12 | ||
625 | #define RT5645_G_DAC_R1_SM_R_MASK (0x3 << 10) | ||
626 | #define RT5645_G_DAC_R1_SM_R_SFT 10 | ||
627 | #define RT5645_G_DAC_R2_SM_R_MASK (0x3 << 8) | ||
628 | #define RT5645_G_DAC_R2_SM_R_SFT 8 | ||
629 | #define RT5645_G_OM_R_SM_R_MASK (0x3 << 6) | ||
630 | #define RT5645_G_OM_R_SM_R_SFT 6 | ||
631 | #define RT5645_M_BST2_R_SM_R (0x1 << 5) | ||
632 | #define RT5645_M_BST2_R_SM_R_SFT 5 | ||
633 | #define RT5645_M_IN_R_SM_R (0x1 << 3) | ||
634 | #define RT5645_M_IN_R_SM_R_SFT 3 | ||
635 | #define RT5645_M_DAC_R1_SM_R (0x1 << 1) | ||
636 | #define RT5645_M_DAC_R1_SM_R_SFT 1 | ||
637 | #define RT5645_M_DAC_R2_SM_R (0x1 << 2) | ||
638 | #define RT5645_M_DAC_R2_SM_R_SFT 2 | ||
639 | #define RT5645_M_BST3_R_SM_R (0x1 << 4) | ||
640 | #define RT5645_M_BST3_R_SM_R_SFT 4 | ||
641 | |||
642 | /* SPOLMIX Control (0x48) */ | ||
643 | #define RT5645_M_DAC_L1_SPM_L (0x1 << 15) | ||
644 | #define RT5645_M_DAC_L1_SPM_L_SFT 15 | ||
645 | #define RT5645_M_DAC_R1_SPM_L (0x1 << 14) | ||
646 | #define RT5645_M_DAC_R1_SPM_L_SFT 14 | ||
647 | #define RT5645_M_SV_L_SPM_L (0x1 << 13) | ||
648 | #define RT5645_M_SV_L_SPM_L_SFT 13 | ||
649 | #define RT5645_M_SV_R_SPM_L (0x1 << 12) | ||
650 | #define RT5645_M_SV_R_SPM_L_SFT 12 | ||
651 | #define RT5645_M_BST3_SPM_L (0x1 << 11) | ||
652 | #define RT5645_M_BST3_SPM_L_SFT 11 | ||
653 | #define RT5645_M_DAC_R1_SPM_R (0x1 << 2) | ||
654 | #define RT5645_M_DAC_R1_SPM_R_SFT 2 | ||
655 | #define RT5645_M_BST3_SPM_R (0x1 << 1) | ||
656 | #define RT5645_M_BST3_SPM_R_SFT 1 | ||
657 | #define RT5645_M_SV_R_SPM_R (0x1 << 0) | ||
658 | #define RT5645_M_SV_R_SPM_R_SFT 0 | ||
659 | |||
660 | /* Mono Output Mixer Control (0x4c) */ | ||
661 | #define RT5645_M_OV_L_MM (0x1 << 9) | ||
662 | #define RT5645_M_OV_L_MM_SFT 9 | ||
663 | #define RT5645_M_DAC_L2_MA (0x1 << 8) | ||
664 | #define RT5645_M_DAC_L2_MA_SFT 8 | ||
665 | #define RT5645_G_MONOMIX_MASK (0x1 << 10) | ||
666 | #define RT5645_G_MONOMIX_SFT 10 | ||
667 | #define RT5645_M_BST2_MM (0x1 << 4) | ||
668 | #define RT5645_M_BST2_MM_SFT 4 | ||
669 | #define RT5645_M_DAC_R1_MM (0x1 << 3) | ||
670 | #define RT5645_M_DAC_R1_MM_SFT 3 | ||
671 | #define RT5645_M_DAC_R2_MM (0x1 << 2) | ||
672 | #define RT5645_M_DAC_R2_MM_SFT 2 | ||
673 | #define RT5645_M_DAC_L2_MM (0x1 << 1) | ||
674 | #define RT5645_M_DAC_L2_MM_SFT 1 | ||
675 | #define RT5645_M_BST3_MM (0x1 << 0) | ||
676 | #define RT5645_M_BST3_MM_SFT 0 | ||
677 | |||
678 | /* Output Left Mixer Control 1 (0x4d) */ | ||
679 | #define RT5645_G_BST3_OM_L_MASK (0x7 << 13) | ||
680 | #define RT5645_G_BST3_OM_L_SFT 13 | ||
681 | #define RT5645_G_BST2_OM_L_MASK (0x7 << 10) | ||
682 | #define RT5645_G_BST2_OM_L_SFT 10 | ||
683 | #define RT5645_G_BST1_OM_L_MASK (0x7 << 7) | ||
684 | #define RT5645_G_BST1_OM_L_SFT 7 | ||
685 | #define RT5645_G_IN_L_OM_L_MASK (0x7 << 4) | ||
686 | #define RT5645_G_IN_L_OM_L_SFT 4 | ||
687 | #define RT5645_G_RM_L_OM_L_MASK (0x7 << 1) | ||
688 | #define RT5645_G_RM_L_OM_L_SFT 1 | ||
689 | |||
690 | /* Output Left Mixer Control 2 (0x4e) */ | ||
691 | #define RT5645_G_DAC_R2_OM_L_MASK (0x7 << 13) | ||
692 | #define RT5645_G_DAC_R2_OM_L_SFT 13 | ||
693 | #define RT5645_G_DAC_L2_OM_L_MASK (0x7 << 10) | ||
694 | #define RT5645_G_DAC_L2_OM_L_SFT 10 | ||
695 | #define RT5645_G_DAC_L1_OM_L_MASK (0x7 << 7) | ||
696 | #define RT5645_G_DAC_L1_OM_L_SFT 7 | ||
697 | |||
698 | /* Output Left Mixer Control 3 (0x4f) */ | ||
699 | #define RT5645_M_BST3_OM_L (0x1 << 4) | ||
700 | #define RT5645_M_BST3_OM_L_SFT 4 | ||
701 | #define RT5645_M_BST1_OM_L (0x1 << 3) | ||
702 | #define RT5645_M_BST1_OM_L_SFT 3 | ||
703 | #define RT5645_M_IN_L_OM_L (0x1 << 2) | ||
704 | #define RT5645_M_IN_L_OM_L_SFT 2 | ||
705 | #define RT5645_M_DAC_L2_OM_L (0x1 << 1) | ||
706 | #define RT5645_M_DAC_L2_OM_L_SFT 1 | ||
707 | #define RT5645_M_DAC_L1_OM_L (0x1) | ||
708 | #define RT5645_M_DAC_L1_OM_L_SFT 0 | ||
709 | |||
710 | /* Output Right Mixer Control 1 (0x50) */ | ||
711 | #define RT5645_G_BST4_OM_R_MASK (0x7 << 13) | ||
712 | #define RT5645_G_BST4_OM_R_SFT 13 | ||
713 | #define RT5645_G_BST2_OM_R_MASK (0x7 << 10) | ||
714 | #define RT5645_G_BST2_OM_R_SFT 10 | ||
715 | #define RT5645_G_BST1_OM_R_MASK (0x7 << 7) | ||
716 | #define RT5645_G_BST1_OM_R_SFT 7 | ||
717 | #define RT5645_G_IN_R_OM_R_MASK (0x7 << 4) | ||
718 | #define RT5645_G_IN_R_OM_R_SFT 4 | ||
719 | #define RT5645_G_RM_R_OM_R_MASK (0x7 << 1) | ||
720 | #define RT5645_G_RM_R_OM_R_SFT 1 | ||
721 | |||
722 | /* Output Right Mixer Control 2 (0x51) */ | ||
723 | #define RT5645_G_DAC_L2_OM_R_MASK (0x7 << 13) | ||
724 | #define RT5645_G_DAC_L2_OM_R_SFT 13 | ||
725 | #define RT5645_G_DAC_R2_OM_R_MASK (0x7 << 10) | ||
726 | #define RT5645_G_DAC_R2_OM_R_SFT 10 | ||
727 | #define RT5645_G_DAC_R1_OM_R_MASK (0x7 << 7) | ||
728 | #define RT5645_G_DAC_R1_OM_R_SFT 7 | ||
729 | |||
730 | /* Output Right Mixer Control 3 (0x52) */ | ||
731 | #define RT5645_M_BST3_OM_R (0x1 << 4) | ||
732 | #define RT5645_M_BST3_OM_R_SFT 4 | ||
733 | #define RT5645_M_BST2_OM_R (0x1 << 3) | ||
734 | #define RT5645_M_BST2_OM_R_SFT 3 | ||
735 | #define RT5645_M_IN_R_OM_R (0x1 << 2) | ||
736 | #define RT5645_M_IN_R_OM_R_SFT 2 | ||
737 | #define RT5645_M_DAC_R2_OM_R (0x1 << 1) | ||
738 | #define RT5645_M_DAC_R2_OM_R_SFT 1 | ||
739 | #define RT5645_M_DAC_R1_OM_R (0x1) | ||
740 | #define RT5645_M_DAC_R1_OM_R_SFT 0 | ||
741 | |||
742 | /* LOUT Mixer Control (0x53) */ | ||
743 | #define RT5645_M_DAC_L1_LM (0x1 << 15) | ||
744 | #define RT5645_M_DAC_L1_LM_SFT 15 | ||
745 | #define RT5645_M_DAC_R1_LM (0x1 << 14) | ||
746 | #define RT5645_M_DAC_R1_LM_SFT 14 | ||
747 | #define RT5645_M_OV_L_LM (0x1 << 13) | ||
748 | #define RT5645_M_OV_L_LM_SFT 13 | ||
749 | #define RT5645_M_OV_R_LM (0x1 << 12) | ||
750 | #define RT5645_M_OV_R_LM_SFT 12 | ||
751 | #define RT5645_G_LOUTMIX_MASK (0x1 << 11) | ||
752 | #define RT5645_G_LOUTMIX_SFT 11 | ||
753 | |||
754 | /* Power Management for Digital 1 (0x61) */ | ||
755 | #define RT5645_PWR_I2S1 (0x1 << 15) | ||
756 | #define RT5645_PWR_I2S1_BIT 15 | ||
757 | #define RT5645_PWR_I2S2 (0x1 << 14) | ||
758 | #define RT5645_PWR_I2S2_BIT 14 | ||
759 | #define RT5645_PWR_I2S3 (0x1 << 13) | ||
760 | #define RT5645_PWR_I2S3_BIT 13 | ||
761 | #define RT5645_PWR_DAC_L1 (0x1 << 12) | ||
762 | #define RT5645_PWR_DAC_L1_BIT 12 | ||
763 | #define RT5645_PWR_DAC_R1 (0x1 << 11) | ||
764 | #define RT5645_PWR_DAC_R1_BIT 11 | ||
765 | #define RT5645_PWR_CLS_D_R (0x1 << 9) | ||
766 | #define RT5645_PWR_CLS_D_R_BIT 9 | ||
767 | #define RT5645_PWR_CLS_D_L (0x1 << 8) | ||
768 | #define RT5645_PWR_CLS_D_L_BIT 8 | ||
769 | #define RT5645_PWR_ADC_R (0x1 << 1) | ||
770 | #define RT5645_PWR_ADC_R_BIT 1 | ||
771 | #define RT5645_PWR_DAC_L2 (0x1 << 7) | ||
772 | #define RT5645_PWR_DAC_L2_BIT 7 | ||
773 | #define RT5645_PWR_DAC_R2 (0x1 << 6) | ||
774 | #define RT5645_PWR_DAC_R2_BIT 6 | ||
775 | #define RT5645_PWR_ADC_L (0x1 << 2) | ||
776 | #define RT5645_PWR_ADC_L_BIT 2 | ||
777 | #define RT5645_PWR_ADC_R (0x1 << 1) | ||
778 | #define RT5645_PWR_ADC_R_BIT 1 | ||
779 | #define RT5645_PWR_CLS_D (0x1) | ||
780 | #define RT5645_PWR_CLS_D_BIT 0 | ||
781 | |||
782 | /* Power Management for Digital 2 (0x62) */ | ||
783 | #define RT5645_PWR_ADC_S1F (0x1 << 15) | ||
784 | #define RT5645_PWR_ADC_S1F_BIT 15 | ||
785 | #define RT5645_PWR_ADC_MF_L (0x1 << 14) | ||
786 | #define RT5645_PWR_ADC_MF_L_BIT 14 | ||
787 | #define RT5645_PWR_ADC_MF_R (0x1 << 13) | ||
788 | #define RT5645_PWR_ADC_MF_R_BIT 13 | ||
789 | #define RT5645_PWR_I2S_DSP (0x1 << 12) | ||
790 | #define RT5645_PWR_I2S_DSP_BIT 12 | ||
791 | #define RT5645_PWR_DAC_S1F (0x1 << 11) | ||
792 | #define RT5645_PWR_DAC_S1F_BIT 11 | ||
793 | #define RT5645_PWR_DAC_MF_L (0x1 << 10) | ||
794 | #define RT5645_PWR_DAC_MF_L_BIT 10 | ||
795 | #define RT5645_PWR_DAC_MF_R (0x1 << 9) | ||
796 | #define RT5645_PWR_DAC_MF_R_BIT 9 | ||
797 | #define RT5645_PWR_ADC_S2F (0x1 << 8) | ||
798 | #define RT5645_PWR_ADC_S2F_BIT 8 | ||
799 | #define RT5645_PWR_PDM1 (0x1 << 7) | ||
800 | #define RT5645_PWR_PDM1_BIT 7 | ||
801 | #define RT5645_PWR_PDM2 (0x1 << 6) | ||
802 | #define RT5645_PWR_PDM2_BIT 6 | ||
803 | #define RT5645_PWR_IPTV (0x1 << 1) | ||
804 | #define RT5645_PWR_IPTV_BIT 1 | ||
805 | #define RT5645_PWR_PAD (0x1) | ||
806 | #define RT5645_PWR_PAD_BIT 0 | ||
807 | |||
808 | /* Power Management for Analog 1 (0x63) */ | ||
809 | #define RT5645_PWR_VREF1 (0x1 << 15) | ||
810 | #define RT5645_PWR_VREF1_BIT 15 | ||
811 | #define RT5645_PWR_FV1 (0x1 << 14) | ||
812 | #define RT5645_PWR_FV1_BIT 14 | ||
813 | #define RT5645_PWR_MB (0x1 << 13) | ||
814 | #define RT5645_PWR_MB_BIT 13 | ||
815 | #define RT5645_PWR_LM (0x1 << 12) | ||
816 | #define RT5645_PWR_LM_BIT 12 | ||
817 | #define RT5645_PWR_BG (0x1 << 11) | ||
818 | #define RT5645_PWR_BG_BIT 11 | ||
819 | #define RT5645_PWR_MA (0x1 << 10) | ||
820 | #define RT5645_PWR_MA_BIT 10 | ||
821 | #define RT5645_PWR_HP_L (0x1 << 7) | ||
822 | #define RT5645_PWR_HP_L_BIT 7 | ||
823 | #define RT5645_PWR_HP_R (0x1 << 6) | ||
824 | #define RT5645_PWR_HP_R_BIT 6 | ||
825 | #define RT5645_PWR_HA (0x1 << 5) | ||
826 | #define RT5645_PWR_HA_BIT 5 | ||
827 | #define RT5645_PWR_VREF2 (0x1 << 4) | ||
828 | #define RT5645_PWR_VREF2_BIT 4 | ||
829 | #define RT5645_PWR_FV2 (0x1 << 3) | ||
830 | #define RT5645_PWR_FV2_BIT 3 | ||
831 | #define RT5645_LDO_SEL_MASK (0x3) | ||
832 | #define RT5645_LDO_SEL_SFT 0 | ||
833 | |||
834 | /* Power Management for Analog 2 (0x64) */ | ||
835 | #define RT5645_PWR_BST1 (0x1 << 15) | ||
836 | #define RT5645_PWR_BST1_BIT 15 | ||
837 | #define RT5645_PWR_BST2 (0x1 << 14) | ||
838 | #define RT5645_PWR_BST2_BIT 14 | ||
839 | #define RT5645_PWR_BST3 (0x1 << 13) | ||
840 | #define RT5645_PWR_BST3_BIT 13 | ||
841 | #define RT5645_PWR_BST4 (0x1 << 12) | ||
842 | #define RT5645_PWR_BST4_BIT 12 | ||
843 | #define RT5645_PWR_MB1 (0x1 << 11) | ||
844 | #define RT5645_PWR_MB1_BIT 11 | ||
845 | #define RT5645_PWR_MB2 (0x1 << 10) | ||
846 | #define RT5645_PWR_MB2_BIT 10 | ||
847 | #define RT5645_PWR_PLL (0x1 << 9) | ||
848 | #define RT5645_PWR_PLL_BIT 9 | ||
849 | #define RT5645_PWR_BST2_P (0x1 << 5) | ||
850 | #define RT5645_PWR_BST2_P_BIT 5 | ||
851 | #define RT5645_PWR_BST3_P (0x1 << 4) | ||
852 | #define RT5645_PWR_BST3_P_BIT 4 | ||
853 | #define RT5645_PWR_BST4_P (0x1 << 3) | ||
854 | #define RT5645_PWR_BST4_P_BIT 3 | ||
855 | #define RT5645_PWR_JD1 (0x1 << 2) | ||
856 | #define RT5645_PWR_JD1_BIT 2 | ||
857 | #define RT5645_PWR_JD (0x1 << 1) | ||
858 | #define RT5645_PWR_JD_BIT 1 | ||
859 | |||
860 | /* Power Management for Mixer (0x65) */ | ||
861 | #define RT5645_PWR_OM_L (0x1 << 15) | ||
862 | #define RT5645_PWR_OM_L_BIT 15 | ||
863 | #define RT5645_PWR_OM_R (0x1 << 14) | ||
864 | #define RT5645_PWR_OM_R_BIT 14 | ||
865 | #define RT5645_PWR_SM_L (0x1 << 13) | ||
866 | #define RT5645_PWR_SM_L_BIT 13 | ||
867 | #define RT5645_PWR_SM_R (0x1 << 12) | ||
868 | #define RT5645_PWR_SM_R_BIT 12 | ||
869 | #define RT5645_PWR_RM_L (0x1 << 11) | ||
870 | #define RT5645_PWR_RM_L_BIT 11 | ||
871 | #define RT5645_PWR_RM_R (0x1 << 10) | ||
872 | #define RT5645_PWR_RM_R_BIT 10 | ||
873 | #define RT5645_PWR_MM (0x1 << 8) | ||
874 | #define RT5645_PWR_MM_BIT 8 | ||
875 | #define RT5645_PWR_HM_L (0x1 << 7) | ||
876 | #define RT5645_PWR_HM_L_BIT 7 | ||
877 | #define RT5645_PWR_HM_R (0x1 << 6) | ||
878 | #define RT5645_PWR_HM_R_BIT 6 | ||
879 | #define RT5645_PWR_LDO2 (0x1 << 1) | ||
880 | #define RT5645_PWR_LDO2_BIT 1 | ||
881 | |||
882 | /* Power Management for Volume (0x66) */ | ||
883 | #define RT5645_PWR_SV_L (0x1 << 15) | ||
884 | #define RT5645_PWR_SV_L_BIT 15 | ||
885 | #define RT5645_PWR_SV_R (0x1 << 14) | ||
886 | #define RT5645_PWR_SV_R_BIT 14 | ||
887 | #define RT5645_PWR_HV_L (0x1 << 11) | ||
888 | #define RT5645_PWR_HV_L_BIT 11 | ||
889 | #define RT5645_PWR_HV_R (0x1 << 10) | ||
890 | #define RT5645_PWR_HV_R_BIT 10 | ||
891 | #define RT5645_PWR_IN_L (0x1 << 9) | ||
892 | #define RT5645_PWR_IN_L_BIT 9 | ||
893 | #define RT5645_PWR_IN_R (0x1 << 8) | ||
894 | #define RT5645_PWR_IN_R_BIT 8 | ||
895 | #define RT5645_PWR_MIC_DET (0x1 << 5) | ||
896 | #define RT5645_PWR_MIC_DET_BIT 5 | ||
897 | |||
898 | /* I2S1/2 Audio Serial Data Port Control (0x70 0x71) */ | ||
899 | #define RT5645_I2S_MS_MASK (0x1 << 15) | ||
900 | #define RT5645_I2S_MS_SFT 15 | ||
901 | #define RT5645_I2S_MS_M (0x0 << 15) | ||
902 | #define RT5645_I2S_MS_S (0x1 << 15) | ||
903 | #define RT5645_I2S_O_CP_MASK (0x3 << 10) | ||
904 | #define RT5645_I2S_O_CP_SFT 10 | ||
905 | #define RT5645_I2S_O_CP_OFF (0x0 << 10) | ||
906 | #define RT5645_I2S_O_CP_U_LAW (0x1 << 10) | ||
907 | #define RT5645_I2S_O_CP_A_LAW (0x2 << 10) | ||
908 | #define RT5645_I2S_I_CP_MASK (0x3 << 8) | ||
909 | #define RT5645_I2S_I_CP_SFT 8 | ||
910 | #define RT5645_I2S_I_CP_OFF (0x0 << 8) | ||
911 | #define RT5645_I2S_I_CP_U_LAW (0x1 << 8) | ||
912 | #define RT5645_I2S_I_CP_A_LAW (0x2 << 8) | ||
913 | #define RT5645_I2S_BP_MASK (0x1 << 7) | ||
914 | #define RT5645_I2S_BP_SFT 7 | ||
915 | #define RT5645_I2S_BP_NOR (0x0 << 7) | ||
916 | #define RT5645_I2S_BP_INV (0x1 << 7) | ||
917 | #define RT5645_I2S_DL_MASK (0x3 << 2) | ||
918 | #define RT5645_I2S_DL_SFT 2 | ||
919 | #define RT5645_I2S_DL_16 (0x0 << 2) | ||
920 | #define RT5645_I2S_DL_20 (0x1 << 2) | ||
921 | #define RT5645_I2S_DL_24 (0x2 << 2) | ||
922 | #define RT5645_I2S_DL_8 (0x3 << 2) | ||
923 | #define RT5645_I2S_DF_MASK (0x3) | ||
924 | #define RT5645_I2S_DF_SFT 0 | ||
925 | #define RT5645_I2S_DF_I2S (0x0) | ||
926 | #define RT5645_I2S_DF_LEFT (0x1) | ||
927 | #define RT5645_I2S_DF_PCM_A (0x2) | ||
928 | #define RT5645_I2S_DF_PCM_B (0x3) | ||
929 | |||
930 | /* I2S2 Audio Serial Data Port Control (0x71) */ | ||
931 | #define RT5645_I2S2_SDI_MASK (0x1 << 6) | ||
932 | #define RT5645_I2S2_SDI_SFT 6 | ||
933 | #define RT5645_I2S2_SDI_I2S1 (0x0 << 6) | ||
934 | #define RT5645_I2S2_SDI_I2S2 (0x1 << 6) | ||
935 | |||
936 | /* ADC/DAC Clock Control 1 (0x73) */ | ||
937 | #define RT5645_I2S_BCLK_MS1_MASK (0x1 << 15) | ||
938 | #define RT5645_I2S_BCLK_MS1_SFT 15 | ||
939 | #define RT5645_I2S_BCLK_MS1_32 (0x0 << 15) | ||
940 | #define RT5645_I2S_BCLK_MS1_64 (0x1 << 15) | ||
941 | #define RT5645_I2S_PD1_MASK (0x7 << 12) | ||
942 | #define RT5645_I2S_PD1_SFT 12 | ||
943 | #define RT5645_I2S_PD1_1 (0x0 << 12) | ||
944 | #define RT5645_I2S_PD1_2 (0x1 << 12) | ||
945 | #define RT5645_I2S_PD1_3 (0x2 << 12) | ||
946 | #define RT5645_I2S_PD1_4 (0x3 << 12) | ||
947 | #define RT5645_I2S_PD1_6 (0x4 << 12) | ||
948 | #define RT5645_I2S_PD1_8 (0x5 << 12) | ||
949 | #define RT5645_I2S_PD1_12 (0x6 << 12) | ||
950 | #define RT5645_I2S_PD1_16 (0x7 << 12) | ||
951 | #define RT5645_I2S_BCLK_MS2_MASK (0x1 << 11) | ||
952 | #define RT5645_I2S_BCLK_MS2_SFT 11 | ||
953 | #define RT5645_I2S_BCLK_MS2_32 (0x0 << 11) | ||
954 | #define RT5645_I2S_BCLK_MS2_64 (0x1 << 11) | ||
955 | #define RT5645_I2S_PD2_MASK (0x7 << 8) | ||
956 | #define RT5645_I2S_PD2_SFT 8 | ||
957 | #define RT5645_I2S_PD2_1 (0x0 << 8) | ||
958 | #define RT5645_I2S_PD2_2 (0x1 << 8) | ||
959 | #define RT5645_I2S_PD2_3 (0x2 << 8) | ||
960 | #define RT5645_I2S_PD2_4 (0x3 << 8) | ||
961 | #define RT5645_I2S_PD2_6 (0x4 << 8) | ||
962 | #define RT5645_I2S_PD2_8 (0x5 << 8) | ||
963 | #define RT5645_I2S_PD2_12 (0x6 << 8) | ||
964 | #define RT5645_I2S_PD2_16 (0x7 << 8) | ||
965 | #define RT5645_I2S_BCLK_MS3_MASK (0x1 << 7) | ||
966 | #define RT5645_I2S_BCLK_MS3_SFT 7 | ||
967 | #define RT5645_I2S_BCLK_MS3_32 (0x0 << 7) | ||
968 | #define RT5645_I2S_BCLK_MS3_64 (0x1 << 7) | ||
969 | #define RT5645_I2S_PD3_MASK (0x7 << 4) | ||
970 | #define RT5645_I2S_PD3_SFT 4 | ||
971 | #define RT5645_I2S_PD3_1 (0x0 << 4) | ||
972 | #define RT5645_I2S_PD3_2 (0x1 << 4) | ||
973 | #define RT5645_I2S_PD3_3 (0x2 << 4) | ||
974 | #define RT5645_I2S_PD3_4 (0x3 << 4) | ||
975 | #define RT5645_I2S_PD3_6 (0x4 << 4) | ||
976 | #define RT5645_I2S_PD3_8 (0x5 << 4) | ||
977 | #define RT5645_I2S_PD3_12 (0x6 << 4) | ||
978 | #define RT5645_I2S_PD3_16 (0x7 << 4) | ||
979 | #define RT5645_DAC_OSR_MASK (0x3 << 2) | ||
980 | #define RT5645_DAC_OSR_SFT 2 | ||
981 | #define RT5645_DAC_OSR_128 (0x0 << 2) | ||
982 | #define RT5645_DAC_OSR_64 (0x1 << 2) | ||
983 | #define RT5645_DAC_OSR_32 (0x2 << 2) | ||
984 | #define RT5645_DAC_OSR_16 (0x3 << 2) | ||
985 | #define RT5645_ADC_OSR_MASK (0x3) | ||
986 | #define RT5645_ADC_OSR_SFT 0 | ||
987 | #define RT5645_ADC_OSR_128 (0x0) | ||
988 | #define RT5645_ADC_OSR_64 (0x1) | ||
989 | #define RT5645_ADC_OSR_32 (0x2) | ||
990 | #define RT5645_ADC_OSR_16 (0x3) | ||
991 | |||
992 | /* ADC/DAC Clock Control 2 (0x74) */ | ||
993 | #define RT5645_DAC_L_OSR_MASK (0x3 << 14) | ||
994 | #define RT5645_DAC_L_OSR_SFT 14 | ||
995 | #define RT5645_DAC_L_OSR_128 (0x0 << 14) | ||
996 | #define RT5645_DAC_L_OSR_64 (0x1 << 14) | ||
997 | #define RT5645_DAC_L_OSR_32 (0x2 << 14) | ||
998 | #define RT5645_DAC_L_OSR_16 (0x3 << 14) | ||
999 | #define RT5645_ADC_R_OSR_MASK (0x3 << 12) | ||
1000 | #define RT5645_ADC_R_OSR_SFT 12 | ||
1001 | #define RT5645_ADC_R_OSR_128 (0x0 << 12) | ||
1002 | #define RT5645_ADC_R_OSR_64 (0x1 << 12) | ||
1003 | #define RT5645_ADC_R_OSR_32 (0x2 << 12) | ||
1004 | #define RT5645_ADC_R_OSR_16 (0x3 << 12) | ||
1005 | #define RT5645_DAHPF_EN (0x1 << 11) | ||
1006 | #define RT5645_DAHPF_EN_SFT 11 | ||
1007 | #define RT5645_ADHPF_EN (0x1 << 10) | ||
1008 | #define RT5645_ADHPF_EN_SFT 10 | ||
1009 | |||
1010 | /* Digital Microphone Control (0x75) */ | ||
1011 | #define RT5645_DMIC_1_EN_MASK (0x1 << 15) | ||
1012 | #define RT5645_DMIC_1_EN_SFT 15 | ||
1013 | #define RT5645_DMIC_1_DIS (0x0 << 15) | ||
1014 | #define RT5645_DMIC_1_EN (0x1 << 15) | ||
1015 | #define RT5645_DMIC_2_EN_MASK (0x1 << 14) | ||
1016 | #define RT5645_DMIC_2_EN_SFT 14 | ||
1017 | #define RT5645_DMIC_2_DIS (0x0 << 14) | ||
1018 | #define RT5645_DMIC_2_EN (0x1 << 14) | ||
1019 | #define RT5645_DMIC_1L_LH_MASK (0x1 << 13) | ||
1020 | #define RT5645_DMIC_1L_LH_SFT 13 | ||
1021 | #define RT5645_DMIC_1L_LH_FALLING (0x0 << 13) | ||
1022 | #define RT5645_DMIC_1L_LH_RISING (0x1 << 13) | ||
1023 | #define RT5645_DMIC_1R_LH_MASK (0x1 << 12) | ||
1024 | #define RT5645_DMIC_1R_LH_SFT 12 | ||
1025 | #define RT5645_DMIC_1R_LH_FALLING (0x0 << 12) | ||
1026 | #define RT5645_DMIC_1R_LH_RISING (0x1 << 12) | ||
1027 | #define RT5645_DMIC_2_DP_MASK (0x3 << 10) | ||
1028 | #define RT5645_DMIC_2_DP_SFT 10 | ||
1029 | #define RT5645_DMIC_2_DP_GPIO6 (0x0 << 10) | ||
1030 | #define RT5645_DMIC_2_DP_GPIO10 (0x1 << 10) | ||
1031 | #define RT5645_DMIC_2_DP_GPIO12 (0x2 << 10) | ||
1032 | #define RT5645_DMIC_2_DP_IN2P (0x3 << 10) | ||
1033 | #define RT5645_DMIC_2L_LH_MASK (0x1 << 9) | ||
1034 | #define RT5645_DMIC_2L_LH_SFT 9 | ||
1035 | #define RT5645_DMIC_2L_LH_FALLING (0x0 << 9) | ||
1036 | #define RT5645_DMIC_2L_LH_RISING (0x1 << 9) | ||
1037 | #define RT5645_DMIC_2R_LH_MASK (0x1 << 8) | ||
1038 | #define RT5645_DMIC_2R_LH_SFT 8 | ||
1039 | #define RT5645_DMIC_2R_LH_FALLING (0x0 << 8) | ||
1040 | #define RT5645_DMIC_2R_LH_RISING (0x1 << 8) | ||
1041 | #define RT5645_DMIC_CLK_MASK (0x7 << 5) | ||
1042 | #define RT5645_DMIC_CLK_SFT 5 | ||
1043 | #define RT5645_DMIC_3_EN_MASK (0x1 << 4) | ||
1044 | #define RT5645_DMIC_3_EN_SFT 4 | ||
1045 | #define RT5645_DMIC_3_DIS (0x0 << 4) | ||
1046 | #define RT5645_DMIC_3_EN (0x1 << 4) | ||
1047 | #define RT5645_DMIC_1_DP_MASK (0x3 << 0) | ||
1048 | #define RT5645_DMIC_1_DP_SFT 0 | ||
1049 | #define RT5645_DMIC_1_DP_GPIO5 (0x0 << 0) | ||
1050 | #define RT5645_DMIC_1_DP_IN2N (0x1 << 0) | ||
1051 | #define RT5645_DMIC_1_DP_GPIO11 (0x2 << 0) | ||
1052 | |||
1053 | /* TDM Control 1 (0x77) */ | ||
1054 | #define RT5645_IF1_ADC_IN_MASK (0x3 << 8) | ||
1055 | #define RT5645_IF1_ADC_IN_SFT 8 | ||
1056 | |||
1057 | /* Global Clock Control (0x80) */ | ||
1058 | #define RT5645_SCLK_SRC_MASK (0x3 << 14) | ||
1059 | #define RT5645_SCLK_SRC_SFT 14 | ||
1060 | #define RT5645_SCLK_SRC_MCLK (0x0 << 14) | ||
1061 | #define RT5645_SCLK_SRC_PLL1 (0x1 << 14) | ||
1062 | #define RT5645_SCLK_SRC_RCCLK (0x2 << 14) /* 15MHz */ | ||
1063 | #define RT5645_PLL1_SRC_MASK (0x3 << 12) | ||
1064 | #define RT5645_PLL1_SRC_SFT 12 | ||
1065 | #define RT5645_PLL1_SRC_MCLK (0x0 << 12) | ||
1066 | #define RT5645_PLL1_SRC_BCLK1 (0x1 << 12) | ||
1067 | #define RT5645_PLL1_SRC_BCLK2 (0x2 << 12) | ||
1068 | #define RT5645_PLL1_SRC_BCLK3 (0x3 << 12) | ||
1069 | #define RT5645_PLL1_PD_MASK (0x1 << 3) | ||
1070 | #define RT5645_PLL1_PD_SFT 3 | ||
1071 | #define RT5645_PLL1_PD_1 (0x0 << 3) | ||
1072 | #define RT5645_PLL1_PD_2 (0x1 << 3) | ||
1073 | |||
1074 | #define RT5645_PLL_INP_MAX 40000000 | ||
1075 | #define RT5645_PLL_INP_MIN 256000 | ||
1076 | /* PLL M/N/K Code Control 1 (0x81) */ | ||
1077 | #define RT5645_PLL_N_MAX 0x1ff | ||
1078 | #define RT5645_PLL_N_MASK (RT5645_PLL_N_MAX << 7) | ||
1079 | #define RT5645_PLL_N_SFT 7 | ||
1080 | #define RT5645_PLL_K_MAX 0x1f | ||
1081 | #define RT5645_PLL_K_MASK (RT5645_PLL_K_MAX) | ||
1082 | #define RT5645_PLL_K_SFT 0 | ||
1083 | |||
1084 | /* PLL M/N/K Code Control 2 (0x82) */ | ||
1085 | #define RT5645_PLL_M_MAX 0xf | ||
1086 | #define RT5645_PLL_M_MASK (RT5645_PLL_M_MAX << 12) | ||
1087 | #define RT5645_PLL_M_SFT 12 | ||
1088 | #define RT5645_PLL_M_BP (0x1 << 11) | ||
1089 | #define RT5645_PLL_M_BP_SFT 11 | ||
1090 | |||
1091 | /* ASRC Control 1 (0x83) */ | ||
1092 | #define RT5645_STO_T_MASK (0x1 << 15) | ||
1093 | #define RT5645_STO_T_SFT 15 | ||
1094 | #define RT5645_STO_T_SCLK (0x0 << 15) | ||
1095 | #define RT5645_STO_T_LRCK1 (0x1 << 15) | ||
1096 | #define RT5645_M1_T_MASK (0x1 << 14) | ||
1097 | #define RT5645_M1_T_SFT 14 | ||
1098 | #define RT5645_M1_T_I2S2 (0x0 << 14) | ||
1099 | #define RT5645_M1_T_I2S2_D3 (0x1 << 14) | ||
1100 | #define RT5645_I2S2_F_MASK (0x1 << 12) | ||
1101 | #define RT5645_I2S2_F_SFT 12 | ||
1102 | #define RT5645_I2S2_F_I2S2_D2 (0x0 << 12) | ||
1103 | #define RT5645_I2S2_F_I2S1_TCLK (0x1 << 12) | ||
1104 | #define RT5645_DMIC_1_M_MASK (0x1 << 9) | ||
1105 | #define RT5645_DMIC_1_M_SFT 9 | ||
1106 | #define RT5645_DMIC_1_M_NOR (0x0 << 9) | ||
1107 | #define RT5645_DMIC_1_M_ASYN (0x1 << 9) | ||
1108 | #define RT5645_DMIC_2_M_MASK (0x1 << 8) | ||
1109 | #define RT5645_DMIC_2_M_SFT 8 | ||
1110 | #define RT5645_DMIC_2_M_NOR (0x0 << 8) | ||
1111 | #define RT5645_DMIC_2_M_ASYN (0x1 << 8) | ||
1112 | |||
1113 | /* ASRC Control 2 (0x84) */ | ||
1114 | #define RT5645_MDA_L_M_MASK (0x1 << 15) | ||
1115 | #define RT5645_MDA_L_M_SFT 15 | ||
1116 | #define RT5645_MDA_L_M_NOR (0x0 << 15) | ||
1117 | #define RT5645_MDA_L_M_ASYN (0x1 << 15) | ||
1118 | #define RT5645_MDA_R_M_MASK (0x1 << 14) | ||
1119 | #define RT5645_MDA_R_M_SFT 14 | ||
1120 | #define RT5645_MDA_R_M_NOR (0x0 << 14) | ||
1121 | #define RT5645_MDA_R_M_ASYN (0x1 << 14) | ||
1122 | #define RT5645_MAD_L_M_MASK (0x1 << 13) | ||
1123 | #define RT5645_MAD_L_M_SFT 13 | ||
1124 | #define RT5645_MAD_L_M_NOR (0x0 << 13) | ||
1125 | #define RT5645_MAD_L_M_ASYN (0x1 << 13) | ||
1126 | #define RT5645_MAD_R_M_MASK (0x1 << 12) | ||
1127 | #define RT5645_MAD_R_M_SFT 12 | ||
1128 | #define RT5645_MAD_R_M_NOR (0x0 << 12) | ||
1129 | #define RT5645_MAD_R_M_ASYN (0x1 << 12) | ||
1130 | #define RT5645_ADC_M_MASK (0x1 << 11) | ||
1131 | #define RT5645_ADC_M_SFT 11 | ||
1132 | #define RT5645_ADC_M_NOR (0x0 << 11) | ||
1133 | #define RT5645_ADC_M_ASYN (0x1 << 11) | ||
1134 | #define RT5645_STO_DAC_M_MASK (0x1 << 5) | ||
1135 | #define RT5645_STO_DAC_M_SFT 5 | ||
1136 | #define RT5645_STO_DAC_M_NOR (0x0 << 5) | ||
1137 | #define RT5645_STO_DAC_M_ASYN (0x1 << 5) | ||
1138 | #define RT5645_I2S1_R_D_MASK (0x1 << 4) | ||
1139 | #define RT5645_I2S1_R_D_SFT 4 | ||
1140 | #define RT5645_I2S1_R_D_DIS (0x0 << 4) | ||
1141 | #define RT5645_I2S1_R_D_EN (0x1 << 4) | ||
1142 | #define RT5645_I2S2_R_D_MASK (0x1 << 3) | ||
1143 | #define RT5645_I2S2_R_D_SFT 3 | ||
1144 | #define RT5645_I2S2_R_D_DIS (0x0 << 3) | ||
1145 | #define RT5645_I2S2_R_D_EN (0x1 << 3) | ||
1146 | #define RT5645_PRE_SCLK_MASK (0x3) | ||
1147 | #define RT5645_PRE_SCLK_SFT 0 | ||
1148 | #define RT5645_PRE_SCLK_512 (0x0) | ||
1149 | #define RT5645_PRE_SCLK_1024 (0x1) | ||
1150 | #define RT5645_PRE_SCLK_2048 (0x2) | ||
1151 | |||
1152 | /* ASRC Control 3 (0x85) */ | ||
1153 | #define RT5645_I2S1_RATE_MASK (0xf << 12) | ||
1154 | #define RT5645_I2S1_RATE_SFT 12 | ||
1155 | #define RT5645_I2S2_RATE_MASK (0xf << 8) | ||
1156 | #define RT5645_I2S2_RATE_SFT 8 | ||
1157 | |||
1158 | /* ASRC Control 4 (0x89) */ | ||
1159 | #define RT5645_I2S1_PD_MASK (0x7 << 12) | ||
1160 | #define RT5645_I2S1_PD_SFT 12 | ||
1161 | #define RT5645_I2S2_PD_MASK (0x7 << 8) | ||
1162 | #define RT5645_I2S2_PD_SFT 8 | ||
1163 | |||
1164 | /* HPOUT Over Current Detection (0x8b) */ | ||
1165 | #define RT5645_HP_OVCD_MASK (0x1 << 10) | ||
1166 | #define RT5645_HP_OVCD_SFT 10 | ||
1167 | #define RT5645_HP_OVCD_DIS (0x0 << 10) | ||
1168 | #define RT5645_HP_OVCD_EN (0x1 << 10) | ||
1169 | #define RT5645_HP_OC_TH_MASK (0x3 << 8) | ||
1170 | #define RT5645_HP_OC_TH_SFT 8 | ||
1171 | #define RT5645_HP_OC_TH_90 (0x0 << 8) | ||
1172 | #define RT5645_HP_OC_TH_105 (0x1 << 8) | ||
1173 | #define RT5645_HP_OC_TH_120 (0x2 << 8) | ||
1174 | #define RT5645_HP_OC_TH_135 (0x3 << 8) | ||
1175 | |||
1176 | /* Class D Over Current Control (0x8c) */ | ||
1177 | #define RT5645_CLSD_OC_MASK (0x1 << 9) | ||
1178 | #define RT5645_CLSD_OC_SFT 9 | ||
1179 | #define RT5645_CLSD_OC_PU (0x0 << 9) | ||
1180 | #define RT5645_CLSD_OC_PD (0x1 << 9) | ||
1181 | #define RT5645_AUTO_PD_MASK (0x1 << 8) | ||
1182 | #define RT5645_AUTO_PD_SFT 8 | ||
1183 | #define RT5645_AUTO_PD_DIS (0x0 << 8) | ||
1184 | #define RT5645_AUTO_PD_EN (0x1 << 8) | ||
1185 | #define RT5645_CLSD_OC_TH_MASK (0x3f) | ||
1186 | #define RT5645_CLSD_OC_TH_SFT 0 | ||
1187 | |||
1188 | /* Class D Output Control (0x8d) */ | ||
1189 | #define RT5645_CLSD_RATIO_MASK (0xf << 12) | ||
1190 | #define RT5645_CLSD_RATIO_SFT 12 | ||
1191 | #define RT5645_CLSD_OM_MASK (0x1 << 11) | ||
1192 | #define RT5645_CLSD_OM_SFT 11 | ||
1193 | #define RT5645_CLSD_OM_MONO (0x0 << 11) | ||
1194 | #define RT5645_CLSD_OM_STO (0x1 << 11) | ||
1195 | #define RT5645_CLSD_SCH_MASK (0x1 << 10) | ||
1196 | #define RT5645_CLSD_SCH_SFT 10 | ||
1197 | #define RT5645_CLSD_SCH_L (0x0 << 10) | ||
1198 | #define RT5645_CLSD_SCH_S (0x1 << 10) | ||
1199 | |||
1200 | /* Depop Mode Control 1 (0x8e) */ | ||
1201 | #define RT5645_SMT_TRIG_MASK (0x1 << 15) | ||
1202 | #define RT5645_SMT_TRIG_SFT 15 | ||
1203 | #define RT5645_SMT_TRIG_DIS (0x0 << 15) | ||
1204 | #define RT5645_SMT_TRIG_EN (0x1 << 15) | ||
1205 | #define RT5645_HP_L_SMT_MASK (0x1 << 9) | ||
1206 | #define RT5645_HP_L_SMT_SFT 9 | ||
1207 | #define RT5645_HP_L_SMT_DIS (0x0 << 9) | ||
1208 | #define RT5645_HP_L_SMT_EN (0x1 << 9) | ||
1209 | #define RT5645_HP_R_SMT_MASK (0x1 << 8) | ||
1210 | #define RT5645_HP_R_SMT_SFT 8 | ||
1211 | #define RT5645_HP_R_SMT_DIS (0x0 << 8) | ||
1212 | #define RT5645_HP_R_SMT_EN (0x1 << 8) | ||
1213 | #define RT5645_HP_CD_PD_MASK (0x1 << 7) | ||
1214 | #define RT5645_HP_CD_PD_SFT 7 | ||
1215 | #define RT5645_HP_CD_PD_DIS (0x0 << 7) | ||
1216 | #define RT5645_HP_CD_PD_EN (0x1 << 7) | ||
1217 | #define RT5645_RSTN_MASK (0x1 << 6) | ||
1218 | #define RT5645_RSTN_SFT 6 | ||
1219 | #define RT5645_RSTN_DIS (0x0 << 6) | ||
1220 | #define RT5645_RSTN_EN (0x1 << 6) | ||
1221 | #define RT5645_RSTP_MASK (0x1 << 5) | ||
1222 | #define RT5645_RSTP_SFT 5 | ||
1223 | #define RT5645_RSTP_DIS (0x0 << 5) | ||
1224 | #define RT5645_RSTP_EN (0x1 << 5) | ||
1225 | #define RT5645_HP_CO_MASK (0x1 << 4) | ||
1226 | #define RT5645_HP_CO_SFT 4 | ||
1227 | #define RT5645_HP_CO_DIS (0x0 << 4) | ||
1228 | #define RT5645_HP_CO_EN (0x1 << 4) | ||
1229 | #define RT5645_HP_CP_MASK (0x1 << 3) | ||
1230 | #define RT5645_HP_CP_SFT 3 | ||
1231 | #define RT5645_HP_CP_PD (0x0 << 3) | ||
1232 | #define RT5645_HP_CP_PU (0x1 << 3) | ||
1233 | #define RT5645_HP_SG_MASK (0x1 << 2) | ||
1234 | #define RT5645_HP_SG_SFT 2 | ||
1235 | #define RT5645_HP_SG_DIS (0x0 << 2) | ||
1236 | #define RT5645_HP_SG_EN (0x1 << 2) | ||
1237 | #define RT5645_HP_DP_MASK (0x1 << 1) | ||
1238 | #define RT5645_HP_DP_SFT 1 | ||
1239 | #define RT5645_HP_DP_PD (0x0 << 1) | ||
1240 | #define RT5645_HP_DP_PU (0x1 << 1) | ||
1241 | #define RT5645_HP_CB_MASK (0x1) | ||
1242 | #define RT5645_HP_CB_SFT 0 | ||
1243 | #define RT5645_HP_CB_PD (0x0) | ||
1244 | #define RT5645_HP_CB_PU (0x1) | ||
1245 | |||
1246 | /* Depop Mode Control 2 (0x8f) */ | ||
1247 | #define RT5645_DEPOP_MASK (0x1 << 13) | ||
1248 | #define RT5645_DEPOP_SFT 13 | ||
1249 | #define RT5645_DEPOP_AUTO (0x0 << 13) | ||
1250 | #define RT5645_DEPOP_MAN (0x1 << 13) | ||
1251 | #define RT5645_RAMP_MASK (0x1 << 12) | ||
1252 | #define RT5645_RAMP_SFT 12 | ||
1253 | #define RT5645_RAMP_DIS (0x0 << 12) | ||
1254 | #define RT5645_RAMP_EN (0x1 << 12) | ||
1255 | #define RT5645_BPS_MASK (0x1 << 11) | ||
1256 | #define RT5645_BPS_SFT 11 | ||
1257 | #define RT5645_BPS_DIS (0x0 << 11) | ||
1258 | #define RT5645_BPS_EN (0x1 << 11) | ||
1259 | #define RT5645_FAST_UPDN_MASK (0x1 << 10) | ||
1260 | #define RT5645_FAST_UPDN_SFT 10 | ||
1261 | #define RT5645_FAST_UPDN_DIS (0x0 << 10) | ||
1262 | #define RT5645_FAST_UPDN_EN (0x1 << 10) | ||
1263 | #define RT5645_MRES_MASK (0x3 << 8) | ||
1264 | #define RT5645_MRES_SFT 8 | ||
1265 | #define RT5645_MRES_15MO (0x0 << 8) | ||
1266 | #define RT5645_MRES_25MO (0x1 << 8) | ||
1267 | #define RT5645_MRES_35MO (0x2 << 8) | ||
1268 | #define RT5645_MRES_45MO (0x3 << 8) | ||
1269 | #define RT5645_VLO_MASK (0x1 << 7) | ||
1270 | #define RT5645_VLO_SFT 7 | ||
1271 | #define RT5645_VLO_3V (0x0 << 7) | ||
1272 | #define RT5645_VLO_32V (0x1 << 7) | ||
1273 | #define RT5645_DIG_DP_MASK (0x1 << 6) | ||
1274 | #define RT5645_DIG_DP_SFT 6 | ||
1275 | #define RT5645_DIG_DP_DIS (0x0 << 6) | ||
1276 | #define RT5645_DIG_DP_EN (0x1 << 6) | ||
1277 | #define RT5645_DP_TH_MASK (0x3 << 4) | ||
1278 | #define RT5645_DP_TH_SFT 4 | ||
1279 | |||
1280 | /* Depop Mode Control 3 (0x90) */ | ||
1281 | #define RT5645_CP_SYS_MASK (0x7 << 12) | ||
1282 | #define RT5645_CP_SYS_SFT 12 | ||
1283 | #define RT5645_CP_FQ1_MASK (0x7 << 8) | ||
1284 | #define RT5645_CP_FQ1_SFT 8 | ||
1285 | #define RT5645_CP_FQ2_MASK (0x7 << 4) | ||
1286 | #define RT5645_CP_FQ2_SFT 4 | ||
1287 | #define RT5645_CP_FQ3_MASK (0x7) | ||
1288 | #define RT5645_CP_FQ3_SFT 0 | ||
1289 | #define RT5645_CP_FQ_1_5_KHZ 0 | ||
1290 | #define RT5645_CP_FQ_3_KHZ 1 | ||
1291 | #define RT5645_CP_FQ_6_KHZ 2 | ||
1292 | #define RT5645_CP_FQ_12_KHZ 3 | ||
1293 | #define RT5645_CP_FQ_24_KHZ 4 | ||
1294 | #define RT5645_CP_FQ_48_KHZ 5 | ||
1295 | #define RT5645_CP_FQ_96_KHZ 6 | ||
1296 | #define RT5645_CP_FQ_192_KHZ 7 | ||
1297 | |||
1298 | /* PV detection and SPK gain control (0x92) */ | ||
1299 | #define RT5645_PVDD_DET_MASK (0x1 << 15) | ||
1300 | #define RT5645_PVDD_DET_SFT 15 | ||
1301 | #define RT5645_PVDD_DET_DIS (0x0 << 15) | ||
1302 | #define RT5645_PVDD_DET_EN (0x1 << 15) | ||
1303 | #define RT5645_SPK_AG_MASK (0x1 << 14) | ||
1304 | #define RT5645_SPK_AG_SFT 14 | ||
1305 | #define RT5645_SPK_AG_DIS (0x0 << 14) | ||
1306 | #define RT5645_SPK_AG_EN (0x1 << 14) | ||
1307 | |||
1308 | /* Micbias Control (0x93) */ | ||
1309 | #define RT5645_MIC1_BS_MASK (0x1 << 15) | ||
1310 | #define RT5645_MIC1_BS_SFT 15 | ||
1311 | #define RT5645_MIC1_BS_9AV (0x0 << 15) | ||
1312 | #define RT5645_MIC1_BS_75AV (0x1 << 15) | ||
1313 | #define RT5645_MIC2_BS_MASK (0x1 << 14) | ||
1314 | #define RT5645_MIC2_BS_SFT 14 | ||
1315 | #define RT5645_MIC2_BS_9AV (0x0 << 14) | ||
1316 | #define RT5645_MIC2_BS_75AV (0x1 << 14) | ||
1317 | #define RT5645_MIC1_CLK_MASK (0x1 << 13) | ||
1318 | #define RT5645_MIC1_CLK_SFT 13 | ||
1319 | #define RT5645_MIC1_CLK_DIS (0x0 << 13) | ||
1320 | #define RT5645_MIC1_CLK_EN (0x1 << 13) | ||
1321 | #define RT5645_MIC2_CLK_MASK (0x1 << 12) | ||
1322 | #define RT5645_MIC2_CLK_SFT 12 | ||
1323 | #define RT5645_MIC2_CLK_DIS (0x0 << 12) | ||
1324 | #define RT5645_MIC2_CLK_EN (0x1 << 12) | ||
1325 | #define RT5645_MIC1_OVCD_MASK (0x1 << 11) | ||
1326 | #define RT5645_MIC1_OVCD_SFT 11 | ||
1327 | #define RT5645_MIC1_OVCD_DIS (0x0 << 11) | ||
1328 | #define RT5645_MIC1_OVCD_EN (0x1 << 11) | ||
1329 | #define RT5645_MIC1_OVTH_MASK (0x3 << 9) | ||
1330 | #define RT5645_MIC1_OVTH_SFT 9 | ||
1331 | #define RT5645_MIC1_OVTH_600UA (0x0 << 9) | ||
1332 | #define RT5645_MIC1_OVTH_1500UA (0x1 << 9) | ||
1333 | #define RT5645_MIC1_OVTH_2000UA (0x2 << 9) | ||
1334 | #define RT5645_MIC2_OVCD_MASK (0x1 << 8) | ||
1335 | #define RT5645_MIC2_OVCD_SFT 8 | ||
1336 | #define RT5645_MIC2_OVCD_DIS (0x0 << 8) | ||
1337 | #define RT5645_MIC2_OVCD_EN (0x1 << 8) | ||
1338 | #define RT5645_MIC2_OVTH_MASK (0x3 << 6) | ||
1339 | #define RT5645_MIC2_OVTH_SFT 6 | ||
1340 | #define RT5645_MIC2_OVTH_600UA (0x0 << 6) | ||
1341 | #define RT5645_MIC2_OVTH_1500UA (0x1 << 6) | ||
1342 | #define RT5645_MIC2_OVTH_2000UA (0x2 << 6) | ||
1343 | #define RT5645_PWR_MB_MASK (0x1 << 5) | ||
1344 | #define RT5645_PWR_MB_SFT 5 | ||
1345 | #define RT5645_PWR_MB_PD (0x0 << 5) | ||
1346 | #define RT5645_PWR_MB_PU (0x1 << 5) | ||
1347 | #define RT5645_PWR_CLK25M_MASK (0x1 << 4) | ||
1348 | #define RT5645_PWR_CLK25M_SFT 4 | ||
1349 | #define RT5645_PWR_CLK25M_PD (0x0 << 4) | ||
1350 | #define RT5645_PWR_CLK25M_PU (0x1 << 4) | ||
1351 | |||
1352 | /* VAD Control 4 (0x9d) */ | ||
1353 | #define RT5645_VAD_SEL_MASK (0x3 << 8) | ||
1354 | #define RT5645_VAD_SEL_SFT 8 | ||
1355 | |||
1356 | /* EQ Control 1 (0xb0) */ | ||
1357 | #define RT5645_EQ_SRC_MASK (0x1 << 15) | ||
1358 | #define RT5645_EQ_SRC_SFT 15 | ||
1359 | #define RT5645_EQ_SRC_DAC (0x0 << 15) | ||
1360 | #define RT5645_EQ_SRC_ADC (0x1 << 15) | ||
1361 | #define RT5645_EQ_UPD (0x1 << 14) | ||
1362 | #define RT5645_EQ_UPD_BIT 14 | ||
1363 | #define RT5645_EQ_CD_MASK (0x1 << 13) | ||
1364 | #define RT5645_EQ_CD_SFT 13 | ||
1365 | #define RT5645_EQ_CD_DIS (0x0 << 13) | ||
1366 | #define RT5645_EQ_CD_EN (0x1 << 13) | ||
1367 | #define RT5645_EQ_DITH_MASK (0x3 << 8) | ||
1368 | #define RT5645_EQ_DITH_SFT 8 | ||
1369 | #define RT5645_EQ_DITH_NOR (0x0 << 8) | ||
1370 | #define RT5645_EQ_DITH_LSB (0x1 << 8) | ||
1371 | #define RT5645_EQ_DITH_LSB_1 (0x2 << 8) | ||
1372 | #define RT5645_EQ_DITH_LSB_2 (0x3 << 8) | ||
1373 | |||
1374 | /* EQ Control 2 (0xb1) */ | ||
1375 | #define RT5645_EQ_HPF1_M_MASK (0x1 << 8) | ||
1376 | #define RT5645_EQ_HPF1_M_SFT 8 | ||
1377 | #define RT5645_EQ_HPF1_M_HI (0x0 << 8) | ||
1378 | #define RT5645_EQ_HPF1_M_1ST (0x1 << 8) | ||
1379 | #define RT5645_EQ_LPF1_M_MASK (0x1 << 7) | ||
1380 | #define RT5645_EQ_LPF1_M_SFT 7 | ||
1381 | #define RT5645_EQ_LPF1_M_LO (0x0 << 7) | ||
1382 | #define RT5645_EQ_LPF1_M_1ST (0x1 << 7) | ||
1383 | #define RT5645_EQ_HPF2_MASK (0x1 << 6) | ||
1384 | #define RT5645_EQ_HPF2_SFT 6 | ||
1385 | #define RT5645_EQ_HPF2_DIS (0x0 << 6) | ||
1386 | #define RT5645_EQ_HPF2_EN (0x1 << 6) | ||
1387 | #define RT5645_EQ_HPF1_MASK (0x1 << 5) | ||
1388 | #define RT5645_EQ_HPF1_SFT 5 | ||
1389 | #define RT5645_EQ_HPF1_DIS (0x0 << 5) | ||
1390 | #define RT5645_EQ_HPF1_EN (0x1 << 5) | ||
1391 | #define RT5645_EQ_BPF4_MASK (0x1 << 4) | ||
1392 | #define RT5645_EQ_BPF4_SFT 4 | ||
1393 | #define RT5645_EQ_BPF4_DIS (0x0 << 4) | ||
1394 | #define RT5645_EQ_BPF4_EN (0x1 << 4) | ||
1395 | #define RT5645_EQ_BPF3_MASK (0x1 << 3) | ||
1396 | #define RT5645_EQ_BPF3_SFT 3 | ||
1397 | #define RT5645_EQ_BPF3_DIS (0x0 << 3) | ||
1398 | #define RT5645_EQ_BPF3_EN (0x1 << 3) | ||
1399 | #define RT5645_EQ_BPF2_MASK (0x1 << 2) | ||
1400 | #define RT5645_EQ_BPF2_SFT 2 | ||
1401 | #define RT5645_EQ_BPF2_DIS (0x0 << 2) | ||
1402 | #define RT5645_EQ_BPF2_EN (0x1 << 2) | ||
1403 | #define RT5645_EQ_BPF1_MASK (0x1 << 1) | ||
1404 | #define RT5645_EQ_BPF1_SFT 1 | ||
1405 | #define RT5645_EQ_BPF1_DIS (0x0 << 1) | ||
1406 | #define RT5645_EQ_BPF1_EN (0x1 << 1) | ||
1407 | #define RT5645_EQ_LPF_MASK (0x1) | ||
1408 | #define RT5645_EQ_LPF_SFT 0 | ||
1409 | #define RT5645_EQ_LPF_DIS (0x0) | ||
1410 | #define RT5645_EQ_LPF_EN (0x1) | ||
1411 | #define RT5645_EQ_CTRL_MASK (0x7f) | ||
1412 | |||
1413 | /* Memory Test (0xb2) */ | ||
1414 | #define RT5645_MT_MASK (0x1 << 15) | ||
1415 | #define RT5645_MT_SFT 15 | ||
1416 | #define RT5645_MT_DIS (0x0 << 15) | ||
1417 | #define RT5645_MT_EN (0x1 << 15) | ||
1418 | |||
1419 | /* DRC/AGC Control 1 (0xb4) */ | ||
1420 | #define RT5645_DRC_AGC_P_MASK (0x1 << 15) | ||
1421 | #define RT5645_DRC_AGC_P_SFT 15 | ||
1422 | #define RT5645_DRC_AGC_P_DAC (0x0 << 15) | ||
1423 | #define RT5645_DRC_AGC_P_ADC (0x1 << 15) | ||
1424 | #define RT5645_DRC_AGC_MASK (0x1 << 14) | ||
1425 | #define RT5645_DRC_AGC_SFT 14 | ||
1426 | #define RT5645_DRC_AGC_DIS (0x0 << 14) | ||
1427 | #define RT5645_DRC_AGC_EN (0x1 << 14) | ||
1428 | #define RT5645_DRC_AGC_UPD (0x1 << 13) | ||
1429 | #define RT5645_DRC_AGC_UPD_BIT 13 | ||
1430 | #define RT5645_DRC_AGC_AR_MASK (0x1f << 8) | ||
1431 | #define RT5645_DRC_AGC_AR_SFT 8 | ||
1432 | #define RT5645_DRC_AGC_R_MASK (0x7 << 5) | ||
1433 | #define RT5645_DRC_AGC_R_SFT 5 | ||
1434 | #define RT5645_DRC_AGC_R_48K (0x1 << 5) | ||
1435 | #define RT5645_DRC_AGC_R_96K (0x2 << 5) | ||
1436 | #define RT5645_DRC_AGC_R_192K (0x3 << 5) | ||
1437 | #define RT5645_DRC_AGC_R_441K (0x5 << 5) | ||
1438 | #define RT5645_DRC_AGC_R_882K (0x6 << 5) | ||
1439 | #define RT5645_DRC_AGC_R_1764K (0x7 << 5) | ||
1440 | #define RT5645_DRC_AGC_RC_MASK (0x1f) | ||
1441 | #define RT5645_DRC_AGC_RC_SFT 0 | ||
1442 | |||
1443 | /* DRC/AGC Control 2 (0xb5) */ | ||
1444 | #define RT5645_DRC_AGC_POB_MASK (0x3f << 8) | ||
1445 | #define RT5645_DRC_AGC_POB_SFT 8 | ||
1446 | #define RT5645_DRC_AGC_CP_MASK (0x1 << 7) | ||
1447 | #define RT5645_DRC_AGC_CP_SFT 7 | ||
1448 | #define RT5645_DRC_AGC_CP_DIS (0x0 << 7) | ||
1449 | #define RT5645_DRC_AGC_CP_EN (0x1 << 7) | ||
1450 | #define RT5645_DRC_AGC_CPR_MASK (0x3 << 5) | ||
1451 | #define RT5645_DRC_AGC_CPR_SFT 5 | ||
1452 | #define RT5645_DRC_AGC_CPR_1_1 (0x0 << 5) | ||
1453 | #define RT5645_DRC_AGC_CPR_1_2 (0x1 << 5) | ||
1454 | #define RT5645_DRC_AGC_CPR_1_3 (0x2 << 5) | ||
1455 | #define RT5645_DRC_AGC_CPR_1_4 (0x3 << 5) | ||
1456 | #define RT5645_DRC_AGC_PRB_MASK (0x1f) | ||
1457 | #define RT5645_DRC_AGC_PRB_SFT 0 | ||
1458 | |||
1459 | /* DRC/AGC Control 3 (0xb6) */ | ||
1460 | #define RT5645_DRC_AGC_NGB_MASK (0xf << 12) | ||
1461 | #define RT5645_DRC_AGC_NGB_SFT 12 | ||
1462 | #define RT5645_DRC_AGC_TAR_MASK (0x1f << 7) | ||
1463 | #define RT5645_DRC_AGC_TAR_SFT 7 | ||
1464 | #define RT5645_DRC_AGC_NG_MASK (0x1 << 6) | ||
1465 | #define RT5645_DRC_AGC_NG_SFT 6 | ||
1466 | #define RT5645_DRC_AGC_NG_DIS (0x0 << 6) | ||
1467 | #define RT5645_DRC_AGC_NG_EN (0x1 << 6) | ||
1468 | #define RT5645_DRC_AGC_NGH_MASK (0x1 << 5) | ||
1469 | #define RT5645_DRC_AGC_NGH_SFT 5 | ||
1470 | #define RT5645_DRC_AGC_NGH_DIS (0x0 << 5) | ||
1471 | #define RT5645_DRC_AGC_NGH_EN (0x1 << 5) | ||
1472 | #define RT5645_DRC_AGC_NGT_MASK (0x1f) | ||
1473 | #define RT5645_DRC_AGC_NGT_SFT 0 | ||
1474 | |||
1475 | /* ANC Control 1 (0xb8) */ | ||
1476 | #define RT5645_ANC_M_MASK (0x1 << 15) | ||
1477 | #define RT5645_ANC_M_SFT 15 | ||
1478 | #define RT5645_ANC_M_NOR (0x0 << 15) | ||
1479 | #define RT5645_ANC_M_REV (0x1 << 15) | ||
1480 | #define RT5645_ANC_MASK (0x1 << 14) | ||
1481 | #define RT5645_ANC_SFT 14 | ||
1482 | #define RT5645_ANC_DIS (0x0 << 14) | ||
1483 | #define RT5645_ANC_EN (0x1 << 14) | ||
1484 | #define RT5645_ANC_MD_MASK (0x3 << 12) | ||
1485 | #define RT5645_ANC_MD_SFT 12 | ||
1486 | #define RT5645_ANC_MD_DIS (0x0 << 12) | ||
1487 | #define RT5645_ANC_MD_67MS (0x1 << 12) | ||
1488 | #define RT5645_ANC_MD_267MS (0x2 << 12) | ||
1489 | #define RT5645_ANC_MD_1067MS (0x3 << 12) | ||
1490 | #define RT5645_ANC_SN_MASK (0x1 << 11) | ||
1491 | #define RT5645_ANC_SN_SFT 11 | ||
1492 | #define RT5645_ANC_SN_DIS (0x0 << 11) | ||
1493 | #define RT5645_ANC_SN_EN (0x1 << 11) | ||
1494 | #define RT5645_ANC_CLK_MASK (0x1 << 10) | ||
1495 | #define RT5645_ANC_CLK_SFT 10 | ||
1496 | #define RT5645_ANC_CLK_ANC (0x0 << 10) | ||
1497 | #define RT5645_ANC_CLK_REG (0x1 << 10) | ||
1498 | #define RT5645_ANC_ZCD_MASK (0x3 << 8) | ||
1499 | #define RT5645_ANC_ZCD_SFT 8 | ||
1500 | #define RT5645_ANC_ZCD_DIS (0x0 << 8) | ||
1501 | #define RT5645_ANC_ZCD_T1 (0x1 << 8) | ||
1502 | #define RT5645_ANC_ZCD_T2 (0x2 << 8) | ||
1503 | #define RT5645_ANC_ZCD_WT (0x3 << 8) | ||
1504 | #define RT5645_ANC_CS_MASK (0x1 << 7) | ||
1505 | #define RT5645_ANC_CS_SFT 7 | ||
1506 | #define RT5645_ANC_CS_DIS (0x0 << 7) | ||
1507 | #define RT5645_ANC_CS_EN (0x1 << 7) | ||
1508 | #define RT5645_ANC_SW_MASK (0x1 << 6) | ||
1509 | #define RT5645_ANC_SW_SFT 6 | ||
1510 | #define RT5645_ANC_SW_NOR (0x0 << 6) | ||
1511 | #define RT5645_ANC_SW_AUTO (0x1 << 6) | ||
1512 | #define RT5645_ANC_CO_L_MASK (0x3f) | ||
1513 | #define RT5645_ANC_CO_L_SFT 0 | ||
1514 | |||
1515 | /* ANC Control 2 (0xb6) */ | ||
1516 | #define RT5645_ANC_FG_R_MASK (0xf << 12) | ||
1517 | #define RT5645_ANC_FG_R_SFT 12 | ||
1518 | #define RT5645_ANC_FG_L_MASK (0xf << 8) | ||
1519 | #define RT5645_ANC_FG_L_SFT 8 | ||
1520 | #define RT5645_ANC_CG_R_MASK (0xf << 4) | ||
1521 | #define RT5645_ANC_CG_R_SFT 4 | ||
1522 | #define RT5645_ANC_CG_L_MASK (0xf) | ||
1523 | #define RT5645_ANC_CG_L_SFT 0 | ||
1524 | |||
1525 | /* ANC Control 3 (0xb6) */ | ||
1526 | #define RT5645_ANC_CD_MASK (0x1 << 6) | ||
1527 | #define RT5645_ANC_CD_SFT 6 | ||
1528 | #define RT5645_ANC_CD_BOTH (0x0 << 6) | ||
1529 | #define RT5645_ANC_CD_IND (0x1 << 6) | ||
1530 | #define RT5645_ANC_CO_R_MASK (0x3f) | ||
1531 | #define RT5645_ANC_CO_R_SFT 0 | ||
1532 | |||
1533 | /* Jack Detect Control (0xbb) */ | ||
1534 | #define RT5645_JD_MASK (0x7 << 13) | ||
1535 | #define RT5645_JD_SFT 13 | ||
1536 | #define RT5645_JD_DIS (0x0 << 13) | ||
1537 | #define RT5645_JD_GPIO1 (0x1 << 13) | ||
1538 | #define RT5645_JD_JD1_IN4P (0x2 << 13) | ||
1539 | #define RT5645_JD_JD2_IN4N (0x3 << 13) | ||
1540 | #define RT5645_JD_GPIO2 (0x4 << 13) | ||
1541 | #define RT5645_JD_GPIO3 (0x5 << 13) | ||
1542 | #define RT5645_JD_GPIO4 (0x6 << 13) | ||
1543 | #define RT5645_JD_HP_MASK (0x1 << 11) | ||
1544 | #define RT5645_JD_HP_SFT 11 | ||
1545 | #define RT5645_JD_HP_DIS (0x0 << 11) | ||
1546 | #define RT5645_JD_HP_EN (0x1 << 11) | ||
1547 | #define RT5645_JD_HP_TRG_MASK (0x1 << 10) | ||
1548 | #define RT5645_JD_HP_TRG_SFT 10 | ||
1549 | #define RT5645_JD_HP_TRG_LO (0x0 << 10) | ||
1550 | #define RT5645_JD_HP_TRG_HI (0x1 << 10) | ||
1551 | #define RT5645_JD_SPL_MASK (0x1 << 9) | ||
1552 | #define RT5645_JD_SPL_SFT 9 | ||
1553 | #define RT5645_JD_SPL_DIS (0x0 << 9) | ||
1554 | #define RT5645_JD_SPL_EN (0x1 << 9) | ||
1555 | #define RT5645_JD_SPL_TRG_MASK (0x1 << 8) | ||
1556 | #define RT5645_JD_SPL_TRG_SFT 8 | ||
1557 | #define RT5645_JD_SPL_TRG_LO (0x0 << 8) | ||
1558 | #define RT5645_JD_SPL_TRG_HI (0x1 << 8) | ||
1559 | #define RT5645_JD_SPR_MASK (0x1 << 7) | ||
1560 | #define RT5645_JD_SPR_SFT 7 | ||
1561 | #define RT5645_JD_SPR_DIS (0x0 << 7) | ||
1562 | #define RT5645_JD_SPR_EN (0x1 << 7) | ||
1563 | #define RT5645_JD_SPR_TRG_MASK (0x1 << 6) | ||
1564 | #define RT5645_JD_SPR_TRG_SFT 6 | ||
1565 | #define RT5645_JD_SPR_TRG_LO (0x0 << 6) | ||
1566 | #define RT5645_JD_SPR_TRG_HI (0x1 << 6) | ||
1567 | #define RT5645_JD_MO_MASK (0x1 << 5) | ||
1568 | #define RT5645_JD_MO_SFT 5 | ||
1569 | #define RT5645_JD_MO_DIS (0x0 << 5) | ||
1570 | #define RT5645_JD_MO_EN (0x1 << 5) | ||
1571 | #define RT5645_JD_MO_TRG_MASK (0x1 << 4) | ||
1572 | #define RT5645_JD_MO_TRG_SFT 4 | ||
1573 | #define RT5645_JD_MO_TRG_LO (0x0 << 4) | ||
1574 | #define RT5645_JD_MO_TRG_HI (0x1 << 4) | ||
1575 | #define RT5645_JD_LO_MASK (0x1 << 3) | ||
1576 | #define RT5645_JD_LO_SFT 3 | ||
1577 | #define RT5645_JD_LO_DIS (0x0 << 3) | ||
1578 | #define RT5645_JD_LO_EN (0x1 << 3) | ||
1579 | #define RT5645_JD_LO_TRG_MASK (0x1 << 2) | ||
1580 | #define RT5645_JD_LO_TRG_SFT 2 | ||
1581 | #define RT5645_JD_LO_TRG_LO (0x0 << 2) | ||
1582 | #define RT5645_JD_LO_TRG_HI (0x1 << 2) | ||
1583 | #define RT5645_JD1_IN4P_MASK (0x1 << 1) | ||
1584 | #define RT5645_JD1_IN4P_SFT 1 | ||
1585 | #define RT5645_JD1_IN4P_DIS (0x0 << 1) | ||
1586 | #define RT5645_JD1_IN4P_EN (0x1 << 1) | ||
1587 | #define RT5645_JD2_IN4N_MASK (0x1) | ||
1588 | #define RT5645_JD2_IN4N_SFT 0 | ||
1589 | #define RT5645_JD2_IN4N_DIS (0x0) | ||
1590 | #define RT5645_JD2_IN4N_EN (0x1) | ||
1591 | |||
1592 | /* Jack detect for ANC (0xbc) */ | ||
1593 | #define RT5645_ANC_DET_MASK (0x3 << 4) | ||
1594 | #define RT5645_ANC_DET_SFT 4 | ||
1595 | #define RT5645_ANC_DET_DIS (0x0 << 4) | ||
1596 | #define RT5645_ANC_DET_MB1 (0x1 << 4) | ||
1597 | #define RT5645_ANC_DET_MB2 (0x2 << 4) | ||
1598 | #define RT5645_ANC_DET_JD (0x3 << 4) | ||
1599 | #define RT5645_AD_TRG_MASK (0x1 << 3) | ||
1600 | #define RT5645_AD_TRG_SFT 3 | ||
1601 | #define RT5645_AD_TRG_LO (0x0 << 3) | ||
1602 | #define RT5645_AD_TRG_HI (0x1 << 3) | ||
1603 | #define RT5645_ANCM_DET_MASK (0x3 << 4) | ||
1604 | #define RT5645_ANCM_DET_SFT 4 | ||
1605 | #define RT5645_ANCM_DET_DIS (0x0 << 4) | ||
1606 | #define RT5645_ANCM_DET_MB1 (0x1 << 4) | ||
1607 | #define RT5645_ANCM_DET_MB2 (0x2 << 4) | ||
1608 | #define RT5645_ANCM_DET_JD (0x3 << 4) | ||
1609 | #define RT5645_AMD_TRG_MASK (0x1 << 3) | ||
1610 | #define RT5645_AMD_TRG_SFT 3 | ||
1611 | #define RT5645_AMD_TRG_LO (0x0 << 3) | ||
1612 | #define RT5645_AMD_TRG_HI (0x1 << 3) | ||
1613 | |||
1614 | /* IRQ Control 1 (0xbd) */ | ||
1615 | #define RT5645_IRQ_JD_MASK (0x1 << 15) | ||
1616 | #define RT5645_IRQ_JD_SFT 15 | ||
1617 | #define RT5645_IRQ_JD_BP (0x0 << 15) | ||
1618 | #define RT5645_IRQ_JD_NOR (0x1 << 15) | ||
1619 | #define RT5645_IRQ_OT_MASK (0x1 << 14) | ||
1620 | #define RT5645_IRQ_OT_SFT 14 | ||
1621 | #define RT5645_IRQ_OT_BP (0x0 << 14) | ||
1622 | #define RT5645_IRQ_OT_NOR (0x1 << 14) | ||
1623 | #define RT5645_JD_STKY_MASK (0x1 << 13) | ||
1624 | #define RT5645_JD_STKY_SFT 13 | ||
1625 | #define RT5645_JD_STKY_DIS (0x0 << 13) | ||
1626 | #define RT5645_JD_STKY_EN (0x1 << 13) | ||
1627 | #define RT5645_OT_STKY_MASK (0x1 << 12) | ||
1628 | #define RT5645_OT_STKY_SFT 12 | ||
1629 | #define RT5645_OT_STKY_DIS (0x0 << 12) | ||
1630 | #define RT5645_OT_STKY_EN (0x1 << 12) | ||
1631 | #define RT5645_JD_P_MASK (0x1 << 11) | ||
1632 | #define RT5645_JD_P_SFT 11 | ||
1633 | #define RT5645_JD_P_NOR (0x0 << 11) | ||
1634 | #define RT5645_JD_P_INV (0x1 << 11) | ||
1635 | #define RT5645_OT_P_MASK (0x1 << 10) | ||
1636 | #define RT5645_OT_P_SFT 10 | ||
1637 | #define RT5645_OT_P_NOR (0x0 << 10) | ||
1638 | #define RT5645_OT_P_INV (0x1 << 10) | ||
1639 | |||
1640 | /* IRQ Control 2 (0xbe) */ | ||
1641 | #define RT5645_IRQ_MB1_OC_MASK (0x1 << 15) | ||
1642 | #define RT5645_IRQ_MB1_OC_SFT 15 | ||
1643 | #define RT5645_IRQ_MB1_OC_BP (0x0 << 15) | ||
1644 | #define RT5645_IRQ_MB1_OC_NOR (0x1 << 15) | ||
1645 | #define RT5645_IRQ_MB2_OC_MASK (0x1 << 14) | ||
1646 | #define RT5645_IRQ_MB2_OC_SFT 14 | ||
1647 | #define RT5645_IRQ_MB2_OC_BP (0x0 << 14) | ||
1648 | #define RT5645_IRQ_MB2_OC_NOR (0x1 << 14) | ||
1649 | #define RT5645_MB1_OC_STKY_MASK (0x1 << 13) | ||
1650 | #define RT5645_MB1_OC_STKY_SFT 13 | ||
1651 | #define RT5645_MB1_OC_STKY_DIS (0x0 << 13) | ||
1652 | #define RT5645_MB1_OC_STKY_EN (0x1 << 13) | ||
1653 | #define RT5645_MB2_OC_STKY_MASK (0x1 << 12) | ||
1654 | #define RT5645_MB2_OC_STKY_SFT 12 | ||
1655 | #define RT5645_MB2_OC_STKY_DIS (0x0 << 12) | ||
1656 | #define RT5645_MB2_OC_STKY_EN (0x1 << 12) | ||
1657 | #define RT5645_MB1_OC_P_MASK (0x1 << 7) | ||
1658 | #define RT5645_MB1_OC_P_SFT 7 | ||
1659 | #define RT5645_MB1_OC_P_NOR (0x0 << 7) | ||
1660 | #define RT5645_MB1_OC_P_INV (0x1 << 7) | ||
1661 | #define RT5645_MB2_OC_P_MASK (0x1 << 6) | ||
1662 | #define RT5645_MB2_OC_P_SFT 6 | ||
1663 | #define RT5645_MB2_OC_P_NOR (0x0 << 6) | ||
1664 | #define RT5645_MB2_OC_P_INV (0x1 << 6) | ||
1665 | #define RT5645_MB1_OC_CLR (0x1 << 3) | ||
1666 | #define RT5645_MB1_OC_CLR_SFT 3 | ||
1667 | #define RT5645_MB2_OC_CLR (0x1 << 2) | ||
1668 | #define RT5645_MB2_OC_CLR_SFT 2 | ||
1669 | |||
1670 | /* GPIO Control 1 (0xc0) */ | ||
1671 | #define RT5645_GP1_PIN_MASK (0x1 << 15) | ||
1672 | #define RT5645_GP1_PIN_SFT 15 | ||
1673 | #define RT5645_GP1_PIN_GPIO1 (0x0 << 15) | ||
1674 | #define RT5645_GP1_PIN_IRQ (0x1 << 15) | ||
1675 | #define RT5645_GP2_PIN_MASK (0x1 << 14) | ||
1676 | #define RT5645_GP2_PIN_SFT 14 | ||
1677 | #define RT5645_GP2_PIN_GPIO2 (0x0 << 14) | ||
1678 | #define RT5645_GP2_PIN_DMIC1_SCL (0x1 << 14) | ||
1679 | #define RT5645_GP3_PIN_MASK (0x3 << 12) | ||
1680 | #define RT5645_GP3_PIN_SFT 12 | ||
1681 | #define RT5645_GP3_PIN_GPIO3 (0x0 << 12) | ||
1682 | #define RT5645_GP3_PIN_DMIC1_SDA (0x1 << 12) | ||
1683 | #define RT5645_GP3_PIN_IRQ (0x2 << 12) | ||
1684 | #define RT5645_GP4_PIN_MASK (0x1 << 11) | ||
1685 | #define RT5645_GP4_PIN_SFT 11 | ||
1686 | #define RT5645_GP4_PIN_GPIO4 (0x0 << 11) | ||
1687 | #define RT5645_GP4_PIN_DMIC2_SDA (0x1 << 11) | ||
1688 | #define RT5645_DP_SIG_MASK (0x1 << 10) | ||
1689 | #define RT5645_DP_SIG_SFT 10 | ||
1690 | #define RT5645_DP_SIG_TEST (0x0 << 10) | ||
1691 | #define RT5645_DP_SIG_AP (0x1 << 10) | ||
1692 | #define RT5645_GPIO_M_MASK (0x1 << 9) | ||
1693 | #define RT5645_GPIO_M_SFT 9 | ||
1694 | #define RT5645_GPIO_M_FLT (0x0 << 9) | ||
1695 | #define RT5645_GPIO_M_PH (0x1 << 9) | ||
1696 | #define RT5645_I2S2_SEL (0x1 << 8) | ||
1697 | #define RT5645_I2S2_SEL_SFT 8 | ||
1698 | #define RT5645_GP5_PIN_MASK (0x1 << 7) | ||
1699 | #define RT5645_GP5_PIN_SFT 7 | ||
1700 | #define RT5645_GP5_PIN_GPIO5 (0x0 << 7) | ||
1701 | #define RT5645_GP5_PIN_DMIC1_SDA (0x1 << 7) | ||
1702 | #define RT5645_GP6_PIN_MASK (0x1 << 6) | ||
1703 | #define RT5645_GP6_PIN_SFT 6 | ||
1704 | #define RT5645_GP6_PIN_GPIO6 (0x0 << 6) | ||
1705 | #define RT5645_GP6_PIN_DMIC2_SDA (0x1 << 6) | ||
1706 | #define RT5645_GP8_PIN_MASK (0x1 << 3) | ||
1707 | #define RT5645_GP8_PIN_SFT 3 | ||
1708 | #define RT5645_GP8_PIN_GPIO8 (0x0 << 3) | ||
1709 | #define RT5645_GP8_PIN_DMIC2_SDA (0x1 << 3) | ||
1710 | #define RT5645_GP12_PIN_MASK (0x1 << 2) | ||
1711 | #define RT5645_GP12_PIN_SFT 2 | ||
1712 | #define RT5645_GP12_PIN_GPIO12 (0x0 << 2) | ||
1713 | #define RT5645_GP12_PIN_DMIC2_SDA (0x1 << 2) | ||
1714 | #define RT5645_GP11_PIN_MASK (0x1 << 1) | ||
1715 | #define RT5645_GP11_PIN_SFT 1 | ||
1716 | #define RT5645_GP11_PIN_GPIO11 (0x0 << 1) | ||
1717 | #define RT5645_GP11_PIN_DMIC1_SDA (0x1 << 1) | ||
1718 | #define RT5645_GP10_PIN_MASK (0x1) | ||
1719 | #define RT5645_GP10_PIN_SFT 0 | ||
1720 | #define RT5645_GP10_PIN_GPIO10 (0x0) | ||
1721 | #define RT5645_GP10_PIN_DMIC2_SDA (0x1) | ||
1722 | |||
1723 | /* GPIO Control 3 (0xc2) */ | ||
1724 | #define RT5645_GP4_PF_MASK (0x1 << 11) | ||
1725 | #define RT5645_GP4_PF_SFT 11 | ||
1726 | #define RT5645_GP4_PF_IN (0x0 << 11) | ||
1727 | #define RT5645_GP4_PF_OUT (0x1 << 11) | ||
1728 | #define RT5645_GP4_OUT_MASK (0x1 << 10) | ||
1729 | #define RT5645_GP4_OUT_SFT 10 | ||
1730 | #define RT5645_GP4_OUT_LO (0x0 << 10) | ||
1731 | #define RT5645_GP4_OUT_HI (0x1 << 10) | ||
1732 | #define RT5645_GP4_P_MASK (0x1 << 9) | ||
1733 | #define RT5645_GP4_P_SFT 9 | ||
1734 | #define RT5645_GP4_P_NOR (0x0 << 9) | ||
1735 | #define RT5645_GP4_P_INV (0x1 << 9) | ||
1736 | #define RT5645_GP3_PF_MASK (0x1 << 8) | ||
1737 | #define RT5645_GP3_PF_SFT 8 | ||
1738 | #define RT5645_GP3_PF_IN (0x0 << 8) | ||
1739 | #define RT5645_GP3_PF_OUT (0x1 << 8) | ||
1740 | #define RT5645_GP3_OUT_MASK (0x1 << 7) | ||
1741 | #define RT5645_GP3_OUT_SFT 7 | ||
1742 | #define RT5645_GP3_OUT_LO (0x0 << 7) | ||
1743 | #define RT5645_GP3_OUT_HI (0x1 << 7) | ||
1744 | #define RT5645_GP3_P_MASK (0x1 << 6) | ||
1745 | #define RT5645_GP3_P_SFT 6 | ||
1746 | #define RT5645_GP3_P_NOR (0x0 << 6) | ||
1747 | #define RT5645_GP3_P_INV (0x1 << 6) | ||
1748 | #define RT5645_GP2_PF_MASK (0x1 << 5) | ||
1749 | #define RT5645_GP2_PF_SFT 5 | ||
1750 | #define RT5645_GP2_PF_IN (0x0 << 5) | ||
1751 | #define RT5645_GP2_PF_OUT (0x1 << 5) | ||
1752 | #define RT5645_GP2_OUT_MASK (0x1 << 4) | ||
1753 | #define RT5645_GP2_OUT_SFT 4 | ||
1754 | #define RT5645_GP2_OUT_LO (0x0 << 4) | ||
1755 | #define RT5645_GP2_OUT_HI (0x1 << 4) | ||
1756 | #define RT5645_GP2_P_MASK (0x1 << 3) | ||
1757 | #define RT5645_GP2_P_SFT 3 | ||
1758 | #define RT5645_GP2_P_NOR (0x0 << 3) | ||
1759 | #define RT5645_GP2_P_INV (0x1 << 3) | ||
1760 | #define RT5645_GP1_PF_MASK (0x1 << 2) | ||
1761 | #define RT5645_GP1_PF_SFT 2 | ||
1762 | #define RT5645_GP1_PF_IN (0x0 << 2) | ||
1763 | #define RT5645_GP1_PF_OUT (0x1 << 2) | ||
1764 | #define RT5645_GP1_OUT_MASK (0x1 << 1) | ||
1765 | #define RT5645_GP1_OUT_SFT 1 | ||
1766 | #define RT5645_GP1_OUT_LO (0x0 << 1) | ||
1767 | #define RT5645_GP1_OUT_HI (0x1 << 1) | ||
1768 | #define RT5645_GP1_P_MASK (0x1) | ||
1769 | #define RT5645_GP1_P_SFT 0 | ||
1770 | #define RT5645_GP1_P_NOR (0x0) | ||
1771 | #define RT5645_GP1_P_INV (0x1) | ||
1772 | |||
1773 | /* Programmable Register Array Control 1 (0xc8) */ | ||
1774 | #define RT5645_REG_SEQ_MASK (0xf << 12) | ||
1775 | #define RT5645_REG_SEQ_SFT 12 | ||
1776 | #define RT5645_SEQ1_ST_MASK (0x1 << 11) /*RO*/ | ||
1777 | #define RT5645_SEQ1_ST_SFT 11 | ||
1778 | #define RT5645_SEQ1_ST_RUN (0x0 << 11) | ||
1779 | #define RT5645_SEQ1_ST_FIN (0x1 << 11) | ||
1780 | #define RT5645_SEQ2_ST_MASK (0x1 << 10) /*RO*/ | ||
1781 | #define RT5645_SEQ2_ST_SFT 10 | ||
1782 | #define RT5645_SEQ2_ST_RUN (0x0 << 10) | ||
1783 | #define RT5645_SEQ2_ST_FIN (0x1 << 10) | ||
1784 | #define RT5645_REG_LV_MASK (0x1 << 9) | ||
1785 | #define RT5645_REG_LV_SFT 9 | ||
1786 | #define RT5645_REG_LV_MX (0x0 << 9) | ||
1787 | #define RT5645_REG_LV_PR (0x1 << 9) | ||
1788 | #define RT5645_SEQ_2_PT_MASK (0x1 << 8) | ||
1789 | #define RT5645_SEQ_2_PT_BIT 8 | ||
1790 | #define RT5645_REG_IDX_MASK (0xff) | ||
1791 | #define RT5645_REG_IDX_SFT 0 | ||
1792 | |||
1793 | /* Programmable Register Array Control 2 (0xc9) */ | ||
1794 | #define RT5645_REG_DAT_MASK (0xffff) | ||
1795 | #define RT5645_REG_DAT_SFT 0 | ||
1796 | |||
1797 | /* Programmable Register Array Control 3 (0xca) */ | ||
1798 | #define RT5645_SEQ_DLY_MASK (0xff << 8) | ||
1799 | #define RT5645_SEQ_DLY_SFT 8 | ||
1800 | #define RT5645_PROG_MASK (0x1 << 7) | ||
1801 | #define RT5645_PROG_SFT 7 | ||
1802 | #define RT5645_PROG_DIS (0x0 << 7) | ||
1803 | #define RT5645_PROG_EN (0x1 << 7) | ||
1804 | #define RT5645_SEQ1_PT_RUN (0x1 << 6) | ||
1805 | #define RT5645_SEQ1_PT_RUN_BIT 6 | ||
1806 | #define RT5645_SEQ2_PT_RUN (0x1 << 5) | ||
1807 | #define RT5645_SEQ2_PT_RUN_BIT 5 | ||
1808 | |||
1809 | /* Programmable Register Array Control 4 (0xcb) */ | ||
1810 | #define RT5645_SEQ1_START_MASK (0xf << 8) | ||
1811 | #define RT5645_SEQ1_START_SFT 8 | ||
1812 | #define RT5645_SEQ1_END_MASK (0xf) | ||
1813 | #define RT5645_SEQ1_END_SFT 0 | ||
1814 | |||
1815 | /* Programmable Register Array Control 5 (0xcc) */ | ||
1816 | #define RT5645_SEQ2_START_MASK (0xf << 8) | ||
1817 | #define RT5645_SEQ2_START_SFT 8 | ||
1818 | #define RT5645_SEQ2_END_MASK (0xf) | ||
1819 | #define RT5645_SEQ2_END_SFT 0 | ||
1820 | |||
1821 | /* Scramble Function (0xcd) */ | ||
1822 | #define RT5645_SCB_KEY_MASK (0xff) | ||
1823 | #define RT5645_SCB_KEY_SFT 0 | ||
1824 | |||
1825 | /* Scramble Control (0xce) */ | ||
1826 | #define RT5645_SCB_SWAP_MASK (0x1 << 15) | ||
1827 | #define RT5645_SCB_SWAP_SFT 15 | ||
1828 | #define RT5645_SCB_SWAP_DIS (0x0 << 15) | ||
1829 | #define RT5645_SCB_SWAP_EN (0x1 << 15) | ||
1830 | #define RT5645_SCB_MASK (0x1 << 14) | ||
1831 | #define RT5645_SCB_SFT 14 | ||
1832 | #define RT5645_SCB_DIS (0x0 << 14) | ||
1833 | #define RT5645_SCB_EN (0x1 << 14) | ||
1834 | |||
1835 | /* Baseback Control (0xcf) */ | ||
1836 | #define RT5645_BB_MASK (0x1 << 15) | ||
1837 | #define RT5645_BB_SFT 15 | ||
1838 | #define RT5645_BB_DIS (0x0 << 15) | ||
1839 | #define RT5645_BB_EN (0x1 << 15) | ||
1840 | #define RT5645_BB_CT_MASK (0x7 << 12) | ||
1841 | #define RT5645_BB_CT_SFT 12 | ||
1842 | #define RT5645_BB_CT_A (0x0 << 12) | ||
1843 | #define RT5645_BB_CT_B (0x1 << 12) | ||
1844 | #define RT5645_BB_CT_C (0x2 << 12) | ||
1845 | #define RT5645_BB_CT_D (0x3 << 12) | ||
1846 | #define RT5645_M_BB_L_MASK (0x1 << 9) | ||
1847 | #define RT5645_M_BB_L_SFT 9 | ||
1848 | #define RT5645_M_BB_R_MASK (0x1 << 8) | ||
1849 | #define RT5645_M_BB_R_SFT 8 | ||
1850 | #define RT5645_M_BB_HPF_L_MASK (0x1 << 7) | ||
1851 | #define RT5645_M_BB_HPF_L_SFT 7 | ||
1852 | #define RT5645_M_BB_HPF_R_MASK (0x1 << 6) | ||
1853 | #define RT5645_M_BB_HPF_R_SFT 6 | ||
1854 | #define RT5645_G_BB_BST_MASK (0x3f) | ||
1855 | #define RT5645_G_BB_BST_SFT 0 | ||
1856 | |||
1857 | /* MP3 Plus Control 1 (0xd0) */ | ||
1858 | #define RT5645_M_MP3_L_MASK (0x1 << 15) | ||
1859 | #define RT5645_M_MP3_L_SFT 15 | ||
1860 | #define RT5645_M_MP3_R_MASK (0x1 << 14) | ||
1861 | #define RT5645_M_MP3_R_SFT 14 | ||
1862 | #define RT5645_M_MP3_MASK (0x1 << 13) | ||
1863 | #define RT5645_M_MP3_SFT 13 | ||
1864 | #define RT5645_M_MP3_DIS (0x0 << 13) | ||
1865 | #define RT5645_M_MP3_EN (0x1 << 13) | ||
1866 | #define RT5645_EG_MP3_MASK (0x1f << 8) | ||
1867 | #define RT5645_EG_MP3_SFT 8 | ||
1868 | #define RT5645_MP3_HLP_MASK (0x1 << 7) | ||
1869 | #define RT5645_MP3_HLP_SFT 7 | ||
1870 | #define RT5645_MP3_HLP_DIS (0x0 << 7) | ||
1871 | #define RT5645_MP3_HLP_EN (0x1 << 7) | ||
1872 | #define RT5645_M_MP3_ORG_L_MASK (0x1 << 6) | ||
1873 | #define RT5645_M_MP3_ORG_L_SFT 6 | ||
1874 | #define RT5645_M_MP3_ORG_R_MASK (0x1 << 5) | ||
1875 | #define RT5645_M_MP3_ORG_R_SFT 5 | ||
1876 | |||
1877 | /* MP3 Plus Control 2 (0xd1) */ | ||
1878 | #define RT5645_MP3_WT_MASK (0x1 << 13) | ||
1879 | #define RT5645_MP3_WT_SFT 13 | ||
1880 | #define RT5645_MP3_WT_1_4 (0x0 << 13) | ||
1881 | #define RT5645_MP3_WT_1_2 (0x1 << 13) | ||
1882 | #define RT5645_OG_MP3_MASK (0x1f << 8) | ||
1883 | #define RT5645_OG_MP3_SFT 8 | ||
1884 | #define RT5645_HG_MP3_MASK (0x3f) | ||
1885 | #define RT5645_HG_MP3_SFT 0 | ||
1886 | |||
1887 | /* 3D HP Control 1 (0xd2) */ | ||
1888 | #define RT5645_3D_CF_MASK (0x1 << 15) | ||
1889 | #define RT5645_3D_CF_SFT 15 | ||
1890 | #define RT5645_3D_CF_DIS (0x0 << 15) | ||
1891 | #define RT5645_3D_CF_EN (0x1 << 15) | ||
1892 | #define RT5645_3D_HP_MASK (0x1 << 14) | ||
1893 | #define RT5645_3D_HP_SFT 14 | ||
1894 | #define RT5645_3D_HP_DIS (0x0 << 14) | ||
1895 | #define RT5645_3D_HP_EN (0x1 << 14) | ||
1896 | #define RT5645_3D_BT_MASK (0x1 << 13) | ||
1897 | #define RT5645_3D_BT_SFT 13 | ||
1898 | #define RT5645_3D_BT_DIS (0x0 << 13) | ||
1899 | #define RT5645_3D_BT_EN (0x1 << 13) | ||
1900 | #define RT5645_3D_1F_MIX_MASK (0x3 << 11) | ||
1901 | #define RT5645_3D_1F_MIX_SFT 11 | ||
1902 | #define RT5645_3D_HP_M_MASK (0x1 << 10) | ||
1903 | #define RT5645_3D_HP_M_SFT 10 | ||
1904 | #define RT5645_3D_HP_M_SUR (0x0 << 10) | ||
1905 | #define RT5645_3D_HP_M_FRO (0x1 << 10) | ||
1906 | #define RT5645_M_3D_HRTF_MASK (0x1 << 9) | ||
1907 | #define RT5645_M_3D_HRTF_SFT 9 | ||
1908 | #define RT5645_M_3D_D2H_MASK (0x1 << 8) | ||
1909 | #define RT5645_M_3D_D2H_SFT 8 | ||
1910 | #define RT5645_M_3D_D2R_MASK (0x1 << 7) | ||
1911 | #define RT5645_M_3D_D2R_SFT 7 | ||
1912 | #define RT5645_M_3D_REVB_MASK (0x1 << 6) | ||
1913 | #define RT5645_M_3D_REVB_SFT 6 | ||
1914 | |||
1915 | /* Adjustable high pass filter control 1 (0xd3) */ | ||
1916 | #define RT5645_2ND_HPF_MASK (0x1 << 15) | ||
1917 | #define RT5645_2ND_HPF_SFT 15 | ||
1918 | #define RT5645_2ND_HPF_DIS (0x0 << 15) | ||
1919 | #define RT5645_2ND_HPF_EN (0x1 << 15) | ||
1920 | #define RT5645_HPF_CF_L_MASK (0x7 << 12) | ||
1921 | #define RT5645_HPF_CF_L_SFT 12 | ||
1922 | #define RT5645_1ST_HPF_MASK (0x1 << 11) | ||
1923 | #define RT5645_1ST_HPF_SFT 11 | ||
1924 | #define RT5645_1ST_HPF_DIS (0x0 << 11) | ||
1925 | #define RT5645_1ST_HPF_EN (0x1 << 11) | ||
1926 | #define RT5645_HPF_CF_R_MASK (0x7 << 8) | ||
1927 | #define RT5645_HPF_CF_R_SFT 8 | ||
1928 | #define RT5645_ZD_T_MASK (0x3 << 6) | ||
1929 | #define RT5645_ZD_T_SFT 6 | ||
1930 | #define RT5645_ZD_F_MASK (0x3 << 4) | ||
1931 | #define RT5645_ZD_F_SFT 4 | ||
1932 | #define RT5645_ZD_F_IM (0x0 << 4) | ||
1933 | #define RT5645_ZD_F_ZC_IM (0x1 << 4) | ||
1934 | #define RT5645_ZD_F_ZC_IOD (0x2 << 4) | ||
1935 | #define RT5645_ZD_F_UN (0x3 << 4) | ||
1936 | |||
1937 | /* HP calibration control and Amp detection (0xd6) */ | ||
1938 | #define RT5645_SI_DAC_MASK (0x1 << 11) | ||
1939 | #define RT5645_SI_DAC_SFT 11 | ||
1940 | #define RT5645_SI_DAC_AUTO (0x0 << 11) | ||
1941 | #define RT5645_SI_DAC_TEST (0x1 << 11) | ||
1942 | #define RT5645_DC_CAL_M_MASK (0x1 << 10) | ||
1943 | #define RT5645_DC_CAL_M_SFT 10 | ||
1944 | #define RT5645_DC_CAL_M_CAL (0x0 << 10) | ||
1945 | #define RT5645_DC_CAL_M_NOR (0x1 << 10) | ||
1946 | #define RT5645_DC_CAL_MASK (0x1 << 9) | ||
1947 | #define RT5645_DC_CAL_SFT 9 | ||
1948 | #define RT5645_DC_CAL_DIS (0x0 << 9) | ||
1949 | #define RT5645_DC_CAL_EN (0x1 << 9) | ||
1950 | #define RT5645_HPD_RCV_MASK (0x7 << 6) | ||
1951 | #define RT5645_HPD_RCV_SFT 6 | ||
1952 | #define RT5645_HPD_PS_MASK (0x1 << 5) | ||
1953 | #define RT5645_HPD_PS_SFT 5 | ||
1954 | #define RT5645_HPD_PS_DIS (0x0 << 5) | ||
1955 | #define RT5645_HPD_PS_EN (0x1 << 5) | ||
1956 | #define RT5645_CAL_M_MASK (0x1 << 4) | ||
1957 | #define RT5645_CAL_M_SFT 4 | ||
1958 | #define RT5645_CAL_M_DEP (0x0 << 4) | ||
1959 | #define RT5645_CAL_M_CAL (0x1 << 4) | ||
1960 | #define RT5645_CAL_MASK (0x1 << 3) | ||
1961 | #define RT5645_CAL_SFT 3 | ||
1962 | #define RT5645_CAL_DIS (0x0 << 3) | ||
1963 | #define RT5645_CAL_EN (0x1 << 3) | ||
1964 | #define RT5645_CAL_TEST_MASK (0x1 << 2) | ||
1965 | #define RT5645_CAL_TEST_SFT 2 | ||
1966 | #define RT5645_CAL_TEST_DIS (0x0 << 2) | ||
1967 | #define RT5645_CAL_TEST_EN (0x1 << 2) | ||
1968 | #define RT5645_CAL_P_MASK (0x3) | ||
1969 | #define RT5645_CAL_P_SFT 0 | ||
1970 | #define RT5645_CAL_P_NONE (0x0) | ||
1971 | #define RT5645_CAL_P_CAL (0x1) | ||
1972 | #define RT5645_CAL_P_DAC_CAL (0x2) | ||
1973 | |||
1974 | /* Soft volume and zero cross control 1 (0xd9) */ | ||
1975 | #define RT5645_SV_MASK (0x1 << 15) | ||
1976 | #define RT5645_SV_SFT 15 | ||
1977 | #define RT5645_SV_DIS (0x0 << 15) | ||
1978 | #define RT5645_SV_EN (0x1 << 15) | ||
1979 | #define RT5645_SPO_SV_MASK (0x1 << 14) | ||
1980 | #define RT5645_SPO_SV_SFT 14 | ||
1981 | #define RT5645_SPO_SV_DIS (0x0 << 14) | ||
1982 | #define RT5645_SPO_SV_EN (0x1 << 14) | ||
1983 | #define RT5645_OUT_SV_MASK (0x1 << 13) | ||
1984 | #define RT5645_OUT_SV_SFT 13 | ||
1985 | #define RT5645_OUT_SV_DIS (0x0 << 13) | ||
1986 | #define RT5645_OUT_SV_EN (0x1 << 13) | ||
1987 | #define RT5645_HP_SV_MASK (0x1 << 12) | ||
1988 | #define RT5645_HP_SV_SFT 12 | ||
1989 | #define RT5645_HP_SV_DIS (0x0 << 12) | ||
1990 | #define RT5645_HP_SV_EN (0x1 << 12) | ||
1991 | #define RT5645_ZCD_DIG_MASK (0x1 << 11) | ||
1992 | #define RT5645_ZCD_DIG_SFT 11 | ||
1993 | #define RT5645_ZCD_DIG_DIS (0x0 << 11) | ||
1994 | #define RT5645_ZCD_DIG_EN (0x1 << 11) | ||
1995 | #define RT5645_ZCD_MASK (0x1 << 10) | ||
1996 | #define RT5645_ZCD_SFT 10 | ||
1997 | #define RT5645_ZCD_PD (0x0 << 10) | ||
1998 | #define RT5645_ZCD_PU (0x1 << 10) | ||
1999 | #define RT5645_M_ZCD_MASK (0x3f << 4) | ||
2000 | #define RT5645_M_ZCD_SFT 4 | ||
2001 | #define RT5645_M_ZCD_RM_L (0x1 << 9) | ||
2002 | #define RT5645_M_ZCD_RM_R (0x1 << 8) | ||
2003 | #define RT5645_M_ZCD_SM_L (0x1 << 7) | ||
2004 | #define RT5645_M_ZCD_SM_R (0x1 << 6) | ||
2005 | #define RT5645_M_ZCD_OM_L (0x1 << 5) | ||
2006 | #define RT5645_M_ZCD_OM_R (0x1 << 4) | ||
2007 | #define RT5645_SV_DLY_MASK (0xf) | ||
2008 | #define RT5645_SV_DLY_SFT 0 | ||
2009 | |||
2010 | /* Soft volume and zero cross control 2 (0xda) */ | ||
2011 | #define RT5645_ZCD_HP_MASK (0x1 << 15) | ||
2012 | #define RT5645_ZCD_HP_SFT 15 | ||
2013 | #define RT5645_ZCD_HP_DIS (0x0 << 15) | ||
2014 | #define RT5645_ZCD_HP_EN (0x1 << 15) | ||
2015 | |||
2016 | |||
2017 | /* Codec Private Register definition */ | ||
2018 | /* 3D Speaker Control (0x63) */ | ||
2019 | #define RT5645_3D_SPK_MASK (0x1 << 15) | ||
2020 | #define RT5645_3D_SPK_SFT 15 | ||
2021 | #define RT5645_3D_SPK_DIS (0x0 << 15) | ||
2022 | #define RT5645_3D_SPK_EN (0x1 << 15) | ||
2023 | #define RT5645_3D_SPK_M_MASK (0x3 << 13) | ||
2024 | #define RT5645_3D_SPK_M_SFT 13 | ||
2025 | #define RT5645_3D_SPK_CG_MASK (0x1f << 8) | ||
2026 | #define RT5645_3D_SPK_CG_SFT 8 | ||
2027 | #define RT5645_3D_SPK_SG_MASK (0x1f) | ||
2028 | #define RT5645_3D_SPK_SG_SFT 0 | ||
2029 | |||
2030 | /* Wind Noise Detection Control 1 (0x6c) */ | ||
2031 | #define RT5645_WND_MASK (0x1 << 15) | ||
2032 | #define RT5645_WND_SFT 15 | ||
2033 | #define RT5645_WND_DIS (0x0 << 15) | ||
2034 | #define RT5645_WND_EN (0x1 << 15) | ||
2035 | |||
2036 | /* Wind Noise Detection Control 2 (0x6d) */ | ||
2037 | #define RT5645_WND_FC_NW_MASK (0x3f << 10) | ||
2038 | #define RT5645_WND_FC_NW_SFT 10 | ||
2039 | #define RT5645_WND_FC_WK_MASK (0x3f << 4) | ||
2040 | #define RT5645_WND_FC_WK_SFT 4 | ||
2041 | |||
2042 | /* Wind Noise Detection Control 3 (0x6e) */ | ||
2043 | #define RT5645_HPF_FC_MASK (0x3f << 6) | ||
2044 | #define RT5645_HPF_FC_SFT 6 | ||
2045 | #define RT5645_WND_FC_ST_MASK (0x3f) | ||
2046 | #define RT5645_WND_FC_ST_SFT 0 | ||
2047 | |||
2048 | /* Wind Noise Detection Control 4 (0x6f) */ | ||
2049 | #define RT5645_WND_TH_LO_MASK (0x3ff) | ||
2050 | #define RT5645_WND_TH_LO_SFT 0 | ||
2051 | |||
2052 | /* Wind Noise Detection Control 5 (0x70) */ | ||
2053 | #define RT5645_WND_TH_HI_MASK (0x3ff) | ||
2054 | #define RT5645_WND_TH_HI_SFT 0 | ||
2055 | |||
2056 | /* Wind Noise Detection Control 8 (0x73) */ | ||
2057 | #define RT5645_WND_WIND_MASK (0x1 << 13) /* Read-Only */ | ||
2058 | #define RT5645_WND_WIND_SFT 13 | ||
2059 | #define RT5645_WND_STRONG_MASK (0x1 << 12) /* Read-Only */ | ||
2060 | #define RT5645_WND_STRONG_SFT 12 | ||
2061 | enum { | ||
2062 | RT5645_NO_WIND, | ||
2063 | RT5645_BREEZE, | ||
2064 | RT5645_STORM, | ||
2065 | }; | ||
2066 | |||
2067 | /* Dipole Speaker Interface (0x75) */ | ||
2068 | #define RT5645_DP_ATT_MASK (0x3 << 14) | ||
2069 | #define RT5645_DP_ATT_SFT 14 | ||
2070 | #define RT5645_DP_SPK_MASK (0x1 << 10) | ||
2071 | #define RT5645_DP_SPK_SFT 10 | ||
2072 | #define RT5645_DP_SPK_DIS (0x0 << 10) | ||
2073 | #define RT5645_DP_SPK_EN (0x1 << 10) | ||
2074 | |||
2075 | /* EQ Pre Volume Control (0xb3) */ | ||
2076 | #define RT5645_EQ_PRE_VOL_MASK (0xffff) | ||
2077 | #define RT5645_EQ_PRE_VOL_SFT 0 | ||
2078 | |||
2079 | /* EQ Post Volume Control (0xb4) */ | ||
2080 | #define RT5645_EQ_PST_VOL_MASK (0xffff) | ||
2081 | #define RT5645_EQ_PST_VOL_SFT 0 | ||
2082 | |||
2083 | /* Jack Detect Control 3 (0xf8) */ | ||
2084 | #define RT5645_CMP_MIC_IN_DET_MASK (0x7 << 12) | ||
2085 | #define RT5645_JD_CBJ_EN (0x1 << 7) | ||
2086 | #define RT5645_JD_CBJ_POL (0x1 << 6) | ||
2087 | #define RT5645_JD_TRI_CBJ_SEL_MASK (0x7 << 3) | ||
2088 | #define RT5645_JD_TRI_CBJ_SEL_SFT (3) | ||
2089 | #define RT5645_JD_TRI_HPO_SEL_MASK (0x7) | ||
2090 | #define RT5645_JD_TRI_HPO_SEL_SFT (0) | ||
2091 | #define RT5645_JD_F_GPIO_JD1 (0x0) | ||
2092 | #define RT5645_JD_F_JD1_1 (0x1) | ||
2093 | #define RT5645_JD_F_JD1_2 (0x2) | ||
2094 | #define RT5645_JD_F_JD2 (0x3) | ||
2095 | #define RT5645_JD_F_JD3 (0x4) | ||
2096 | #define RT5645_JD_F_GPIO_JD2 (0x5) | ||
2097 | #define RT5645_JD_F_MX0B_12 (0x6) | ||
2098 | |||
2099 | /* Digital Misc Control (0xfa) */ | ||
2100 | #define RT5645_RST_DSP (0x1 << 13) | ||
2101 | #define RT5645_IF1_ADC1_IN1_SEL (0x1 << 12) | ||
2102 | #define RT5645_IF1_ADC1_IN1_SFT 12 | ||
2103 | #define RT5645_IF1_ADC1_IN2_SEL (0x1 << 11) | ||
2104 | #define RT5645_IF1_ADC1_IN2_SFT 11 | ||
2105 | #define RT5645_IF1_ADC2_IN1_SEL (0x1 << 10) | ||
2106 | #define RT5645_IF1_ADC2_IN1_SFT 10 | ||
2107 | #define RT5645_DIG_GATE_CTRL 0x1 | ||
2108 | |||
2109 | /* General Control2 (0xfb) */ | ||
2110 | #define RT5645_RXDC_SRC_MASK (0x1 << 7) | ||
2111 | #define RT5645_RXDC_SRC_STO (0x0 << 7) | ||
2112 | #define RT5645_RXDC_SRC_MONO (0x1 << 7) | ||
2113 | #define RT5645_RXDC_SRC_SFT (7) | ||
2114 | #define RT5645_RXDP2_SEL_MASK (0x1 << 3) | ||
2115 | #define RT5645_RXDP2_SEL_IF2 (0x0 << 3) | ||
2116 | #define RT5645_RXDP2_SEL_ADC (0x1 << 3) | ||
2117 | #define RT5645_RXDP2_SEL_SFT (3) | ||
2118 | |||
2119 | |||
2120 | /* Vendor ID (0xfd) */ | ||
2121 | #define RT5645_VER_C 0x2 | ||
2122 | #define RT5645_VER_D 0x3 | ||
2123 | |||
2124 | |||
2125 | /* Volume Rescale */ | ||
2126 | #define RT5645_VOL_RSCL_MAX 0x27 | ||
2127 | #define RT5645_VOL_RSCL_RANGE 0x1F | ||
2128 | /* Debug String Length */ | ||
2129 | #define RT5645_REG_DISP_LEN 23 | ||
2130 | |||
2131 | |||
2132 | /* System Clock Source */ | ||
2133 | enum { | ||
2134 | RT5645_SCLK_S_MCLK, | ||
2135 | RT5645_SCLK_S_PLL1, | ||
2136 | RT5645_SCLK_S_RCCLK, | ||
2137 | }; | ||
2138 | |||
2139 | /* PLL1 Source */ | ||
2140 | enum { | ||
2141 | RT5645_PLL1_S_MCLK, | ||
2142 | RT5645_PLL1_S_BCLK1, | ||
2143 | RT5645_PLL1_S_BCLK2, | ||
2144 | }; | ||
2145 | |||
2146 | enum { | ||
2147 | RT5645_AIF1, | ||
2148 | RT5645_AIF2, | ||
2149 | RT5645_AIFS, | ||
2150 | }; | ||
2151 | |||
2152 | enum { | ||
2153 | RT5645_DMIC_DATA_IN2P, | ||
2154 | RT5645_DMIC_DATA_GPIO6, | ||
2155 | RT5645_DMIC_DATA_GPIO10, | ||
2156 | RT5645_DMIC_DATA_GPIO12, | ||
2157 | }; | ||
2158 | |||
2159 | enum { | ||
2160 | RT5645_DMIC_DATA_IN2N, | ||
2161 | RT5645_DMIC_DATA_GPIO5, | ||
2162 | RT5645_DMIC_DATA_GPIO11, | ||
2163 | }; | ||
2164 | |||
2165 | struct rt5645_pll_code { | ||
2166 | bool m_bp; /* Indicates bypass m code or not. */ | ||
2167 | int m_code; | ||
2168 | int n_code; | ||
2169 | int k_code; | ||
2170 | }; | ||
2171 | |||
2172 | struct rt5645_priv { | ||
2173 | struct snd_soc_codec *codec; | ||
2174 | struct rt5645_platform_data pdata; | ||
2175 | struct regmap *regmap; | ||
2176 | |||
2177 | int sysclk; | ||
2178 | int sysclk_src; | ||
2179 | int lrck[RT5645_AIFS]; | ||
2180 | int bclk[RT5645_AIFS]; | ||
2181 | int master[RT5645_AIFS]; | ||
2182 | |||
2183 | int pll_src; | ||
2184 | int pll_in; | ||
2185 | int pll_out; | ||
2186 | }; | ||
2187 | |||
2188 | #endif /* __RT5645_H__ */ | ||
diff --git a/sound/soc/codecs/rt5651.c b/sound/soc/codecs/rt5651.c new file mode 100644 index 000000000000..9c88d89f41f0 --- /dev/null +++ b/sound/soc/codecs/rt5651.c | |||
@@ -0,0 +1,1897 @@ | |||
1 | /* | ||
2 | * rt5651.c -- RT5651 ALSA SoC audio codec driver | ||
3 | * | ||
4 | * Copyright 2014 Realtek Semiconductor Corp. | ||
5 | * Author: Bard Liao <bardliao@realtek.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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/moduleparam.h> | ||
14 | #include <linux/init.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/pm.h> | ||
17 | #include <linux/i2c.h> | ||
18 | #include <linux/regmap.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <sound/core.h> | ||
22 | #include <sound/pcm.h> | ||
23 | #include <sound/pcm_params.h> | ||
24 | #include <sound/soc.h> | ||
25 | #include <sound/soc-dapm.h> | ||
26 | #include <sound/initval.h> | ||
27 | #include <sound/tlv.h> | ||
28 | |||
29 | #include "rt5651.h" | ||
30 | |||
31 | #define RT5651_DEVICE_ID_VALUE 0x6281 | ||
32 | |||
33 | #define RT5651_PR_RANGE_BASE (0xff + 1) | ||
34 | #define RT5651_PR_SPACING 0x100 | ||
35 | |||
36 | #define RT5651_PR_BASE (RT5651_PR_RANGE_BASE + (0 * RT5651_PR_SPACING)) | ||
37 | |||
38 | static const struct regmap_range_cfg rt5651_ranges[] = { | ||
39 | { .name = "PR", .range_min = RT5651_PR_BASE, | ||
40 | .range_max = RT5651_PR_BASE + 0xb4, | ||
41 | .selector_reg = RT5651_PRIV_INDEX, | ||
42 | .selector_mask = 0xff, | ||
43 | .selector_shift = 0x0, | ||
44 | .window_start = RT5651_PRIV_DATA, | ||
45 | .window_len = 0x1, }, | ||
46 | }; | ||
47 | |||
48 | static struct reg_default init_list[] = { | ||
49 | {RT5651_PR_BASE + 0x3d, 0x3e00}, | ||
50 | }; | ||
51 | |||
52 | static const struct reg_default rt5651_reg[] = { | ||
53 | { 0x00, 0x0000 }, | ||
54 | { 0x02, 0xc8c8 }, | ||
55 | { 0x03, 0xc8c8 }, | ||
56 | { 0x05, 0x0000 }, | ||
57 | { 0x0d, 0x0000 }, | ||
58 | { 0x0e, 0x0000 }, | ||
59 | { 0x0f, 0x0808 }, | ||
60 | { 0x10, 0x0808 }, | ||
61 | { 0x19, 0xafaf }, | ||
62 | { 0x1a, 0xafaf }, | ||
63 | { 0x1b, 0x0c00 }, | ||
64 | { 0x1c, 0x2f2f }, | ||
65 | { 0x1d, 0x2f2f }, | ||
66 | { 0x1e, 0x0000 }, | ||
67 | { 0x27, 0x7860 }, | ||
68 | { 0x28, 0x7070 }, | ||
69 | { 0x29, 0x8080 }, | ||
70 | { 0x2a, 0x5252 }, | ||
71 | { 0x2b, 0x5454 }, | ||
72 | { 0x2f, 0x0000 }, | ||
73 | { 0x30, 0x5000 }, | ||
74 | { 0x3b, 0x0000 }, | ||
75 | { 0x3c, 0x006f }, | ||
76 | { 0x3d, 0x0000 }, | ||
77 | { 0x3e, 0x006f }, | ||
78 | { 0x45, 0x6000 }, | ||
79 | { 0x4d, 0x0000 }, | ||
80 | { 0x4e, 0x0000 }, | ||
81 | { 0x4f, 0x0279 }, | ||
82 | { 0x50, 0x0000 }, | ||
83 | { 0x51, 0x0000 }, | ||
84 | { 0x52, 0x0279 }, | ||
85 | { 0x53, 0xf000 }, | ||
86 | { 0x61, 0x0000 }, | ||
87 | { 0x62, 0x0000 }, | ||
88 | { 0x63, 0x00c0 }, | ||
89 | { 0x64, 0x0000 }, | ||
90 | { 0x65, 0x0000 }, | ||
91 | { 0x66, 0x0000 }, | ||
92 | { 0x70, 0x8000 }, | ||
93 | { 0x71, 0x8000 }, | ||
94 | { 0x73, 0x1104 }, | ||
95 | { 0x74, 0x0c00 }, | ||
96 | { 0x75, 0x1400 }, | ||
97 | { 0x77, 0x0c00 }, | ||
98 | { 0x78, 0x4000 }, | ||
99 | { 0x79, 0x0123 }, | ||
100 | { 0x80, 0x0000 }, | ||
101 | { 0x81, 0x0000 }, | ||
102 | { 0x82, 0x0000 }, | ||
103 | { 0x83, 0x0800 }, | ||
104 | { 0x84, 0x0000 }, | ||
105 | { 0x85, 0x0008 }, | ||
106 | { 0x89, 0x0000 }, | ||
107 | { 0x8e, 0x0004 }, | ||
108 | { 0x8f, 0x1100 }, | ||
109 | { 0x90, 0x0000 }, | ||
110 | { 0x93, 0x2000 }, | ||
111 | { 0x94, 0x0200 }, | ||
112 | { 0xb0, 0x2080 }, | ||
113 | { 0xb1, 0x0000 }, | ||
114 | { 0xb4, 0x2206 }, | ||
115 | { 0xb5, 0x1f00 }, | ||
116 | { 0xb6, 0x0000 }, | ||
117 | { 0xbb, 0x0000 }, | ||
118 | { 0xbc, 0x0000 }, | ||
119 | { 0xbd, 0x0000 }, | ||
120 | { 0xbe, 0x0000 }, | ||
121 | { 0xbf, 0x0000 }, | ||
122 | { 0xc0, 0x0400 }, | ||
123 | { 0xc1, 0x0000 }, | ||
124 | { 0xc2, 0x0000 }, | ||
125 | { 0xcf, 0x0013 }, | ||
126 | { 0xd0, 0x0680 }, | ||
127 | { 0xd1, 0x1c17 }, | ||
128 | { 0xd3, 0xb320 }, | ||
129 | { 0xd9, 0x0809 }, | ||
130 | { 0xfa, 0x0010 }, | ||
131 | { 0xfe, 0x10ec }, | ||
132 | { 0xff, 0x6281 }, | ||
133 | }; | ||
134 | |||
135 | static bool rt5651_volatile_register(struct device *dev, unsigned int reg) | ||
136 | { | ||
137 | int i; | ||
138 | |||
139 | for (i = 0; i < ARRAY_SIZE(rt5651_ranges); i++) { | ||
140 | if ((reg >= rt5651_ranges[i].window_start && | ||
141 | reg <= rt5651_ranges[i].window_start + | ||
142 | rt5651_ranges[i].window_len) || | ||
143 | (reg >= rt5651_ranges[i].range_min && | ||
144 | reg <= rt5651_ranges[i].range_max)) { | ||
145 | return true; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | switch (reg) { | ||
150 | case RT5651_RESET: | ||
151 | case RT5651_PRIV_DATA: | ||
152 | case RT5651_EQ_CTRL1: | ||
153 | case RT5651_ALC_1: | ||
154 | case RT5651_IRQ_CTRL2: | ||
155 | case RT5651_INT_IRQ_ST: | ||
156 | case RT5651_PGM_REG_ARR1: | ||
157 | case RT5651_PGM_REG_ARR3: | ||
158 | case RT5651_VENDOR_ID: | ||
159 | case RT5651_DEVICE_ID: | ||
160 | return true; | ||
161 | default: | ||
162 | return false; | ||
163 | } | ||
164 | } | ||
165 | |||
166 | static bool rt5651_readable_register(struct device *dev, unsigned int reg) | ||
167 | { | ||
168 | int i; | ||
169 | |||
170 | for (i = 0; i < ARRAY_SIZE(rt5651_ranges); i++) { | ||
171 | if ((reg >= rt5651_ranges[i].window_start && | ||
172 | reg <= rt5651_ranges[i].window_start + | ||
173 | rt5651_ranges[i].window_len) || | ||
174 | (reg >= rt5651_ranges[i].range_min && | ||
175 | reg <= rt5651_ranges[i].range_max)) { | ||
176 | return true; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | switch (reg) { | ||
181 | case RT5651_RESET: | ||
182 | case RT5651_VERSION_ID: | ||
183 | case RT5651_VENDOR_ID: | ||
184 | case RT5651_DEVICE_ID: | ||
185 | case RT5651_HP_VOL: | ||
186 | case RT5651_LOUT_CTRL1: | ||
187 | case RT5651_LOUT_CTRL2: | ||
188 | case RT5651_IN1_IN2: | ||
189 | case RT5651_IN3: | ||
190 | case RT5651_INL1_INR1_VOL: | ||
191 | case RT5651_INL2_INR2_VOL: | ||
192 | case RT5651_DAC1_DIG_VOL: | ||
193 | case RT5651_DAC2_DIG_VOL: | ||
194 | case RT5651_DAC2_CTRL: | ||
195 | case RT5651_ADC_DIG_VOL: | ||
196 | case RT5651_ADC_DATA: | ||
197 | case RT5651_ADC_BST_VOL: | ||
198 | case RT5651_STO1_ADC_MIXER: | ||
199 | case RT5651_STO2_ADC_MIXER: | ||
200 | case RT5651_AD_DA_MIXER: | ||
201 | case RT5651_STO_DAC_MIXER: | ||
202 | case RT5651_DD_MIXER: | ||
203 | case RT5651_DIG_INF_DATA: | ||
204 | case RT5651_PDM_CTL: | ||
205 | case RT5651_REC_L1_MIXER: | ||
206 | case RT5651_REC_L2_MIXER: | ||
207 | case RT5651_REC_R1_MIXER: | ||
208 | case RT5651_REC_R2_MIXER: | ||
209 | case RT5651_HPO_MIXER: | ||
210 | case RT5651_OUT_L1_MIXER: | ||
211 | case RT5651_OUT_L2_MIXER: | ||
212 | case RT5651_OUT_L3_MIXER: | ||
213 | case RT5651_OUT_R1_MIXER: | ||
214 | case RT5651_OUT_R2_MIXER: | ||
215 | case RT5651_OUT_R3_MIXER: | ||
216 | case RT5651_LOUT_MIXER: | ||
217 | case RT5651_PWR_DIG1: | ||
218 | case RT5651_PWR_DIG2: | ||
219 | case RT5651_PWR_ANLG1: | ||
220 | case RT5651_PWR_ANLG2: | ||
221 | case RT5651_PWR_MIXER: | ||
222 | case RT5651_PWR_VOL: | ||
223 | case RT5651_PRIV_INDEX: | ||
224 | case RT5651_PRIV_DATA: | ||
225 | case RT5651_I2S1_SDP: | ||
226 | case RT5651_I2S2_SDP: | ||
227 | case RT5651_ADDA_CLK1: | ||
228 | case RT5651_ADDA_CLK2: | ||
229 | case RT5651_DMIC: | ||
230 | case RT5651_TDM_CTL_1: | ||
231 | case RT5651_TDM_CTL_2: | ||
232 | case RT5651_TDM_CTL_3: | ||
233 | case RT5651_GLB_CLK: | ||
234 | case RT5651_PLL_CTRL1: | ||
235 | case RT5651_PLL_CTRL2: | ||
236 | case RT5651_PLL_MODE_1: | ||
237 | case RT5651_PLL_MODE_2: | ||
238 | case RT5651_PLL_MODE_3: | ||
239 | case RT5651_PLL_MODE_4: | ||
240 | case RT5651_PLL_MODE_5: | ||
241 | case RT5651_PLL_MODE_6: | ||
242 | case RT5651_PLL_MODE_7: | ||
243 | case RT5651_DEPOP_M1: | ||
244 | case RT5651_DEPOP_M2: | ||
245 | case RT5651_DEPOP_M3: | ||
246 | case RT5651_CHARGE_PUMP: | ||
247 | case RT5651_MICBIAS: | ||
248 | case RT5651_A_JD_CTL1: | ||
249 | case RT5651_EQ_CTRL1: | ||
250 | case RT5651_EQ_CTRL2: | ||
251 | case RT5651_ALC_1: | ||
252 | case RT5651_ALC_2: | ||
253 | case RT5651_ALC_3: | ||
254 | case RT5651_JD_CTRL1: | ||
255 | case RT5651_JD_CTRL2: | ||
256 | case RT5651_IRQ_CTRL1: | ||
257 | case RT5651_IRQ_CTRL2: | ||
258 | case RT5651_INT_IRQ_ST: | ||
259 | case RT5651_GPIO_CTRL1: | ||
260 | case RT5651_GPIO_CTRL2: | ||
261 | case RT5651_GPIO_CTRL3: | ||
262 | case RT5651_PGM_REG_ARR1: | ||
263 | case RT5651_PGM_REG_ARR2: | ||
264 | case RT5651_PGM_REG_ARR3: | ||
265 | case RT5651_PGM_REG_ARR4: | ||
266 | case RT5651_PGM_REG_ARR5: | ||
267 | case RT5651_SCB_FUNC: | ||
268 | case RT5651_SCB_CTRL: | ||
269 | case RT5651_BASE_BACK: | ||
270 | case RT5651_MP3_PLUS1: | ||
271 | case RT5651_MP3_PLUS2: | ||
272 | case RT5651_ADJ_HPF_CTRL1: | ||
273 | case RT5651_ADJ_HPF_CTRL2: | ||
274 | case RT5651_HP_CALIB_AMP_DET: | ||
275 | case RT5651_HP_CALIB2: | ||
276 | case RT5651_SV_ZCD1: | ||
277 | case RT5651_SV_ZCD2: | ||
278 | case RT5651_D_MISC: | ||
279 | case RT5651_DUMMY2: | ||
280 | case RT5651_DUMMY3: | ||
281 | return true; | ||
282 | default: | ||
283 | return false; | ||
284 | } | ||
285 | } | ||
286 | |||
287 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); | ||
288 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); | ||
289 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | ||
290 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -17625, 375, 0); | ||
291 | static const DECLARE_TLV_DB_SCALE(adc_bst_tlv, 0, 1200, 0); | ||
292 | |||
293 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52} dB */ | ||
294 | static unsigned int bst_tlv[] = { | ||
295 | TLV_DB_RANGE_HEAD(7), | ||
296 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
297 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | ||
298 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | ||
299 | 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), | ||
300 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | ||
301 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | ||
302 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), | ||
303 | }; | ||
304 | |||
305 | /* Interface data select */ | ||
306 | static const char * const rt5651_data_select[] = { | ||
307 | "Normal", "Swap", "left copy to right", "right copy to left"}; | ||
308 | |||
309 | static SOC_ENUM_SINGLE_DECL(rt5651_if2_dac_enum, RT5651_DIG_INF_DATA, | ||
310 | RT5651_IF2_DAC_SEL_SFT, rt5651_data_select); | ||
311 | |||
312 | static SOC_ENUM_SINGLE_DECL(rt5651_if2_adc_enum, RT5651_DIG_INF_DATA, | ||
313 | RT5651_IF2_ADC_SEL_SFT, rt5651_data_select); | ||
314 | |||
315 | static const struct snd_kcontrol_new rt5651_snd_controls[] = { | ||
316 | /* Headphone Output Volume */ | ||
317 | SOC_DOUBLE_TLV("HP Playback Volume", RT5651_HP_VOL, | ||
318 | RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 39, 1, out_vol_tlv), | ||
319 | /* OUTPUT Control */ | ||
320 | SOC_DOUBLE_TLV("OUT Playback Volume", RT5651_LOUT_CTRL1, | ||
321 | RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, 39, 1, out_vol_tlv), | ||
322 | |||
323 | /* DAC Digital Volume */ | ||
324 | SOC_DOUBLE("DAC2 Playback Switch", RT5651_DAC2_CTRL, | ||
325 | RT5651_M_DAC_L2_VOL_SFT, RT5651_M_DAC_R2_VOL_SFT, 1, 1), | ||
326 | SOC_DOUBLE_TLV("DAC1 Playback Volume", RT5651_DAC1_DIG_VOL, | ||
327 | RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, | ||
328 | 175, 0, dac_vol_tlv), | ||
329 | SOC_DOUBLE_TLV("Mono DAC Playback Volume", RT5651_DAC2_DIG_VOL, | ||
330 | RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, | ||
331 | 175, 0, dac_vol_tlv), | ||
332 | /* IN1/IN2 Control */ | ||
333 | SOC_SINGLE_TLV("IN1 Boost", RT5651_IN1_IN2, | ||
334 | RT5651_BST_SFT1, 8, 0, bst_tlv), | ||
335 | SOC_SINGLE_TLV("IN2 Boost", RT5651_IN1_IN2, | ||
336 | RT5651_BST_SFT2, 8, 0, bst_tlv), | ||
337 | /* INL/INR Volume Control */ | ||
338 | SOC_DOUBLE_TLV("IN Capture Volume", RT5651_INL1_INR1_VOL, | ||
339 | RT5651_INL_VOL_SFT, RT5651_INR_VOL_SFT, | ||
340 | 31, 1, in_vol_tlv), | ||
341 | /* ADC Digital Volume Control */ | ||
342 | SOC_DOUBLE("ADC Capture Switch", RT5651_ADC_DIG_VOL, | ||
343 | RT5651_L_MUTE_SFT, RT5651_R_MUTE_SFT, 1, 1), | ||
344 | SOC_DOUBLE_TLV("ADC Capture Volume", RT5651_ADC_DIG_VOL, | ||
345 | RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, | ||
346 | 127, 0, adc_vol_tlv), | ||
347 | SOC_DOUBLE_TLV("Mono ADC Capture Volume", RT5651_ADC_DATA, | ||
348 | RT5651_L_VOL_SFT, RT5651_R_VOL_SFT, | ||
349 | 127, 0, adc_vol_tlv), | ||
350 | /* ADC Boost Volume Control */ | ||
351 | SOC_DOUBLE_TLV("ADC Boost Gain", RT5651_ADC_BST_VOL, | ||
352 | RT5651_ADC_L_BST_SFT, RT5651_ADC_R_BST_SFT, | ||
353 | 3, 0, adc_bst_tlv), | ||
354 | |||
355 | /* ASRC */ | ||
356 | SOC_SINGLE("IF1 ASRC Switch", RT5651_PLL_MODE_1, | ||
357 | RT5651_STO1_T_SFT, 1, 0), | ||
358 | SOC_SINGLE("IF2 ASRC Switch", RT5651_PLL_MODE_1, | ||
359 | RT5651_STO2_T_SFT, 1, 0), | ||
360 | SOC_SINGLE("DMIC ASRC Switch", RT5651_PLL_MODE_1, | ||
361 | RT5651_DMIC_1_M_SFT, 1, 0), | ||
362 | |||
363 | SOC_ENUM("ADC IF2 Data Switch", rt5651_if2_adc_enum), | ||
364 | SOC_ENUM("DAC IF2 Data Switch", rt5651_if2_dac_enum), | ||
365 | }; | ||
366 | |||
367 | /** | ||
368 | * set_dmic_clk - Set parameter of dmic. | ||
369 | * | ||
370 | * @w: DAPM widget. | ||
371 | * @kcontrol: The kcontrol of this widget. | ||
372 | * @event: Event id. | ||
373 | * | ||
374 | * Choose dmic clock between 1MHz and 3MHz. | ||
375 | * It is better for clock to approximate 3MHz. | ||
376 | */ | ||
377 | static int set_dmic_clk(struct snd_soc_dapm_widget *w, | ||
378 | struct snd_kcontrol *kcontrol, int event) | ||
379 | { | ||
380 | struct snd_soc_codec *codec = w->codec; | ||
381 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
382 | int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL; | ||
383 | int i, rate, red, bound, temp; | ||
384 | |||
385 | rate = rt5651->sysclk; | ||
386 | red = 3000000 * 12; | ||
387 | for (i = 0; i < ARRAY_SIZE(div); i++) { | ||
388 | bound = div[i] * 3000000; | ||
389 | if (rate > bound) | ||
390 | continue; | ||
391 | temp = bound - rate; | ||
392 | if (temp < red) { | ||
393 | red = temp; | ||
394 | idx = i; | ||
395 | } | ||
396 | } | ||
397 | if (idx < 0) | ||
398 | dev_err(codec->dev, "Failed to set DMIC clock\n"); | ||
399 | else | ||
400 | snd_soc_update_bits(codec, RT5651_DMIC, RT5651_DMIC_CLK_MASK, | ||
401 | idx << RT5651_DMIC_CLK_SFT); | ||
402 | |||
403 | return idx; | ||
404 | } | ||
405 | |||
406 | static int is_sysclk_from_pll(struct snd_soc_dapm_widget *source, | ||
407 | struct snd_soc_dapm_widget *sink) | ||
408 | { | ||
409 | unsigned int val; | ||
410 | |||
411 | val = snd_soc_read(source->codec, RT5651_GLB_CLK); | ||
412 | val &= RT5651_SCLK_SRC_MASK; | ||
413 | if (val == RT5651_SCLK_SRC_PLL1) | ||
414 | return 1; | ||
415 | else | ||
416 | return 0; | ||
417 | } | ||
418 | |||
419 | /* Digital Mixer */ | ||
420 | static const struct snd_kcontrol_new rt5651_sto1_adc_l_mix[] = { | ||
421 | SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO1_ADC_MIXER, | ||
422 | RT5651_M_STO1_ADC_L1_SFT, 1, 1), | ||
423 | SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO1_ADC_MIXER, | ||
424 | RT5651_M_STO1_ADC_L2_SFT, 1, 1), | ||
425 | }; | ||
426 | |||
427 | static const struct snd_kcontrol_new rt5651_sto1_adc_r_mix[] = { | ||
428 | SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO1_ADC_MIXER, | ||
429 | RT5651_M_STO1_ADC_R1_SFT, 1, 1), | ||
430 | SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO1_ADC_MIXER, | ||
431 | RT5651_M_STO1_ADC_R2_SFT, 1, 1), | ||
432 | }; | ||
433 | |||
434 | static const struct snd_kcontrol_new rt5651_sto2_adc_l_mix[] = { | ||
435 | SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO2_ADC_MIXER, | ||
436 | RT5651_M_STO2_ADC_L1_SFT, 1, 1), | ||
437 | SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO2_ADC_MIXER, | ||
438 | RT5651_M_STO2_ADC_L2_SFT, 1, 1), | ||
439 | }; | ||
440 | |||
441 | static const struct snd_kcontrol_new rt5651_sto2_adc_r_mix[] = { | ||
442 | SOC_DAPM_SINGLE("ADC1 Switch", RT5651_STO2_ADC_MIXER, | ||
443 | RT5651_M_STO2_ADC_R1_SFT, 1, 1), | ||
444 | SOC_DAPM_SINGLE("ADC2 Switch", RT5651_STO2_ADC_MIXER, | ||
445 | RT5651_M_STO2_ADC_R2_SFT, 1, 1), | ||
446 | }; | ||
447 | |||
448 | static const struct snd_kcontrol_new rt5651_dac_l_mix[] = { | ||
449 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5651_AD_DA_MIXER, | ||
450 | RT5651_M_ADCMIX_L_SFT, 1, 1), | ||
451 | SOC_DAPM_SINGLE("INF1 Switch", RT5651_AD_DA_MIXER, | ||
452 | RT5651_M_IF1_DAC_L_SFT, 1, 1), | ||
453 | }; | ||
454 | |||
455 | static const struct snd_kcontrol_new rt5651_dac_r_mix[] = { | ||
456 | SOC_DAPM_SINGLE("Stereo ADC Switch", RT5651_AD_DA_MIXER, | ||
457 | RT5651_M_ADCMIX_R_SFT, 1, 1), | ||
458 | SOC_DAPM_SINGLE("INF1 Switch", RT5651_AD_DA_MIXER, | ||
459 | RT5651_M_IF1_DAC_R_SFT, 1, 1), | ||
460 | }; | ||
461 | |||
462 | static const struct snd_kcontrol_new rt5651_sto_dac_l_mix[] = { | ||
463 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_STO_DAC_MIXER, | ||
464 | RT5651_M_DAC_L1_MIXL_SFT, 1, 1), | ||
465 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5651_STO_DAC_MIXER, | ||
466 | RT5651_M_DAC_L2_MIXL_SFT, 1, 1), | ||
467 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_STO_DAC_MIXER, | ||
468 | RT5651_M_DAC_R1_MIXL_SFT, 1, 1), | ||
469 | }; | ||
470 | |||
471 | static const struct snd_kcontrol_new rt5651_sto_dac_r_mix[] = { | ||
472 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_STO_DAC_MIXER, | ||
473 | RT5651_M_DAC_R1_MIXR_SFT, 1, 1), | ||
474 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5651_STO_DAC_MIXER, | ||
475 | RT5651_M_DAC_R2_MIXR_SFT, 1, 1), | ||
476 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_STO_DAC_MIXER, | ||
477 | RT5651_M_DAC_L1_MIXR_SFT, 1, 1), | ||
478 | }; | ||
479 | |||
480 | static const struct snd_kcontrol_new rt5651_dd_dac_l_mix[] = { | ||
481 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_DD_MIXER, | ||
482 | RT5651_M_STO_DD_L1_SFT, 1, 1), | ||
483 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5651_DD_MIXER, | ||
484 | RT5651_M_STO_DD_L2_SFT, 1, 1), | ||
485 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5651_DD_MIXER, | ||
486 | RT5651_M_STO_DD_R2_L_SFT, 1, 1), | ||
487 | }; | ||
488 | |||
489 | static const struct snd_kcontrol_new rt5651_dd_dac_r_mix[] = { | ||
490 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_DD_MIXER, | ||
491 | RT5651_M_STO_DD_R1_SFT, 1, 1), | ||
492 | SOC_DAPM_SINGLE("DAC R2 Switch", RT5651_DD_MIXER, | ||
493 | RT5651_M_STO_DD_R2_SFT, 1, 1), | ||
494 | SOC_DAPM_SINGLE("DAC L2 Switch", RT5651_DD_MIXER, | ||
495 | RT5651_M_STO_DD_L2_R_SFT, 1, 1), | ||
496 | }; | ||
497 | |||
498 | /* Analog Input Mixer */ | ||
499 | static const struct snd_kcontrol_new rt5651_rec_l_mix[] = { | ||
500 | SOC_DAPM_SINGLE("INL1 Switch", RT5651_REC_L2_MIXER, | ||
501 | RT5651_M_IN1_L_RM_L_SFT, 1, 1), | ||
502 | SOC_DAPM_SINGLE("BST3 Switch", RT5651_REC_L2_MIXER, | ||
503 | RT5651_M_BST3_RM_L_SFT, 1, 1), | ||
504 | SOC_DAPM_SINGLE("BST2 Switch", RT5651_REC_L2_MIXER, | ||
505 | RT5651_M_BST2_RM_L_SFT, 1, 1), | ||
506 | SOC_DAPM_SINGLE("BST1 Switch", RT5651_REC_L2_MIXER, | ||
507 | RT5651_M_BST1_RM_L_SFT, 1, 1), | ||
508 | }; | ||
509 | |||
510 | static const struct snd_kcontrol_new rt5651_rec_r_mix[] = { | ||
511 | SOC_DAPM_SINGLE("INR1 Switch", RT5651_REC_R2_MIXER, | ||
512 | RT5651_M_IN1_R_RM_R_SFT, 1, 1), | ||
513 | SOC_DAPM_SINGLE("BST3 Switch", RT5651_REC_R2_MIXER, | ||
514 | RT5651_M_BST3_RM_R_SFT, 1, 1), | ||
515 | SOC_DAPM_SINGLE("BST2 Switch", RT5651_REC_R2_MIXER, | ||
516 | RT5651_M_BST2_RM_R_SFT, 1, 1), | ||
517 | SOC_DAPM_SINGLE("BST1 Switch", RT5651_REC_R2_MIXER, | ||
518 | RT5651_M_BST1_RM_R_SFT, 1, 1), | ||
519 | }; | ||
520 | |||
521 | /* Analog Output Mixer */ | ||
522 | |||
523 | static const struct snd_kcontrol_new rt5651_out_l_mix[] = { | ||
524 | SOC_DAPM_SINGLE("BST1 Switch", RT5651_OUT_L3_MIXER, | ||
525 | RT5651_M_BST1_OM_L_SFT, 1, 1), | ||
526 | SOC_DAPM_SINGLE("BST2 Switch", RT5651_OUT_L3_MIXER, | ||
527 | RT5651_M_BST2_OM_L_SFT, 1, 1), | ||
528 | SOC_DAPM_SINGLE("INL1 Switch", RT5651_OUT_L3_MIXER, | ||
529 | RT5651_M_IN1_L_OM_L_SFT, 1, 1), | ||
530 | SOC_DAPM_SINGLE("REC MIXL Switch", RT5651_OUT_L3_MIXER, | ||
531 | RT5651_M_RM_L_OM_L_SFT, 1, 1), | ||
532 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_OUT_L3_MIXER, | ||
533 | RT5651_M_DAC_L1_OM_L_SFT, 1, 1), | ||
534 | }; | ||
535 | |||
536 | static const struct snd_kcontrol_new rt5651_out_r_mix[] = { | ||
537 | SOC_DAPM_SINGLE("BST2 Switch", RT5651_OUT_R3_MIXER, | ||
538 | RT5651_M_BST2_OM_R_SFT, 1, 1), | ||
539 | SOC_DAPM_SINGLE("BST1 Switch", RT5651_OUT_R3_MIXER, | ||
540 | RT5651_M_BST1_OM_R_SFT, 1, 1), | ||
541 | SOC_DAPM_SINGLE("INR1 Switch", RT5651_OUT_R3_MIXER, | ||
542 | RT5651_M_IN1_R_OM_R_SFT, 1, 1), | ||
543 | SOC_DAPM_SINGLE("REC MIXR Switch", RT5651_OUT_R3_MIXER, | ||
544 | RT5651_M_RM_R_OM_R_SFT, 1, 1), | ||
545 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_OUT_R3_MIXER, | ||
546 | RT5651_M_DAC_R1_OM_R_SFT, 1, 1), | ||
547 | }; | ||
548 | |||
549 | static const struct snd_kcontrol_new rt5651_hpo_mix[] = { | ||
550 | SOC_DAPM_SINGLE("HPO MIX DAC1 Switch", RT5651_HPO_MIXER, | ||
551 | RT5651_M_DAC1_HM_SFT, 1, 1), | ||
552 | SOC_DAPM_SINGLE("HPO MIX HPVOL Switch", RT5651_HPO_MIXER, | ||
553 | RT5651_M_HPVOL_HM_SFT, 1, 1), | ||
554 | }; | ||
555 | |||
556 | static const struct snd_kcontrol_new rt5651_lout_mix[] = { | ||
557 | SOC_DAPM_SINGLE("DAC L1 Switch", RT5651_LOUT_MIXER, | ||
558 | RT5651_M_DAC_L1_LM_SFT, 1, 1), | ||
559 | SOC_DAPM_SINGLE("DAC R1 Switch", RT5651_LOUT_MIXER, | ||
560 | RT5651_M_DAC_R1_LM_SFT, 1, 1), | ||
561 | SOC_DAPM_SINGLE("OUTVOL L Switch", RT5651_LOUT_MIXER, | ||
562 | RT5651_M_OV_L_LM_SFT, 1, 1), | ||
563 | SOC_DAPM_SINGLE("OUTVOL R Switch", RT5651_LOUT_MIXER, | ||
564 | RT5651_M_OV_R_LM_SFT, 1, 1), | ||
565 | }; | ||
566 | |||
567 | static const struct snd_kcontrol_new outvol_l_control = | ||
568 | SOC_DAPM_SINGLE("Switch", RT5651_LOUT_CTRL1, | ||
569 | RT5651_VOL_L_SFT, 1, 1); | ||
570 | |||
571 | static const struct snd_kcontrol_new outvol_r_control = | ||
572 | SOC_DAPM_SINGLE("Switch", RT5651_LOUT_CTRL1, | ||
573 | RT5651_VOL_R_SFT, 1, 1); | ||
574 | |||
575 | static const struct snd_kcontrol_new lout_l_mute_control = | ||
576 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_LOUT_CTRL1, | ||
577 | RT5651_L_MUTE_SFT, 1, 1); | ||
578 | |||
579 | static const struct snd_kcontrol_new lout_r_mute_control = | ||
580 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_LOUT_CTRL1, | ||
581 | RT5651_R_MUTE_SFT, 1, 1); | ||
582 | |||
583 | static const struct snd_kcontrol_new hpovol_l_control = | ||
584 | SOC_DAPM_SINGLE("Switch", RT5651_HP_VOL, | ||
585 | RT5651_VOL_L_SFT, 1, 1); | ||
586 | |||
587 | static const struct snd_kcontrol_new hpovol_r_control = | ||
588 | SOC_DAPM_SINGLE("Switch", RT5651_HP_VOL, | ||
589 | RT5651_VOL_R_SFT, 1, 1); | ||
590 | |||
591 | static const struct snd_kcontrol_new hpo_l_mute_control = | ||
592 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_HP_VOL, | ||
593 | RT5651_L_MUTE_SFT, 1, 1); | ||
594 | |||
595 | static const struct snd_kcontrol_new hpo_r_mute_control = | ||
596 | SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5651_HP_VOL, | ||
597 | RT5651_R_MUTE_SFT, 1, 1); | ||
598 | |||
599 | /* INL/R source */ | ||
600 | static const char * const rt5651_inl_src[] = {"IN2P", "HPOVOLLP"}; | ||
601 | |||
602 | static SOC_ENUM_SINGLE_DECL( | ||
603 | rt5651_inl_enum, RT5651_INL1_INR1_VOL, | ||
604 | RT5651_INL_SEL_SFT, rt5651_inl_src); | ||
605 | |||
606 | static const struct snd_kcontrol_new rt5651_inl1_mux = | ||
607 | SOC_DAPM_ENUM("INL1 source", rt5651_inl_enum); | ||
608 | |||
609 | static const char * const rt5651_inr1_src[] = {"IN2N", "HPOVOLRP"}; | ||
610 | |||
611 | static SOC_ENUM_SINGLE_DECL( | ||
612 | rt5651_inr1_enum, RT5651_INL1_INR1_VOL, | ||
613 | RT5651_INR_SEL_SFT, rt5651_inr1_src); | ||
614 | |||
615 | static const struct snd_kcontrol_new rt5651_inr1_mux = | ||
616 | SOC_DAPM_ENUM("INR1 source", rt5651_inr1_enum); | ||
617 | |||
618 | static const char * const rt5651_inl2_src[] = {"IN3P", "OUTVOLLP"}; | ||
619 | |||
620 | static SOC_ENUM_SINGLE_DECL( | ||
621 | rt5651_inl2_enum, RT5651_INL2_INR2_VOL, | ||
622 | RT5651_INL_SEL_SFT, rt5651_inl2_src); | ||
623 | |||
624 | static const struct snd_kcontrol_new rt5651_inl2_mux = | ||
625 | SOC_DAPM_ENUM("INL2 source", rt5651_inl2_enum); | ||
626 | |||
627 | static const char * const rt5651_inr2_src[] = {"IN3N", "OUTVOLRP"}; | ||
628 | |||
629 | static SOC_ENUM_SINGLE_DECL( | ||
630 | rt5651_inr2_enum, RT5651_INL2_INR2_VOL, | ||
631 | RT5651_INR_SEL_SFT, rt5651_inr2_src); | ||
632 | |||
633 | static const struct snd_kcontrol_new rt5651_inr2_mux = | ||
634 | SOC_DAPM_ENUM("INR2 source", rt5651_inr2_enum); | ||
635 | |||
636 | |||
637 | /* Stereo ADC source */ | ||
638 | static const char * const rt5651_stereo1_adc1_src[] = {"DD MIX", "ADC"}; | ||
639 | |||
640 | static SOC_ENUM_SINGLE_DECL( | ||
641 | rt5651_stereo1_adc1_enum, RT5651_STO1_ADC_MIXER, | ||
642 | RT5651_STO1_ADC_1_SRC_SFT, rt5651_stereo1_adc1_src); | ||
643 | |||
644 | static const struct snd_kcontrol_new rt5651_sto1_adc_l1_mux = | ||
645 | SOC_DAPM_ENUM("Stereo1 ADC L1 source", rt5651_stereo1_adc1_enum); | ||
646 | |||
647 | static const struct snd_kcontrol_new rt5651_sto1_adc_r1_mux = | ||
648 | SOC_DAPM_ENUM("Stereo1 ADC R1 source", rt5651_stereo1_adc1_enum); | ||
649 | |||
650 | static const char * const rt5651_stereo1_adc2_src[] = {"DMIC", "DD MIX"}; | ||
651 | |||
652 | static SOC_ENUM_SINGLE_DECL( | ||
653 | rt5651_stereo1_adc2_enum, RT5651_STO1_ADC_MIXER, | ||
654 | RT5651_STO1_ADC_2_SRC_SFT, rt5651_stereo1_adc2_src); | ||
655 | |||
656 | static const struct snd_kcontrol_new rt5651_sto1_adc_l2_mux = | ||
657 | SOC_DAPM_ENUM("Stereo1 ADC L2 source", rt5651_stereo1_adc2_enum); | ||
658 | |||
659 | static const struct snd_kcontrol_new rt5651_sto1_adc_r2_mux = | ||
660 | SOC_DAPM_ENUM("Stereo1 ADC R2 source", rt5651_stereo1_adc2_enum); | ||
661 | |||
662 | /* Mono ADC source */ | ||
663 | static const char * const rt5651_sto2_adc_l1_src[] = {"DD MIXL", "ADCL"}; | ||
664 | |||
665 | static SOC_ENUM_SINGLE_DECL( | ||
666 | rt5651_sto2_adc_l1_enum, RT5651_STO1_ADC_MIXER, | ||
667 | RT5651_STO2_ADC_L1_SRC_SFT, rt5651_sto2_adc_l1_src); | ||
668 | |||
669 | static const struct snd_kcontrol_new rt5651_sto2_adc_l1_mux = | ||
670 | SOC_DAPM_ENUM("Stereo2 ADC1 left source", rt5651_sto2_adc_l1_enum); | ||
671 | |||
672 | static const char * const rt5651_sto2_adc_l2_src[] = {"DMIC L", "DD MIXL"}; | ||
673 | |||
674 | static SOC_ENUM_SINGLE_DECL( | ||
675 | rt5651_sto2_adc_l2_enum, RT5651_STO1_ADC_MIXER, | ||
676 | RT5651_STO2_ADC_L2_SRC_SFT, rt5651_sto2_adc_l2_src); | ||
677 | |||
678 | static const struct snd_kcontrol_new rt5651_sto2_adc_l2_mux = | ||
679 | SOC_DAPM_ENUM("Stereo2 ADC2 left source", rt5651_sto2_adc_l2_enum); | ||
680 | |||
681 | static const char * const rt5651_sto2_adc_r1_src[] = {"DD MIXR", "ADCR"}; | ||
682 | |||
683 | static SOC_ENUM_SINGLE_DECL( | ||
684 | rt5651_sto2_adc_r1_enum, RT5651_STO1_ADC_MIXER, | ||
685 | RT5651_STO2_ADC_R1_SRC_SFT, rt5651_sto2_adc_r1_src); | ||
686 | |||
687 | static const struct snd_kcontrol_new rt5651_sto2_adc_r1_mux = | ||
688 | SOC_DAPM_ENUM("Stereo2 ADC1 right source", rt5651_sto2_adc_r1_enum); | ||
689 | |||
690 | static const char * const rt5651_sto2_adc_r2_src[] = {"DMIC R", "DD MIXR"}; | ||
691 | |||
692 | static SOC_ENUM_SINGLE_DECL( | ||
693 | rt5651_sto2_adc_r2_enum, RT5651_STO1_ADC_MIXER, | ||
694 | RT5651_STO2_ADC_R2_SRC_SFT, rt5651_sto2_adc_r2_src); | ||
695 | |||
696 | static const struct snd_kcontrol_new rt5651_sto2_adc_r2_mux = | ||
697 | SOC_DAPM_ENUM("Stereo2 ADC2 right source", rt5651_sto2_adc_r2_enum); | ||
698 | |||
699 | /* DAC2 channel source */ | ||
700 | |||
701 | static const char * const rt5651_dac_src[] = {"IF1", "IF2"}; | ||
702 | |||
703 | static SOC_ENUM_SINGLE_DECL(rt5651_dac_l2_enum, RT5651_DAC2_CTRL, | ||
704 | RT5651_SEL_DAC_L2_SFT, rt5651_dac_src); | ||
705 | |||
706 | static const struct snd_kcontrol_new rt5651_dac_l2_mux = | ||
707 | SOC_DAPM_ENUM("DAC2 left channel source", rt5651_dac_l2_enum); | ||
708 | |||
709 | static SOC_ENUM_SINGLE_DECL( | ||
710 | rt5651_dac_r2_enum, RT5651_DAC2_CTRL, | ||
711 | RT5651_SEL_DAC_R2_SFT, rt5651_dac_src); | ||
712 | |||
713 | static const struct snd_kcontrol_new rt5651_dac_r2_mux = | ||
714 | SOC_DAPM_ENUM("DAC2 right channel source", rt5651_dac_r2_enum); | ||
715 | |||
716 | /* IF2_ADC channel source */ | ||
717 | |||
718 | static const char * const rt5651_adc_src[] = {"IF1 ADC1", "IF1 ADC2"}; | ||
719 | |||
720 | static SOC_ENUM_SINGLE_DECL(rt5651_if2_adc_src_enum, RT5651_DIG_INF_DATA, | ||
721 | RT5651_IF2_ADC_SRC_SFT, rt5651_adc_src); | ||
722 | |||
723 | static const struct snd_kcontrol_new rt5651_if2_adc_src_mux = | ||
724 | SOC_DAPM_ENUM("IF2 ADC channel source", rt5651_if2_adc_src_enum); | ||
725 | |||
726 | /* PDM select */ | ||
727 | static const char * const rt5651_pdm_sel[] = {"DD MIX", "Stereo DAC MIX"}; | ||
728 | |||
729 | static SOC_ENUM_SINGLE_DECL( | ||
730 | rt5651_pdm_l_sel_enum, RT5651_PDM_CTL, | ||
731 | RT5651_PDM_L_SEL_SFT, rt5651_pdm_sel); | ||
732 | |||
733 | static SOC_ENUM_SINGLE_DECL( | ||
734 | rt5651_pdm_r_sel_enum, RT5651_PDM_CTL, | ||
735 | RT5651_PDM_R_SEL_SFT, rt5651_pdm_sel); | ||
736 | |||
737 | static const struct snd_kcontrol_new rt5651_pdm_l_mux = | ||
738 | SOC_DAPM_ENUM("PDM L select", rt5651_pdm_l_sel_enum); | ||
739 | |||
740 | static const struct snd_kcontrol_new rt5651_pdm_r_mux = | ||
741 | SOC_DAPM_ENUM("PDM R select", rt5651_pdm_r_sel_enum); | ||
742 | |||
743 | static int rt5651_amp_power_event(struct snd_soc_dapm_widget *w, | ||
744 | struct snd_kcontrol *kcontrol, int event) | ||
745 | { | ||
746 | struct snd_soc_codec *codec = w->codec; | ||
747 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
748 | |||
749 | switch (event) { | ||
750 | case SND_SOC_DAPM_POST_PMU: | ||
751 | /* depop parameters */ | ||
752 | regmap_update_bits(rt5651->regmap, RT5651_PR_BASE + | ||
753 | RT5651_CHPUMP_INT_REG1, 0x0700, 0x0200); | ||
754 | regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M2, | ||
755 | RT5651_DEPOP_MASK, RT5651_DEPOP_MAN); | ||
756 | regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M1, | ||
757 | RT5651_HP_CP_MASK | RT5651_HP_SG_MASK | | ||
758 | RT5651_HP_CB_MASK, RT5651_HP_CP_PU | | ||
759 | RT5651_HP_SG_DIS | RT5651_HP_CB_PU); | ||
760 | regmap_write(rt5651->regmap, RT5651_PR_BASE + | ||
761 | RT5651_HP_DCC_INT1, 0x9f00); | ||
762 | /* headphone amp power on */ | ||
763 | regmap_update_bits(rt5651->regmap, RT5651_PWR_ANLG1, | ||
764 | RT5651_PWR_FV1 | RT5651_PWR_FV2, 0); | ||
765 | regmap_update_bits(rt5651->regmap, RT5651_PWR_ANLG1, | ||
766 | RT5651_PWR_HA, | ||
767 | RT5651_PWR_HA); | ||
768 | usleep_range(10000, 15000); | ||
769 | regmap_update_bits(rt5651->regmap, RT5651_PWR_ANLG1, | ||
770 | RT5651_PWR_FV1 | RT5651_PWR_FV2 , | ||
771 | RT5651_PWR_FV1 | RT5651_PWR_FV2); | ||
772 | break; | ||
773 | |||
774 | default: | ||
775 | return 0; | ||
776 | } | ||
777 | |||
778 | return 0; | ||
779 | } | ||
780 | |||
781 | static int rt5651_hp_event(struct snd_soc_dapm_widget *w, | ||
782 | struct snd_kcontrol *kcontrol, int event) | ||
783 | { | ||
784 | struct snd_soc_codec *codec = w->codec; | ||
785 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
786 | |||
787 | switch (event) { | ||
788 | case SND_SOC_DAPM_POST_PMU: | ||
789 | /* headphone unmute sequence */ | ||
790 | regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M2, | ||
791 | RT5651_DEPOP_MASK | RT5651_DIG_DP_MASK, | ||
792 | RT5651_DEPOP_AUTO | RT5651_DIG_DP_EN); | ||
793 | regmap_update_bits(rt5651->regmap, RT5651_CHARGE_PUMP, | ||
794 | RT5651_PM_HP_MASK, RT5651_PM_HP_HV); | ||
795 | |||
796 | regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M3, | ||
797 | RT5651_CP_FQ1_MASK | RT5651_CP_FQ2_MASK | | ||
798 | RT5651_CP_FQ3_MASK, | ||
799 | (RT5651_CP_FQ_192_KHZ << RT5651_CP_FQ1_SFT) | | ||
800 | (RT5651_CP_FQ_12_KHZ << RT5651_CP_FQ2_SFT) | | ||
801 | (RT5651_CP_FQ_192_KHZ << RT5651_CP_FQ3_SFT)); | ||
802 | |||
803 | regmap_write(rt5651->regmap, RT5651_PR_BASE + | ||
804 | RT5651_MAMP_INT_REG2, 0x1c00); | ||
805 | regmap_update_bits(rt5651->regmap, RT5651_DEPOP_M1, | ||
806 | RT5651_HP_CP_MASK | RT5651_HP_SG_MASK, | ||
807 | RT5651_HP_CP_PD | RT5651_HP_SG_EN); | ||
808 | regmap_update_bits(rt5651->regmap, RT5651_PR_BASE + | ||
809 | RT5651_CHPUMP_INT_REG1, 0x0700, 0x0400); | ||
810 | rt5651->hp_mute = 0; | ||
811 | break; | ||
812 | |||
813 | case SND_SOC_DAPM_PRE_PMD: | ||
814 | rt5651->hp_mute = 1; | ||
815 | usleep_range(70000, 75000); | ||
816 | break; | ||
817 | |||
818 | default: | ||
819 | return 0; | ||
820 | } | ||
821 | |||
822 | return 0; | ||
823 | } | ||
824 | |||
825 | static int rt5651_hp_post_event(struct snd_soc_dapm_widget *w, | ||
826 | struct snd_kcontrol *kcontrol, int event) | ||
827 | { | ||
828 | struct snd_soc_codec *codec = w->codec; | ||
829 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
830 | |||
831 | switch (event) { | ||
832 | case SND_SOC_DAPM_POST_PMU: | ||
833 | if (!rt5651->hp_mute) | ||
834 | usleep_range(80000, 85000); | ||
835 | |||
836 | break; | ||
837 | |||
838 | default: | ||
839 | return 0; | ||
840 | } | ||
841 | |||
842 | return 0; | ||
843 | } | ||
844 | |||
845 | static int rt5651_bst1_event(struct snd_soc_dapm_widget *w, | ||
846 | struct snd_kcontrol *kcontrol, int event) | ||
847 | { | ||
848 | struct snd_soc_codec *codec = w->codec; | ||
849 | |||
850 | switch (event) { | ||
851 | case SND_SOC_DAPM_POST_PMU: | ||
852 | snd_soc_update_bits(codec, RT5651_PWR_ANLG2, | ||
853 | RT5651_PWR_BST1_OP2, RT5651_PWR_BST1_OP2); | ||
854 | break; | ||
855 | |||
856 | case SND_SOC_DAPM_PRE_PMD: | ||
857 | snd_soc_update_bits(codec, RT5651_PWR_ANLG2, | ||
858 | RT5651_PWR_BST1_OP2, 0); | ||
859 | break; | ||
860 | |||
861 | default: | ||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | return 0; | ||
866 | } | ||
867 | |||
868 | static int rt5651_bst2_event(struct snd_soc_dapm_widget *w, | ||
869 | struct snd_kcontrol *kcontrol, int event) | ||
870 | { | ||
871 | struct snd_soc_codec *codec = w->codec; | ||
872 | |||
873 | switch (event) { | ||
874 | case SND_SOC_DAPM_POST_PMU: | ||
875 | snd_soc_update_bits(codec, RT5651_PWR_ANLG2, | ||
876 | RT5651_PWR_BST2_OP2, RT5651_PWR_BST2_OP2); | ||
877 | break; | ||
878 | |||
879 | case SND_SOC_DAPM_PRE_PMD: | ||
880 | snd_soc_update_bits(codec, RT5651_PWR_ANLG2, | ||
881 | RT5651_PWR_BST2_OP2, 0); | ||
882 | break; | ||
883 | |||
884 | default: | ||
885 | return 0; | ||
886 | } | ||
887 | |||
888 | return 0; | ||
889 | } | ||
890 | |||
891 | static int rt5651_bst3_event(struct snd_soc_dapm_widget *w, | ||
892 | struct snd_kcontrol *kcontrol, int event) | ||
893 | { | ||
894 | struct snd_soc_codec *codec = w->codec; | ||
895 | |||
896 | switch (event) { | ||
897 | case SND_SOC_DAPM_POST_PMU: | ||
898 | snd_soc_update_bits(codec, RT5651_PWR_ANLG2, | ||
899 | RT5651_PWR_BST3_OP2, RT5651_PWR_BST3_OP2); | ||
900 | break; | ||
901 | |||
902 | case SND_SOC_DAPM_PRE_PMD: | ||
903 | snd_soc_update_bits(codec, RT5651_PWR_ANLG2, | ||
904 | RT5651_PWR_BST3_OP2, 0); | ||
905 | break; | ||
906 | |||
907 | default: | ||
908 | return 0; | ||
909 | } | ||
910 | |||
911 | return 0; | ||
912 | } | ||
913 | |||
914 | static const struct snd_soc_dapm_widget rt5651_dapm_widgets[] = { | ||
915 | /* ASRC */ | ||
916 | SND_SOC_DAPM_SUPPLY_S("I2S1 ASRC", 1, RT5651_PLL_MODE_2, | ||
917 | 15, 0, NULL, 0), | ||
918 | SND_SOC_DAPM_SUPPLY_S("I2S2 ASRC", 1, RT5651_PLL_MODE_2, | ||
919 | 14, 0, NULL, 0), | ||
920 | SND_SOC_DAPM_SUPPLY_S("STO1 DAC ASRC", 1, RT5651_PLL_MODE_2, | ||
921 | 13, 0, NULL, 0), | ||
922 | SND_SOC_DAPM_SUPPLY_S("STO2 DAC ASRC", 1, RT5651_PLL_MODE_2, | ||
923 | 12, 0, NULL, 0), | ||
924 | SND_SOC_DAPM_SUPPLY_S("ADC ASRC", 1, RT5651_PLL_MODE_2, | ||
925 | 11, 0, NULL, 0), | ||
926 | |||
927 | SND_SOC_DAPM_SUPPLY("PLL1", RT5651_PWR_ANLG2, | ||
928 | RT5651_PWR_PLL_BIT, 0, NULL, 0), | ||
929 | /* Input Side */ | ||
930 | /* micbias */ | ||
931 | SND_SOC_DAPM_SUPPLY("LDO", RT5651_PWR_ANLG1, | ||
932 | RT5651_PWR_LDO_BIT, 0, NULL, 0), | ||
933 | SND_SOC_DAPM_MICBIAS("micbias1", RT5651_PWR_ANLG2, | ||
934 | RT5651_PWR_MB1_BIT, 0), | ||
935 | /* Input Lines */ | ||
936 | SND_SOC_DAPM_INPUT("MIC1"), | ||
937 | SND_SOC_DAPM_INPUT("MIC2"), | ||
938 | SND_SOC_DAPM_INPUT("MIC3"), | ||
939 | |||
940 | SND_SOC_DAPM_INPUT("IN1P"), | ||
941 | SND_SOC_DAPM_INPUT("IN2P"), | ||
942 | SND_SOC_DAPM_INPUT("IN2N"), | ||
943 | SND_SOC_DAPM_INPUT("IN3P"), | ||
944 | SND_SOC_DAPM_INPUT("DMIC L1"), | ||
945 | SND_SOC_DAPM_INPUT("DMIC R1"), | ||
946 | SND_SOC_DAPM_SUPPLY("DMIC CLK", RT5651_DMIC, RT5651_DMIC_1_EN_SFT, | ||
947 | 0, set_dmic_clk, SND_SOC_DAPM_PRE_PMU), | ||
948 | /* Boost */ | ||
949 | SND_SOC_DAPM_PGA_E("BST1", RT5651_PWR_ANLG2, | ||
950 | RT5651_PWR_BST1_BIT, 0, NULL, 0, rt5651_bst1_event, | ||
951 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
952 | SND_SOC_DAPM_PGA_E("BST2", RT5651_PWR_ANLG2, | ||
953 | RT5651_PWR_BST2_BIT, 0, NULL, 0, rt5651_bst2_event, | ||
954 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
955 | SND_SOC_DAPM_PGA_E("BST3", RT5651_PWR_ANLG2, | ||
956 | RT5651_PWR_BST3_BIT, 0, NULL, 0, rt5651_bst3_event, | ||
957 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
958 | /* Input Volume */ | ||
959 | SND_SOC_DAPM_PGA("INL1 VOL", RT5651_PWR_VOL, | ||
960 | RT5651_PWR_IN1_L_BIT, 0, NULL, 0), | ||
961 | SND_SOC_DAPM_PGA("INR1 VOL", RT5651_PWR_VOL, | ||
962 | RT5651_PWR_IN1_R_BIT, 0, NULL, 0), | ||
963 | SND_SOC_DAPM_PGA("INL2 VOL", RT5651_PWR_VOL, | ||
964 | RT5651_PWR_IN2_L_BIT, 0, NULL, 0), | ||
965 | SND_SOC_DAPM_PGA("INR2 VOL", RT5651_PWR_VOL, | ||
966 | RT5651_PWR_IN2_R_BIT, 0, NULL, 0), | ||
967 | /* IN Mux */ | ||
968 | SND_SOC_DAPM_MUX("INL1 Mux", SND_SOC_NOPM, 0, 0, &rt5651_inl1_mux), | ||
969 | SND_SOC_DAPM_MUX("INR1 Mux", SND_SOC_NOPM, 0, 0, &rt5651_inr1_mux), | ||
970 | SND_SOC_DAPM_MUX("INL2 Mux", SND_SOC_NOPM, 0, 0, &rt5651_inl2_mux), | ||
971 | SND_SOC_DAPM_MUX("INR2 Mux", SND_SOC_NOPM, 0, 0, &rt5651_inr2_mux), | ||
972 | /* REC Mixer */ | ||
973 | SND_SOC_DAPM_MIXER("RECMIXL", RT5651_PWR_MIXER, RT5651_PWR_RM_L_BIT, 0, | ||
974 | rt5651_rec_l_mix, ARRAY_SIZE(rt5651_rec_l_mix)), | ||
975 | SND_SOC_DAPM_MIXER("RECMIXR", RT5651_PWR_MIXER, RT5651_PWR_RM_R_BIT, 0, | ||
976 | rt5651_rec_r_mix, ARRAY_SIZE(rt5651_rec_r_mix)), | ||
977 | /* ADCs */ | ||
978 | SND_SOC_DAPM_ADC("ADC L", NULL, SND_SOC_NOPM, 0, 0), | ||
979 | SND_SOC_DAPM_ADC("ADC R", NULL, SND_SOC_NOPM, 0, 0), | ||
980 | SND_SOC_DAPM_SUPPLY("ADC L Power", RT5651_PWR_DIG1, | ||
981 | RT5651_PWR_ADC_L_BIT, 0, NULL, 0), | ||
982 | SND_SOC_DAPM_SUPPLY("ADC R Power", RT5651_PWR_DIG1, | ||
983 | RT5651_PWR_ADC_R_BIT, 0, NULL, 0), | ||
984 | /* ADC Mux */ | ||
985 | SND_SOC_DAPM_MUX("Stereo1 ADC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
986 | &rt5651_sto1_adc_l2_mux), | ||
987 | SND_SOC_DAPM_MUX("Stereo1 ADC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
988 | &rt5651_sto1_adc_r2_mux), | ||
989 | SND_SOC_DAPM_MUX("Stereo1 ADC L1 Mux", SND_SOC_NOPM, 0, 0, | ||
990 | &rt5651_sto1_adc_l1_mux), | ||
991 | SND_SOC_DAPM_MUX("Stereo1 ADC R1 Mux", SND_SOC_NOPM, 0, 0, | ||
992 | &rt5651_sto1_adc_r1_mux), | ||
993 | SND_SOC_DAPM_MUX("Stereo2 ADC L2 Mux", SND_SOC_NOPM, 0, 0, | ||
994 | &rt5651_sto2_adc_l2_mux), | ||
995 | SND_SOC_DAPM_MUX("Stereo2 ADC L1 Mux", SND_SOC_NOPM, 0, 0, | ||
996 | &rt5651_sto2_adc_l1_mux), | ||
997 | SND_SOC_DAPM_MUX("Stereo2 ADC R1 Mux", SND_SOC_NOPM, 0, 0, | ||
998 | &rt5651_sto2_adc_r1_mux), | ||
999 | SND_SOC_DAPM_MUX("Stereo2 ADC R2 Mux", SND_SOC_NOPM, 0, 0, | ||
1000 | &rt5651_sto2_adc_r2_mux), | ||
1001 | /* ADC Mixer */ | ||
1002 | SND_SOC_DAPM_SUPPLY("Stereo1 Filter", RT5651_PWR_DIG2, | ||
1003 | RT5651_PWR_ADC_STO1_F_BIT, 0, NULL, 0), | ||
1004 | SND_SOC_DAPM_SUPPLY("Stereo2 Filter", RT5651_PWR_DIG2, | ||
1005 | RT5651_PWR_ADC_STO2_F_BIT, 0, NULL, 0), | ||
1006 | SND_SOC_DAPM_MIXER("Stereo1 ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
1007 | rt5651_sto1_adc_l_mix, | ||
1008 | ARRAY_SIZE(rt5651_sto1_adc_l_mix)), | ||
1009 | SND_SOC_DAPM_MIXER("Stereo1 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
1010 | rt5651_sto1_adc_r_mix, | ||
1011 | ARRAY_SIZE(rt5651_sto1_adc_r_mix)), | ||
1012 | SND_SOC_DAPM_MIXER("Stereo2 ADC MIXL", SND_SOC_NOPM, 0, 0, | ||
1013 | rt5651_sto2_adc_l_mix, | ||
1014 | ARRAY_SIZE(rt5651_sto2_adc_l_mix)), | ||
1015 | SND_SOC_DAPM_MIXER("Stereo2 ADC MIXR", SND_SOC_NOPM, 0, 0, | ||
1016 | rt5651_sto2_adc_r_mix, | ||
1017 | ARRAY_SIZE(rt5651_sto2_adc_r_mix)), | ||
1018 | |||
1019 | /* Digital Interface */ | ||
1020 | SND_SOC_DAPM_SUPPLY("I2S1", RT5651_PWR_DIG1, | ||
1021 | RT5651_PWR_I2S1_BIT, 0, NULL, 0), | ||
1022 | SND_SOC_DAPM_PGA("IF1 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1023 | SND_SOC_DAPM_PGA("IF1 DAC1 L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1024 | SND_SOC_DAPM_PGA("IF1 DAC1 R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1025 | SND_SOC_DAPM_PGA("IF1 ADC1", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1026 | SND_SOC_DAPM_PGA("IF1 DAC2 L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1027 | SND_SOC_DAPM_PGA("IF1 DAC2 R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1028 | SND_SOC_DAPM_PGA("IF1 ADC2", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1029 | SND_SOC_DAPM_SUPPLY("I2S2", RT5651_PWR_DIG1, | ||
1030 | RT5651_PWR_I2S2_BIT, 0, NULL, 0), | ||
1031 | SND_SOC_DAPM_PGA("IF2 DAC", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1032 | SND_SOC_DAPM_PGA("IF2 DAC L", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1033 | SND_SOC_DAPM_PGA("IF2 DAC R", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1034 | SND_SOC_DAPM_MUX("IF2 ADC", SND_SOC_NOPM, 0, 0, | ||
1035 | &rt5651_if2_adc_src_mux), | ||
1036 | |||
1037 | /* Digital Interface Select */ | ||
1038 | |||
1039 | SND_SOC_DAPM_MUX("PDM L Mux", RT5651_PDM_CTL, | ||
1040 | RT5651_M_PDM_L_SFT, 1, &rt5651_pdm_l_mux), | ||
1041 | SND_SOC_DAPM_MUX("PDM R Mux", RT5651_PDM_CTL, | ||
1042 | RT5651_M_PDM_R_SFT, 1, &rt5651_pdm_r_mux), | ||
1043 | /* Audio Interface */ | ||
1044 | SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1045 | SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1046 | SND_SOC_DAPM_AIF_IN("AIF2RX", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
1047 | SND_SOC_DAPM_AIF_OUT("AIF2TX", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
1048 | |||
1049 | /* Audio DSP */ | ||
1050 | SND_SOC_DAPM_PGA("Audio DSP", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1051 | |||
1052 | /* Output Side */ | ||
1053 | /* DAC mixer before sound effect */ | ||
1054 | SND_SOC_DAPM_MIXER("DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1055 | rt5651_dac_l_mix, ARRAY_SIZE(rt5651_dac_l_mix)), | ||
1056 | SND_SOC_DAPM_MIXER("DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1057 | rt5651_dac_r_mix, ARRAY_SIZE(rt5651_dac_r_mix)), | ||
1058 | |||
1059 | /* DAC2 channel Mux */ | ||
1060 | SND_SOC_DAPM_MUX("DAC L2 Mux", SND_SOC_NOPM, 0, 0, &rt5651_dac_l2_mux), | ||
1061 | SND_SOC_DAPM_MUX("DAC R2 Mux", SND_SOC_NOPM, 0, 0, &rt5651_dac_r2_mux), | ||
1062 | SND_SOC_DAPM_PGA("DAC L2 Volume", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1063 | SND_SOC_DAPM_PGA("DAC R2 Volume", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
1064 | |||
1065 | SND_SOC_DAPM_SUPPLY("Stero1 DAC Power", RT5651_PWR_DIG2, | ||
1066 | RT5651_PWR_DAC_STO1_F_BIT, 0, NULL, 0), | ||
1067 | SND_SOC_DAPM_SUPPLY("Stero2 DAC Power", RT5651_PWR_DIG2, | ||
1068 | RT5651_PWR_DAC_STO2_F_BIT, 0, NULL, 0), | ||
1069 | /* DAC Mixer */ | ||
1070 | SND_SOC_DAPM_MIXER("Stereo DAC MIXL", SND_SOC_NOPM, 0, 0, | ||
1071 | rt5651_sto_dac_l_mix, | ||
1072 | ARRAY_SIZE(rt5651_sto_dac_l_mix)), | ||
1073 | SND_SOC_DAPM_MIXER("Stereo DAC MIXR", SND_SOC_NOPM, 0, 0, | ||
1074 | rt5651_sto_dac_r_mix, | ||
1075 | ARRAY_SIZE(rt5651_sto_dac_r_mix)), | ||
1076 | SND_SOC_DAPM_MIXER("DD MIXL", SND_SOC_NOPM, 0, 0, | ||
1077 | rt5651_dd_dac_l_mix, | ||
1078 | ARRAY_SIZE(rt5651_dd_dac_l_mix)), | ||
1079 | SND_SOC_DAPM_MIXER("DD MIXR", SND_SOC_NOPM, 0, 0, | ||
1080 | rt5651_dd_dac_r_mix, | ||
1081 | ARRAY_SIZE(rt5651_dd_dac_r_mix)), | ||
1082 | |||
1083 | /* DACs */ | ||
1084 | SND_SOC_DAPM_DAC("DAC L1", NULL, SND_SOC_NOPM, 0, 0), | ||
1085 | SND_SOC_DAPM_DAC("DAC R1", NULL, SND_SOC_NOPM, 0, 0), | ||
1086 | SND_SOC_DAPM_SUPPLY("DAC L1 Power", RT5651_PWR_DIG1, | ||
1087 | RT5651_PWR_DAC_L1_BIT, 0, NULL, 0), | ||
1088 | SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5651_PWR_DIG1, | ||
1089 | RT5651_PWR_DAC_R1_BIT, 0, NULL, 0), | ||
1090 | /* OUT Mixer */ | ||
1091 | SND_SOC_DAPM_MIXER("OUT MIXL", RT5651_PWR_MIXER, RT5651_PWR_OM_L_BIT, | ||
1092 | 0, rt5651_out_l_mix, ARRAY_SIZE(rt5651_out_l_mix)), | ||
1093 | SND_SOC_DAPM_MIXER("OUT MIXR", RT5651_PWR_MIXER, RT5651_PWR_OM_R_BIT, | ||
1094 | 0, rt5651_out_r_mix, ARRAY_SIZE(rt5651_out_r_mix)), | ||
1095 | /* Ouput Volume */ | ||
1096 | SND_SOC_DAPM_SWITCH("OUTVOL L", RT5651_PWR_VOL, | ||
1097 | RT5651_PWR_OV_L_BIT, 0, &outvol_l_control), | ||
1098 | SND_SOC_DAPM_SWITCH("OUTVOL R", RT5651_PWR_VOL, | ||
1099 | RT5651_PWR_OV_R_BIT, 0, &outvol_r_control), | ||
1100 | SND_SOC_DAPM_SWITCH("HPOVOL L", RT5651_PWR_VOL, | ||
1101 | RT5651_PWR_HV_L_BIT, 0, &hpovol_l_control), | ||
1102 | SND_SOC_DAPM_SWITCH("HPOVOL R", RT5651_PWR_VOL, | ||
1103 | RT5651_PWR_HV_R_BIT, 0, &hpovol_r_control), | ||
1104 | SND_SOC_DAPM_PGA("INL1", RT5651_PWR_VOL, | ||
1105 | RT5651_PWR_IN1_L_BIT, 0, NULL, 0), | ||
1106 | SND_SOC_DAPM_PGA("INR1", RT5651_PWR_VOL, | ||
1107 | RT5651_PWR_IN1_R_BIT, 0, NULL, 0), | ||
1108 | SND_SOC_DAPM_PGA("INL2", RT5651_PWR_VOL, | ||
1109 | RT5651_PWR_IN2_L_BIT, 0, NULL, 0), | ||
1110 | SND_SOC_DAPM_PGA("INR2", RT5651_PWR_VOL, | ||
1111 | RT5651_PWR_IN2_R_BIT, 0, NULL, 0), | ||
1112 | /* HPO/LOUT/Mono Mixer */ | ||
1113 | SND_SOC_DAPM_MIXER("HPOL MIX", SND_SOC_NOPM, 0, 0, | ||
1114 | rt5651_hpo_mix, ARRAY_SIZE(rt5651_hpo_mix)), | ||
1115 | SND_SOC_DAPM_MIXER("HPOR MIX", SND_SOC_NOPM, 0, 0, | ||
1116 | rt5651_hpo_mix, ARRAY_SIZE(rt5651_hpo_mix)), | ||
1117 | SND_SOC_DAPM_SUPPLY("HP L Amp", RT5651_PWR_ANLG1, | ||
1118 | RT5651_PWR_HP_L_BIT, 0, NULL, 0), | ||
1119 | SND_SOC_DAPM_SUPPLY("HP R Amp", RT5651_PWR_ANLG1, | ||
1120 | RT5651_PWR_HP_R_BIT, 0, NULL, 0), | ||
1121 | SND_SOC_DAPM_MIXER("LOUT MIX", RT5651_PWR_ANLG1, RT5651_PWR_LM_BIT, 0, | ||
1122 | rt5651_lout_mix, ARRAY_SIZE(rt5651_lout_mix)), | ||
1123 | |||
1124 | SND_SOC_DAPM_SUPPLY("Amp Power", RT5651_PWR_ANLG1, | ||
1125 | RT5651_PWR_HA_BIT, 0, rt5651_amp_power_event, | ||
1126 | SND_SOC_DAPM_POST_PMU), | ||
1127 | SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, rt5651_hp_event, | ||
1128 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
1129 | SND_SOC_DAPM_SWITCH("HPO L Playback", SND_SOC_NOPM, 0, 0, | ||
1130 | &hpo_l_mute_control), | ||
1131 | SND_SOC_DAPM_SWITCH("HPO R Playback", SND_SOC_NOPM, 0, 0, | ||
1132 | &hpo_r_mute_control), | ||
1133 | SND_SOC_DAPM_SWITCH("LOUT L Playback", SND_SOC_NOPM, 0, 0, | ||
1134 | &lout_l_mute_control), | ||
1135 | SND_SOC_DAPM_SWITCH("LOUT R Playback", SND_SOC_NOPM, 0, 0, | ||
1136 | &lout_r_mute_control), | ||
1137 | SND_SOC_DAPM_POST("HP Post", rt5651_hp_post_event), | ||
1138 | |||
1139 | /* Output Lines */ | ||
1140 | SND_SOC_DAPM_OUTPUT("HPOL"), | ||
1141 | SND_SOC_DAPM_OUTPUT("HPOR"), | ||
1142 | SND_SOC_DAPM_OUTPUT("LOUTL"), | ||
1143 | SND_SOC_DAPM_OUTPUT("LOUTR"), | ||
1144 | SND_SOC_DAPM_OUTPUT("PDML"), | ||
1145 | SND_SOC_DAPM_OUTPUT("PDMR"), | ||
1146 | }; | ||
1147 | |||
1148 | static const struct snd_soc_dapm_route rt5651_dapm_routes[] = { | ||
1149 | {"Stero1 DAC Power", NULL, "STO1 DAC ASRC"}, | ||
1150 | {"Stero2 DAC Power", NULL, "STO2 DAC ASRC"}, | ||
1151 | {"I2S1", NULL, "I2S1 ASRC"}, | ||
1152 | {"I2S2", NULL, "I2S2 ASRC"}, | ||
1153 | |||
1154 | {"IN1P", NULL, "LDO"}, | ||
1155 | {"IN2P", NULL, "LDO"}, | ||
1156 | {"IN3P", NULL, "LDO"}, | ||
1157 | |||
1158 | {"IN1P", NULL, "MIC1"}, | ||
1159 | {"IN2P", NULL, "MIC2"}, | ||
1160 | {"IN2N", NULL, "MIC2"}, | ||
1161 | {"IN3P", NULL, "MIC3"}, | ||
1162 | |||
1163 | {"BST1", NULL, "IN1P"}, | ||
1164 | {"BST2", NULL, "IN2P"}, | ||
1165 | {"BST2", NULL, "IN2N"}, | ||
1166 | {"BST3", NULL, "IN3P"}, | ||
1167 | |||
1168 | {"INL1 VOL", NULL, "IN2P"}, | ||
1169 | {"INR1 VOL", NULL, "IN2N"}, | ||
1170 | |||
1171 | {"RECMIXL", "INL1 Switch", "INL1 VOL"}, | ||
1172 | {"RECMIXL", "BST3 Switch", "BST3"}, | ||
1173 | {"RECMIXL", "BST2 Switch", "BST2"}, | ||
1174 | {"RECMIXL", "BST1 Switch", "BST1"}, | ||
1175 | |||
1176 | {"RECMIXR", "INR1 Switch", "INR1 VOL"}, | ||
1177 | {"RECMIXR", "BST3 Switch", "BST3"}, | ||
1178 | {"RECMIXR", "BST2 Switch", "BST2"}, | ||
1179 | {"RECMIXR", "BST1 Switch", "BST1"}, | ||
1180 | |||
1181 | {"ADC L", NULL, "RECMIXL"}, | ||
1182 | {"ADC L", NULL, "ADC L Power"}, | ||
1183 | {"ADC R", NULL, "RECMIXR"}, | ||
1184 | {"ADC R", NULL, "ADC R Power"}, | ||
1185 | |||
1186 | {"DMIC L1", NULL, "DMIC CLK"}, | ||
1187 | {"DMIC R1", NULL, "DMIC CLK"}, | ||
1188 | |||
1189 | {"Stereo1 ADC L2 Mux", "DMIC", "DMIC L1"}, | ||
1190 | {"Stereo1 ADC L2 Mux", "DD MIX", "DD MIXL"}, | ||
1191 | {"Stereo1 ADC L1 Mux", "ADC", "ADC L"}, | ||
1192 | {"Stereo1 ADC L1 Mux", "DD MIX", "DD MIXL"}, | ||
1193 | |||
1194 | {"Stereo1 ADC R1 Mux", "ADC", "ADC R"}, | ||
1195 | {"Stereo1 ADC R1 Mux", "DD MIX", "DD MIXR"}, | ||
1196 | {"Stereo1 ADC R2 Mux", "DMIC", "DMIC R1"}, | ||
1197 | {"Stereo1 ADC R2 Mux", "DD MIX", "DD MIXR"}, | ||
1198 | |||
1199 | {"Stereo2 ADC L2 Mux", "DMIC L", "DMIC L1"}, | ||
1200 | {"Stereo2 ADC L2 Mux", "DD MIXL", "DD MIXL"}, | ||
1201 | {"Stereo2 ADC L1 Mux", "DD MIXL", "DD MIXL"}, | ||
1202 | {"Stereo2 ADC L1 Mux", "ADCL", "ADC L"}, | ||
1203 | |||
1204 | {"Stereo2 ADC R1 Mux", "DD MIXR", "DD MIXR"}, | ||
1205 | {"Stereo2 ADC R1 Mux", "ADCR", "ADC R"}, | ||
1206 | {"Stereo2 ADC R2 Mux", "DMIC R", "DMIC R1"}, | ||
1207 | {"Stereo2 ADC R2 Mux", "DD MIXR", "DD MIXR"}, | ||
1208 | |||
1209 | {"Stereo1 ADC MIXL", "ADC1 Switch", "Stereo1 ADC L1 Mux"}, | ||
1210 | {"Stereo1 ADC MIXL", "ADC2 Switch", "Stereo1 ADC L2 Mux"}, | ||
1211 | {"Stereo1 ADC MIXL", NULL, "Stereo1 Filter"}, | ||
1212 | {"Stereo1 Filter", NULL, "PLL1", is_sysclk_from_pll}, | ||
1213 | {"Stereo1 Filter", NULL, "ADC ASRC"}, | ||
1214 | |||
1215 | {"Stereo1 ADC MIXR", "ADC1 Switch", "Stereo1 ADC R1 Mux"}, | ||
1216 | {"Stereo1 ADC MIXR", "ADC2 Switch", "Stereo1 ADC R2 Mux"}, | ||
1217 | {"Stereo1 ADC MIXR", NULL, "Stereo1 Filter"}, | ||
1218 | |||
1219 | {"Stereo2 ADC MIXL", "ADC1 Switch", "Stereo2 ADC L1 Mux"}, | ||
1220 | {"Stereo2 ADC MIXL", "ADC2 Switch", "Stereo2 ADC L2 Mux"}, | ||
1221 | {"Stereo2 ADC MIXL", NULL, "Stereo2 Filter"}, | ||
1222 | {"Stereo2 Filter", NULL, "PLL1", is_sysclk_from_pll}, | ||
1223 | {"Stereo2 Filter", NULL, "ADC ASRC"}, | ||
1224 | |||
1225 | {"Stereo2 ADC MIXR", "ADC1 Switch", "Stereo2 ADC R1 Mux"}, | ||
1226 | {"Stereo2 ADC MIXR", "ADC2 Switch", "Stereo2 ADC R2 Mux"}, | ||
1227 | {"Stereo2 ADC MIXR", NULL, "Stereo2 Filter"}, | ||
1228 | |||
1229 | {"IF1 ADC2", NULL, "Stereo2 ADC MIXL"}, | ||
1230 | {"IF1 ADC2", NULL, "Stereo2 ADC MIXR"}, | ||
1231 | {"IF1 ADC1", NULL, "Stereo1 ADC MIXL"}, | ||
1232 | {"IF1 ADC1", NULL, "Stereo1 ADC MIXR"}, | ||
1233 | |||
1234 | {"IF1 ADC1", NULL, "I2S1"}, | ||
1235 | |||
1236 | {"IF2 ADC", "IF1 ADC1", "IF1 ADC1"}, | ||
1237 | {"IF2 ADC", "IF1 ADC2", "IF1 ADC2"}, | ||
1238 | {"IF2 ADC", NULL, "I2S2"}, | ||
1239 | |||
1240 | {"AIF1TX", NULL, "IF1 ADC1"}, | ||
1241 | {"AIF1TX", NULL, "IF1 ADC2"}, | ||
1242 | {"AIF2TX", NULL, "IF2 ADC"}, | ||
1243 | |||
1244 | {"IF1 DAC", NULL, "AIF1RX"}, | ||
1245 | {"IF1 DAC", NULL, "I2S1"}, | ||
1246 | {"IF2 DAC", NULL, "AIF2RX"}, | ||
1247 | {"IF2 DAC", NULL, "I2S2"}, | ||
1248 | |||
1249 | {"IF1 DAC1 L", NULL, "IF1 DAC"}, | ||
1250 | {"IF1 DAC1 R", NULL, "IF1 DAC"}, | ||
1251 | {"IF1 DAC2 L", NULL, "IF1 DAC"}, | ||
1252 | {"IF1 DAC2 R", NULL, "IF1 DAC"}, | ||
1253 | {"IF2 DAC L", NULL, "IF2 DAC"}, | ||
1254 | {"IF2 DAC R", NULL, "IF2 DAC"}, | ||
1255 | |||
1256 | {"DAC MIXL", "Stereo ADC Switch", "Stereo1 ADC MIXL"}, | ||
1257 | {"DAC MIXL", "INF1 Switch", "IF1 DAC1 L"}, | ||
1258 | {"DAC MIXR", "Stereo ADC Switch", "Stereo1 ADC MIXR"}, | ||
1259 | {"DAC MIXR", "INF1 Switch", "IF1 DAC1 R"}, | ||
1260 | |||
1261 | {"Audio DSP", NULL, "DAC MIXL"}, | ||
1262 | {"Audio DSP", NULL, "DAC MIXR"}, | ||
1263 | |||
1264 | {"DAC L2 Mux", "IF1", "IF1 DAC2 L"}, | ||
1265 | {"DAC L2 Mux", "IF2", "IF2 DAC L"}, | ||
1266 | {"DAC L2 Volume", NULL, "DAC L2 Mux"}, | ||
1267 | |||
1268 | {"DAC R2 Mux", "IF1", "IF1 DAC2 R"}, | ||
1269 | {"DAC R2 Mux", "IF2", "IF2 DAC R"}, | ||
1270 | {"DAC R2 Volume", NULL, "DAC R2 Mux"}, | ||
1271 | |||
1272 | {"Stereo DAC MIXL", "DAC L1 Switch", "Audio DSP"}, | ||
1273 | {"Stereo DAC MIXL", "DAC L2 Switch", "DAC L2 Volume"}, | ||
1274 | {"Stereo DAC MIXL", "DAC R1 Switch", "DAC MIXR"}, | ||
1275 | {"Stereo DAC MIXL", NULL, "Stero1 DAC Power"}, | ||
1276 | {"Stereo DAC MIXL", NULL, "Stero2 DAC Power"}, | ||
1277 | {"Stereo DAC MIXR", "DAC R1 Switch", "Audio DSP"}, | ||
1278 | {"Stereo DAC MIXR", "DAC R2 Switch", "DAC R2 Volume"}, | ||
1279 | {"Stereo DAC MIXR", "DAC L1 Switch", "DAC MIXL"}, | ||
1280 | {"Stereo DAC MIXR", NULL, "Stero1 DAC Power"}, | ||
1281 | {"Stereo DAC MIXR", NULL, "Stero2 DAC Power"}, | ||
1282 | |||
1283 | {"PDM L Mux", "Stereo DAC MIX", "Stereo DAC MIXL"}, | ||
1284 | {"PDM L Mux", "DD MIX", "DAC MIXL"}, | ||
1285 | {"PDM R Mux", "Stereo DAC MIX", "Stereo DAC MIXR"}, | ||
1286 | {"PDM R Mux", "DD MIX", "DAC MIXR"}, | ||
1287 | |||
1288 | {"DAC L1", NULL, "Stereo DAC MIXL"}, | ||
1289 | {"DAC L1", NULL, "PLL1", is_sysclk_from_pll}, | ||
1290 | {"DAC L1", NULL, "DAC L1 Power"}, | ||
1291 | {"DAC R1", NULL, "Stereo DAC MIXR"}, | ||
1292 | {"DAC R1", NULL, "PLL1", is_sysclk_from_pll}, | ||
1293 | {"DAC R1", NULL, "DAC R1 Power"}, | ||
1294 | |||
1295 | {"DD MIXL", "DAC L1 Switch", "DAC MIXL"}, | ||
1296 | {"DD MIXL", "DAC L2 Switch", "DAC L2 Volume"}, | ||
1297 | {"DD MIXL", "DAC R2 Switch", "DAC R2 Volume"}, | ||
1298 | {"DD MIXL", NULL, "Stero2 DAC Power"}, | ||
1299 | |||
1300 | {"DD MIXR", "DAC R1 Switch", "DAC MIXR"}, | ||
1301 | {"DD MIXR", "DAC R2 Switch", "DAC R2 Volume"}, | ||
1302 | {"DD MIXR", "DAC L2 Switch", "DAC L2 Volume"}, | ||
1303 | {"DD MIXR", NULL, "Stero2 DAC Power"}, | ||
1304 | |||
1305 | {"OUT MIXL", "BST1 Switch", "BST1"}, | ||
1306 | {"OUT MIXL", "BST2 Switch", "BST2"}, | ||
1307 | {"OUT MIXL", "INL1 Switch", "INL1 VOL"}, | ||
1308 | {"OUT MIXL", "REC MIXL Switch", "RECMIXL"}, | ||
1309 | {"OUT MIXL", "DAC L1 Switch", "DAC L1"}, | ||
1310 | |||
1311 | {"OUT MIXR", "BST2 Switch", "BST2"}, | ||
1312 | {"OUT MIXR", "BST1 Switch", "BST1"}, | ||
1313 | {"OUT MIXR", "INR1 Switch", "INR1 VOL"}, | ||
1314 | {"OUT MIXR", "REC MIXR Switch", "RECMIXR"}, | ||
1315 | {"OUT MIXR", "DAC R1 Switch", "DAC R1"}, | ||
1316 | |||
1317 | {"HPOVOL L", "Switch", "OUT MIXL"}, | ||
1318 | {"HPOVOL R", "Switch", "OUT MIXR"}, | ||
1319 | {"OUTVOL L", "Switch", "OUT MIXL"}, | ||
1320 | {"OUTVOL R", "Switch", "OUT MIXR"}, | ||
1321 | |||
1322 | {"HPOL MIX", "HPO MIX DAC1 Switch", "DAC L1"}, | ||
1323 | {"HPOL MIX", "HPO MIX HPVOL Switch", "HPOVOL L"}, | ||
1324 | {"HPOL MIX", NULL, "HP L Amp"}, | ||
1325 | {"HPOR MIX", "HPO MIX DAC1 Switch", "DAC R1"}, | ||
1326 | {"HPOR MIX", "HPO MIX HPVOL Switch", "HPOVOL R"}, | ||
1327 | {"HPOR MIX", NULL, "HP R Amp"}, | ||
1328 | |||
1329 | {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, | ||
1330 | {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, | ||
1331 | {"LOUT MIX", "OUTVOL L Switch", "OUTVOL L"}, | ||
1332 | {"LOUT MIX", "OUTVOL R Switch", "OUTVOL R"}, | ||
1333 | |||
1334 | {"HP Amp", NULL, "HPOL MIX"}, | ||
1335 | {"HP Amp", NULL, "HPOR MIX"}, | ||
1336 | {"HP Amp", NULL, "Amp Power"}, | ||
1337 | {"HPO L Playback", "Switch", "HP Amp"}, | ||
1338 | {"HPO R Playback", "Switch", "HP Amp"}, | ||
1339 | {"HPOL", NULL, "HPO L Playback"}, | ||
1340 | {"HPOR", NULL, "HPO R Playback"}, | ||
1341 | |||
1342 | {"LOUT L Playback", "Switch", "LOUT MIX"}, | ||
1343 | {"LOUT R Playback", "Switch", "LOUT MIX"}, | ||
1344 | {"LOUTL", NULL, "LOUT L Playback"}, | ||
1345 | {"LOUTL", NULL, "Amp Power"}, | ||
1346 | {"LOUTR", NULL, "LOUT R Playback"}, | ||
1347 | {"LOUTR", NULL, "Amp Power"}, | ||
1348 | |||
1349 | {"PDML", NULL, "PDM L Mux"}, | ||
1350 | {"PDMR", NULL, "PDM R Mux"}, | ||
1351 | }; | ||
1352 | |||
1353 | static int get_clk_info(int sclk, int rate) | ||
1354 | { | ||
1355 | int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16}; | ||
1356 | |||
1357 | if (sclk <= 0 || rate <= 0) | ||
1358 | return -EINVAL; | ||
1359 | |||
1360 | rate = rate << 8; | ||
1361 | for (i = 0; i < ARRAY_SIZE(pd); i++) | ||
1362 | if (sclk == rate * pd[i]) | ||
1363 | return i; | ||
1364 | |||
1365 | return -EINVAL; | ||
1366 | } | ||
1367 | |||
1368 | static int rt5651_hw_params(struct snd_pcm_substream *substream, | ||
1369 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
1370 | { | ||
1371 | struct snd_soc_codec *codec = dai->codec; | ||
1372 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1373 | unsigned int val_len = 0, val_clk, mask_clk; | ||
1374 | int pre_div, bclk_ms, frame_size; | ||
1375 | |||
1376 | rt5651->lrck[dai->id] = params_rate(params); | ||
1377 | pre_div = get_clk_info(rt5651->sysclk, rt5651->lrck[dai->id]); | ||
1378 | |||
1379 | if (pre_div < 0) { | ||
1380 | dev_err(codec->dev, "Unsupported clock setting\n"); | ||
1381 | return -EINVAL; | ||
1382 | } | ||
1383 | frame_size = snd_soc_params_to_frame_size(params); | ||
1384 | if (frame_size < 0) { | ||
1385 | dev_err(codec->dev, "Unsupported frame size: %d\n", frame_size); | ||
1386 | return -EINVAL; | ||
1387 | } | ||
1388 | bclk_ms = frame_size > 32 ? 1 : 0; | ||
1389 | rt5651->bclk[dai->id] = rt5651->lrck[dai->id] * (32 << bclk_ms); | ||
1390 | |||
1391 | dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n", | ||
1392 | rt5651->bclk[dai->id], rt5651->lrck[dai->id]); | ||
1393 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n", | ||
1394 | bclk_ms, pre_div, dai->id); | ||
1395 | |||
1396 | switch (params_format(params)) { | ||
1397 | case SNDRV_PCM_FORMAT_S16_LE: | ||
1398 | break; | ||
1399 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
1400 | val_len |= RT5651_I2S_DL_20; | ||
1401 | break; | ||
1402 | case SNDRV_PCM_FORMAT_S24_LE: | ||
1403 | val_len |= RT5651_I2S_DL_24; | ||
1404 | break; | ||
1405 | case SNDRV_PCM_FORMAT_S8: | ||
1406 | val_len |= RT5651_I2S_DL_8; | ||
1407 | break; | ||
1408 | default: | ||
1409 | return -EINVAL; | ||
1410 | } | ||
1411 | |||
1412 | switch (dai->id) { | ||
1413 | case RT5651_AIF1: | ||
1414 | mask_clk = RT5651_I2S_PD1_MASK; | ||
1415 | val_clk = pre_div << RT5651_I2S_PD1_SFT; | ||
1416 | snd_soc_update_bits(codec, RT5651_I2S1_SDP, | ||
1417 | RT5651_I2S_DL_MASK, val_len); | ||
1418 | snd_soc_update_bits(codec, RT5651_ADDA_CLK1, mask_clk, val_clk); | ||
1419 | break; | ||
1420 | case RT5651_AIF2: | ||
1421 | mask_clk = RT5651_I2S_BCLK_MS2_MASK | RT5651_I2S_PD2_MASK; | ||
1422 | val_clk = pre_div << RT5651_I2S_PD2_SFT; | ||
1423 | snd_soc_update_bits(codec, RT5651_I2S2_SDP, | ||
1424 | RT5651_I2S_DL_MASK, val_len); | ||
1425 | snd_soc_update_bits(codec, RT5651_ADDA_CLK1, mask_clk, val_clk); | ||
1426 | break; | ||
1427 | default: | ||
1428 | dev_err(codec->dev, "Wrong dai->id: %d\n", dai->id); | ||
1429 | return -EINVAL; | ||
1430 | } | ||
1431 | |||
1432 | return 0; | ||
1433 | } | ||
1434 | |||
1435 | static int rt5651_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
1436 | { | ||
1437 | struct snd_soc_codec *codec = dai->codec; | ||
1438 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1439 | unsigned int reg_val = 0; | ||
1440 | |||
1441 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
1442 | case SND_SOC_DAIFMT_CBM_CFM: | ||
1443 | rt5651->master[dai->id] = 1; | ||
1444 | break; | ||
1445 | case SND_SOC_DAIFMT_CBS_CFS: | ||
1446 | reg_val |= RT5651_I2S_MS_S; | ||
1447 | rt5651->master[dai->id] = 0; | ||
1448 | break; | ||
1449 | default: | ||
1450 | return -EINVAL; | ||
1451 | } | ||
1452 | |||
1453 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
1454 | case SND_SOC_DAIFMT_NB_NF: | ||
1455 | break; | ||
1456 | case SND_SOC_DAIFMT_IB_NF: | ||
1457 | reg_val |= RT5651_I2S_BP_INV; | ||
1458 | break; | ||
1459 | default: | ||
1460 | return -EINVAL; | ||
1461 | } | ||
1462 | |||
1463 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
1464 | case SND_SOC_DAIFMT_I2S: | ||
1465 | break; | ||
1466 | case SND_SOC_DAIFMT_LEFT_J: | ||
1467 | reg_val |= RT5651_I2S_DF_LEFT; | ||
1468 | break; | ||
1469 | case SND_SOC_DAIFMT_DSP_A: | ||
1470 | reg_val |= RT5651_I2S_DF_PCM_A; | ||
1471 | break; | ||
1472 | case SND_SOC_DAIFMT_DSP_B: | ||
1473 | reg_val |= RT5651_I2S_DF_PCM_B; | ||
1474 | break; | ||
1475 | default: | ||
1476 | return -EINVAL; | ||
1477 | } | ||
1478 | |||
1479 | switch (dai->id) { | ||
1480 | case RT5651_AIF1: | ||
1481 | snd_soc_update_bits(codec, RT5651_I2S1_SDP, | ||
1482 | RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK | | ||
1483 | RT5651_I2S_DF_MASK, reg_val); | ||
1484 | break; | ||
1485 | case RT5651_AIF2: | ||
1486 | snd_soc_update_bits(codec, RT5651_I2S2_SDP, | ||
1487 | RT5651_I2S_MS_MASK | RT5651_I2S_BP_MASK | | ||
1488 | RT5651_I2S_DF_MASK, reg_val); | ||
1489 | break; | ||
1490 | default: | ||
1491 | dev_err(codec->dev, "Wrong dai->id: %d\n", dai->id); | ||
1492 | return -EINVAL; | ||
1493 | } | ||
1494 | return 0; | ||
1495 | } | ||
1496 | |||
1497 | static int rt5651_set_dai_sysclk(struct snd_soc_dai *dai, | ||
1498 | int clk_id, unsigned int freq, int dir) | ||
1499 | { | ||
1500 | struct snd_soc_codec *codec = dai->codec; | ||
1501 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1502 | unsigned int reg_val = 0; | ||
1503 | |||
1504 | if (freq == rt5651->sysclk && clk_id == rt5651->sysclk_src) | ||
1505 | return 0; | ||
1506 | |||
1507 | switch (clk_id) { | ||
1508 | case RT5651_SCLK_S_MCLK: | ||
1509 | reg_val |= RT5651_SCLK_SRC_MCLK; | ||
1510 | break; | ||
1511 | case RT5651_SCLK_S_PLL1: | ||
1512 | reg_val |= RT5651_SCLK_SRC_PLL1; | ||
1513 | break; | ||
1514 | case RT5651_SCLK_S_RCCLK: | ||
1515 | reg_val |= RT5651_SCLK_SRC_RCCLK; | ||
1516 | break; | ||
1517 | default: | ||
1518 | dev_err(codec->dev, "Invalid clock id (%d)\n", clk_id); | ||
1519 | return -EINVAL; | ||
1520 | } | ||
1521 | snd_soc_update_bits(codec, RT5651_GLB_CLK, | ||
1522 | RT5651_SCLK_SRC_MASK, reg_val); | ||
1523 | rt5651->sysclk = freq; | ||
1524 | rt5651->sysclk_src = clk_id; | ||
1525 | |||
1526 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n", freq, clk_id); | ||
1527 | |||
1528 | return 0; | ||
1529 | } | ||
1530 | |||
1531 | /** | ||
1532 | * rt5651_pll_calc - Calcualte PLL M/N/K code. | ||
1533 | * @freq_in: external clock provided to codec. | ||
1534 | * @freq_out: target clock which codec works on. | ||
1535 | * @pll_code: Pointer to structure with M, N, K and bypass flag. | ||
1536 | * | ||
1537 | * Calcualte M/N/K code to configure PLL for codec. And K is assigned to 2 | ||
1538 | * which make calculation more efficiently. | ||
1539 | * | ||
1540 | * Returns 0 for success or negative error code. | ||
1541 | */ | ||
1542 | static int rt5651_pll_calc(const unsigned int freq_in, | ||
1543 | const unsigned int freq_out, struct rt5651_pll_code *pll_code) | ||
1544 | { | ||
1545 | int max_n = RT5651_PLL_N_MAX, max_m = RT5651_PLL_M_MAX; | ||
1546 | int n = 0, m = 0, red, n_t, m_t, in_t, out_t; | ||
1547 | int red_t = abs(freq_out - freq_in); | ||
1548 | bool bypass = false; | ||
1549 | |||
1550 | if (RT5651_PLL_INP_MAX < freq_in || RT5651_PLL_INP_MIN > freq_in) | ||
1551 | return -EINVAL; | ||
1552 | |||
1553 | for (n_t = 0; n_t <= max_n; n_t++) { | ||
1554 | in_t = (freq_in >> 1) + (freq_in >> 2) * n_t; | ||
1555 | if (in_t < 0) | ||
1556 | continue; | ||
1557 | if (in_t == freq_out) { | ||
1558 | bypass = true; | ||
1559 | n = n_t; | ||
1560 | goto code_find; | ||
1561 | } | ||
1562 | for (m_t = 0; m_t <= max_m; m_t++) { | ||
1563 | out_t = in_t / (m_t + 2); | ||
1564 | red = abs(out_t - freq_out); | ||
1565 | if (red < red_t) { | ||
1566 | n = n_t; | ||
1567 | m = m_t; | ||
1568 | if (red == 0) | ||
1569 | goto code_find; | ||
1570 | red_t = red; | ||
1571 | } | ||
1572 | } | ||
1573 | } | ||
1574 | pr_debug("Only get approximation about PLL\n"); | ||
1575 | |||
1576 | code_find: | ||
1577 | pll_code->m_bp = bypass; | ||
1578 | pll_code->m_code = m; | ||
1579 | pll_code->n_code = n; | ||
1580 | pll_code->k_code = 2; | ||
1581 | return 0; | ||
1582 | } | ||
1583 | |||
1584 | static int rt5651_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, | ||
1585 | unsigned int freq_in, unsigned int freq_out) | ||
1586 | { | ||
1587 | struct snd_soc_codec *codec = dai->codec; | ||
1588 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1589 | struct rt5651_pll_code *pll_code = &rt5651->pll_code; | ||
1590 | int ret; | ||
1591 | |||
1592 | if (source == rt5651->pll_src && freq_in == rt5651->pll_in && | ||
1593 | freq_out == rt5651->pll_out) | ||
1594 | return 0; | ||
1595 | |||
1596 | if (!freq_in || !freq_out) { | ||
1597 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
1598 | |||
1599 | rt5651->pll_in = 0; | ||
1600 | rt5651->pll_out = 0; | ||
1601 | snd_soc_update_bits(codec, RT5651_GLB_CLK, | ||
1602 | RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_MCLK); | ||
1603 | return 0; | ||
1604 | } | ||
1605 | |||
1606 | switch (source) { | ||
1607 | case RT5651_PLL1_S_MCLK: | ||
1608 | snd_soc_update_bits(codec, RT5651_GLB_CLK, | ||
1609 | RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_MCLK); | ||
1610 | break; | ||
1611 | case RT5651_PLL1_S_BCLK1: | ||
1612 | snd_soc_update_bits(codec, RT5651_GLB_CLK, | ||
1613 | RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK1); | ||
1614 | break; | ||
1615 | case RT5651_PLL1_S_BCLK2: | ||
1616 | snd_soc_update_bits(codec, RT5651_GLB_CLK, | ||
1617 | RT5651_PLL1_SRC_MASK, RT5651_PLL1_SRC_BCLK2); | ||
1618 | break; | ||
1619 | default: | ||
1620 | dev_err(codec->dev, "Unknown PLL source %d\n", source); | ||
1621 | return -EINVAL; | ||
1622 | } | ||
1623 | |||
1624 | ret = rt5651_pll_calc(freq_in, freq_out, pll_code); | ||
1625 | if (ret < 0) { | ||
1626 | dev_err(codec->dev, "Unsupport input clock %d\n", freq_in); | ||
1627 | return ret; | ||
1628 | } | ||
1629 | |||
1630 | dev_dbg(codec->dev, "bypass=%d m=%d n=%d k=2\n", pll_code->m_bp, | ||
1631 | (pll_code->m_bp ? 0 : pll_code->m_code), pll_code->n_code); | ||
1632 | |||
1633 | snd_soc_write(codec, RT5651_PLL_CTRL1, | ||
1634 | pll_code->n_code << RT5651_PLL_N_SFT | pll_code->k_code); | ||
1635 | snd_soc_write(codec, RT5651_PLL_CTRL2, | ||
1636 | (pll_code->m_bp ? 0 : pll_code->m_code) << RT5651_PLL_M_SFT | | ||
1637 | pll_code->m_bp << RT5651_PLL_M_BP_SFT); | ||
1638 | |||
1639 | rt5651->pll_in = freq_in; | ||
1640 | rt5651->pll_out = freq_out; | ||
1641 | rt5651->pll_src = source; | ||
1642 | |||
1643 | return 0; | ||
1644 | } | ||
1645 | |||
1646 | static int rt5651_set_bias_level(struct snd_soc_codec *codec, | ||
1647 | enum snd_soc_bias_level level) | ||
1648 | { | ||
1649 | switch (level) { | ||
1650 | case SND_SOC_BIAS_PREPARE: | ||
1651 | if (SND_SOC_BIAS_STANDBY == codec->dapm.bias_level) { | ||
1652 | snd_soc_update_bits(codec, RT5651_PWR_ANLG1, | ||
1653 | RT5651_PWR_VREF1 | RT5651_PWR_MB | | ||
1654 | RT5651_PWR_BG | RT5651_PWR_VREF2, | ||
1655 | RT5651_PWR_VREF1 | RT5651_PWR_MB | | ||
1656 | RT5651_PWR_BG | RT5651_PWR_VREF2); | ||
1657 | usleep_range(10000, 15000); | ||
1658 | snd_soc_update_bits(codec, RT5651_PWR_ANLG1, | ||
1659 | RT5651_PWR_FV1 | RT5651_PWR_FV2, | ||
1660 | RT5651_PWR_FV1 | RT5651_PWR_FV2); | ||
1661 | snd_soc_update_bits(codec, RT5651_PWR_ANLG1, | ||
1662 | RT5651_PWR_LDO_DVO_MASK, | ||
1663 | RT5651_PWR_LDO_DVO_1_2V); | ||
1664 | snd_soc_update_bits(codec, RT5651_D_MISC, 0x1, 0x1); | ||
1665 | if (snd_soc_read(codec, RT5651_PLL_MODE_1) & 0x9200) | ||
1666 | snd_soc_update_bits(codec, RT5651_D_MISC, | ||
1667 | 0xc00, 0xc00); | ||
1668 | } | ||
1669 | break; | ||
1670 | |||
1671 | case SND_SOC_BIAS_STANDBY: | ||
1672 | snd_soc_write(codec, RT5651_D_MISC, 0x0010); | ||
1673 | snd_soc_write(codec, RT5651_PWR_DIG1, 0x0000); | ||
1674 | snd_soc_write(codec, RT5651_PWR_DIG2, 0x0000); | ||
1675 | snd_soc_write(codec, RT5651_PWR_VOL, 0x0000); | ||
1676 | snd_soc_write(codec, RT5651_PWR_MIXER, 0x0000); | ||
1677 | snd_soc_write(codec, RT5651_PWR_ANLG1, 0x0000); | ||
1678 | snd_soc_write(codec, RT5651_PWR_ANLG2, 0x0000); | ||
1679 | break; | ||
1680 | |||
1681 | default: | ||
1682 | break; | ||
1683 | } | ||
1684 | codec->dapm.bias_level = level; | ||
1685 | |||
1686 | return 0; | ||
1687 | } | ||
1688 | |||
1689 | static int rt5651_probe(struct snd_soc_codec *codec) | ||
1690 | { | ||
1691 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1692 | |||
1693 | rt5651->codec = codec; | ||
1694 | |||
1695 | snd_soc_update_bits(codec, RT5651_PWR_ANLG1, | ||
1696 | RT5651_PWR_VREF1 | RT5651_PWR_MB | | ||
1697 | RT5651_PWR_BG | RT5651_PWR_VREF2, | ||
1698 | RT5651_PWR_VREF1 | RT5651_PWR_MB | | ||
1699 | RT5651_PWR_BG | RT5651_PWR_VREF2); | ||
1700 | usleep_range(10000, 15000); | ||
1701 | snd_soc_update_bits(codec, RT5651_PWR_ANLG1, | ||
1702 | RT5651_PWR_FV1 | RT5651_PWR_FV2, | ||
1703 | RT5651_PWR_FV1 | RT5651_PWR_FV2); | ||
1704 | |||
1705 | rt5651_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1706 | |||
1707 | return 0; | ||
1708 | } | ||
1709 | |||
1710 | #ifdef CONFIG_PM | ||
1711 | static int rt5651_suspend(struct snd_soc_codec *codec) | ||
1712 | { | ||
1713 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1714 | |||
1715 | regcache_cache_only(rt5651->regmap, true); | ||
1716 | regcache_mark_dirty(rt5651->regmap); | ||
1717 | return 0; | ||
1718 | } | ||
1719 | |||
1720 | static int rt5651_resume(struct snd_soc_codec *codec) | ||
1721 | { | ||
1722 | struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); | ||
1723 | |||
1724 | regcache_cache_only(rt5651->regmap, false); | ||
1725 | snd_soc_cache_sync(codec); | ||
1726 | |||
1727 | return 0; | ||
1728 | } | ||
1729 | #else | ||
1730 | #define rt5651_suspend NULL | ||
1731 | #define rt5651_resume NULL | ||
1732 | #endif | ||
1733 | |||
1734 | #define RT5651_STEREO_RATES SNDRV_PCM_RATE_8000_96000 | ||
1735 | #define RT5651_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
1736 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) | ||
1737 | |||
1738 | static const struct snd_soc_dai_ops rt5651_aif_dai_ops = { | ||
1739 | .hw_params = rt5651_hw_params, | ||
1740 | .set_fmt = rt5651_set_dai_fmt, | ||
1741 | .set_sysclk = rt5651_set_dai_sysclk, | ||
1742 | .set_pll = rt5651_set_dai_pll, | ||
1743 | }; | ||
1744 | |||
1745 | static struct snd_soc_dai_driver rt5651_dai[] = { | ||
1746 | { | ||
1747 | .name = "rt5651-aif1", | ||
1748 | .id = RT5651_AIF1, | ||
1749 | .playback = { | ||
1750 | .stream_name = "AIF1 Playback", | ||
1751 | .channels_min = 1, | ||
1752 | .channels_max = 2, | ||
1753 | .rates = RT5651_STEREO_RATES, | ||
1754 | .formats = RT5651_FORMATS, | ||
1755 | }, | ||
1756 | .capture = { | ||
1757 | .stream_name = "AIF1 Capture", | ||
1758 | .channels_min = 1, | ||
1759 | .channels_max = 2, | ||
1760 | .rates = RT5651_STEREO_RATES, | ||
1761 | .formats = RT5651_FORMATS, | ||
1762 | }, | ||
1763 | .ops = &rt5651_aif_dai_ops, | ||
1764 | }, | ||
1765 | { | ||
1766 | .name = "rt5651-aif2", | ||
1767 | .id = RT5651_AIF2, | ||
1768 | .playback = { | ||
1769 | .stream_name = "AIF2 Playback", | ||
1770 | .channels_min = 1, | ||
1771 | .channels_max = 2, | ||
1772 | .rates = RT5651_STEREO_RATES, | ||
1773 | .formats = RT5651_FORMATS, | ||
1774 | }, | ||
1775 | .capture = { | ||
1776 | .stream_name = "AIF2 Capture", | ||
1777 | .channels_min = 1, | ||
1778 | .channels_max = 2, | ||
1779 | .rates = RT5651_STEREO_RATES, | ||
1780 | .formats = RT5651_FORMATS, | ||
1781 | }, | ||
1782 | .ops = &rt5651_aif_dai_ops, | ||
1783 | }, | ||
1784 | }; | ||
1785 | |||
1786 | static struct snd_soc_codec_driver soc_codec_dev_rt5651 = { | ||
1787 | .probe = rt5651_probe, | ||
1788 | .suspend = rt5651_suspend, | ||
1789 | .resume = rt5651_resume, | ||
1790 | .set_bias_level = rt5651_set_bias_level, | ||
1791 | .idle_bias_off = true, | ||
1792 | .controls = rt5651_snd_controls, | ||
1793 | .num_controls = ARRAY_SIZE(rt5651_snd_controls), | ||
1794 | .dapm_widgets = rt5651_dapm_widgets, | ||
1795 | .num_dapm_widgets = ARRAY_SIZE(rt5651_dapm_widgets), | ||
1796 | .dapm_routes = rt5651_dapm_routes, | ||
1797 | .num_dapm_routes = ARRAY_SIZE(rt5651_dapm_routes), | ||
1798 | }; | ||
1799 | |||
1800 | static const struct regmap_config rt5651_regmap = { | ||
1801 | .reg_bits = 8, | ||
1802 | .val_bits = 16, | ||
1803 | |||
1804 | .max_register = RT5651_DEVICE_ID + 1 + (ARRAY_SIZE(rt5651_ranges) * | ||
1805 | RT5651_PR_SPACING), | ||
1806 | .volatile_reg = rt5651_volatile_register, | ||
1807 | .readable_reg = rt5651_readable_register, | ||
1808 | |||
1809 | .cache_type = REGCACHE_RBTREE, | ||
1810 | .reg_defaults = rt5651_reg, | ||
1811 | .num_reg_defaults = ARRAY_SIZE(rt5651_reg), | ||
1812 | .ranges = rt5651_ranges, | ||
1813 | .num_ranges = ARRAY_SIZE(rt5651_ranges), | ||
1814 | }; | ||
1815 | |||
1816 | static const struct i2c_device_id rt5651_i2c_id[] = { | ||
1817 | { "rt5651", 0 }, | ||
1818 | { } | ||
1819 | }; | ||
1820 | MODULE_DEVICE_TABLE(i2c, rt5651_i2c_id); | ||
1821 | |||
1822 | static int rt5651_i2c_probe(struct i2c_client *i2c, | ||
1823 | const struct i2c_device_id *id) | ||
1824 | { | ||
1825 | struct rt5651_platform_data *pdata = dev_get_platdata(&i2c->dev); | ||
1826 | struct rt5651_priv *rt5651; | ||
1827 | int ret; | ||
1828 | |||
1829 | rt5651 = devm_kzalloc(&i2c->dev, sizeof(*rt5651), | ||
1830 | GFP_KERNEL); | ||
1831 | if (NULL == rt5651) | ||
1832 | return -ENOMEM; | ||
1833 | |||
1834 | i2c_set_clientdata(i2c, rt5651); | ||
1835 | |||
1836 | if (pdata) | ||
1837 | rt5651->pdata = *pdata; | ||
1838 | |||
1839 | rt5651->regmap = devm_regmap_init_i2c(i2c, &rt5651_regmap); | ||
1840 | if (IS_ERR(rt5651->regmap)) { | ||
1841 | ret = PTR_ERR(rt5651->regmap); | ||
1842 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n", | ||
1843 | ret); | ||
1844 | return ret; | ||
1845 | } | ||
1846 | |||
1847 | regmap_read(rt5651->regmap, RT5651_DEVICE_ID, &ret); | ||
1848 | if (ret != RT5651_DEVICE_ID_VALUE) { | ||
1849 | dev_err(&i2c->dev, | ||
1850 | "Device with ID register %x is not rt5651\n", ret); | ||
1851 | return -ENODEV; | ||
1852 | } | ||
1853 | |||
1854 | regmap_write(rt5651->regmap, RT5651_RESET, 0); | ||
1855 | |||
1856 | ret = regmap_register_patch(rt5651->regmap, init_list, | ||
1857 | ARRAY_SIZE(init_list)); | ||
1858 | if (ret != 0) | ||
1859 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n", ret); | ||
1860 | |||
1861 | if (rt5651->pdata.in2_diff) | ||
1862 | regmap_update_bits(rt5651->regmap, RT5651_IN1_IN2, | ||
1863 | RT5651_IN_DF2, RT5651_IN_DF2); | ||
1864 | |||
1865 | if (rt5651->pdata.dmic_en) | ||
1866 | regmap_update_bits(rt5651->regmap, RT5651_GPIO_CTRL1, | ||
1867 | RT5651_GP2_PIN_MASK, RT5651_GP2_PIN_DMIC1_SCL); | ||
1868 | |||
1869 | rt5651->hp_mute = 1; | ||
1870 | |||
1871 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5651, | ||
1872 | rt5651_dai, ARRAY_SIZE(rt5651_dai)); | ||
1873 | |||
1874 | return ret; | ||
1875 | } | ||
1876 | |||
1877 | static int rt5651_i2c_remove(struct i2c_client *i2c) | ||
1878 | { | ||
1879 | snd_soc_unregister_codec(&i2c->dev); | ||
1880 | |||
1881 | return 0; | ||
1882 | } | ||
1883 | |||
1884 | static struct i2c_driver rt5651_i2c_driver = { | ||
1885 | .driver = { | ||
1886 | .name = "rt5651", | ||
1887 | .owner = THIS_MODULE, | ||
1888 | }, | ||
1889 | .probe = rt5651_i2c_probe, | ||
1890 | .remove = rt5651_i2c_remove, | ||
1891 | .id_table = rt5651_i2c_id, | ||
1892 | }; | ||
1893 | module_i2c_driver(rt5651_i2c_driver); | ||
1894 | |||
1895 | MODULE_DESCRIPTION("ASoC RT5651 driver"); | ||
1896 | MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>"); | ||
1897 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/sound/soc/codecs/rt5651.h b/sound/soc/codecs/rt5651.h new file mode 100644 index 000000000000..a28bd0c3d613 --- /dev/null +++ b/sound/soc/codecs/rt5651.h | |||
@@ -0,0 +1,2081 @@ | |||
1 | /* | ||
2 | * rt5651.h -- RT5651 ALSA SoC audio driver | ||
3 | * | ||
4 | * Copyright 2011 Realtek Microelectronics | ||
5 | * Author: Johnny Hsu <johnnyhsu@realtek.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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __RT5651_H__ | ||
13 | #define __RT5651_H__ | ||
14 | |||
15 | #include <sound/rt5651.h> | ||
16 | |||
17 | /* Info */ | ||
18 | #define RT5651_RESET 0x00 | ||
19 | #define RT5651_VERSION_ID 0xfd | ||
20 | #define RT5651_VENDOR_ID 0xfe | ||
21 | #define RT5651_DEVICE_ID 0xff | ||
22 | /* I/O - Output */ | ||
23 | #define RT5651_HP_VOL 0x02 | ||
24 | #define RT5651_LOUT_CTRL1 0x03 | ||
25 | #define RT5651_LOUT_CTRL2 0x05 | ||
26 | /* I/O - Input */ | ||
27 | #define RT5651_IN1_IN2 0x0d | ||
28 | #define RT5651_IN3 0x0e | ||
29 | #define RT5651_INL1_INR1_VOL 0x0f | ||
30 | #define RT5651_INL2_INR2_VOL 0x10 | ||
31 | /* I/O - ADC/DAC/DMIC */ | ||
32 | #define RT5651_DAC1_DIG_VOL 0x19 | ||
33 | #define RT5651_DAC2_DIG_VOL 0x1a | ||
34 | #define RT5651_DAC2_CTRL 0x1b | ||
35 | #define RT5651_ADC_DIG_VOL 0x1c | ||
36 | #define RT5651_ADC_DATA 0x1d | ||
37 | #define RT5651_ADC_BST_VOL 0x1e | ||
38 | /* Mixer - D-D */ | ||
39 | #define RT5651_STO1_ADC_MIXER 0x27 | ||
40 | #define RT5651_STO2_ADC_MIXER 0x28 | ||
41 | #define RT5651_AD_DA_MIXER 0x29 | ||
42 | #define RT5651_STO_DAC_MIXER 0x2a | ||
43 | #define RT5651_DD_MIXER 0x2b | ||
44 | #define RT5651_DIG_INF_DATA 0x2f | ||
45 | /* PDM */ | ||
46 | #define RT5651_PDM_CTL 0x30 | ||
47 | #define RT5651_PDM_I2C_CTL1 0x31 | ||
48 | #define RT5651_PDM_I2C_CTL2 0x32 | ||
49 | #define RT5651_PDM_I2C_DATA_W 0x33 | ||
50 | #define RT5651_PDM_I2C_DATA_R 0x34 | ||
51 | /* Mixer - ADC */ | ||
52 | #define RT5651_REC_L1_MIXER 0x3b | ||
53 | #define RT5651_REC_L2_MIXER 0x3c | ||
54 | #define RT5651_REC_R1_MIXER 0x3d | ||
55 | #define RT5651_REC_R2_MIXER 0x3e | ||
56 | /* Mixer - DAC */ | ||
57 | #define RT5651_HPO_MIXER 0x45 | ||
58 | #define RT5651_OUT_L1_MIXER 0x4d | ||
59 | #define RT5651_OUT_L2_MIXER 0x4e | ||
60 | #define RT5651_OUT_L3_MIXER 0x4f | ||
61 | #define RT5651_OUT_R1_MIXER 0x50 | ||
62 | #define RT5651_OUT_R2_MIXER 0x51 | ||
63 | #define RT5651_OUT_R3_MIXER 0x52 | ||
64 | #define RT5651_LOUT_MIXER 0x53 | ||
65 | /* Power */ | ||
66 | #define RT5651_PWR_DIG1 0x61 | ||
67 | #define RT5651_PWR_DIG2 0x62 | ||
68 | #define RT5651_PWR_ANLG1 0x63 | ||
69 | #define RT5651_PWR_ANLG2 0x64 | ||
70 | #define RT5651_PWR_MIXER 0x65 | ||
71 | #define RT5651_PWR_VOL 0x66 | ||
72 | /* Private Register Control */ | ||
73 | #define RT5651_PRIV_INDEX 0x6a | ||
74 | #define RT5651_PRIV_DATA 0x6c | ||
75 | /* Format - ADC/DAC */ | ||
76 | #define RT5651_I2S1_SDP 0x70 | ||
77 | #define RT5651_I2S2_SDP 0x71 | ||
78 | #define RT5651_ADDA_CLK1 0x73 | ||
79 | #define RT5651_ADDA_CLK2 0x74 | ||
80 | #define RT5651_DMIC 0x75 | ||
81 | /* TDM Control */ | ||
82 | #define RT5651_TDM_CTL_1 0x77 | ||
83 | #define RT5651_TDM_CTL_2 0x78 | ||
84 | #define RT5651_TDM_CTL_3 0x79 | ||
85 | /* Function - Analog */ | ||
86 | #define RT5651_GLB_CLK 0x80 | ||
87 | #define RT5651_PLL_CTRL1 0x81 | ||
88 | #define RT5651_PLL_CTRL2 0x82 | ||
89 | #define RT5651_PLL_MODE_1 0x83 | ||
90 | #define RT5651_PLL_MODE_2 0x84 | ||
91 | #define RT5651_PLL_MODE_3 0x85 | ||
92 | #define RT5651_PLL_MODE_4 0x86 | ||
93 | #define RT5651_PLL_MODE_5 0x87 | ||
94 | #define RT5651_PLL_MODE_6 0x89 | ||
95 | #define RT5651_PLL_MODE_7 0x8a | ||
96 | #define RT5651_DEPOP_M1 0x8e | ||
97 | #define RT5651_DEPOP_M2 0x8f | ||
98 | #define RT5651_DEPOP_M3 0x90 | ||
99 | #define RT5651_CHARGE_PUMP 0x91 | ||
100 | #define RT5651_MICBIAS 0x93 | ||
101 | #define RT5651_A_JD_CTL1 0x94 | ||
102 | /* Function - Digital */ | ||
103 | #define RT5651_EQ_CTRL1 0xb0 | ||
104 | #define RT5651_EQ_CTRL2 0xb1 | ||
105 | #define RT5651_ALC_1 0xb4 | ||
106 | #define RT5651_ALC_2 0xb5 | ||
107 | #define RT5651_ALC_3 0xb6 | ||
108 | #define RT5651_JD_CTRL1 0xbb | ||
109 | #define RT5651_JD_CTRL2 0xbc | ||
110 | #define RT5651_IRQ_CTRL1 0xbd | ||
111 | #define RT5651_IRQ_CTRL2 0xbe | ||
112 | #define RT5651_INT_IRQ_ST 0xbf | ||
113 | #define RT5651_GPIO_CTRL1 0xc0 | ||
114 | #define RT5651_GPIO_CTRL2 0xc1 | ||
115 | #define RT5651_GPIO_CTRL3 0xc2 | ||
116 | #define RT5651_PGM_REG_ARR1 0xc8 | ||
117 | #define RT5651_PGM_REG_ARR2 0xc9 | ||
118 | #define RT5651_PGM_REG_ARR3 0xca | ||
119 | #define RT5651_PGM_REG_ARR4 0xcb | ||
120 | #define RT5651_PGM_REG_ARR5 0xcc | ||
121 | #define RT5651_SCB_FUNC 0xcd | ||
122 | #define RT5651_SCB_CTRL 0xce | ||
123 | #define RT5651_BASE_BACK 0xcf | ||
124 | #define RT5651_MP3_PLUS1 0xd0 | ||
125 | #define RT5651_MP3_PLUS2 0xd1 | ||
126 | #define RT5651_ADJ_HPF_CTRL1 0xd3 | ||
127 | #define RT5651_ADJ_HPF_CTRL2 0xd4 | ||
128 | #define RT5651_HP_CALIB_AMP_DET 0xd6 | ||
129 | #define RT5651_HP_CALIB2 0xd7 | ||
130 | #define RT5651_SV_ZCD1 0xd9 | ||
131 | #define RT5651_SV_ZCD2 0xda | ||
132 | #define RT5651_D_MISC 0xfa | ||
133 | /* Dummy Register */ | ||
134 | #define RT5651_DUMMY2 0xfb | ||
135 | #define RT5651_DUMMY3 0xfc | ||
136 | |||
137 | |||
138 | /* Index of Codec Private Register definition */ | ||
139 | #define RT5651_BIAS_CUR1 0x12 | ||
140 | #define RT5651_BIAS_CUR3 0x14 | ||
141 | #define RT5651_CLSD_INT_REG1 0x1c | ||
142 | #define RT5651_CHPUMP_INT_REG1 0x24 | ||
143 | #define RT5651_MAMP_INT_REG2 0x37 | ||
144 | #define RT5651_CHOP_DAC_ADC 0x3d | ||
145 | #define RT5651_3D_SPK 0x63 | ||
146 | #define RT5651_WND_1 0x6c | ||
147 | #define RT5651_WND_2 0x6d | ||
148 | #define RT5651_WND_3 0x6e | ||
149 | #define RT5651_WND_4 0x6f | ||
150 | #define RT5651_WND_5 0x70 | ||
151 | #define RT5651_WND_8 0x73 | ||
152 | #define RT5651_DIP_SPK_INF 0x75 | ||
153 | #define RT5651_HP_DCC_INT1 0x77 | ||
154 | #define RT5651_EQ_BW_LOP 0xa0 | ||
155 | #define RT5651_EQ_GN_LOP 0xa1 | ||
156 | #define RT5651_EQ_FC_BP1 0xa2 | ||
157 | #define RT5651_EQ_BW_BP1 0xa3 | ||
158 | #define RT5651_EQ_GN_BP1 0xa4 | ||
159 | #define RT5651_EQ_FC_BP2 0xa5 | ||
160 | #define RT5651_EQ_BW_BP2 0xa6 | ||
161 | #define RT5651_EQ_GN_BP2 0xa7 | ||
162 | #define RT5651_EQ_FC_BP3 0xa8 | ||
163 | #define RT5651_EQ_BW_BP3 0xa9 | ||
164 | #define RT5651_EQ_GN_BP3 0xaa | ||
165 | #define RT5651_EQ_FC_BP4 0xab | ||
166 | #define RT5651_EQ_BW_BP4 0xac | ||
167 | #define RT5651_EQ_GN_BP4 0xad | ||
168 | #define RT5651_EQ_FC_HIP1 0xae | ||
169 | #define RT5651_EQ_GN_HIP1 0xaf | ||
170 | #define RT5651_EQ_FC_HIP2 0xb0 | ||
171 | #define RT5651_EQ_BW_HIP2 0xb1 | ||
172 | #define RT5651_EQ_GN_HIP2 0xb2 | ||
173 | #define RT5651_EQ_PRE_VOL 0xb3 | ||
174 | #define RT5651_EQ_PST_VOL 0xb4 | ||
175 | |||
176 | |||
177 | /* global definition */ | ||
178 | #define RT5651_L_MUTE (0x1 << 15) | ||
179 | #define RT5651_L_MUTE_SFT 15 | ||
180 | #define RT5651_VOL_L_MUTE (0x1 << 14) | ||
181 | #define RT5651_VOL_L_SFT 14 | ||
182 | #define RT5651_R_MUTE (0x1 << 7) | ||
183 | #define RT5651_R_MUTE_SFT 7 | ||
184 | #define RT5651_VOL_R_MUTE (0x1 << 6) | ||
185 | #define RT5651_VOL_R_SFT 6 | ||
186 | #define RT5651_L_VOL_MASK (0x3f << 8) | ||
187 | #define RT5651_L_VOL_SFT 8 | ||
188 | #define RT5651_R_VOL_MASK (0x3f) | ||
189 | #define RT5651_R_VOL_SFT 0 | ||
190 | |||
191 | /* LOUT Control 2(0x05) */ | ||
192 | #define RT5651_EN_DFO (0x1 << 15) | ||
193 | |||
194 | /* IN1 and IN2 Control (0x0d) */ | ||
195 | /* IN3 and IN4 Control (0x0e) */ | ||
196 | #define RT5651_BST_MASK1 (0xf<<12) | ||
197 | #define RT5651_BST_SFT1 12 | ||
198 | #define RT5651_BST_MASK2 (0xf<<8) | ||
199 | #define RT5651_BST_SFT2 8 | ||
200 | #define RT5651_IN_DF1 (0x1 << 7) | ||
201 | #define RT5651_IN_SFT1 7 | ||
202 | #define RT5651_IN_DF2 (0x1 << 6) | ||
203 | #define RT5651_IN_SFT2 6 | ||
204 | |||
205 | /* INL1 and INR1 Volume Control (0x0f) */ | ||
206 | /* INL2 and INR2 Volume Control (0x10) */ | ||
207 | #define RT5651_INL_SEL_MASK (0x1 << 15) | ||
208 | #define RT5651_INL_SEL_SFT 15 | ||
209 | #define RT5651_INL_SEL_IN4P (0x0 << 15) | ||
210 | #define RT5651_INL_SEL_MONOP (0x1 << 15) | ||
211 | #define RT5651_INL_VOL_MASK (0x1f << 8) | ||
212 | #define RT5651_INL_VOL_SFT 8 | ||
213 | #define RT5651_INR_SEL_MASK (0x1 << 7) | ||
214 | #define RT5651_INR_SEL_SFT 7 | ||
215 | #define RT5651_INR_SEL_IN4N (0x0 << 7) | ||
216 | #define RT5651_INR_SEL_MONON (0x1 << 7) | ||
217 | #define RT5651_INR_VOL_MASK (0x1f) | ||
218 | #define RT5651_INR_VOL_SFT 0 | ||
219 | |||
220 | /* DAC1 Digital Volume (0x19) */ | ||
221 | #define RT5651_DAC_L1_VOL_MASK (0xff << 8) | ||
222 | #define RT5651_DAC_L1_VOL_SFT 8 | ||
223 | #define RT5651_DAC_R1_VOL_MASK (0xff) | ||
224 | #define RT5651_DAC_R1_VOL_SFT 0 | ||
225 | |||
226 | /* DAC2 Digital Volume (0x1a) */ | ||
227 | #define RT5651_DAC_L2_VOL_MASK (0xff << 8) | ||
228 | #define RT5651_DAC_L2_VOL_SFT 8 | ||
229 | #define RT5651_DAC_R2_VOL_MASK (0xff) | ||
230 | #define RT5651_DAC_R2_VOL_SFT 0 | ||
231 | |||
232 | /* DAC2 Control (0x1b) */ | ||
233 | #define RT5651_M_DAC_L2_VOL (0x1 << 13) | ||
234 | #define RT5651_M_DAC_L2_VOL_SFT 13 | ||
235 | #define RT5651_M_DAC_R2_VOL (0x1 << 12) | ||
236 | #define RT5651_M_DAC_R2_VOL_SFT 12 | ||
237 | #define RT5651_SEL_DAC_L2 (0x1 << 11) | ||
238 | #define RT5651_IF2_DAC_L2 (0x1 << 11) | ||
239 | #define RT5651_IF1_DAC_L2 (0x0 << 11) | ||
240 | #define RT5651_SEL_DAC_L2_SFT 11 | ||
241 | #define RT5651_SEL_DAC_R2 (0x1 << 10) | ||
242 | #define RT5651_IF2_DAC_R2 (0x1 << 11) | ||
243 | #define RT5651_IF1_DAC_R2 (0x0 << 11) | ||
244 | #define RT5651_SEL_DAC_R2_SFT 10 | ||
245 | |||
246 | /* ADC Digital Volume Control (0x1c) */ | ||
247 | #define RT5651_ADC_L_VOL_MASK (0x7f << 8) | ||
248 | #define RT5651_ADC_L_VOL_SFT 8 | ||
249 | #define RT5651_ADC_R_VOL_MASK (0x7f) | ||
250 | #define RT5651_ADC_R_VOL_SFT 0 | ||
251 | |||
252 | /* Mono ADC Digital Volume Control (0x1d) */ | ||
253 | #define RT5651_M_MONO_ADC_L (0x1 << 15) | ||
254 | #define RT5651_M_MONO_ADC_L_SFT 15 | ||
255 | #define RT5651_MONO_ADC_L_VOL_MASK (0x7f << 8) | ||
256 | #define RT5651_MONO_ADC_L_VOL_SFT 8 | ||
257 | #define RT5651_M_MONO_ADC_R (0x1 << 7) | ||
258 | #define RT5651_M_MONO_ADC_R_SFT 7 | ||
259 | #define RT5651_MONO_ADC_R_VOL_MASK (0x7f) | ||
260 | #define RT5651_MONO_ADC_R_VOL_SFT 0 | ||
261 | |||
262 | /* ADC Boost Volume Control (0x1e) */ | ||
263 | #define RT5651_ADC_L_BST_MASK (0x3 << 14) | ||
264 | #define RT5651_ADC_L_BST_SFT 14 | ||
265 | #define RT5651_ADC_R_BST_MASK (0x3 << 12) | ||
266 | #define RT5651_ADC_R_BST_SFT 12 | ||
267 | #define RT5651_ADC_COMP_MASK (0x3 << 10) | ||
268 | #define RT5651_ADC_COMP_SFT 10 | ||
269 | |||
270 | /* Stereo ADC1 Mixer Control (0x27) */ | ||
271 | #define RT5651_M_STO1_ADC_L1 (0x1 << 14) | ||
272 | #define RT5651_M_STO1_ADC_L1_SFT 14 | ||
273 | #define RT5651_M_STO1_ADC_L2 (0x1 << 13) | ||
274 | #define RT5651_M_STO1_ADC_L2_SFT 13 | ||
275 | #define RT5651_STO1_ADC_1_SRC_MASK (0x1 << 12) | ||
276 | #define RT5651_STO1_ADC_1_SRC_SFT 12 | ||
277 | #define RT5651_STO1_ADC_1_SRC_ADC (0x1 << 12) | ||
278 | #define RT5651_STO1_ADC_1_SRC_DACMIX (0x0 << 12) | ||
279 | #define RT5651_STO1_ADC_2_SRC_MASK (0x1 << 11) | ||
280 | #define RT5651_STO1_ADC_2_SRC_SFT 11 | ||
281 | #define RT5651_STO1_ADC_2_SRC_DMIC (0x0 << 11) | ||
282 | #define RT5651_STO1_ADC_2_SRC_DACMIXR (0x1 << 11) | ||
283 | #define RT5651_M_STO1_ADC_R1 (0x1 << 6) | ||
284 | #define RT5651_M_STO1_ADC_R1_SFT 6 | ||
285 | #define RT5651_M_STO1_ADC_R2 (0x1 << 5) | ||
286 | #define RT5651_M_STO1_ADC_R2_SFT 5 | ||
287 | |||
288 | /* Stereo ADC2 Mixer Control (0x28) */ | ||
289 | #define RT5651_M_STO2_ADC_L1 (0x1 << 14) | ||
290 | #define RT5651_M_STO2_ADC_L1_SFT 14 | ||
291 | #define RT5651_M_STO2_ADC_L2 (0x1 << 13) | ||
292 | #define RT5651_M_STO2_ADC_L2_SFT 13 | ||
293 | #define RT5651_STO2_ADC_L1_SRC_MASK (0x1 << 12) | ||
294 | #define RT5651_STO2_ADC_L1_SRC_SFT 12 | ||
295 | #define RT5651_STO2_ADC_L1_SRC_DACMIXL (0x0 << 12) | ||
296 | #define RT5651_STO2_ADC_L1_SRC_ADCL (0x1 << 12) | ||
297 | #define RT5651_STO2_ADC_L2_SRC_MASK (0x1 << 11) | ||
298 | #define RT5651_STO2_ADC_L2_SRC_SFT 11 | ||
299 | #define RT5651_STO2_ADC_L2_SRC_DMIC (0x0 << 11) | ||
300 | #define RT5651_STO2_ADC_L2_SRC_DACMIXR (0x1 << 11) | ||
301 | #define RT5651_M_STO2_ADC_R1 (0x1 << 6) | ||
302 | #define RT5651_M_STO2_ADC_R1_SFT 6 | ||
303 | #define RT5651_M_STO2_ADC_R2 (0x1 << 5) | ||
304 | #define RT5651_M_STO2_ADC_R2_SFT 5 | ||
305 | #define RT5651_STO2_ADC_R1_SRC_MASK (0x1 << 4) | ||
306 | #define RT5651_STO2_ADC_R1_SRC_SFT 4 | ||
307 | #define RT5651_STO2_ADC_R1_SRC_ADCR (0x1 << 4) | ||
308 | #define RT5651_STO2_ADC_R1_SRC_DACMIXR (0x0 << 4) | ||
309 | #define RT5651_STO2_ADC_R2_SRC_MASK (0x1 << 3) | ||
310 | #define RT5651_STO2_ADC_R2_SRC_SFT 3 | ||
311 | #define RT5651_STO2_ADC_R2_SRC_DMIC (0x0 << 3) | ||
312 | #define RT5651_STO2_ADC_R2_SRC_DACMIXR (0x1 << 3) | ||
313 | |||
314 | /* ADC Mixer to DAC Mixer Control (0x29) */ | ||
315 | #define RT5651_M_ADCMIX_L (0x1 << 15) | ||
316 | #define RT5651_M_ADCMIX_L_SFT 15 | ||
317 | #define RT5651_M_IF1_DAC_L (0x1 << 14) | ||
318 | #define RT5651_M_IF1_DAC_L_SFT 14 | ||
319 | #define RT5651_M_ADCMIX_R (0x1 << 7) | ||
320 | #define RT5651_M_ADCMIX_R_SFT 7 | ||
321 | #define RT5651_M_IF1_DAC_R (0x1 << 6) | ||
322 | #define RT5651_M_IF1_DAC_R_SFT 6 | ||
323 | |||
324 | /* Stereo DAC Mixer Control (0x2a) */ | ||
325 | #define RT5651_M_DAC_L1_MIXL (0x1 << 14) | ||
326 | #define RT5651_M_DAC_L1_MIXL_SFT 14 | ||
327 | #define RT5651_DAC_L1_STO_L_VOL_MASK (0x1 << 13) | ||
328 | #define RT5651_DAC_L1_STO_L_VOL_SFT 13 | ||
329 | #define RT5651_M_DAC_L2_MIXL (0x1 << 12) | ||
330 | #define RT5651_M_DAC_L2_MIXL_SFT 12 | ||
331 | #define RT5651_DAC_L2_STO_L_VOL_MASK (0x1 << 11) | ||
332 | #define RT5651_DAC_L2_STO_L_VOL_SFT 11 | ||
333 | #define RT5651_M_DAC_R1_MIXL (0x1 << 9) | ||
334 | #define RT5651_M_DAC_R1_MIXL_SFT 9 | ||
335 | #define RT5651_DAC_R1_STO_L_VOL_MASK (0x1 << 8) | ||
336 | #define RT5651_DAC_R1_STO_L_VOL_SFT 8 | ||
337 | #define RT5651_M_DAC_R1_MIXR (0x1 << 6) | ||
338 | #define RT5651_M_DAC_R1_MIXR_SFT 6 | ||
339 | #define RT5651_DAC_R1_STO_R_VOL_MASK (0x1 << 5) | ||
340 | #define RT5651_DAC_R1_STO_R_VOL_SFT 5 | ||
341 | #define RT5651_M_DAC_R2_MIXR (0x1 << 4) | ||
342 | #define RT5651_M_DAC_R2_MIXR_SFT 4 | ||
343 | #define RT5651_DAC_R2_STO_R_VOL_MASK (0x1 << 3) | ||
344 | #define RT5651_DAC_R2_STO_R_VOL_SFT 3 | ||
345 | #define RT5651_M_DAC_L1_MIXR (0x1 << 1) | ||
346 | #define RT5651_M_DAC_L1_MIXR_SFT 1 | ||
347 | #define RT5651_DAC_L1_STO_R_VOL_MASK (0x1) | ||
348 | #define RT5651_DAC_L1_STO_R_VOL_SFT 0 | ||
349 | |||
350 | /* DD Mixer Control (0x2b) */ | ||
351 | #define RT5651_M_STO_DD_L1 (0x1 << 14) | ||
352 | #define RT5651_M_STO_DD_L1_SFT 14 | ||
353 | #define RT5651_STO_DD_L1_VOL_MASK (0x1 << 13) | ||
354 | #define RT5651_DAC_DD_L1_VOL_SFT 13 | ||
355 | #define RT5651_M_STO_DD_L2 (0x1 << 12) | ||
356 | #define RT5651_M_STO_DD_L2_SFT 12 | ||
357 | #define RT5651_STO_DD_L2_VOL_MASK (0x1 << 11) | ||
358 | #define RT5651_STO_DD_L2_VOL_SFT 11 | ||
359 | #define RT5651_M_STO_DD_R2_L (0x1 << 10) | ||
360 | #define RT5651_M_STO_DD_R2_L_SFT 10 | ||
361 | #define RT5651_STO_DD_R2_L_VOL_MASK (0x1 << 9) | ||
362 | #define RT5651_STO_DD_R2_L_VOL_SFT 9 | ||
363 | #define RT5651_M_STO_DD_R1 (0x1 << 6) | ||
364 | #define RT5651_M_STO_DD_R1_SFT 6 | ||
365 | #define RT5651_STO_DD_R1_VOL_MASK (0x1 << 5) | ||
366 | #define RT5651_STO_DD_R1_VOL_SFT 5 | ||
367 | #define RT5651_M_STO_DD_R2 (0x1 << 4) | ||
368 | #define RT5651_M_STO_DD_R2_SFT 4 | ||
369 | #define RT5651_STO_DD_R2_VOL_MASK (0x1 << 3) | ||
370 | #define RT5651_STO_DD_R2_VOL_SFT 3 | ||
371 | #define RT5651_M_STO_DD_L2_R (0x1 << 2) | ||
372 | #define RT5651_M_STO_DD_L2_R_SFT 2 | ||
373 | #define RT5651_STO_DD_L2_R_VOL_MASK (0x1 << 1) | ||
374 | #define RT5651_STO_DD_L2_R_VOL_SFT 1 | ||
375 | |||
376 | /* Digital Mixer Control (0x2c) */ | ||
377 | #define RT5651_M_STO_L_DAC_L (0x1 << 15) | ||
378 | #define RT5651_M_STO_L_DAC_L_SFT 15 | ||
379 | #define RT5651_STO_L_DAC_L_VOL_MASK (0x1 << 14) | ||
380 | #define RT5651_STO_L_DAC_L_VOL_SFT 14 | ||
381 | #define RT5651_M_DAC_L2_DAC_L (0x1 << 13) | ||
382 | #define RT5651_M_DAC_L2_DAC_L_SFT 13 | ||
383 | #define RT5651_DAC_L2_DAC_L_VOL_MASK (0x1 << 12) | ||
384 | #define RT5651_DAC_L2_DAC_L_VOL_SFT 12 | ||
385 | #define RT5651_M_STO_R_DAC_R (0x1 << 11) | ||
386 | #define RT5651_M_STO_R_DAC_R_SFT 11 | ||
387 | #define RT5651_STO_R_DAC_R_VOL_MASK (0x1 << 10) | ||
388 | #define RT5651_STO_R_DAC_R_VOL_SFT 10 | ||
389 | #define RT5651_M_DAC_R2_DAC_R (0x1 << 9) | ||
390 | #define RT5651_M_DAC_R2_DAC_R_SFT 9 | ||
391 | #define RT5651_DAC_R2_DAC_R_VOL_MASK (0x1 << 8) | ||
392 | #define RT5651_DAC_R2_DAC_R_VOL_SFT 8 | ||
393 | |||
394 | /* DSP Path Control 1 (0x2d) */ | ||
395 | #define RT5651_RXDP_SRC_MASK (0x1 << 15) | ||
396 | #define RT5651_RXDP_SRC_SFT 15 | ||
397 | #define RT5651_RXDP_SRC_NOR (0x0 << 15) | ||
398 | #define RT5651_RXDP_SRC_DIV3 (0x1 << 15) | ||
399 | #define RT5651_TXDP_SRC_MASK (0x1 << 14) | ||
400 | #define RT5651_TXDP_SRC_SFT 14 | ||
401 | #define RT5651_TXDP_SRC_NOR (0x0 << 14) | ||
402 | #define RT5651_TXDP_SRC_DIV3 (0x1 << 14) | ||
403 | |||
404 | /* DSP Path Control 2 (0x2e) */ | ||
405 | #define RT5651_DAC_L2_SEL_MASK (0x3 << 14) | ||
406 | #define RT5651_DAC_L2_SEL_SFT 14 | ||
407 | #define RT5651_DAC_L2_SEL_IF2 (0x0 << 14) | ||
408 | #define RT5651_DAC_L2_SEL_IF3 (0x1 << 14) | ||
409 | #define RT5651_DAC_L2_SEL_TXDC (0x2 << 14) | ||
410 | #define RT5651_DAC_L2_SEL_BASS (0x3 << 14) | ||
411 | #define RT5651_DAC_R2_SEL_MASK (0x3 << 12) | ||
412 | #define RT5651_DAC_R2_SEL_SFT 12 | ||
413 | #define RT5651_DAC_R2_SEL_IF2 (0x0 << 12) | ||
414 | #define RT5651_DAC_R2_SEL_IF3 (0x1 << 12) | ||
415 | #define RT5651_DAC_R2_SEL_TXDC (0x2 << 12) | ||
416 | #define RT5651_IF2_ADC_L_SEL_MASK (0x1 << 11) | ||
417 | #define RT5651_IF2_ADC_L_SEL_SFT 11 | ||
418 | #define RT5651_IF2_ADC_L_SEL_TXDP (0x0 << 11) | ||
419 | #define RT5651_IF2_ADC_L_SEL_PASS (0x1 << 11) | ||
420 | #define RT5651_IF2_ADC_R_SEL_MASK (0x1 << 10) | ||
421 | #define RT5651_IF2_ADC_R_SEL_SFT 10 | ||
422 | #define RT5651_IF2_ADC_R_SEL_TXDP (0x0 << 10) | ||
423 | #define RT5651_IF2_ADC_R_SEL_PASS (0x1 << 10) | ||
424 | #define RT5651_RXDC_SEL_MASK (0x3 << 8) | ||
425 | #define RT5651_RXDC_SEL_SFT 8 | ||
426 | #define RT5651_RXDC_SEL_NOR (0x0 << 8) | ||
427 | #define RT5651_RXDC_SEL_L2R (0x1 << 8) | ||
428 | #define RT5651_RXDC_SEL_R2L (0x2 << 8) | ||
429 | #define RT5651_RXDC_SEL_SWAP (0x3 << 8) | ||
430 | #define RT5651_RXDP_SEL_MASK (0x3 << 6) | ||
431 | #define RT5651_RXDP_SEL_SFT 6 | ||
432 | #define RT5651_RXDP_SEL_NOR (0x0 << 6) | ||
433 | #define RT5651_RXDP_SEL_L2R (0x1 << 6) | ||
434 | #define RT5651_RXDP_SEL_R2L (0x2 << 6) | ||
435 | #define RT5651_RXDP_SEL_SWAP (0x3 << 6) | ||
436 | #define RT5651_TXDC_SEL_MASK (0x3 << 4) | ||
437 | #define RT5651_TXDC_SEL_SFT 4 | ||
438 | #define RT5651_TXDC_SEL_NOR (0x0 << 4) | ||
439 | #define RT5651_TXDC_SEL_L2R (0x1 << 4) | ||
440 | #define RT5651_TXDC_SEL_R2L (0x2 << 4) | ||
441 | #define RT5651_TXDC_SEL_SWAP (0x3 << 4) | ||
442 | #define RT5651_TXDP_SEL_MASK (0x3 << 2) | ||
443 | #define RT5651_TXDP_SEL_SFT 2 | ||
444 | #define RT5651_TXDP_SEL_NOR (0x0 << 2) | ||
445 | #define RT5651_TXDP_SEL_L2R (0x1 << 2) | ||
446 | #define RT5651_TXDP_SEL_R2L (0x2 << 2) | ||
447 | #define RT5651_TRXDP_SEL_SWAP (0x3 << 2) | ||
448 | |||
449 | /* Digital Interface Data Control (0x2f) */ | ||
450 | #define RT5651_IF2_DAC_SEL_MASK (0x3 << 10) | ||
451 | #define RT5651_IF2_DAC_SEL_SFT 10 | ||
452 | #define RT5651_IF2_DAC_SEL_NOR (0x0 << 10) | ||
453 | #define RT5651_IF2_DAC_SEL_SWAP (0x1 << 10) | ||
454 | #define RT5651_IF2_DAC_SEL_L2R (0x2 << 10) | ||
455 | #define RT5651_IF2_DAC_SEL_R2L (0x3 << 10) | ||
456 | #define RT5651_IF2_ADC_SEL_MASK (0x3 << 8) | ||
457 | #define RT5651_IF2_ADC_SEL_SFT 8 | ||
458 | #define RT5651_IF2_ADC_SEL_NOR (0x0 << 8) | ||
459 | #define RT5651_IF2_ADC_SEL_SWAP (0x1 << 8) | ||
460 | #define RT5651_IF2_ADC_SEL_L2R (0x2 << 8) | ||
461 | #define RT5651_IF2_ADC_SEL_R2L (0x3 << 8) | ||
462 | #define RT5651_IF2_ADC_SRC_MASK (0x1 << 7) | ||
463 | #define RT5651_IF2_ADC_SRC_SFT 7 | ||
464 | #define RT5651_IF1_ADC1 (0x0 << 7) | ||
465 | #define RT5651_IF1_ADC2 (0x1 << 7) | ||
466 | |||
467 | /* PDM Output Control (0x30) */ | ||
468 | #define RT5651_PDM_L_SEL_MASK (0x1 << 15) | ||
469 | #define RT5651_PDM_L_SEL_SFT 15 | ||
470 | #define RT5651_PDM_L_SEL_DD_L (0x0 << 15) | ||
471 | #define RT5651_PDM_L_SEL_STO_L (0x1 << 15) | ||
472 | #define RT5651_M_PDM_L (0x1 << 14) | ||
473 | #define RT5651_M_PDM_L_SFT 14 | ||
474 | #define RT5651_PDM_R_SEL_MASK (0x1 << 13) | ||
475 | #define RT5651_PDM_R_SEL_SFT 13 | ||
476 | #define RT5651_PDM_R_SEL_DD_L (0x0 << 13) | ||
477 | #define RT5651_PDM_R_SEL_STO_L (0x1 << 13) | ||
478 | #define RT5651_M_PDM_R (0x1 << 12) | ||
479 | #define RT5651_M_PDM_R_SFT 12 | ||
480 | #define RT5651_PDM_BUSY (0x1 << 6) | ||
481 | #define RT5651_PDM_BUSY_SFT 6 | ||
482 | #define RT5651_PDM_PATTERN_SEL_MASK (0x1 << 5) | ||
483 | #define RT5651_PDM_PATTERN_SEL_64 (0x0 << 5) | ||
484 | #define RT5651_PDM_PATTERN_SEL_128 (0x1 << 5) | ||
485 | #define RT5651_PDM_VOL_MASK (0x1 << 4) | ||
486 | #define RT5651_PDM_VOL_SFT 4 | ||
487 | #define RT5651_PDM_DIV_MASK (0x3) | ||
488 | #define RT5651_PDM_DIV_SFT 0 | ||
489 | #define RT5651_PDM_DIV_1 0 | ||
490 | #define RT5651_PDM_DIV_2 1 | ||
491 | #define RT5651_PDM_DIV_3 2 | ||
492 | #define RT5651_PDM_DIV_4 3 | ||
493 | |||
494 | /* PDM I2C/Data Control 1 (0x31) */ | ||
495 | #define RT5651_PDM_I2C_ID_MASK (0xf << 12) | ||
496 | #define PT5631_PDM_CMD_EXE (0x1 << 11) | ||
497 | #define RT5651_PDM_I2C_CMD_MASK (0x1 << 10) | ||
498 | #define RT5651_PDM_I2C_CMD_R (0x0 << 10) | ||
499 | #define RT5651_PDM_I2C_CMD_W (0x1 << 10) | ||
500 | #define RT5651_PDM_I2C_CMD_EXE (0x1 << 9) | ||
501 | #define RT5651_PDM_I2C_NORMAL (0x0 << 8) | ||
502 | #define RT5651_PDM_I2C_BUSY (0x1 << 8) | ||
503 | |||
504 | /* PDM I2C/Data Control 2 (0x32) */ | ||
505 | #define RT5651_PDM_I2C_ADDR (0xff << 8) | ||
506 | #define RT5651_PDM_I2C_CMD_PATTERN (0xff) | ||
507 | |||
508 | |||
509 | /* REC Left Mixer Control 1 (0x3b) */ | ||
510 | #define RT5651_G_LN_L2_RM_L_MASK (0x7 << 13) | ||
511 | #define RT5651_G_IN_L2_RM_L_SFT 13 | ||
512 | #define RT5651_G_LN_L1_RM_L_MASK (0x7 << 10) | ||
513 | #define RT5651_G_IN_L1_RM_L_SFT 10 | ||
514 | #define RT5651_G_BST3_RM_L_MASK (0x7 << 4) | ||
515 | #define RT5651_G_BST3_RM_L_SFT 4 | ||
516 | #define RT5651_G_BST2_RM_L_MASK (0x7 << 1) | ||
517 | #define RT5651_G_BST2_RM_L_SFT 1 | ||
518 | |||
519 | /* REC Left Mixer Control 2 (0x3c) */ | ||
520 | #define RT5651_G_BST1_RM_L_MASK (0x7 << 13) | ||
521 | #define RT5651_G_BST1_RM_L_SFT 13 | ||
522 | #define RT5651_G_OM_L_RM_L_MASK (0x7 << 10) | ||
523 | #define RT5651_G_OM_L_RM_L_SFT 10 | ||
524 | #define RT5651_M_IN2_L_RM_L (0x1 << 6) | ||
525 | #define RT5651_M_IN2_L_RM_L_SFT 6 | ||
526 | #define RT5651_M_IN1_L_RM_L (0x1 << 5) | ||
527 | #define RT5651_M_IN1_L_RM_L_SFT 5 | ||
528 | #define RT5651_M_BST3_RM_L (0x1 << 3) | ||
529 | #define RT5651_M_BST3_RM_L_SFT 3 | ||
530 | #define RT5651_M_BST2_RM_L (0x1 << 2) | ||
531 | #define RT5651_M_BST2_RM_L_SFT 2 | ||
532 | #define RT5651_M_BST1_RM_L (0x1 << 1) | ||
533 | #define RT5651_M_BST1_RM_L_SFT 1 | ||
534 | #define RT5651_M_OM_L_RM_L (0x1) | ||
535 | #define RT5651_M_OM_L_RM_L_SFT 0 | ||
536 | |||
537 | /* REC Right Mixer Control 1 (0x3d) */ | ||
538 | #define RT5651_G_IN2_R_RM_R_MASK (0x7 << 13) | ||
539 | #define RT5651_G_IN2_R_RM_R_SFT 13 | ||
540 | #define RT5651_G_IN1_R_RM_R_MASK (0x7 << 10) | ||
541 | #define RT5651_G_IN1_R_RM_R_SFT 10 | ||
542 | #define RT5651_G_BST3_RM_R_MASK (0x7 << 4) | ||
543 | #define RT5651_G_BST3_RM_R_SFT 4 | ||
544 | #define RT5651_G_BST2_RM_R_MASK (0x7 << 1) | ||
545 | #define RT5651_G_BST2_RM_R_SFT 1 | ||
546 | |||
547 | /* REC Right Mixer Control 2 (0x3e) */ | ||
548 | #define RT5651_G_BST1_RM_R_MASK (0x7 << 13) | ||
549 | #define RT5651_G_BST1_RM_R_SFT 13 | ||
550 | #define RT5651_G_OM_R_RM_R_MASK (0x7 << 10) | ||
551 | #define RT5651_G_OM_R_RM_R_SFT 10 | ||
552 | #define RT5651_M_IN2_R_RM_R (0x1 << 6) | ||
553 | #define RT5651_M_IN2_R_RM_R_SFT 6 | ||
554 | #define RT5651_M_IN1_R_RM_R (0x1 << 5) | ||
555 | #define RT5651_M_IN1_R_RM_R_SFT 5 | ||
556 | #define RT5651_M_BST3_RM_R (0x1 << 3) | ||
557 | #define RT5651_M_BST3_RM_R_SFT 3 | ||
558 | #define RT5651_M_BST2_RM_R (0x1 << 2) | ||
559 | #define RT5651_M_BST2_RM_R_SFT 2 | ||
560 | #define RT5651_M_BST1_RM_R (0x1 << 1) | ||
561 | #define RT5651_M_BST1_RM_R_SFT 1 | ||
562 | #define RT5651_M_OM_R_RM_R (0x1) | ||
563 | #define RT5651_M_OM_R_RM_R_SFT 0 | ||
564 | |||
565 | /* HPMIX Control (0x45) */ | ||
566 | #define RT5651_M_DAC1_HM (0x1 << 14) | ||
567 | #define RT5651_M_DAC1_HM_SFT 14 | ||
568 | #define RT5651_M_HPVOL_HM (0x1 << 13) | ||
569 | #define RT5651_M_HPVOL_HM_SFT 13 | ||
570 | #define RT5651_G_HPOMIX_MASK (0x1 << 12) | ||
571 | #define RT5651_G_HPOMIX_SFT 12 | ||
572 | |||
573 | /* SPK Left Mixer Control (0x46) */ | ||
574 | #define RT5651_G_RM_L_SM_L_MASK (0x3 << 14) | ||
575 | #define RT5651_G_RM_L_SM_L_SFT 14 | ||
576 | #define RT5651_G_IN_L_SM_L_MASK (0x3 << 12) | ||
577 | #define RT5651_G_IN_L_SM_L_SFT 12 | ||
578 | #define RT5651_G_DAC_L1_SM_L_MASK (0x3 << 10) | ||
579 | #define RT5651_G_DAC_L1_SM_L_SFT 10 | ||
580 | #define RT5651_G_DAC_L2_SM_L_MASK (0x3 << 8) | ||
581 | #define RT5651_G_DAC_L2_SM_L_SFT 8 | ||
582 | #define RT5651_G_OM_L_SM_L_MASK (0x3 << 6) | ||
583 | #define RT5651_G_OM_L_SM_L_SFT 6 | ||
584 | #define RT5651_M_RM_L_SM_L (0x1 << 5) | ||
585 | #define RT5651_M_RM_L_SM_L_SFT 5 | ||
586 | #define RT5651_M_IN_L_SM_L (0x1 << 4) | ||
587 | #define RT5651_M_IN_L_SM_L_SFT 4 | ||
588 | #define RT5651_M_DAC_L1_SM_L (0x1 << 3) | ||
589 | #define RT5651_M_DAC_L1_SM_L_SFT 3 | ||
590 | #define RT5651_M_DAC_L2_SM_L (0x1 << 2) | ||
591 | #define RT5651_M_DAC_L2_SM_L_SFT 2 | ||
592 | #define RT5651_M_OM_L_SM_L (0x1 << 1) | ||
593 | #define RT5651_M_OM_L_SM_L_SFT 1 | ||
594 | |||
595 | /* SPK Right Mixer Control (0x47) */ | ||
596 | #define RT5651_G_RM_R_SM_R_MASK (0x3 << 14) | ||
597 | #define RT5651_G_RM_R_SM_R_SFT 14 | ||
598 | #define RT5651_G_IN_R_SM_R_MASK (0x3 << 12) | ||
599 | #define RT5651_G_IN_R_SM_R_SFT 12 | ||
600 | #define RT5651_G_DAC_R1_SM_R_MASK (0x3 << 10) | ||
601 | #define RT5651_G_DAC_R1_SM_R_SFT 10 | ||
602 | #define RT5651_G_DAC_R2_SM_R_MASK (0x3 << 8) | ||
603 | #define RT5651_G_DAC_R2_SM_R_SFT 8 | ||
604 | #define RT5651_G_OM_R_SM_R_MASK (0x3 << 6) | ||
605 | #define RT5651_G_OM_R_SM_R_SFT 6 | ||
606 | #define RT5651_M_RM_R_SM_R (0x1 << 5) | ||
607 | #define RT5651_M_RM_R_SM_R_SFT 5 | ||
608 | #define RT5651_M_IN_R_SM_R (0x1 << 4) | ||
609 | #define RT5651_M_IN_R_SM_R_SFT 4 | ||
610 | #define RT5651_M_DAC_R1_SM_R (0x1 << 3) | ||
611 | #define RT5651_M_DAC_R1_SM_R_SFT 3 | ||
612 | #define RT5651_M_DAC_R2_SM_R (0x1 << 2) | ||
613 | #define RT5651_M_DAC_R2_SM_R_SFT 2 | ||
614 | #define RT5651_M_OM_R_SM_R (0x1 << 1) | ||
615 | #define RT5651_M_OM_R_SM_R_SFT 1 | ||
616 | |||
617 | /* SPOLMIX Control (0x48) */ | ||
618 | #define RT5651_M_DAC_R1_SPM_L (0x1 << 15) | ||
619 | #define RT5651_M_DAC_R1_SPM_L_SFT 15 | ||
620 | #define RT5651_M_DAC_L1_SPM_L (0x1 << 14) | ||
621 | #define RT5651_M_DAC_L1_SPM_L_SFT 14 | ||
622 | #define RT5651_M_SV_R_SPM_L (0x1 << 13) | ||
623 | #define RT5651_M_SV_R_SPM_L_SFT 13 | ||
624 | #define RT5651_M_SV_L_SPM_L (0x1 << 12) | ||
625 | #define RT5651_M_SV_L_SPM_L_SFT 12 | ||
626 | #define RT5651_M_BST1_SPM_L (0x1 << 11) | ||
627 | #define RT5651_M_BST1_SPM_L_SFT 11 | ||
628 | |||
629 | /* SPORMIX Control (0x49) */ | ||
630 | #define RT5651_M_DAC_R1_SPM_R (0x1 << 13) | ||
631 | #define RT5651_M_DAC_R1_SPM_R_SFT 13 | ||
632 | #define RT5651_M_SV_R_SPM_R (0x1 << 12) | ||
633 | #define RT5651_M_SV_R_SPM_R_SFT 12 | ||
634 | #define RT5651_M_BST1_SPM_R (0x1 << 11) | ||
635 | #define RT5651_M_BST1_SPM_R_SFT 11 | ||
636 | |||
637 | /* SPOLMIX / SPORMIX Ratio Control (0x4a) */ | ||
638 | #define RT5651_SPO_CLSD_RATIO_MASK (0x7) | ||
639 | #define RT5651_SPO_CLSD_RATIO_SFT 0 | ||
640 | |||
641 | /* Mono Output Mixer Control (0x4c) */ | ||
642 | #define RT5651_M_DAC_R2_MM (0x1 << 15) | ||
643 | #define RT5651_M_DAC_R2_MM_SFT 15 | ||
644 | #define RT5651_M_DAC_L2_MM (0x1 << 14) | ||
645 | #define RT5651_M_DAC_L2_MM_SFT 14 | ||
646 | #define RT5651_M_OV_R_MM (0x1 << 13) | ||
647 | #define RT5651_M_OV_R_MM_SFT 13 | ||
648 | #define RT5651_M_OV_L_MM (0x1 << 12) | ||
649 | #define RT5651_M_OV_L_MM_SFT 12 | ||
650 | #define RT5651_M_BST1_MM (0x1 << 11) | ||
651 | #define RT5651_M_BST1_MM_SFT 11 | ||
652 | #define RT5651_G_MONOMIX_MASK (0x1 << 10) | ||
653 | #define RT5651_G_MONOMIX_SFT 10 | ||
654 | |||
655 | /* Output Left Mixer Control 1 (0x4d) */ | ||
656 | #define RT5651_G_BST2_OM_L_MASK (0x7 << 10) | ||
657 | #define RT5651_G_BST2_OM_L_SFT 10 | ||
658 | #define RT5651_G_BST1_OM_L_MASK (0x7 << 7) | ||
659 | #define RT5651_G_BST1_OM_L_SFT 7 | ||
660 | #define RT5651_G_IN1_L_OM_L_MASK (0x7 << 4) | ||
661 | #define RT5651_G_IN1_L_OM_L_SFT 4 | ||
662 | #define RT5651_G_RM_L_OM_L_MASK (0x7 << 1) | ||
663 | #define RT5651_G_RM_L_OM_L_SFT 1 | ||
664 | |||
665 | /* Output Left Mixer Control 2 (0x4e) */ | ||
666 | #define RT5651_G_DAC_L1_OM_L_MASK (0x7 << 7) | ||
667 | #define RT5651_G_DAC_L1_OM_L_SFT 7 | ||
668 | #define RT5651_G_IN2_L_OM_L_MASK (0x7 << 4) | ||
669 | #define RT5651_G_IN2_L_OM_L_SFT 4 | ||
670 | |||
671 | /* Output Left Mixer Control 3 (0x4f) */ | ||
672 | #define RT5651_M_IN2_L_OM_L (0x1 << 9) | ||
673 | #define RT5651_M_IN2_L_OM_L_SFT 9 | ||
674 | #define RT5651_M_BST2_OM_L (0x1 << 6) | ||
675 | #define RT5651_M_BST2_OM_L_SFT 6 | ||
676 | #define RT5651_M_BST1_OM_L (0x1 << 5) | ||
677 | #define RT5651_M_BST1_OM_L_SFT 5 | ||
678 | #define RT5651_M_IN1_L_OM_L (0x1 << 4) | ||
679 | #define RT5651_M_IN1_L_OM_L_SFT 4 | ||
680 | #define RT5651_M_RM_L_OM_L (0x1 << 3) | ||
681 | #define RT5651_M_RM_L_OM_L_SFT 3 | ||
682 | #define RT5651_M_DAC_L1_OM_L (0x1) | ||
683 | #define RT5651_M_DAC_L1_OM_L_SFT 0 | ||
684 | |||
685 | /* Output Right Mixer Control 1 (0x50) */ | ||
686 | #define RT5651_G_BST2_OM_R_MASK (0x7 << 10) | ||
687 | #define RT5651_G_BST2_OM_R_SFT 10 | ||
688 | #define RT5651_G_BST1_OM_R_MASK (0x7 << 7) | ||
689 | #define RT5651_G_BST1_OM_R_SFT 7 | ||
690 | #define RT5651_G_IN1_R_OM_R_MASK (0x7 << 4) | ||
691 | #define RT5651_G_IN1_R_OM_R_SFT 4 | ||
692 | #define RT5651_G_RM_R_OM_R_MASK (0x7 << 1) | ||
693 | #define RT5651_G_RM_R_OM_R_SFT 1 | ||
694 | |||
695 | /* Output Right Mixer Control 2 (0x51) */ | ||
696 | #define RT5651_G_DAC_R1_OM_R_MASK (0x7 << 7) | ||
697 | #define RT5651_G_DAC_R1_OM_R_SFT 7 | ||
698 | #define RT5651_G_IN2_R_OM_R_MASK (0x7 << 4) | ||
699 | #define RT5651_G_IN2_R_OM_R_SFT 4 | ||
700 | |||
701 | /* Output Right Mixer Control 3 (0x52) */ | ||
702 | #define RT5651_M_IN2_R_OM_R (0x1 << 9) | ||
703 | #define RT5651_M_IN2_R_OM_R_SFT 9 | ||
704 | #define RT5651_M_BST2_OM_R (0x1 << 6) | ||
705 | #define RT5651_M_BST2_OM_R_SFT 6 | ||
706 | #define RT5651_M_BST1_OM_R (0x1 << 5) | ||
707 | #define RT5651_M_BST1_OM_R_SFT 5 | ||
708 | #define RT5651_M_IN1_R_OM_R (0x1 << 4) | ||
709 | #define RT5651_M_IN1_R_OM_R_SFT 4 | ||
710 | #define RT5651_M_RM_R_OM_R (0x1 << 3) | ||
711 | #define RT5651_M_RM_R_OM_R_SFT 3 | ||
712 | #define RT5651_M_DAC_R1_OM_R (0x1) | ||
713 | #define RT5651_M_DAC_R1_OM_R_SFT 0 | ||
714 | |||
715 | /* LOUT Mixer Control (0x53) */ | ||
716 | #define RT5651_M_DAC_L1_LM (0x1 << 15) | ||
717 | #define RT5651_M_DAC_L1_LM_SFT 15 | ||
718 | #define RT5651_M_DAC_R1_LM (0x1 << 14) | ||
719 | #define RT5651_M_DAC_R1_LM_SFT 14 | ||
720 | #define RT5651_M_OV_L_LM (0x1 << 13) | ||
721 | #define RT5651_M_OV_L_LM_SFT 13 | ||
722 | #define RT5651_M_OV_R_LM (0x1 << 12) | ||
723 | #define RT5651_M_OV_R_LM_SFT 12 | ||
724 | #define RT5651_G_LOUTMIX_MASK (0x1 << 11) | ||
725 | #define RT5651_G_LOUTMIX_SFT 11 | ||
726 | |||
727 | /* Power Management for Digital 1 (0x61) */ | ||
728 | #define RT5651_PWR_I2S1 (0x1 << 15) | ||
729 | #define RT5651_PWR_I2S1_BIT 15 | ||
730 | #define RT5651_PWR_I2S2 (0x1 << 14) | ||
731 | #define RT5651_PWR_I2S2_BIT 14 | ||
732 | #define RT5651_PWR_DAC_L1 (0x1 << 12) | ||
733 | #define RT5651_PWR_DAC_L1_BIT 12 | ||
734 | #define RT5651_PWR_DAC_R1 (0x1 << 11) | ||
735 | #define RT5651_PWR_DAC_R1_BIT 11 | ||
736 | #define RT5651_PWR_ADC_L (0x1 << 2) | ||
737 | #define RT5651_PWR_ADC_L_BIT 2 | ||
738 | #define RT5651_PWR_ADC_R (0x1 << 1) | ||
739 | #define RT5651_PWR_ADC_R_BIT 1 | ||
740 | |||
741 | /* Power Management for Digital 2 (0x62) */ | ||
742 | #define RT5651_PWR_ADC_STO1_F (0x1 << 15) | ||
743 | #define RT5651_PWR_ADC_STO1_F_BIT 15 | ||
744 | #define RT5651_PWR_ADC_STO2_F (0x1 << 14) | ||
745 | #define RT5651_PWR_ADC_STO2_F_BIT 14 | ||
746 | #define RT5651_PWR_DAC_STO1_F (0x1 << 11) | ||
747 | #define RT5651_PWR_DAC_STO1_F_BIT 11 | ||
748 | #define RT5651_PWR_DAC_STO2_F (0x1 << 10) | ||
749 | #define RT5651_PWR_DAC_STO2_F_BIT 10 | ||
750 | #define RT5651_PWR_PDM (0x1 << 9) | ||
751 | #define RT5651_PWR_PDM_BIT 9 | ||
752 | |||
753 | /* Power Management for Analog 1 (0x63) */ | ||
754 | #define RT5651_PWR_VREF1 (0x1 << 15) | ||
755 | #define RT5651_PWR_VREF1_BIT 15 | ||
756 | #define RT5651_PWR_FV1 (0x1 << 14) | ||
757 | #define RT5651_PWR_FV1_BIT 14 | ||
758 | #define RT5651_PWR_MB (0x1 << 13) | ||
759 | #define RT5651_PWR_MB_BIT 13 | ||
760 | #define RT5651_PWR_LM (0x1 << 12) | ||
761 | #define RT5651_PWR_LM_BIT 12 | ||
762 | #define RT5651_PWR_BG (0x1 << 11) | ||
763 | #define RT5651_PWR_BG_BIT 11 | ||
764 | #define RT5651_PWR_HP_L (0x1 << 7) | ||
765 | #define RT5651_PWR_HP_L_BIT 7 | ||
766 | #define RT5651_PWR_HP_R (0x1 << 6) | ||
767 | #define RT5651_PWR_HP_R_BIT 6 | ||
768 | #define RT5651_PWR_HA (0x1 << 5) | ||
769 | #define RT5651_PWR_HA_BIT 5 | ||
770 | #define RT5651_PWR_VREF2 (0x1 << 4) | ||
771 | #define RT5651_PWR_VREF2_BIT 4 | ||
772 | #define RT5651_PWR_FV2 (0x1 << 3) | ||
773 | #define RT5651_PWR_FV2_BIT 3 | ||
774 | #define RT5651_PWR_LDO (0x1 << 2) | ||
775 | #define RT5651_PWR_LDO_BIT 2 | ||
776 | #define RT5651_PWR_LDO_DVO_MASK (0x3) | ||
777 | #define RT5651_PWR_LDO_DVO_1_0V 0 | ||
778 | #define RT5651_PWR_LDO_DVO_1_1V 1 | ||
779 | #define RT5651_PWR_LDO_DVO_1_2V 2 | ||
780 | #define RT5651_PWR_LDO_DVO_1_3V 3 | ||
781 | |||
782 | /* Power Management for Analog 2 (0x64) */ | ||
783 | #define RT5651_PWR_BST1 (0x1 << 15) | ||
784 | #define RT5651_PWR_BST1_BIT 15 | ||
785 | #define RT5651_PWR_BST2 (0x1 << 14) | ||
786 | #define RT5651_PWR_BST2_BIT 14 | ||
787 | #define RT5651_PWR_BST3 (0x1 << 13) | ||
788 | #define RT5651_PWR_BST3_BIT 13 | ||
789 | #define RT5651_PWR_MB1 (0x1 << 11) | ||
790 | #define RT5651_PWR_MB1_BIT 11 | ||
791 | #define RT5651_PWR_PLL (0x1 << 9) | ||
792 | #define RT5651_PWR_PLL_BIT 9 | ||
793 | #define RT5651_PWR_BST1_OP2 (0x1 << 5) | ||
794 | #define RT5651_PWR_BST1_OP2_BIT 5 | ||
795 | #define RT5651_PWR_BST2_OP2 (0x1 << 4) | ||
796 | #define RT5651_PWR_BST2_OP2_BIT 4 | ||
797 | #define RT5651_PWR_BST3_OP2 (0x1 << 3) | ||
798 | #define RT5651_PWR_BST3_OP2_BIT 3 | ||
799 | #define RT5651_PWR_JD_M (0x1 << 2) | ||
800 | #define RT5651_PWM_JD_M_BIT 2 | ||
801 | #define RT5651_PWR_JD2 (0x1 << 1) | ||
802 | #define RT5651_PWM_JD2_BIT 1 | ||
803 | #define RT5651_PWR_JD3 (0x1) | ||
804 | #define RT5651_PWM_JD3_BIT 0 | ||
805 | |||
806 | /* Power Management for Mixer (0x65) */ | ||
807 | #define RT5651_PWR_OM_L (0x1 << 15) | ||
808 | #define RT5651_PWR_OM_L_BIT 15 | ||
809 | #define RT5651_PWR_OM_R (0x1 << 14) | ||
810 | #define RT5651_PWR_OM_R_BIT 14 | ||
811 | #define RT5651_PWR_RM_L (0x1 << 11) | ||
812 | #define RT5651_PWR_RM_L_BIT 11 | ||
813 | #define RT5651_PWR_RM_R (0x1 << 10) | ||
814 | #define RT5651_PWR_RM_R_BIT 10 | ||
815 | |||
816 | /* Power Management for Volume (0x66) */ | ||
817 | #define RT5651_PWR_OV_L (0x1 << 13) | ||
818 | #define RT5651_PWR_OV_L_BIT 13 | ||
819 | #define RT5651_PWR_OV_R (0x1 << 12) | ||
820 | #define RT5651_PWR_OV_R_BIT 12 | ||
821 | #define RT5651_PWR_HV_L (0x1 << 11) | ||
822 | #define RT5651_PWR_HV_L_BIT 11 | ||
823 | #define RT5651_PWR_HV_R (0x1 << 10) | ||
824 | #define RT5651_PWR_HV_R_BIT 10 | ||
825 | #define RT5651_PWR_IN1_L (0x1 << 9) | ||
826 | #define RT5651_PWR_IN1_L_BIT 9 | ||
827 | #define RT5651_PWR_IN1_R (0x1 << 8) | ||
828 | #define RT5651_PWR_IN1_R_BIT 8 | ||
829 | #define RT5651_PWR_IN2_L (0x1 << 7) | ||
830 | #define RT5651_PWR_IN2_L_BIT 7 | ||
831 | #define RT5651_PWR_IN2_R (0x1 << 6) | ||
832 | #define RT5651_PWR_IN2_R_BIT 6 | ||
833 | |||
834 | /* I2S1/2/3 Audio Serial Data Port Control (0x70 0x71) */ | ||
835 | #define RT5651_I2S_MS_MASK (0x1 << 15) | ||
836 | #define RT5651_I2S_MS_SFT 15 | ||
837 | #define RT5651_I2S_MS_M (0x0 << 15) | ||
838 | #define RT5651_I2S_MS_S (0x1 << 15) | ||
839 | #define RT5651_I2S_O_CP_MASK (0x3 << 10) | ||
840 | #define RT5651_I2S_O_CP_SFT 10 | ||
841 | #define RT5651_I2S_O_CP_OFF (0x0 << 10) | ||
842 | #define RT5651_I2S_O_CP_U_LAW (0x1 << 10) | ||
843 | #define RT5651_I2S_O_CP_A_LAW (0x2 << 10) | ||
844 | #define RT5651_I2S_I_CP_MASK (0x3 << 8) | ||
845 | #define RT5651_I2S_I_CP_SFT 8 | ||
846 | #define RT5651_I2S_I_CP_OFF (0x0 << 8) | ||
847 | #define RT5651_I2S_I_CP_U_LAW (0x1 << 8) | ||
848 | #define RT5651_I2S_I_CP_A_LAW (0x2 << 8) | ||
849 | #define RT5651_I2S_BP_MASK (0x1 << 7) | ||
850 | #define RT5651_I2S_BP_SFT 7 | ||
851 | #define RT5651_I2S_BP_NOR (0x0 << 7) | ||
852 | #define RT5651_I2S_BP_INV (0x1 << 7) | ||
853 | #define RT5651_I2S_DL_MASK (0x3 << 2) | ||
854 | #define RT5651_I2S_DL_SFT 2 | ||
855 | #define RT5651_I2S_DL_16 (0x0 << 2) | ||
856 | #define RT5651_I2S_DL_20 (0x1 << 2) | ||
857 | #define RT5651_I2S_DL_24 (0x2 << 2) | ||
858 | #define RT5651_I2S_DL_8 (0x3 << 2) | ||
859 | #define RT5651_I2S_DF_MASK (0x3) | ||
860 | #define RT5651_I2S_DF_SFT 0 | ||
861 | #define RT5651_I2S_DF_I2S (0x0) | ||
862 | #define RT5651_I2S_DF_LEFT (0x1) | ||
863 | #define RT5651_I2S_DF_PCM_A (0x2) | ||
864 | #define RT5651_I2S_DF_PCM_B (0x3) | ||
865 | |||
866 | /* ADC/DAC Clock Control 1 (0x73) */ | ||
867 | #define RT5651_I2S_PD1_MASK (0x7 << 12) | ||
868 | #define RT5651_I2S_PD1_SFT 12 | ||
869 | #define RT5651_I2S_PD1_1 (0x0 << 12) | ||
870 | #define RT5651_I2S_PD1_2 (0x1 << 12) | ||
871 | #define RT5651_I2S_PD1_3 (0x2 << 12) | ||
872 | #define RT5651_I2S_PD1_4 (0x3 << 12) | ||
873 | #define RT5651_I2S_PD1_6 (0x4 << 12) | ||
874 | #define RT5651_I2S_PD1_8 (0x5 << 12) | ||
875 | #define RT5651_I2S_PD1_12 (0x6 << 12) | ||
876 | #define RT5651_I2S_PD1_16 (0x7 << 12) | ||
877 | #define RT5651_I2S_BCLK_MS2_MASK (0x1 << 11) | ||
878 | #define RT5651_I2S_BCLK_MS2_SFT 11 | ||
879 | #define RT5651_I2S_BCLK_MS2_32 (0x0 << 11) | ||
880 | #define RT5651_I2S_BCLK_MS2_64 (0x1 << 11) | ||
881 | #define RT5651_I2S_PD2_MASK (0x7 << 8) | ||
882 | #define RT5651_I2S_PD2_SFT 8 | ||
883 | #define RT5651_I2S_PD2_1 (0x0 << 8) | ||
884 | #define RT5651_I2S_PD2_2 (0x1 << 8) | ||
885 | #define RT5651_I2S_PD2_3 (0x2 << 8) | ||
886 | #define RT5651_I2S_PD2_4 (0x3 << 8) | ||
887 | #define RT5651_I2S_PD2_6 (0x4 << 8) | ||
888 | #define RT5651_I2S_PD2_8 (0x5 << 8) | ||
889 | #define RT5651_I2S_PD2_12 (0x6 << 8) | ||
890 | #define RT5651_I2S_PD2_16 (0x7 << 8) | ||
891 | #define RT5651_DAC_OSR_MASK (0x3 << 2) | ||
892 | #define RT5651_DAC_OSR_SFT 2 | ||
893 | #define RT5651_DAC_OSR_128 (0x0 << 2) | ||
894 | #define RT5651_DAC_OSR_64 (0x1 << 2) | ||
895 | #define RT5651_DAC_OSR_32 (0x2 << 2) | ||
896 | #define RT5651_DAC_OSR_128_3 (0x3 << 2) | ||
897 | #define RT5651_ADC_OSR_MASK (0x3) | ||
898 | #define RT5651_ADC_OSR_SFT 0 | ||
899 | #define RT5651_ADC_OSR_128 (0x0) | ||
900 | #define RT5651_ADC_OSR_64 (0x1) | ||
901 | #define RT5651_ADC_OSR_32 (0x2) | ||
902 | #define RT5651_ADC_OSR_128_3 (0x3) | ||
903 | |||
904 | /* ADC/DAC Clock Control 2 (0x74) */ | ||
905 | #define RT5651_DAHPF_EN (0x1 << 11) | ||
906 | #define RT5651_DAHPF_EN_SFT 11 | ||
907 | #define RT5651_ADHPF_EN (0x1 << 10) | ||
908 | #define RT5651_ADHPF_EN_SFT 10 | ||
909 | |||
910 | /* Digital Microphone Control (0x75) */ | ||
911 | #define RT5651_DMIC_1_EN_MASK (0x1 << 15) | ||
912 | #define RT5651_DMIC_1_EN_SFT 15 | ||
913 | #define RT5651_DMIC_1_DIS (0x0 << 15) | ||
914 | #define RT5651_DMIC_1_EN (0x1 << 15) | ||
915 | #define RT5651_DMIC_1L_LH_MASK (0x1 << 13) | ||
916 | #define RT5651_DMIC_1L_LH_SFT 13 | ||
917 | #define RT5651_DMIC_1L_LH_FALLING (0x0 << 13) | ||
918 | #define RT5651_DMIC_1L_LH_RISING (0x1 << 13) | ||
919 | #define RT5651_DMIC_1R_LH_MASK (0x1 << 12) | ||
920 | #define RT5651_DMIC_1R_LH_SFT 12 | ||
921 | #define RT5651_DMIC_1R_LH_FALLING (0x0 << 12) | ||
922 | #define RT5651_DMIC_1R_LH_RISING (0x1 << 12) | ||
923 | #define RT5651_DMIC_1_DP_MASK (0x3 << 10) | ||
924 | #define RT5651_DMIC_1_DP_SFT 10 | ||
925 | #define RT5651_DMIC_1_DP_GPIO6 (0x0 << 10) | ||
926 | #define RT5651_DMIC_1_DP_IN1P (0x1 << 10) | ||
927 | #define RT5651_DMIC_2_DP_GPIO8 (0x2 << 10) | ||
928 | #define RT5651_DMIC_CLK_MASK (0x7 << 5) | ||
929 | #define RT5651_DMIC_CLK_SFT 5 | ||
930 | |||
931 | /* TDM Control 1 (0x77) */ | ||
932 | #define RT5651_TDM_INTEL_SEL_MASK (0x1 << 15) | ||
933 | #define RT5651_TDM_INTEL_SEL_SFT 15 | ||
934 | #define RT5651_TDM_INTEL_SEL_64 (0x0 << 15) | ||
935 | #define RT5651_TDM_INTEL_SEL_50 (0x1 << 15) | ||
936 | #define RT5651_TDM_MODE_SEL_MASK (0x1 << 14) | ||
937 | #define RT5651_TDM_MODE_SEL_SFT 14 | ||
938 | #define RT5651_TDM_MODE_SEL_NOR (0x0 << 14) | ||
939 | #define RT5651_TDM_MODE_SEL_TDM (0x1 << 14) | ||
940 | #define RT5651_TDM_CH_NUM_SEL_MASK (0x3 << 12) | ||
941 | #define RT5651_TDM_CH_NUM_SEL_SFT 12 | ||
942 | #define RT5651_TDM_CH_NUM_SEL_2 (0x0 << 12) | ||
943 | #define RT5651_TDM_CH_NUM_SEL_4 (0x1 << 12) | ||
944 | #define RT5651_TDM_CH_NUM_SEL_6 (0x2 << 12) | ||
945 | #define RT5651_TDM_CH_NUM_SEL_8 (0x3 << 12) | ||
946 | #define RT5651_TDM_CH_LEN_SEL_MASK (0x3 << 10) | ||
947 | #define RT5651_TDM_CH_LEN_SEL_SFT 10 | ||
948 | #define RT5651_TDM_CH_LEN_SEL_16 (0x0 << 10) | ||
949 | #define RT5651_TDM_CH_LEN_SEL_20 (0x1 << 10) | ||
950 | #define RT5651_TDM_CH_LEN_SEL_24 (0x2 << 10) | ||
951 | #define RT5651_TDM_CH_LEN_SEL_32 (0x3 << 10) | ||
952 | #define RT5651_TDM_ADC_SEL_MASK (0x1 << 9) | ||
953 | #define RT5651_TDM_ADC_SEL_SFT 9 | ||
954 | #define RT5651_TDM_ADC_SEL_NOR (0x0 << 9) | ||
955 | #define RT5651_TDM_ADC_SEL_SWAP (0x1 << 9) | ||
956 | #define RT5651_TDM_ADC_START_SEL_MASK (0x1 << 8) | ||
957 | #define RT5651_TDM_ADC_START_SEL_SFT 8 | ||
958 | #define RT5651_TDM_ADC_START_SEL_SL0 (0x0 << 8) | ||
959 | #define RT5651_TDM_ADC_START_SEL_SL4 (0x1 << 8) | ||
960 | #define RT5651_TDM_I2S_CH2_SEL_MASK (0x3 << 6) | ||
961 | #define RT5651_TDM_I2S_CH2_SEL_SFT 6 | ||
962 | #define RT5651_TDM_I2S_CH2_SEL_LR (0x0 << 6) | ||
963 | #define RT5651_TDM_I2S_CH2_SEL_RL (0x1 << 6) | ||
964 | #define RT5651_TDM_I2S_CH2_SEL_LL (0x2 << 6) | ||
965 | #define RT5651_TDM_I2S_CH2_SEL_RR (0x3 << 6) | ||
966 | #define RT5651_TDM_I2S_CH4_SEL_MASK (0x3 << 4) | ||
967 | #define RT5651_TDM_I2S_CH4_SEL_SFT 4 | ||
968 | #define RT5651_TDM_I2S_CH4_SEL_LR (0x0 << 4) | ||
969 | #define RT5651_TDM_I2S_CH4_SEL_RL (0x1 << 4) | ||
970 | #define RT5651_TDM_I2S_CH4_SEL_LL (0x2 << 4) | ||
971 | #define RT5651_TDM_I2S_CH4_SEL_RR (0x3 << 4) | ||
972 | #define RT5651_TDM_I2S_CH6_SEL_MASK (0x3 << 2) | ||
973 | #define RT5651_TDM_I2S_CH6_SEL_SFT 2 | ||
974 | #define RT5651_TDM_I2S_CH6_SEL_LR (0x0 << 2) | ||
975 | #define RT5651_TDM_I2S_CH6_SEL_RL (0x1 << 2) | ||
976 | #define RT5651_TDM_I2S_CH6_SEL_LL (0x2 << 2) | ||
977 | #define RT5651_TDM_I2S_CH6_SEL_RR (0x3 << 2) | ||
978 | #define RT5651_TDM_I2S_CH8_SEL_MASK (0x3) | ||
979 | #define RT5651_TDM_I2S_CH8_SEL_SFT 0 | ||
980 | #define RT5651_TDM_I2S_CH8_SEL_LR (0x0) | ||
981 | #define RT5651_TDM_I2S_CH8_SEL_RL (0x1) | ||
982 | #define RT5651_TDM_I2S_CH8_SEL_LL (0x2) | ||
983 | #define RT5651_TDM_I2S_CH8_SEL_RR (0x3) | ||
984 | |||
985 | /* TDM Control 2 (0x78) */ | ||
986 | #define RT5651_TDM_LRCK_POL_SEL_MASK (0x1 << 15) | ||
987 | #define RT5651_TDM_LRCK_POL_SEL_SFT 15 | ||
988 | #define RT5651_TDM_LRCK_POL_SEL_NOR (0x0 << 15) | ||
989 | #define RT5651_TDM_LRCK_POL_SEL_INV (0x1 << 15) | ||
990 | #define RT5651_TDM_CH_VAL_SEL_MASK (0x1 << 14) | ||
991 | #define RT5651_TDM_CH_VAL_SEL_SFT 14 | ||
992 | #define RT5651_TDM_CH_VAL_SEL_CH01 (0x0 << 14) | ||
993 | #define RT5651_TDM_CH_VAL_SEL_CH0123 (0x1 << 14) | ||
994 | #define RT5651_TDM_CH_VAL_EN (0x1 << 13) | ||
995 | #define RT5651_TDM_CH_VAL_SFT 13 | ||
996 | #define RT5651_TDM_LPBK_EN (0x1 << 12) | ||
997 | #define RT5651_TDM_LPBK_SFT 12 | ||
998 | #define RT5651_TDM_LRCK_PULSE_SEL_MASK (0x1 << 11) | ||
999 | #define RT5651_TDM_LRCK_PULSE_SEL_SFT 11 | ||
1000 | #define RT5651_TDM_LRCK_PULSE_SEL_BCLK (0x0 << 11) | ||
1001 | #define RT5651_TDM_LRCK_PULSE_SEL_CH (0x1 << 11) | ||
1002 | #define RT5651_TDM_END_EDGE_SEL_MASK (0x1 << 10) | ||
1003 | #define RT5651_TDM_END_EDGE_SEL_SFT 10 | ||
1004 | #define RT5651_TDM_END_EDGE_SEL_POS (0x0 << 10) | ||
1005 | #define RT5651_TDM_END_EDGE_SEL_NEG (0x1 << 10) | ||
1006 | #define RT5651_TDM_END_EDGE_EN (0x1 << 9) | ||
1007 | #define RT5651_TDM_END_EDGE_EN_SFT 9 | ||
1008 | #define RT5651_TDM_TRAN_EDGE_SEL_MASK (0x1 << 8) | ||
1009 | #define RT5651_TDM_TRAN_EDGE_SEL_SFT 8 | ||
1010 | #define RT5651_TDM_TRAN_EDGE_SEL_POS (0x0 << 8) | ||
1011 | #define RT5651_TDM_TRAN_EDGE_SEL_NEG (0x1 << 8) | ||
1012 | #define RT5651_M_TDM2_L (0x1 << 7) | ||
1013 | #define RT5651_M_TDM2_L_SFT 7 | ||
1014 | #define RT5651_M_TDM2_R (0x1 << 6) | ||
1015 | #define RT5651_M_TDM2_R_SFT 6 | ||
1016 | #define RT5651_M_TDM4_L (0x1 << 5) | ||
1017 | #define RT5651_M_TDM4_L_SFT 5 | ||
1018 | #define RT5651_M_TDM4_R (0x1 << 4) | ||
1019 | #define RT5651_M_TDM4_R_SFT 4 | ||
1020 | |||
1021 | /* TDM Control 3 (0x79) */ | ||
1022 | #define RT5651_CH2_L_SEL_MASK (0x7 << 12) | ||
1023 | #define RT5651_CH2_L_SEL_SFT 12 | ||
1024 | #define RT5651_CH2_L_SEL_SL0 (0x0 << 12) | ||
1025 | #define RT5651_CH2_L_SEL_SL1 (0x1 << 12) | ||
1026 | #define RT5651_CH2_L_SEL_SL2 (0x2 << 12) | ||
1027 | #define RT5651_CH2_L_SEL_SL3 (0x3 << 12) | ||
1028 | #define RT5651_CH2_L_SEL_SL4 (0x4 << 12) | ||
1029 | #define RT5651_CH2_L_SEL_SL5 (0x5 << 12) | ||
1030 | #define RT5651_CH2_L_SEL_SL6 (0x6 << 12) | ||
1031 | #define RT5651_CH2_L_SEL_SL7 (0x7 << 12) | ||
1032 | #define RT5651_CH2_R_SEL_MASK (0x7 << 8) | ||
1033 | #define RT5651_CH2_R_SEL_SFT 8 | ||
1034 | #define RT5651_CH2_R_SEL_SL0 (0x0 << 8) | ||
1035 | #define RT5651_CH2_R_SEL_SL1 (0x1 << 8) | ||
1036 | #define RT5651_CH2_R_SEL_SL2 (0x2 << 8) | ||
1037 | #define RT5651_CH2_R_SEL_SL3 (0x3 << 8) | ||
1038 | #define RT5651_CH2_R_SEL_SL4 (0x4 << 8) | ||
1039 | #define RT5651_CH2_R_SEL_SL5 (0x5 << 8) | ||
1040 | #define RT5651_CH2_R_SEL_SL6 (0x6 << 8) | ||
1041 | #define RT5651_CH2_R_SEL_SL7 (0x7 << 8) | ||
1042 | #define RT5651_CH4_L_SEL_MASK (0x7 << 4) | ||
1043 | #define RT5651_CH4_L_SEL_SFT 4 | ||
1044 | #define RT5651_CH4_L_SEL_SL0 (0x0 << 4) | ||
1045 | #define RT5651_CH4_L_SEL_SL1 (0x1 << 4) | ||
1046 | #define RT5651_CH4_L_SEL_SL2 (0x2 << 4) | ||
1047 | #define RT5651_CH4_L_SEL_SL3 (0x3 << 4) | ||
1048 | #define RT5651_CH4_L_SEL_SL4 (0x4 << 4) | ||
1049 | #define RT5651_CH4_L_SEL_SL5 (0x5 << 4) | ||
1050 | #define RT5651_CH4_L_SEL_SL6 (0x6 << 4) | ||
1051 | #define RT5651_CH4_L_SEL_SL7 (0x7 << 4) | ||
1052 | #define RT5651_CH4_R_SEL_MASK (0x7) | ||
1053 | #define RT5651_CH4_R_SEL_SFT 0 | ||
1054 | #define RT5651_CH4_R_SEL_SL0 (0x0) | ||
1055 | #define RT5651_CH4_R_SEL_SL1 (0x1) | ||
1056 | #define RT5651_CH4_R_SEL_SL2 (0x2) | ||
1057 | #define RT5651_CH4_R_SEL_SL3 (0x3) | ||
1058 | #define RT5651_CH4_R_SEL_SL4 (0x4) | ||
1059 | #define RT5651_CH4_R_SEL_SL5 (0x5) | ||
1060 | #define RT5651_CH4_R_SEL_SL6 (0x6) | ||
1061 | #define RT5651_CH4_R_SEL_SL7 (0x7) | ||
1062 | |||
1063 | /* Global Clock Control (0x80) */ | ||
1064 | #define RT5651_SCLK_SRC_MASK (0x3 << 14) | ||
1065 | #define RT5651_SCLK_SRC_SFT 14 | ||
1066 | #define RT5651_SCLK_SRC_MCLK (0x0 << 14) | ||
1067 | #define RT5651_SCLK_SRC_PLL1 (0x1 << 14) | ||
1068 | #define RT5651_SCLK_SRC_RCCLK (0x2 << 14) | ||
1069 | #define RT5651_PLL1_SRC_MASK (0x3 << 12) | ||
1070 | #define RT5651_PLL1_SRC_SFT 12 | ||
1071 | #define RT5651_PLL1_SRC_MCLK (0x0 << 12) | ||
1072 | #define RT5651_PLL1_SRC_BCLK1 (0x1 << 12) | ||
1073 | #define RT5651_PLL1_SRC_BCLK2 (0x2 << 12) | ||
1074 | #define RT5651_PLL1_PD_MASK (0x1 << 3) | ||
1075 | #define RT5651_PLL1_PD_SFT 3 | ||
1076 | #define RT5651_PLL1_PD_1 (0x0 << 3) | ||
1077 | #define RT5651_PLL1_PD_2 (0x1 << 3) | ||
1078 | |||
1079 | #define RT5651_PLL_INP_MAX 40000000 | ||
1080 | #define RT5651_PLL_INP_MIN 256000 | ||
1081 | /* PLL M/N/K Code Control 1 (0x81) */ | ||
1082 | #define RT5651_PLL_N_MAX 0x1ff | ||
1083 | #define RT5651_PLL_N_MASK (RT5651_PLL_N_MAX << 7) | ||
1084 | #define RT5651_PLL_N_SFT 7 | ||
1085 | #define RT5651_PLL_K_MAX 0x1f | ||
1086 | #define RT5651_PLL_K_MASK (RT5651_PLL_K_MAX) | ||
1087 | #define RT5651_PLL_K_SFT 0 | ||
1088 | |||
1089 | /* PLL M/N/K Code Control 2 (0x82) */ | ||
1090 | #define RT5651_PLL_M_MAX 0xf | ||
1091 | #define RT5651_PLL_M_MASK (RT5651_PLL_M_MAX << 12) | ||
1092 | #define RT5651_PLL_M_SFT 12 | ||
1093 | #define RT5651_PLL_M_BP (0x1 << 11) | ||
1094 | #define RT5651_PLL_M_BP_SFT 11 | ||
1095 | |||
1096 | /* PLL tracking mode 1 (0x83) */ | ||
1097 | #define RT5651_STO1_T_MASK (0x1 << 15) | ||
1098 | #define RT5651_STO1_T_SFT 15 | ||
1099 | #define RT5651_STO1_T_SCLK (0x0 << 15) | ||
1100 | #define RT5651_STO1_T_LRCK1 (0x1 << 15) | ||
1101 | #define RT5651_STO2_T_MASK (0x1 << 12) | ||
1102 | #define RT5651_STO2_T_SFT 12 | ||
1103 | #define RT5651_STO2_T_I2S2 (0x0 << 12) | ||
1104 | #define RT5651_STO2_T_LRCK2 (0x1 << 12) | ||
1105 | #define RT5651_ASRC2_REF_MASK (0x1 << 11) | ||
1106 | #define RT5651_ASRC2_REF_SFT 11 | ||
1107 | #define RT5651_ASRC2_REF_LRCK2 (0x0 << 11) | ||
1108 | #define RT5651_ASRC2_REF_LRCK1 (0x1 << 11) | ||
1109 | #define RT5651_DMIC_1_M_MASK (0x1 << 9) | ||
1110 | #define RT5651_DMIC_1_M_SFT 9 | ||
1111 | #define RT5651_DMIC_1_M_NOR (0x0 << 9) | ||
1112 | #define RT5651_DMIC_1_M_ASYN (0x1 << 9) | ||
1113 | |||
1114 | /* PLL tracking mode 2 (0x84) */ | ||
1115 | #define RT5651_STO1_ASRC_EN (0x1 << 15) | ||
1116 | #define RT5651_STO1_ASRC_EN_SFT 15 | ||
1117 | #define RT5651_STO2_ASRC_EN (0x1 << 14) | ||
1118 | #define RT5651_STO2_ASRC_EN_SFT 14 | ||
1119 | #define RT5651_STO1_DAC_M_MASK (0x1 << 13) | ||
1120 | #define RT5651_STO1_DAC_M_SFT 13 | ||
1121 | #define RT5651_STO1_DAC_M_NOR (0x0 << 13) | ||
1122 | #define RT5651_STO1_DAC_M_ASRC (0x1 << 13) | ||
1123 | #define RT5651_STO2_DAC_M_MASK (0x1 << 12) | ||
1124 | #define RT5651_STO2_DAC_M_SFT 12 | ||
1125 | #define RT5651_STO2_DAC_M_NOR (0x0 << 12) | ||
1126 | #define RT5651_STO2_DAC_M_ASRC (0x1 << 12) | ||
1127 | #define RT5651_ADC_M_MASK (0x1 << 11) | ||
1128 | #define RT5651_ADC_M_SFT 11 | ||
1129 | #define RT5651_ADC_M_NOR (0x0 << 11) | ||
1130 | #define RT5651_ADC_M_ASRC (0x1 << 11) | ||
1131 | #define RT5651_I2S1_R_D_MASK (0x1 << 4) | ||
1132 | #define RT5651_I2S1_R_D_SFT 4 | ||
1133 | #define RT5651_I2S1_R_D_DIS (0x0 << 4) | ||
1134 | #define RT5651_I2S1_R_D_EN (0x1 << 4) | ||
1135 | #define RT5651_I2S2_R_D_MASK (0x1 << 3) | ||
1136 | #define RT5651_I2S2_R_D_SFT 3 | ||
1137 | #define RT5651_I2S2_R_D_DIS (0x0 << 3) | ||
1138 | #define RT5651_I2S2_R_D_EN (0x1 << 3) | ||
1139 | #define RT5651_PRE_SCLK_MASK (0x3) | ||
1140 | #define RT5651_PRE_SCLK_SFT 0 | ||
1141 | #define RT5651_PRE_SCLK_512 (0x0) | ||
1142 | #define RT5651_PRE_SCLK_1024 (0x1) | ||
1143 | #define RT5651_PRE_SCLK_2048 (0x2) | ||
1144 | |||
1145 | /* PLL tracking mode 3 (0x85) */ | ||
1146 | #define RT5651_I2S1_RATE_MASK (0xf << 12) | ||
1147 | #define RT5651_I2S1_RATE_SFT 12 | ||
1148 | #define RT5651_I2S2_RATE_MASK (0xf << 8) | ||
1149 | #define RT5651_I2S2_RATE_SFT 8 | ||
1150 | #define RT5651_G_ASRC_LP_MASK (0x1 << 3) | ||
1151 | #define RT5651_G_ASRC_LP_SFT 3 | ||
1152 | #define RT5651_ASRC_LP_F_M (0x1 << 2) | ||
1153 | #define RT5651_ASRC_LP_F_SFT 2 | ||
1154 | #define RT5651_ASRC_LP_F_NOR (0x0 << 2) | ||
1155 | #define RT5651_ASRC_LP_F_SB (0x1 << 2) | ||
1156 | #define RT5651_FTK_PH_DET_MASK (0x3) | ||
1157 | #define RT5651_FTK_PH_DET_SFT 0 | ||
1158 | #define RT5651_FTK_PH_DET_DIV1 (0x0) | ||
1159 | #define RT5651_FTK_PH_DET_DIV2 (0x1) | ||
1160 | #define RT5651_FTK_PH_DET_DIV4 (0x2) | ||
1161 | #define RT5651_FTK_PH_DET_DIV8 (0x3) | ||
1162 | |||
1163 | /*PLL tracking mode 6 (0x89) */ | ||
1164 | #define RT5651_I2S1_PD_MASK (0x7 << 12) | ||
1165 | #define RT5651_I2S1_PD_SFT 12 | ||
1166 | #define RT5651_I2S2_PD_MASK (0x7 << 8) | ||
1167 | #define RT5651_I2S2_PD_SFT 8 | ||
1168 | |||
1169 | /*PLL tracking mode 7 (0x8a) */ | ||
1170 | #define RT5651_FSI1_RATE_MASK (0xf << 12) | ||
1171 | #define RT5651_FSI1_RATE_SFT 12 | ||
1172 | #define RT5651_FSI2_RATE_MASK (0xf << 8) | ||
1173 | #define RT5651_FSI2_RATE_SFT 8 | ||
1174 | |||
1175 | /* HPOUT Over Current Detection (0x8b) */ | ||
1176 | #define RT5651_HP_OVCD_MASK (0x1 << 10) | ||
1177 | #define RT5651_HP_OVCD_SFT 10 | ||
1178 | #define RT5651_HP_OVCD_DIS (0x0 << 10) | ||
1179 | #define RT5651_HP_OVCD_EN (0x1 << 10) | ||
1180 | #define RT5651_HP_OC_TH_MASK (0x3 << 8) | ||
1181 | #define RT5651_HP_OC_TH_SFT 8 | ||
1182 | #define RT5651_HP_OC_TH_90 (0x0 << 8) | ||
1183 | #define RT5651_HP_OC_TH_105 (0x1 << 8) | ||
1184 | #define RT5651_HP_OC_TH_120 (0x2 << 8) | ||
1185 | #define RT5651_HP_OC_TH_135 (0x3 << 8) | ||
1186 | |||
1187 | /* Depop Mode Control 1 (0x8e) */ | ||
1188 | #define RT5651_SMT_TRIG_MASK (0x1 << 15) | ||
1189 | #define RT5651_SMT_TRIG_SFT 15 | ||
1190 | #define RT5651_SMT_TRIG_DIS (0x0 << 15) | ||
1191 | #define RT5651_SMT_TRIG_EN (0x1 << 15) | ||
1192 | #define RT5651_HP_L_SMT_MASK (0x1 << 9) | ||
1193 | #define RT5651_HP_L_SMT_SFT 9 | ||
1194 | #define RT5651_HP_L_SMT_DIS (0x0 << 9) | ||
1195 | #define RT5651_HP_L_SMT_EN (0x1 << 9) | ||
1196 | #define RT5651_HP_R_SMT_MASK (0x1 << 8) | ||
1197 | #define RT5651_HP_R_SMT_SFT 8 | ||
1198 | #define RT5651_HP_R_SMT_DIS (0x0 << 8) | ||
1199 | #define RT5651_HP_R_SMT_EN (0x1 << 8) | ||
1200 | #define RT5651_HP_CD_PD_MASK (0x1 << 7) | ||
1201 | #define RT5651_HP_CD_PD_SFT 7 | ||
1202 | #define RT5651_HP_CD_PD_DIS (0x0 << 7) | ||
1203 | #define RT5651_HP_CD_PD_EN (0x1 << 7) | ||
1204 | #define RT5651_RSTN_MASK (0x1 << 6) | ||
1205 | #define RT5651_RSTN_SFT 6 | ||
1206 | #define RT5651_RSTN_DIS (0x0 << 6) | ||
1207 | #define RT5651_RSTN_EN (0x1 << 6) | ||
1208 | #define RT5651_RSTP_MASK (0x1 << 5) | ||
1209 | #define RT5651_RSTP_SFT 5 | ||
1210 | #define RT5651_RSTP_DIS (0x0 << 5) | ||
1211 | #define RT5651_RSTP_EN (0x1 << 5) | ||
1212 | #define RT5651_HP_CO_MASK (0x1 << 4) | ||
1213 | #define RT5651_HP_CO_SFT 4 | ||
1214 | #define RT5651_HP_CO_DIS (0x0 << 4) | ||
1215 | #define RT5651_HP_CO_EN (0x1 << 4) | ||
1216 | #define RT5651_HP_CP_MASK (0x1 << 3) | ||
1217 | #define RT5651_HP_CP_SFT 3 | ||
1218 | #define RT5651_HP_CP_PD (0x0 << 3) | ||
1219 | #define RT5651_HP_CP_PU (0x1 << 3) | ||
1220 | #define RT5651_HP_SG_MASK (0x1 << 2) | ||
1221 | #define RT5651_HP_SG_SFT 2 | ||
1222 | #define RT5651_HP_SG_DIS (0x0 << 2) | ||
1223 | #define RT5651_HP_SG_EN (0x1 << 2) | ||
1224 | #define RT5651_HP_DP_MASK (0x1 << 1) | ||
1225 | #define RT5651_HP_DP_SFT 1 | ||
1226 | #define RT5651_HP_DP_PD (0x0 << 1) | ||
1227 | #define RT5651_HP_DP_PU (0x1 << 1) | ||
1228 | #define RT5651_HP_CB_MASK (0x1) | ||
1229 | #define RT5651_HP_CB_SFT 0 | ||
1230 | #define RT5651_HP_CB_PD (0x0) | ||
1231 | #define RT5651_HP_CB_PU (0x1) | ||
1232 | |||
1233 | /* Depop Mode Control 2 (0x8f) */ | ||
1234 | #define RT5651_DEPOP_MASK (0x1 << 13) | ||
1235 | #define RT5651_DEPOP_SFT 13 | ||
1236 | #define RT5651_DEPOP_AUTO (0x0 << 13) | ||
1237 | #define RT5651_DEPOP_MAN (0x1 << 13) | ||
1238 | #define RT5651_RAMP_MASK (0x1 << 12) | ||
1239 | #define RT5651_RAMP_SFT 12 | ||
1240 | #define RT5651_RAMP_DIS (0x0 << 12) | ||
1241 | #define RT5651_RAMP_EN (0x1 << 12) | ||
1242 | #define RT5651_BPS_MASK (0x1 << 11) | ||
1243 | #define RT5651_BPS_SFT 11 | ||
1244 | #define RT5651_BPS_DIS (0x0 << 11) | ||
1245 | #define RT5651_BPS_EN (0x1 << 11) | ||
1246 | #define RT5651_FAST_UPDN_MASK (0x1 << 10) | ||
1247 | #define RT5651_FAST_UPDN_SFT 10 | ||
1248 | #define RT5651_FAST_UPDN_DIS (0x0 << 10) | ||
1249 | #define RT5651_FAST_UPDN_EN (0x1 << 10) | ||
1250 | #define RT5651_MRES_MASK (0x3 << 8) | ||
1251 | #define RT5651_MRES_SFT 8 | ||
1252 | #define RT5651_MRES_15MO (0x0 << 8) | ||
1253 | #define RT5651_MRES_25MO (0x1 << 8) | ||
1254 | #define RT5651_MRES_35MO (0x2 << 8) | ||
1255 | #define RT5651_MRES_45MO (0x3 << 8) | ||
1256 | #define RT5651_VLO_MASK (0x1 << 7) | ||
1257 | #define RT5651_VLO_SFT 7 | ||
1258 | #define RT5651_VLO_3V (0x0 << 7) | ||
1259 | #define RT5651_VLO_32V (0x1 << 7) | ||
1260 | #define RT5651_DIG_DP_MASK (0x1 << 6) | ||
1261 | #define RT5651_DIG_DP_SFT 6 | ||
1262 | #define RT5651_DIG_DP_DIS (0x0 << 6) | ||
1263 | #define RT5651_DIG_DP_EN (0x1 << 6) | ||
1264 | #define RT5651_DP_TH_MASK (0x3 << 4) | ||
1265 | #define RT5651_DP_TH_SFT 4 | ||
1266 | |||
1267 | /* Depop Mode Control 3 (0x90) */ | ||
1268 | #define RT5651_CP_SYS_MASK (0x7 << 12) | ||
1269 | #define RT5651_CP_SYS_SFT 12 | ||
1270 | #define RT5651_CP_FQ1_MASK (0x7 << 8) | ||
1271 | #define RT5651_CP_FQ1_SFT 8 | ||
1272 | #define RT5651_CP_FQ2_MASK (0x7 << 4) | ||
1273 | #define RT5651_CP_FQ2_SFT 4 | ||
1274 | #define RT5651_CP_FQ3_MASK (0x7) | ||
1275 | #define RT5651_CP_FQ3_SFT 0 | ||
1276 | #define RT5651_CP_FQ_1_5_KHZ 0 | ||
1277 | #define RT5651_CP_FQ_3_KHZ 1 | ||
1278 | #define RT5651_CP_FQ_6_KHZ 2 | ||
1279 | #define RT5651_CP_FQ_12_KHZ 3 | ||
1280 | #define RT5651_CP_FQ_24_KHZ 4 | ||
1281 | #define RT5651_CP_FQ_48_KHZ 5 | ||
1282 | #define RT5651_CP_FQ_96_KHZ 6 | ||
1283 | #define RT5651_CP_FQ_192_KHZ 7 | ||
1284 | |||
1285 | /* HPOUT charge pump (0x91) */ | ||
1286 | #define RT5651_OSW_L_MASK (0x1 << 11) | ||
1287 | #define RT5651_OSW_L_SFT 11 | ||
1288 | #define RT5651_OSW_L_DIS (0x0 << 11) | ||
1289 | #define RT5651_OSW_L_EN (0x1 << 11) | ||
1290 | #define RT5651_OSW_R_MASK (0x1 << 10) | ||
1291 | #define RT5651_OSW_R_SFT 10 | ||
1292 | #define RT5651_OSW_R_DIS (0x0 << 10) | ||
1293 | #define RT5651_OSW_R_EN (0x1 << 10) | ||
1294 | #define RT5651_PM_HP_MASK (0x3 << 8) | ||
1295 | #define RT5651_PM_HP_SFT 8 | ||
1296 | #define RT5651_PM_HP_LV (0x0 << 8) | ||
1297 | #define RT5651_PM_HP_MV (0x1 << 8) | ||
1298 | #define RT5651_PM_HP_HV (0x2 << 8) | ||
1299 | #define RT5651_IB_HP_MASK (0x3 << 6) | ||
1300 | #define RT5651_IB_HP_SFT 6 | ||
1301 | #define RT5651_IB_HP_125IL (0x0 << 6) | ||
1302 | #define RT5651_IB_HP_25IL (0x1 << 6) | ||
1303 | #define RT5651_IB_HP_5IL (0x2 << 6) | ||
1304 | #define RT5651_IB_HP_1IL (0x3 << 6) | ||
1305 | |||
1306 | /* Micbias Control (0x93) */ | ||
1307 | #define RT5651_MIC1_BS_MASK (0x1 << 15) | ||
1308 | #define RT5651_MIC1_BS_SFT 15 | ||
1309 | #define RT5651_MIC1_BS_9AV (0x0 << 15) | ||
1310 | #define RT5651_MIC1_BS_75AV (0x1 << 15) | ||
1311 | #define RT5651_MIC1_CLK_MASK (0x1 << 13) | ||
1312 | #define RT5651_MIC1_CLK_SFT 13 | ||
1313 | #define RT5651_MIC1_CLK_DIS (0x0 << 13) | ||
1314 | #define RT5651_MIC1_CLK_EN (0x1 << 13) | ||
1315 | #define RT5651_MIC1_OVCD_MASK (0x1 << 11) | ||
1316 | #define RT5651_MIC1_OVCD_SFT 11 | ||
1317 | #define RT5651_MIC1_OVCD_DIS (0x0 << 11) | ||
1318 | #define RT5651_MIC1_OVCD_EN (0x1 << 11) | ||
1319 | #define RT5651_MIC1_OVTH_MASK (0x3 << 9) | ||
1320 | #define RT5651_MIC1_OVTH_SFT 9 | ||
1321 | #define RT5651_MIC1_OVTH_600UA (0x0 << 9) | ||
1322 | #define RT5651_MIC1_OVTH_1500UA (0x1 << 9) | ||
1323 | #define RT5651_MIC1_OVTH_2000UA (0x2 << 9) | ||
1324 | #define RT5651_PWR_MB_MASK (0x1 << 5) | ||
1325 | #define RT5651_PWR_MB_SFT 5 | ||
1326 | #define RT5651_PWR_MB_PD (0x0 << 5) | ||
1327 | #define RT5651_PWR_MB_PU (0x1 << 5) | ||
1328 | #define RT5651_PWR_CLK12M_MASK (0x1 << 4) | ||
1329 | #define RT5651_PWR_CLK12M_SFT 4 | ||
1330 | #define RT5651_PWR_CLK12M_PD (0x0 << 4) | ||
1331 | #define RT5651_PWR_CLK12M_PU (0x1 << 4) | ||
1332 | |||
1333 | /* Analog JD Control 1 (0x94) */ | ||
1334 | #define RT5651_JD2_CMP_MASK (0x7 << 12) | ||
1335 | #define RT5651_JD2_CMP_SFT 12 | ||
1336 | #define RT5651_JD_PU (0x1 << 11) | ||
1337 | #define RT5651_JD_PU_SFT 11 | ||
1338 | #define RT5651_JD_PD (0x1 << 10) | ||
1339 | #define RT5651_JD_PD_SFT 10 | ||
1340 | #define RT5651_JD_MODE_SEL_MASK (0x3 << 8) | ||
1341 | #define RT5651_JD_MODE_SEL_SFT 8 | ||
1342 | #define RT5651_JD_MODE_SEL_M0 (0x0 << 8) | ||
1343 | #define RT5651_JD_MODE_SEL_M1 (0x1 << 8) | ||
1344 | #define RT5651_JD_MODE_SEL_M2 (0x2 << 8) | ||
1345 | #define RT5651_JD_M_CMP (0x7 << 4) | ||
1346 | #define RT5651_JD_M_CMP_SFT 4 | ||
1347 | #define RT5651_JD_M_PU (0x1 << 3) | ||
1348 | #define RT5651_JD_M_PU_SFT 3 | ||
1349 | #define RT5651_JD_M_PD (0x1 << 2) | ||
1350 | #define RT5651_JD_M_PD_SFT 2 | ||
1351 | #define RT5651_JD_M_MODE_SEL_MASK (0x3) | ||
1352 | #define RT5651_JD_M_MODE_SEL_SFT 0 | ||
1353 | #define RT5651_JD_M_MODE_SEL_M0 (0x0) | ||
1354 | #define RT5651_JD_M_MODE_SEL_M1 (0x1) | ||
1355 | #define RT5651_JD_M_MODE_SEL_M2 (0x2) | ||
1356 | |||
1357 | /* Analog JD Control 2 (0x95) */ | ||
1358 | #define RT5651_JD3_CMP_MASK (0x7 << 12) | ||
1359 | #define RT5651_JD3_CMP_SFT 12 | ||
1360 | |||
1361 | /* EQ Control 1 (0xb0) */ | ||
1362 | #define RT5651_EQ_SRC_MASK (0x1 << 15) | ||
1363 | #define RT5651_EQ_SRC_SFT 15 | ||
1364 | #define RT5651_EQ_SRC_DAC (0x0 << 15) | ||
1365 | #define RT5651_EQ_SRC_ADC (0x1 << 15) | ||
1366 | #define RT5651_EQ_UPD (0x1 << 14) | ||
1367 | #define RT5651_EQ_UPD_BIT 14 | ||
1368 | #define RT5651_EQ_CD_MASK (0x1 << 13) | ||
1369 | #define RT5651_EQ_CD_SFT 13 | ||
1370 | #define RT5651_EQ_CD_DIS (0x0 << 13) | ||
1371 | #define RT5651_EQ_CD_EN (0x1 << 13) | ||
1372 | #define RT5651_EQ_DITH_MASK (0x3 << 8) | ||
1373 | #define RT5651_EQ_DITH_SFT 8 | ||
1374 | #define RT5651_EQ_DITH_NOR (0x0 << 8) | ||
1375 | #define RT5651_EQ_DITH_LSB (0x1 << 8) | ||
1376 | #define RT5651_EQ_DITH_LSB_1 (0x2 << 8) | ||
1377 | #define RT5651_EQ_DITH_LSB_2 (0x3 << 8) | ||
1378 | #define RT5651_EQ_CD_F (0x1 << 7) | ||
1379 | #define RT5651_EQ_CD_F_BIT 7 | ||
1380 | #define RT5651_EQ_STA_HP2 (0x1 << 6) | ||
1381 | #define RT5651_EQ_STA_HP2_BIT 6 | ||
1382 | #define RT5651_EQ_STA_HP1 (0x1 << 5) | ||
1383 | #define RT5651_EQ_STA_HP1_BIT 5 | ||
1384 | #define RT5651_EQ_STA_BP4 (0x1 << 4) | ||
1385 | #define RT5651_EQ_STA_BP4_BIT 4 | ||
1386 | #define RT5651_EQ_STA_BP3 (0x1 << 3) | ||
1387 | #define RT5651_EQ_STA_BP3_BIT 3 | ||
1388 | #define RT5651_EQ_STA_BP2 (0x1 << 2) | ||
1389 | #define RT5651_EQ_STA_BP2_BIT 2 | ||
1390 | #define RT5651_EQ_STA_BP1 (0x1 << 1) | ||
1391 | #define RT5651_EQ_STA_BP1_BIT 1 | ||
1392 | #define RT5651_EQ_STA_LP (0x1) | ||
1393 | #define RT5651_EQ_STA_LP_BIT 0 | ||
1394 | |||
1395 | /* EQ Control 2 (0xb1) */ | ||
1396 | #define RT5651_EQ_HPF1_M_MASK (0x1 << 8) | ||
1397 | #define RT5651_EQ_HPF1_M_SFT 8 | ||
1398 | #define RT5651_EQ_HPF1_M_HI (0x0 << 8) | ||
1399 | #define RT5651_EQ_HPF1_M_1ST (0x1 << 8) | ||
1400 | #define RT5651_EQ_LPF1_M_MASK (0x1 << 7) | ||
1401 | #define RT5651_EQ_LPF1_M_SFT 7 | ||
1402 | #define RT5651_EQ_LPF1_M_LO (0x0 << 7) | ||
1403 | #define RT5651_EQ_LPF1_M_1ST (0x1 << 7) | ||
1404 | #define RT5651_EQ_HPF2_MASK (0x1 << 6) | ||
1405 | #define RT5651_EQ_HPF2_SFT 6 | ||
1406 | #define RT5651_EQ_HPF2_DIS (0x0 << 6) | ||
1407 | #define RT5651_EQ_HPF2_EN (0x1 << 6) | ||
1408 | #define RT5651_EQ_HPF1_MASK (0x1 << 5) | ||
1409 | #define RT5651_EQ_HPF1_SFT 5 | ||
1410 | #define RT5651_EQ_HPF1_DIS (0x0 << 5) | ||
1411 | #define RT5651_EQ_HPF1_EN (0x1 << 5) | ||
1412 | #define RT5651_EQ_BPF4_MASK (0x1 << 4) | ||
1413 | #define RT5651_EQ_BPF4_SFT 4 | ||
1414 | #define RT5651_EQ_BPF4_DIS (0x0 << 4) | ||
1415 | #define RT5651_EQ_BPF4_EN (0x1 << 4) | ||
1416 | #define RT5651_EQ_BPF3_MASK (0x1 << 3) | ||
1417 | #define RT5651_EQ_BPF3_SFT 3 | ||
1418 | #define RT5651_EQ_BPF3_DIS (0x0 << 3) | ||
1419 | #define RT5651_EQ_BPF3_EN (0x1 << 3) | ||
1420 | #define RT5651_EQ_BPF2_MASK (0x1 << 2) | ||
1421 | #define RT5651_EQ_BPF2_SFT 2 | ||
1422 | #define RT5651_EQ_BPF2_DIS (0x0 << 2) | ||
1423 | #define RT5651_EQ_BPF2_EN (0x1 << 2) | ||
1424 | #define RT5651_EQ_BPF1_MASK (0x1 << 1) | ||
1425 | #define RT5651_EQ_BPF1_SFT 1 | ||
1426 | #define RT5651_EQ_BPF1_DIS (0x0 << 1) | ||
1427 | #define RT5651_EQ_BPF1_EN (0x1 << 1) | ||
1428 | #define RT5651_EQ_LPF_MASK (0x1) | ||
1429 | #define RT5651_EQ_LPF_SFT 0 | ||
1430 | #define RT5651_EQ_LPF_DIS (0x0) | ||
1431 | #define RT5651_EQ_LPF_EN (0x1) | ||
1432 | #define RT5651_EQ_CTRL_MASK (0x7f) | ||
1433 | |||
1434 | /* Memory Test (0xb2) */ | ||
1435 | #define RT5651_MT_MASK (0x1 << 15) | ||
1436 | #define RT5651_MT_SFT 15 | ||
1437 | #define RT5651_MT_DIS (0x0 << 15) | ||
1438 | #define RT5651_MT_EN (0x1 << 15) | ||
1439 | |||
1440 | /* ALC Control 1 (0xb4) */ | ||
1441 | #define RT5651_ALC_P_MASK (0x1 << 15) | ||
1442 | #define RT5651_ALC_P_SFT 15 | ||
1443 | #define RT5651_ALC_P_DAC (0x0 << 15) | ||
1444 | #define RT5651_ALC_P_ADC (0x1 << 15) | ||
1445 | #define RT5651_ALC_MASK (0x1 << 14) | ||
1446 | #define RT5651_ALC_SFT 14 | ||
1447 | #define RT5651_ALC_DIS (0x0 << 14) | ||
1448 | #define RT5651_ALC_EN (0x1 << 14) | ||
1449 | #define RT5651_ALC_UPD (0x1 << 13) | ||
1450 | #define RT5651_ALC_UPD_BIT 13 | ||
1451 | #define RT5651_ALC_AR_MASK (0x1f << 8) | ||
1452 | #define RT5651_ALC_AR_SFT 8 | ||
1453 | #define RT5651_ALC_R_MASK (0x7 << 5) | ||
1454 | #define RT5651_ALC_R_SFT 5 | ||
1455 | #define RT5651_ALC_R_48K (0x1 << 5) | ||
1456 | #define RT5651_ALC_R_96K (0x2 << 5) | ||
1457 | #define RT5651_ALC_R_192K (0x3 << 5) | ||
1458 | #define RT5651_ALC_R_441K (0x5 << 5) | ||
1459 | #define RT5651_ALC_R_882K (0x6 << 5) | ||
1460 | #define RT5651_ALC_R_1764K (0x7 << 5) | ||
1461 | #define RT5651_ALC_RC_MASK (0x1f) | ||
1462 | #define RT5651_ALC_RC_SFT 0 | ||
1463 | |||
1464 | /* ALC Control 2 (0xb5) */ | ||
1465 | #define RT5651_ALC_POB_MASK (0x3f << 8) | ||
1466 | #define RT5651_ALC_POB_SFT 8 | ||
1467 | #define RT5651_ALC_DRC_MASK (0x1 << 7) | ||
1468 | #define RT5651_ALC_DRC_SFT 7 | ||
1469 | #define RT5651_ALC_DRC_DIS (0x0 << 7) | ||
1470 | #define RT5651_ALC_DRC_EN (0x1 << 7) | ||
1471 | #define RT5651_ALC_CPR_MASK (0x3 << 5) | ||
1472 | #define RT5651_ALC_CPR_SFT 5 | ||
1473 | #define RT5651_ALC_CPR_1_1 (0x0 << 5) | ||
1474 | #define RT5651_ALC_CPR_1_2 (0x1 << 5) | ||
1475 | #define RT5651_ALC_CPR_1_4 (0x2 << 5) | ||
1476 | #define RT5651_ALC_CPR_1_8 (0x3 << 5) | ||
1477 | #define RT5651_ALC_PRB_MASK (0x1f) | ||
1478 | #define RT5651_ALC_PRB_SFT 0 | ||
1479 | |||
1480 | /* ALC Control 3 (0xb6) */ | ||
1481 | #define RT5651_ALC_NGB_MASK (0xf << 12) | ||
1482 | #define RT5651_ALC_NGB_SFT 12 | ||
1483 | #define RT5651_ALC_TAR_MASK (0x1f << 7) | ||
1484 | #define RT5651_ALC_TAR_SFT 7 | ||
1485 | #define RT5651_ALC_NG_MASK (0x1 << 6) | ||
1486 | #define RT5651_ALC_NG_SFT 6 | ||
1487 | #define RT5651_ALC_NG_DIS (0x0 << 6) | ||
1488 | #define RT5651_ALC_NG_EN (0x1 << 6) | ||
1489 | #define RT5651_ALC_NGH_MASK (0x1 << 5) | ||
1490 | #define RT5651_ALC_NGH_SFT 5 | ||
1491 | #define RT5651_ALC_NGH_DIS (0x0 << 5) | ||
1492 | #define RT5651_ALC_NGH_EN (0x1 << 5) | ||
1493 | #define RT5651_ALC_NGT_MASK (0x1f) | ||
1494 | #define RT5651_ALC_NGT_SFT 0 | ||
1495 | |||
1496 | /* Jack Detect Control 1 (0xbb) */ | ||
1497 | #define RT5651_JD_MASK (0x7 << 13) | ||
1498 | #define RT5651_JD_SFT 13 | ||
1499 | #define RT5651_JD_DIS (0x0 << 13) | ||
1500 | #define RT5651_JD_GPIO1 (0x1 << 13) | ||
1501 | #define RT5651_JD_GPIO2 (0x2 << 13) | ||
1502 | #define RT5651_JD_GPIO3 (0x3 << 13) | ||
1503 | #define RT5651_JD_GPIO4 (0x4 << 13) | ||
1504 | #define RT5651_JD_GPIO5 (0x5 << 13) | ||
1505 | #define RT5651_JD_GPIO6 (0x6 << 13) | ||
1506 | #define RT5651_JD_HP_MASK (0x1 << 11) | ||
1507 | #define RT5651_JD_HP_SFT 11 | ||
1508 | #define RT5651_JD_HP_DIS (0x0 << 11) | ||
1509 | #define RT5651_JD_HP_EN (0x1 << 11) | ||
1510 | #define RT5651_JD_HP_TRG_MASK (0x1 << 10) | ||
1511 | #define RT5651_JD_HP_TRG_SFT 10 | ||
1512 | #define RT5651_JD_HP_TRG_LO (0x0 << 10) | ||
1513 | #define RT5651_JD_HP_TRG_HI (0x1 << 10) | ||
1514 | #define RT5651_JD_SPL_MASK (0x1 << 9) | ||
1515 | #define RT5651_JD_SPL_SFT 9 | ||
1516 | #define RT5651_JD_SPL_DIS (0x0 << 9) | ||
1517 | #define RT5651_JD_SPL_EN (0x1 << 9) | ||
1518 | #define RT5651_JD_SPL_TRG_MASK (0x1 << 8) | ||
1519 | #define RT5651_JD_SPL_TRG_SFT 8 | ||
1520 | #define RT5651_JD_SPL_TRG_LO (0x0 << 8) | ||
1521 | #define RT5651_JD_SPL_TRG_HI (0x1 << 8) | ||
1522 | #define RT5651_JD_SPR_MASK (0x1 << 7) | ||
1523 | #define RT5651_JD_SPR_SFT 7 | ||
1524 | #define RT5651_JD_SPR_DIS (0x0 << 7) | ||
1525 | #define RT5651_JD_SPR_EN (0x1 << 7) | ||
1526 | #define RT5651_JD_SPR_TRG_MASK (0x1 << 6) | ||
1527 | #define RT5651_JD_SPR_TRG_SFT 6 | ||
1528 | #define RT5651_JD_SPR_TRG_LO (0x0 << 6) | ||
1529 | #define RT5651_JD_SPR_TRG_HI (0x1 << 6) | ||
1530 | #define RT5651_JD_LO_MASK (0x1 << 3) | ||
1531 | #define RT5651_JD_LO_SFT 3 | ||
1532 | #define RT5651_JD_LO_DIS (0x0 << 3) | ||
1533 | #define RT5651_JD_LO_EN (0x1 << 3) | ||
1534 | #define RT5651_JD_LO_TRG_MASK (0x1 << 2) | ||
1535 | #define RT5651_JD_LO_TRG_SFT 2 | ||
1536 | #define RT5651_JD_LO_TRG_LO (0x0 << 2) | ||
1537 | #define RT5651_JD_LO_TRG_HI (0x1 << 2) | ||
1538 | |||
1539 | /* Jack Detect Control 2 (0xbc) */ | ||
1540 | #define RT5651_JD_TRG_SEL_MASK (0x7 << 9) | ||
1541 | #define RT5651_JD_TRG_SEL_SFT 9 | ||
1542 | #define RT5651_JD_TRG_SEL_GPIO (0x0 << 9) | ||
1543 | #define RT5651_JD_TRG_SEL_JD1_1 (0x1 << 9) | ||
1544 | #define RT5651_JD_TRG_SEL_JD1_2 (0x2 << 9) | ||
1545 | #define RT5651_JD_TRG_SEL_JD2 (0x3 << 9) | ||
1546 | #define RT5651_JD_TRG_SEL_JD3 (0x4 << 9) | ||
1547 | #define RT5651_JD3_IRQ_EN (0x1 << 8) | ||
1548 | #define RT5651_JD3_IRQ_EN_SFT 8 | ||
1549 | #define RT5651_JD3_EN_STKY (0x1 << 7) | ||
1550 | #define RT5651_JD3_EN_STKY_SFT 7 | ||
1551 | #define RT5651_JD3_INV (0x1 << 6) | ||
1552 | #define RT5651_JD3_INV_SFT 6 | ||
1553 | |||
1554 | /* IRQ Control 1 (0xbd) */ | ||
1555 | #define RT5651_IRQ_JD_MASK (0x1 << 15) | ||
1556 | #define RT5651_IRQ_JD_SFT 15 | ||
1557 | #define RT5651_IRQ_JD_BP (0x0 << 15) | ||
1558 | #define RT5651_IRQ_JD_NOR (0x1 << 15) | ||
1559 | #define RT5651_JD_STKY_MASK (0x1 << 13) | ||
1560 | #define RT5651_JD_STKY_SFT 13 | ||
1561 | #define RT5651_JD_STKY_DIS (0x0 << 13) | ||
1562 | #define RT5651_JD_STKY_EN (0x1 << 13) | ||
1563 | #define RT5651_JD_P_MASK (0x1 << 11) | ||
1564 | #define RT5651_JD_P_SFT 11 | ||
1565 | #define RT5651_JD_P_NOR (0x0 << 11) | ||
1566 | #define RT5651_JD_P_INV (0x1 << 11) | ||
1567 | #define RT5651_JD1_1_IRQ_EN (0x1 << 9) | ||
1568 | #define RT5651_JD1_1_IRQ_EN_SFT 9 | ||
1569 | #define RT5651_JD1_1_EN_STKY (0x1 << 8) | ||
1570 | #define RT5651_JD1_1_EN_STKY_SFT 8 | ||
1571 | #define RT5651_JD1_1_INV (0x1 << 7) | ||
1572 | #define RT5651_JD1_1_INV_SFT 7 | ||
1573 | #define RT5651_JD1_2_IRQ_EN (0x1 << 6) | ||
1574 | #define RT5651_JD1_2_IRQ_EN_SFT 6 | ||
1575 | #define RT5651_JD1_2_EN_STKY (0x1 << 5) | ||
1576 | #define RT5651_JD1_2_EN_STKY_SFT 5 | ||
1577 | #define RT5651_JD1_2_INV (0x1 << 4) | ||
1578 | #define RT5651_JD1_2_INV_SFT 4 | ||
1579 | #define RT5651_JD2_IRQ_EN (0x1 << 3) | ||
1580 | #define RT5651_JD2_IRQ_EN_SFT 3 | ||
1581 | #define RT5651_JD2_EN_STKY (0x1 << 2) | ||
1582 | #define RT5651_JD2_EN_STKY_SFT 2 | ||
1583 | #define RT5651_JD2_INV (0x1 << 1) | ||
1584 | #define RT5651_JD2_INV_SFT 1 | ||
1585 | |||
1586 | /* IRQ Control 2 (0xbe) */ | ||
1587 | #define RT5651_IRQ_MB1_OC_MASK (0x1 << 15) | ||
1588 | #define RT5651_IRQ_MB1_OC_SFT 15 | ||
1589 | #define RT5651_IRQ_MB1_OC_BP (0x0 << 15) | ||
1590 | #define RT5651_IRQ_MB1_OC_NOR (0x1 << 15) | ||
1591 | #define RT5651_MB1_OC_STKY_MASK (0x1 << 11) | ||
1592 | #define RT5651_MB1_OC_STKY_SFT 11 | ||
1593 | #define RT5651_MB1_OC_STKY_DIS (0x0 << 11) | ||
1594 | #define RT5651_MB1_OC_STKY_EN (0x1 << 11) | ||
1595 | #define RT5651_MB1_OC_P_MASK (0x1 << 7) | ||
1596 | #define RT5651_MB1_OC_P_SFT 7 | ||
1597 | #define RT5651_MB1_OC_P_NOR (0x0 << 7) | ||
1598 | #define RT5651_MB1_OC_P_INV (0x1 << 7) | ||
1599 | #define RT5651_MB2_OC_P_MASK (0x1 << 6) | ||
1600 | #define RT5651_MB1_OC_CLR (0x1 << 3) | ||
1601 | #define RT5651_MB1_OC_CLR_SFT 3 | ||
1602 | #define RT5651_STA_GPIO8 (0x1) | ||
1603 | #define RT5651_STA_GPIO8_BIT 0 | ||
1604 | |||
1605 | /* Internal Status and GPIO status (0xbf) */ | ||
1606 | #define RT5651_STA_JD3 (0x1 << 15) | ||
1607 | #define RT5651_STA_JD3_BIT 15 | ||
1608 | #define RT5651_STA_JD2 (0x1 << 14) | ||
1609 | #define RT5651_STA_JD2_BIT 14 | ||
1610 | #define RT5651_STA_JD1_2 (0x1 << 13) | ||
1611 | #define RT5651_STA_JD1_2_BIT 13 | ||
1612 | #define RT5651_STA_JD1_1 (0x1 << 12) | ||
1613 | #define RT5651_STA_JD1_1_BIT 12 | ||
1614 | #define RT5651_STA_GP7 (0x1 << 11) | ||
1615 | #define RT5651_STA_GP7_BIT 11 | ||
1616 | #define RT5651_STA_GP6 (0x1 << 10) | ||
1617 | #define RT5651_STA_GP6_BIT 10 | ||
1618 | #define RT5651_STA_GP5 (0x1 << 9) | ||
1619 | #define RT5651_STA_GP5_BIT 9 | ||
1620 | #define RT5651_STA_GP1 (0x1 << 8) | ||
1621 | #define RT5651_STA_GP1_BIT 8 | ||
1622 | #define RT5651_STA_GP2 (0x1 << 7) | ||
1623 | #define RT5651_STA_GP2_BIT 7 | ||
1624 | #define RT5651_STA_GP3 (0x1 << 6) | ||
1625 | #define RT5651_STA_GP3_BIT 6 | ||
1626 | #define RT5651_STA_GP4 (0x1 << 5) | ||
1627 | #define RT5651_STA_GP4_BIT 5 | ||
1628 | #define RT5651_STA_GP_JD (0x1 << 4) | ||
1629 | #define RT5651_STA_GP_JD_BIT 4 | ||
1630 | |||
1631 | /* GPIO Control 1 (0xc0) */ | ||
1632 | #define RT5651_GP1_PIN_MASK (0x1 << 15) | ||
1633 | #define RT5651_GP1_PIN_SFT 15 | ||
1634 | #define RT5651_GP1_PIN_GPIO1 (0x0 << 15) | ||
1635 | #define RT5651_GP1_PIN_IRQ (0x1 << 15) | ||
1636 | #define RT5651_GP2_PIN_MASK (0x1 << 14) | ||
1637 | #define RT5651_GP2_PIN_SFT 14 | ||
1638 | #define RT5651_GP2_PIN_GPIO2 (0x0 << 14) | ||
1639 | #define RT5651_GP2_PIN_DMIC1_SCL (0x1 << 14) | ||
1640 | #define RT5651_GPIO_M_MASK (0x1 << 9) | ||
1641 | #define RT5651_GPIO_M_SFT 9 | ||
1642 | #define RT5651_GPIO_M_FLT (0x0 << 9) | ||
1643 | #define RT5651_GPIO_M_PH (0x1 << 9) | ||
1644 | #define RT5651_I2S2_SEL_MASK (0x1 << 8) | ||
1645 | #define RT5651_I2S2_SEL_SFT 8 | ||
1646 | #define RT5651_I2S2_SEL_I2S (0x0 << 8) | ||
1647 | #define RT5651_I2S2_SEL_GPIO (0x1 << 8) | ||
1648 | #define RT5651_GP5_PIN_MASK (0x1 << 7) | ||
1649 | #define RT5651_GP5_PIN_SFT 7 | ||
1650 | #define RT5651_GP5_PIN_GPIO5 (0x0 << 7) | ||
1651 | #define RT5651_GP5_PIN_IRQ (0x1 << 7) | ||
1652 | #define RT5651_GP6_PIN_MASK (0x1 << 6) | ||
1653 | #define RT5651_GP6_PIN_SFT 6 | ||
1654 | #define RT5651_GP6_PIN_GPIO6 (0x0 << 6) | ||
1655 | #define RT5651_GP6_PIN_DMIC_SDA (0x1 << 6) | ||
1656 | #define RT5651_GP7_PIN_MASK (0x1 << 5) | ||
1657 | #define RT5651_GP7_PIN_SFT 5 | ||
1658 | #define RT5651_GP7_PIN_GPIO7 (0x0 << 5) | ||
1659 | #define RT5651_GP7_PIN_IRQ (0x1 << 5) | ||
1660 | #define RT5651_GP8_PIN_MASK (0x1 << 4) | ||
1661 | #define RT5651_GP8_PIN_SFT 4 | ||
1662 | #define RT5651_GP8_PIN_GPIO8 (0x0 << 4) | ||
1663 | #define RT5651_GP8_PIN_DMIC_SDA (0x1 << 4) | ||
1664 | #define RT5651_GPIO_PDM_SEL_MASK (0x1 << 3) | ||
1665 | #define RT5651_GPIO_PDM_SEL_SFT 3 | ||
1666 | #define RT5651_GPIO_PDM_SEL_GPIO (0x0 << 3) | ||
1667 | #define RT5651_GPIO_PDM_SEL_PDM (0x1 << 3) | ||
1668 | |||
1669 | /* GPIO Control 2 (0xc1) */ | ||
1670 | #define RT5651_GP5_DR_MASK (0x1 << 14) | ||
1671 | #define RT5651_GP5_DR_SFT 14 | ||
1672 | #define RT5651_GP5_DR_IN (0x0 << 14) | ||
1673 | #define RT5651_GP5_DR_OUT (0x1 << 14) | ||
1674 | #define RT5651_GP5_OUT_MASK (0x1 << 13) | ||
1675 | #define RT5651_GP5_OUT_SFT 13 | ||
1676 | #define RT5651_GP5_OUT_LO (0x0 << 13) | ||
1677 | #define RT5651_GP5_OUT_HI (0x1 << 13) | ||
1678 | #define RT5651_GP5_P_MASK (0x1 << 12) | ||
1679 | #define RT5651_GP5_P_SFT 12 | ||
1680 | #define RT5651_GP5_P_NOR (0x0 << 12) | ||
1681 | #define RT5651_GP5_P_INV (0x1 << 12) | ||
1682 | #define RT5651_GP4_DR_MASK (0x1 << 11) | ||
1683 | #define RT5651_GP4_DR_SFT 11 | ||
1684 | #define RT5651_GP4_DR_IN (0x0 << 11) | ||
1685 | #define RT5651_GP4_DR_OUT (0x1 << 11) | ||
1686 | #define RT5651_GP4_OUT_MASK (0x1 << 10) | ||
1687 | #define RT5651_GP4_OUT_SFT 10 | ||
1688 | #define RT5651_GP4_OUT_LO (0x0 << 10) | ||
1689 | #define RT5651_GP4_OUT_HI (0x1 << 10) | ||
1690 | #define RT5651_GP4_P_MASK (0x1 << 9) | ||
1691 | #define RT5651_GP4_P_SFT 9 | ||
1692 | #define RT5651_GP4_P_NOR (0x0 << 9) | ||
1693 | #define RT5651_GP4_P_INV (0x1 << 9) | ||
1694 | #define RT5651_GP3_DR_MASK (0x1 << 8) | ||
1695 | #define RT5651_GP3_DR_SFT 8 | ||
1696 | #define RT5651_GP3_DR_IN (0x0 << 8) | ||
1697 | #define RT5651_GP3_DR_OUT (0x1 << 8) | ||
1698 | #define RT5651_GP3_OUT_MASK (0x1 << 7) | ||
1699 | #define RT5651_GP3_OUT_SFT 7 | ||
1700 | #define RT5651_GP3_OUT_LO (0x0 << 7) | ||
1701 | #define RT5651_GP3_OUT_HI (0x1 << 7) | ||
1702 | #define RT5651_GP3_P_MASK (0x1 << 6) | ||
1703 | #define RT5651_GP3_P_SFT 6 | ||
1704 | #define RT5651_GP3_P_NOR (0x0 << 6) | ||
1705 | #define RT5651_GP3_P_INV (0x1 << 6) | ||
1706 | #define RT5651_GP2_DR_MASK (0x1 << 5) | ||
1707 | #define RT5651_GP2_DR_SFT 5 | ||
1708 | #define RT5651_GP2_DR_IN (0x0 << 5) | ||
1709 | #define RT5651_GP2_DR_OUT (0x1 << 5) | ||
1710 | #define RT5651_GP2_OUT_MASK (0x1 << 4) | ||
1711 | #define RT5651_GP2_OUT_SFT 4 | ||
1712 | #define RT5651_GP2_OUT_LO (0x0 << 4) | ||
1713 | #define RT5651_GP2_OUT_HI (0x1 << 4) | ||
1714 | #define RT5651_GP2_P_MASK (0x1 << 3) | ||
1715 | #define RT5651_GP2_P_SFT 3 | ||
1716 | #define RT5651_GP2_P_NOR (0x0 << 3) | ||
1717 | #define RT5651_GP2_P_INV (0x1 << 3) | ||
1718 | #define RT5651_GP1_DR_MASK (0x1 << 2) | ||
1719 | #define RT5651_GP1_DR_SFT 2 | ||
1720 | #define RT5651_GP1_DR_IN (0x0 << 2) | ||
1721 | #define RT5651_GP1_DR_OUT (0x1 << 2) | ||
1722 | #define RT5651_GP1_OUT_MASK (0x1 << 1) | ||
1723 | #define RT5651_GP1_OUT_SFT 1 | ||
1724 | #define RT5651_GP1_OUT_LO (0x0 << 1) | ||
1725 | #define RT5651_GP1_OUT_HI (0x1 << 1) | ||
1726 | #define RT5651_GP1_P_MASK (0x1) | ||
1727 | #define RT5651_GP1_P_SFT 0 | ||
1728 | #define RT5651_GP1_P_NOR (0x0) | ||
1729 | #define RT5651_GP1_P_INV (0x1) | ||
1730 | |||
1731 | /* GPIO Control 3 (0xc2) */ | ||
1732 | #define RT5651_GP8_DR_MASK (0x1 << 8) | ||
1733 | #define RT5651_GP8_DR_SFT 8 | ||
1734 | #define RT5651_GP8_DR_IN (0x0 << 8) | ||
1735 | #define RT5651_GP8_DR_OUT (0x1 << 8) | ||
1736 | #define RT5651_GP8_OUT_MASK (0x1 << 7) | ||
1737 | #define RT5651_GP8_OUT_SFT 7 | ||
1738 | #define RT5651_GP8_OUT_LO (0x0 << 7) | ||
1739 | #define RT5651_GP8_OUT_HI (0x1 << 7) | ||
1740 | #define RT5651_GP8_P_MASK (0x1 << 6) | ||
1741 | #define RT5651_GP8_P_SFT 6 | ||
1742 | #define RT5651_GP8_P_NOR (0x0 << 6) | ||
1743 | #define RT5651_GP8_P_INV (0x1 << 6) | ||
1744 | #define RT5651_GP7_DR_MASK (0x1 << 5) | ||
1745 | #define RT5651_GP7_DR_SFT 5 | ||
1746 | #define RT5651_GP7_DR_IN (0x0 << 5) | ||
1747 | #define RT5651_GP7_DR_OUT (0x1 << 5) | ||
1748 | #define RT5651_GP7_OUT_MASK (0x1 << 4) | ||
1749 | #define RT5651_GP7_OUT_SFT 4 | ||
1750 | #define RT5651_GP7_OUT_LO (0x0 << 4) | ||
1751 | #define RT5651_GP7_OUT_HI (0x1 << 4) | ||
1752 | #define RT5651_GP7_P_MASK (0x1 << 3) | ||
1753 | #define RT5651_GP7_P_SFT 3 | ||
1754 | #define RT5651_GP7_P_NOR (0x0 << 3) | ||
1755 | #define RT5651_GP7_P_INV (0x1 << 3) | ||
1756 | #define RT5651_GP6_DR_MASK (0x1 << 2) | ||
1757 | #define RT5651_GP6_DR_SFT 2 | ||
1758 | #define RT5651_GP6_DR_IN (0x0 << 2) | ||
1759 | #define RT5651_GP6_DR_OUT (0x1 << 2) | ||
1760 | #define RT5651_GP6_OUT_MASK (0x1 << 1) | ||
1761 | #define RT5651_GP6_OUT_SFT 1 | ||
1762 | #define RT5651_GP6_OUT_LO (0x0 << 1) | ||
1763 | #define RT5651_GP6_OUT_HI (0x1 << 1) | ||
1764 | #define RT5651_GP6_P_MASK (0x1) | ||
1765 | #define RT5651_GP6_P_SFT 0 | ||
1766 | #define RT5651_GP6_P_NOR (0x0) | ||
1767 | #define RT5651_GP6_P_INV (0x1) | ||
1768 | |||
1769 | /* Scramble Control (0xce) */ | ||
1770 | #define RT5651_SCB_SWAP_MASK (0x1 << 15) | ||
1771 | #define RT5651_SCB_SWAP_SFT 15 | ||
1772 | #define RT5651_SCB_SWAP_DIS (0x0 << 15) | ||
1773 | #define RT5651_SCB_SWAP_EN (0x1 << 15) | ||
1774 | #define RT5651_SCB_MASK (0x1 << 14) | ||
1775 | #define RT5651_SCB_SFT 14 | ||
1776 | #define RT5651_SCB_DIS (0x0 << 14) | ||
1777 | #define RT5651_SCB_EN (0x1 << 14) | ||
1778 | |||
1779 | /* Baseback Control (0xcf) */ | ||
1780 | #define RT5651_BB_MASK (0x1 << 15) | ||
1781 | #define RT5651_BB_SFT 15 | ||
1782 | #define RT5651_BB_DIS (0x0 << 15) | ||
1783 | #define RT5651_BB_EN (0x1 << 15) | ||
1784 | #define RT5651_BB_CT_MASK (0x7 << 12) | ||
1785 | #define RT5651_BB_CT_SFT 12 | ||
1786 | #define RT5651_BB_CT_A (0x0 << 12) | ||
1787 | #define RT5651_BB_CT_B (0x1 << 12) | ||
1788 | #define RT5651_BB_CT_C (0x2 << 12) | ||
1789 | #define RT5651_BB_CT_D (0x3 << 12) | ||
1790 | #define RT5651_M_BB_L_MASK (0x1 << 9) | ||
1791 | #define RT5651_M_BB_L_SFT 9 | ||
1792 | #define RT5651_M_BB_R_MASK (0x1 << 8) | ||
1793 | #define RT5651_M_BB_R_SFT 8 | ||
1794 | #define RT5651_M_BB_HPF_L_MASK (0x1 << 7) | ||
1795 | #define RT5651_M_BB_HPF_L_SFT 7 | ||
1796 | #define RT5651_M_BB_HPF_R_MASK (0x1 << 6) | ||
1797 | #define RT5651_M_BB_HPF_R_SFT 6 | ||
1798 | #define RT5651_G_BB_BST_MASK (0x3f) | ||
1799 | #define RT5651_G_BB_BST_SFT 0 | ||
1800 | |||
1801 | /* MP3 Plus Control 1 (0xd0) */ | ||
1802 | #define RT5651_M_MP3_L_MASK (0x1 << 15) | ||
1803 | #define RT5651_M_MP3_L_SFT 15 | ||
1804 | #define RT5651_M_MP3_R_MASK (0x1 << 14) | ||
1805 | #define RT5651_M_MP3_R_SFT 14 | ||
1806 | #define RT5651_M_MP3_MASK (0x1 << 13) | ||
1807 | #define RT5651_M_MP3_SFT 13 | ||
1808 | #define RT5651_M_MP3_DIS (0x0 << 13) | ||
1809 | #define RT5651_M_MP3_EN (0x1 << 13) | ||
1810 | #define RT5651_EG_MP3_MASK (0x1f << 8) | ||
1811 | #define RT5651_EG_MP3_SFT 8 | ||
1812 | #define RT5651_MP3_HLP_MASK (0x1 << 7) | ||
1813 | #define RT5651_MP3_HLP_SFT 7 | ||
1814 | #define RT5651_MP3_HLP_DIS (0x0 << 7) | ||
1815 | #define RT5651_MP3_HLP_EN (0x1 << 7) | ||
1816 | #define RT5651_M_MP3_ORG_L_MASK (0x1 << 6) | ||
1817 | #define RT5651_M_MP3_ORG_L_SFT 6 | ||
1818 | #define RT5651_M_MP3_ORG_R_MASK (0x1 << 5) | ||
1819 | #define RT5651_M_MP3_ORG_R_SFT 5 | ||
1820 | |||
1821 | /* MP3 Plus Control 2 (0xd1) */ | ||
1822 | #define RT5651_MP3_WT_MASK (0x1 << 13) | ||
1823 | #define RT5651_MP3_WT_SFT 13 | ||
1824 | #define RT5651_MP3_WT_1_4 (0x0 << 13) | ||
1825 | #define RT5651_MP3_WT_1_2 (0x1 << 13) | ||
1826 | #define RT5651_OG_MP3_MASK (0x1f << 8) | ||
1827 | #define RT5651_OG_MP3_SFT 8 | ||
1828 | #define RT5651_HG_MP3_MASK (0x3f) | ||
1829 | #define RT5651_HG_MP3_SFT 0 | ||
1830 | |||
1831 | /* 3D HP Control 1 (0xd2) */ | ||
1832 | #define RT5651_3D_CF_MASK (0x1 << 15) | ||
1833 | #define RT5651_3D_CF_SFT 15 | ||
1834 | #define RT5651_3D_CF_DIS (0x0 << 15) | ||
1835 | #define RT5651_3D_CF_EN (0x1 << 15) | ||
1836 | #define RT5651_3D_HP_MASK (0x1 << 14) | ||
1837 | #define RT5651_3D_HP_SFT 14 | ||
1838 | #define RT5651_3D_HP_DIS (0x0 << 14) | ||
1839 | #define RT5651_3D_HP_EN (0x1 << 14) | ||
1840 | #define RT5651_3D_BT_MASK (0x1 << 13) | ||
1841 | #define RT5651_3D_BT_SFT 13 | ||
1842 | #define RT5651_3D_BT_DIS (0x0 << 13) | ||
1843 | #define RT5651_3D_BT_EN (0x1 << 13) | ||
1844 | #define RT5651_3D_1F_MIX_MASK (0x3 << 11) | ||
1845 | #define RT5651_3D_1F_MIX_SFT 11 | ||
1846 | #define RT5651_3D_HP_M_MASK (0x1 << 10) | ||
1847 | #define RT5651_3D_HP_M_SFT 10 | ||
1848 | #define RT5651_3D_HP_M_SUR (0x0 << 10) | ||
1849 | #define RT5651_3D_HP_M_FRO (0x1 << 10) | ||
1850 | #define RT5651_M_3D_HRTF_MASK (0x1 << 9) | ||
1851 | #define RT5651_M_3D_HRTF_SFT 9 | ||
1852 | #define RT5651_M_3D_D2H_MASK (0x1 << 8) | ||
1853 | #define RT5651_M_3D_D2H_SFT 8 | ||
1854 | #define RT5651_M_3D_D2R_MASK (0x1 << 7) | ||
1855 | #define RT5651_M_3D_D2R_SFT 7 | ||
1856 | #define RT5651_M_3D_REVB_MASK (0x1 << 6) | ||
1857 | #define RT5651_M_3D_REVB_SFT 6 | ||
1858 | |||
1859 | /* Adjustable high pass filter control 1 (0xd3) */ | ||
1860 | #define RT5651_2ND_HPF_MASK (0x1 << 15) | ||
1861 | #define RT5651_2ND_HPF_SFT 15 | ||
1862 | #define RT5651_2ND_HPF_DIS (0x0 << 15) | ||
1863 | #define RT5651_2ND_HPF_EN (0x1 << 15) | ||
1864 | #define RT5651_HPF_CF_L_MASK (0x7 << 12) | ||
1865 | #define RT5651_HPF_CF_L_SFT 12 | ||
1866 | #define RT5651_HPF_CF_R_MASK (0x7 << 8) | ||
1867 | #define RT5651_HPF_CF_R_SFT 8 | ||
1868 | #define RT5651_ZD_T_MASK (0x3 << 6) | ||
1869 | #define RT5651_ZD_T_SFT 6 | ||
1870 | #define RT5651_ZD_F_MASK (0x3 << 4) | ||
1871 | #define RT5651_ZD_F_SFT 4 | ||
1872 | #define RT5651_ZD_F_IM (0x0 << 4) | ||
1873 | #define RT5651_ZD_F_ZC_IM (0x1 << 4) | ||
1874 | #define RT5651_ZD_F_ZC_IOD (0x2 << 4) | ||
1875 | #define RT5651_ZD_F_UN (0x3 << 4) | ||
1876 | |||
1877 | /* Adjustable high pass filter control 2 (0xd4) */ | ||
1878 | #define RT5651_HPF_CF_L_NUM_MASK (0x3f << 8) | ||
1879 | #define RT5651_HPF_CF_L_NUM_SFT 8 | ||
1880 | #define RT5651_HPF_CF_R_NUM_MASK (0x3f) | ||
1881 | #define RT5651_HPF_CF_R_NUM_SFT 0 | ||
1882 | |||
1883 | /* HP calibration control and Amp detection (0xd6) */ | ||
1884 | #define RT5651_SI_DAC_MASK (0x1 << 11) | ||
1885 | #define RT5651_SI_DAC_SFT 11 | ||
1886 | #define RT5651_SI_DAC_AUTO (0x0 << 11) | ||
1887 | #define RT5651_SI_DAC_TEST (0x1 << 11) | ||
1888 | #define RT5651_DC_CAL_M_MASK (0x1 << 10) | ||
1889 | #define RT5651_DC_CAL_M_SFT 10 | ||
1890 | #define RT5651_DC_CAL_M_NOR (0x0 << 10) | ||
1891 | #define RT5651_DC_CAL_M_CAL (0x1 << 10) | ||
1892 | #define RT5651_DC_CAL_MASK (0x1 << 9) | ||
1893 | #define RT5651_DC_CAL_SFT 9 | ||
1894 | #define RT5651_DC_CAL_DIS (0x0 << 9) | ||
1895 | #define RT5651_DC_CAL_EN (0x1 << 9) | ||
1896 | #define RT5651_HPD_RCV_MASK (0x7 << 6) | ||
1897 | #define RT5651_HPD_RCV_SFT 6 | ||
1898 | #define RT5651_HPD_PS_MASK (0x1 << 5) | ||
1899 | #define RT5651_HPD_PS_SFT 5 | ||
1900 | #define RT5651_HPD_PS_DIS (0x0 << 5) | ||
1901 | #define RT5651_HPD_PS_EN (0x1 << 5) | ||
1902 | #define RT5651_CAL_M_MASK (0x1 << 4) | ||
1903 | #define RT5651_CAL_M_SFT 4 | ||
1904 | #define RT5651_CAL_M_DEP (0x0 << 4) | ||
1905 | #define RT5651_CAL_M_CAL (0x1 << 4) | ||
1906 | #define RT5651_CAL_MASK (0x1 << 3) | ||
1907 | #define RT5651_CAL_SFT 3 | ||
1908 | #define RT5651_CAL_DIS (0x0 << 3) | ||
1909 | #define RT5651_CAL_EN (0x1 << 3) | ||
1910 | #define RT5651_CAL_TEST_MASK (0x1 << 2) | ||
1911 | #define RT5651_CAL_TEST_SFT 2 | ||
1912 | #define RT5651_CAL_TEST_DIS (0x0 << 2) | ||
1913 | #define RT5651_CAL_TEST_EN (0x1 << 2) | ||
1914 | #define RT5651_CAL_P_MASK (0x3) | ||
1915 | #define RT5651_CAL_P_SFT 0 | ||
1916 | #define RT5651_CAL_P_NONE (0x0) | ||
1917 | #define RT5651_CAL_P_CAL (0x1) | ||
1918 | #define RT5651_CAL_P_DAC_CAL (0x2) | ||
1919 | |||
1920 | /* Soft volume and zero cross control 1 (0xd9) */ | ||
1921 | #define RT5651_SV_MASK (0x1 << 15) | ||
1922 | #define RT5651_SV_SFT 15 | ||
1923 | #define RT5651_SV_DIS (0x0 << 15) | ||
1924 | #define RT5651_SV_EN (0x1 << 15) | ||
1925 | #define RT5651_OUT_SV_MASK (0x1 << 13) | ||
1926 | #define RT5651_OUT_SV_SFT 13 | ||
1927 | #define RT5651_OUT_SV_DIS (0x0 << 13) | ||
1928 | #define RT5651_OUT_SV_EN (0x1 << 13) | ||
1929 | #define RT5651_HP_SV_MASK (0x1 << 12) | ||
1930 | #define RT5651_HP_SV_SFT 12 | ||
1931 | #define RT5651_HP_SV_DIS (0x0 << 12) | ||
1932 | #define RT5651_HP_SV_EN (0x1 << 12) | ||
1933 | #define RT5651_ZCD_DIG_MASK (0x1 << 11) | ||
1934 | #define RT5651_ZCD_DIG_SFT 11 | ||
1935 | #define RT5651_ZCD_DIG_DIS (0x0 << 11) | ||
1936 | #define RT5651_ZCD_DIG_EN (0x1 << 11) | ||
1937 | #define RT5651_ZCD_MASK (0x1 << 10) | ||
1938 | #define RT5651_ZCD_SFT 10 | ||
1939 | #define RT5651_ZCD_PD (0x0 << 10) | ||
1940 | #define RT5651_ZCD_PU (0x1 << 10) | ||
1941 | #define RT5651_M_ZCD_MASK (0x3f << 4) | ||
1942 | #define RT5651_M_ZCD_SFT 4 | ||
1943 | #define RT5651_M_ZCD_OM_L (0x1 << 7) | ||
1944 | #define RT5651_M_ZCD_OM_R (0x1 << 6) | ||
1945 | #define RT5651_M_ZCD_RM_L (0x1 << 5) | ||
1946 | #define RT5651_M_ZCD_RM_R (0x1 << 4) | ||
1947 | #define RT5651_SV_DLY_MASK (0xf) | ||
1948 | #define RT5651_SV_DLY_SFT 0 | ||
1949 | |||
1950 | /* Soft volume and zero cross control 2 (0xda) */ | ||
1951 | #define RT5651_ZCD_HP_MASK (0x1 << 15) | ||
1952 | #define RT5651_ZCD_HP_SFT 15 | ||
1953 | #define RT5651_ZCD_HP_DIS (0x0 << 15) | ||
1954 | #define RT5651_ZCD_HP_EN (0x1 << 15) | ||
1955 | |||
1956 | /* Digital Misc Control (0xfa) */ | ||
1957 | #define RT5651_I2S2_MS_SP_MASK (0x1 << 8) | ||
1958 | #define RT5651_I2S2_MS_SP_SEL 8 | ||
1959 | #define RT5651_I2S2_MS_SP_64 (0x0 << 8) | ||
1960 | #define RT5651_I2S2_MS_SP_50 (0x1 << 8) | ||
1961 | #define RT5651_CLK_DET_EN (0x1 << 3) | ||
1962 | #define RT5651_CLK_DET_EN_SFT 3 | ||
1963 | #define RT5651_AMP_DET_EN (0x1 << 1) | ||
1964 | #define RT5651_AMP_DET_EN_SFT 1 | ||
1965 | #define RT5651_D_GATE_EN (0x1) | ||
1966 | #define RT5651_D_GATE_EN_SFT 0 | ||
1967 | |||
1968 | /* Codec Private Register definition */ | ||
1969 | /* 3D Speaker Control (0x63) */ | ||
1970 | #define RT5651_3D_SPK_MASK (0x1 << 15) | ||
1971 | #define RT5651_3D_SPK_SFT 15 | ||
1972 | #define RT5651_3D_SPK_DIS (0x0 << 15) | ||
1973 | #define RT5651_3D_SPK_EN (0x1 << 15) | ||
1974 | #define RT5651_3D_SPK_M_MASK (0x3 << 13) | ||
1975 | #define RT5651_3D_SPK_M_SFT 13 | ||
1976 | #define RT5651_3D_SPK_CG_MASK (0x1f << 8) | ||
1977 | #define RT5651_3D_SPK_CG_SFT 8 | ||
1978 | #define RT5651_3D_SPK_SG_MASK (0x1f) | ||
1979 | #define RT5651_3D_SPK_SG_SFT 0 | ||
1980 | |||
1981 | /* Wind Noise Detection Control 1 (0x6c) */ | ||
1982 | #define RT5651_WND_MASK (0x1 << 15) | ||
1983 | #define RT5651_WND_SFT 15 | ||
1984 | #define RT5651_WND_DIS (0x0 << 15) | ||
1985 | #define RT5651_WND_EN (0x1 << 15) | ||
1986 | |||
1987 | /* Wind Noise Detection Control 2 (0x6d) */ | ||
1988 | #define RT5651_WND_FC_NW_MASK (0x3f << 10) | ||
1989 | #define RT5651_WND_FC_NW_SFT 10 | ||
1990 | #define RT5651_WND_FC_WK_MASK (0x3f << 4) | ||
1991 | #define RT5651_WND_FC_WK_SFT 4 | ||
1992 | |||
1993 | /* Wind Noise Detection Control 3 (0x6e) */ | ||
1994 | #define RT5651_HPF_FC_MASK (0x3f << 6) | ||
1995 | #define RT5651_HPF_FC_SFT 6 | ||
1996 | #define RT5651_WND_FC_ST_MASK (0x3f) | ||
1997 | #define RT5651_WND_FC_ST_SFT 0 | ||
1998 | |||
1999 | /* Wind Noise Detection Control 4 (0x6f) */ | ||
2000 | #define RT5651_WND_TH_LO_MASK (0x3ff) | ||
2001 | #define RT5651_WND_TH_LO_SFT 0 | ||
2002 | |||
2003 | /* Wind Noise Detection Control 5 (0x70) */ | ||
2004 | #define RT5651_WND_TH_HI_MASK (0x3ff) | ||
2005 | #define RT5651_WND_TH_HI_SFT 0 | ||
2006 | |||
2007 | /* Wind Noise Detection Control 8 (0x73) */ | ||
2008 | #define RT5651_WND_WIND_MASK (0x1 << 13) /* Read-Only */ | ||
2009 | #define RT5651_WND_WIND_SFT 13 | ||
2010 | #define RT5651_WND_STRONG_MASK (0x1 << 12) /* Read-Only */ | ||
2011 | #define RT5651_WND_STRONG_SFT 12 | ||
2012 | enum { | ||
2013 | RT5651_NO_WIND, | ||
2014 | RT5651_BREEZE, | ||
2015 | RT5651_STORM, | ||
2016 | }; | ||
2017 | |||
2018 | /* Dipole Speaker Interface (0x75) */ | ||
2019 | #define RT5651_DP_ATT_MASK (0x3 << 14) | ||
2020 | #define RT5651_DP_ATT_SFT 14 | ||
2021 | #define RT5651_DP_SPK_MASK (0x1 << 10) | ||
2022 | #define RT5651_DP_SPK_SFT 10 | ||
2023 | #define RT5651_DP_SPK_DIS (0x0 << 10) | ||
2024 | #define RT5651_DP_SPK_EN (0x1 << 10) | ||
2025 | |||
2026 | /* EQ Pre Volume Control (0xb3) */ | ||
2027 | #define RT5651_EQ_PRE_VOL_MASK (0xffff) | ||
2028 | #define RT5651_EQ_PRE_VOL_SFT 0 | ||
2029 | |||
2030 | /* EQ Post Volume Control (0xb4) */ | ||
2031 | #define RT5651_EQ_PST_VOL_MASK (0xffff) | ||
2032 | #define RT5651_EQ_PST_VOL_SFT 0 | ||
2033 | |||
2034 | /* System Clock Source */ | ||
2035 | enum { | ||
2036 | RT5651_SCLK_S_MCLK, | ||
2037 | RT5651_SCLK_S_PLL1, | ||
2038 | RT5651_SCLK_S_RCCLK, | ||
2039 | }; | ||
2040 | |||
2041 | /* PLL1 Source */ | ||
2042 | enum { | ||
2043 | RT5651_PLL1_S_MCLK, | ||
2044 | RT5651_PLL1_S_BCLK1, | ||
2045 | RT5651_PLL1_S_BCLK2, | ||
2046 | }; | ||
2047 | |||
2048 | enum { | ||
2049 | RT5651_AIF1, | ||
2050 | RT5651_AIF2, | ||
2051 | RT5651_AIFS, | ||
2052 | }; | ||
2053 | |||
2054 | struct rt5651_pll_code { | ||
2055 | bool m_bp; /* Indicates bypass m code or not. */ | ||
2056 | int m_code; | ||
2057 | int n_code; | ||
2058 | int k_code; | ||
2059 | }; | ||
2060 | |||
2061 | struct rt5651_priv { | ||
2062 | struct snd_soc_codec *codec; | ||
2063 | struct rt5651_platform_data pdata; | ||
2064 | struct regmap *regmap; | ||
2065 | |||
2066 | int sysclk; | ||
2067 | int sysclk_src; | ||
2068 | int lrck[RT5651_AIFS]; | ||
2069 | int bclk[RT5651_AIFS]; | ||
2070 | int master[RT5651_AIFS]; | ||
2071 | |||
2072 | struct rt5651_pll_code pll_code; | ||
2073 | int pll_src; | ||
2074 | int pll_in; | ||
2075 | int pll_out; | ||
2076 | |||
2077 | int dmic_en; | ||
2078 | bool hp_mute; | ||
2079 | }; | ||
2080 | |||
2081 | #endif /* __RT5651_H__ */ | ||
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index d3ed1be5a186..9626ee0417cd 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -296,7 +296,7 @@ static int dac_info_volsw(struct snd_kcontrol *kcontrol, | |||
296 | static int dac_get_volsw(struct snd_kcontrol *kcontrol, | 296 | static int dac_get_volsw(struct snd_kcontrol *kcontrol, |
297 | struct snd_ctl_elem_value *ucontrol) | 297 | struct snd_ctl_elem_value *ucontrol) |
298 | { | 298 | { |
299 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 299 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
300 | int reg; | 300 | int reg; |
301 | int l; | 301 | int l; |
302 | int r; | 302 | int r; |
@@ -349,7 +349,7 @@ static int dac_get_volsw(struct snd_kcontrol *kcontrol, | |||
349 | static int dac_put_volsw(struct snd_kcontrol *kcontrol, | 349 | static int dac_put_volsw(struct snd_kcontrol *kcontrol, |
350 | struct snd_ctl_elem_value *ucontrol) | 350 | struct snd_ctl_elem_value *ucontrol) |
351 | { | 351 | { |
352 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 352 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
353 | int reg; | 353 | int reg; |
354 | int l; | 354 | int l; |
355 | int r; | 355 | int r; |
@@ -1322,7 +1322,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) | |||
1322 | return ret; | 1322 | return ret; |
1323 | } | 1323 | } |
1324 | 1324 | ||
1325 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), | 1325 | ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), |
1326 | sgtl5000->supplies); | 1326 | sgtl5000->supplies); |
1327 | if (ret) | 1327 | if (ret) |
1328 | goto err_ldo_remove; | 1328 | goto err_ldo_remove; |
@@ -1330,16 +1330,13 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) | |||
1330 | ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), | 1330 | ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), |
1331 | sgtl5000->supplies); | 1331 | sgtl5000->supplies); |
1332 | if (ret) | 1332 | if (ret) |
1333 | goto err_regulator_free; | 1333 | goto err_ldo_remove; |
1334 | 1334 | ||
1335 | /* wait for all power rails bring up */ | 1335 | /* wait for all power rails bring up */ |
1336 | udelay(10); | 1336 | udelay(10); |
1337 | 1337 | ||
1338 | return 0; | 1338 | return 0; |
1339 | 1339 | ||
1340 | err_regulator_free: | ||
1341 | regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), | ||
1342 | sgtl5000->supplies); | ||
1343 | err_ldo_remove: | 1340 | err_ldo_remove: |
1344 | if (!external_vddd) | 1341 | if (!external_vddd) |
1345 | ldo_regulator_remove(codec); | 1342 | ldo_regulator_remove(codec); |
@@ -1409,8 +1406,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1409 | err: | 1406 | err: |
1410 | regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), | 1407 | regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), |
1411 | sgtl5000->supplies); | 1408 | sgtl5000->supplies); |
1412 | regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), | ||
1413 | sgtl5000->supplies); | ||
1414 | ldo_regulator_remove(codec); | 1409 | ldo_regulator_remove(codec); |
1415 | 1410 | ||
1416 | return ret; | 1411 | return ret; |
@@ -1424,8 +1419,6 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) | |||
1424 | 1419 | ||
1425 | regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), | 1420 | regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), |
1426 | sgtl5000->supplies); | 1421 | sgtl5000->supplies); |
1427 | regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies), | ||
1428 | sgtl5000->supplies); | ||
1429 | ldo_regulator_remove(codec); | 1422 | ldo_regulator_remove(codec); |
1430 | 1423 | ||
1431 | return 0; | 1424 | return 0; |
diff --git a/sound/soc/codecs/si476x.c b/sound/soc/codecs/si476x.c index 244c097cd905..f26befb0c297 100644 --- a/sound/soc/codecs/si476x.c +++ b/sound/soc/codecs/si476x.c | |||
@@ -208,13 +208,6 @@ out: | |||
208 | return err; | 208 | return err; |
209 | } | 209 | } |
210 | 210 | ||
211 | static int si476x_codec_probe(struct snd_soc_codec *codec) | ||
212 | { | ||
213 | struct regmap *regmap = dev_get_regmap(codec->dev->parent, NULL); | ||
214 | |||
215 | return snd_soc_codec_set_cache_io(codec, regmap); | ||
216 | } | ||
217 | |||
218 | static struct snd_soc_dai_ops si476x_dai_ops = { | 211 | static struct snd_soc_dai_ops si476x_dai_ops = { |
219 | .hw_params = si476x_codec_hw_params, | 212 | .hw_params = si476x_codec_hw_params, |
220 | .set_fmt = si476x_codec_set_dai_fmt, | 213 | .set_fmt = si476x_codec_set_dai_fmt, |
@@ -238,8 +231,13 @@ static struct snd_soc_dai_driver si476x_dai = { | |||
238 | .ops = &si476x_dai_ops, | 231 | .ops = &si476x_dai_ops, |
239 | }; | 232 | }; |
240 | 233 | ||
234 | static struct regmap *si476x_get_regmap(struct device *dev) | ||
235 | { | ||
236 | return dev_get_regmap(dev->parent, NULL); | ||
237 | } | ||
238 | |||
241 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { | 239 | static struct snd_soc_codec_driver soc_codec_dev_si476x = { |
242 | .probe = si476x_codec_probe, | 240 | .get_regmap = si476x_get_regmap, |
243 | .dapm_widgets = si476x_dapm_widgets, | 241 | .dapm_widgets = si476x_dapm_widgets, |
244 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), | 242 | .num_dapm_widgets = ARRAY_SIZE(si476x_dapm_widgets), |
245 | .dapm_routes = si476x_dapm_routes, | 243 | .dapm_routes = si476x_dapm_routes, |
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 58e7c1f23771..c5177bc5df82 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c | |||
@@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { | |||
279 | {"Mic input mode mux", "Differential", "MICIN1"}, | 279 | {"Mic input mode mux", "Differential", "MICIN1"}, |
280 | }; | 280 | }; |
281 | 281 | ||
282 | static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec) | ||
283 | { | ||
284 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
285 | AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); | ||
286 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
287 | AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); | ||
288 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); | ||
289 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); | ||
290 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
291 | AUDIO_FIFO_START, AUDIO_FIFO_START); | ||
292 | regmap_update_bits(sirf_audio_codec->regmap, | ||
293 | AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE); | ||
294 | } | ||
295 | |||
296 | static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec) | ||
297 | { | ||
298 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); | ||
299 | regmap_update_bits(sirf_audio_codec->regmap, | ||
300 | AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE); | ||
301 | } | ||
302 | |||
303 | static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec, | ||
304 | int channels) | ||
305 | { | ||
306 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
307 | AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); | ||
308 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
309 | AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET); | ||
310 | regmap_write(sirf_audio_codec->regmap, | ||
311 | AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); | ||
312 | regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); | ||
313 | regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
314 | AUDIO_FIFO_START, AUDIO_FIFO_START); | ||
315 | if (channels == 1) | ||
316 | regmap_update_bits(sirf_audio_codec->regmap, | ||
317 | AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
318 | IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); | ||
319 | else | ||
320 | regmap_update_bits(sirf_audio_codec->regmap, | ||
321 | AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
322 | IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); | ||
323 | } | ||
324 | |||
325 | static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec) | ||
326 | { | ||
327 | regmap_update_bits(sirf_audio_codec->regmap, | ||
328 | AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
329 | IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); | ||
330 | } | ||
331 | |||
282 | static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, | 332 | static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, |
283 | int cmd, | 333 | int cmd, |
284 | struct snd_soc_dai *dai) | 334 | struct snd_soc_dai *dai) |
285 | { | 335 | { |
286 | int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
287 | struct snd_soc_codec *codec = dai->codec; | 336 | struct snd_soc_codec *codec = dai->codec; |
288 | u32 val = 0; | 337 | struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec); |
338 | int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
289 | 339 | ||
290 | /* | 340 | /* |
291 | * This is a workaround, When stop playback, | 341 | * This is a workaround, When stop playback, |
@@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, | |||
295 | case SNDRV_PCM_TRIGGER_STOP: | 345 | case SNDRV_PCM_TRIGGER_STOP: |
296 | case SNDRV_PCM_TRIGGER_SUSPEND: | 346 | case SNDRV_PCM_TRIGGER_SUSPEND: |
297 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 347 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
348 | if (playback) { | ||
349 | snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, | ||
350 | IC_HSLEN | IC_HSREN, 0); | ||
351 | sirf_audio_codec_tx_disable(sirf_audio_codec); | ||
352 | } else | ||
353 | sirf_audio_codec_rx_disable(sirf_audio_codec); | ||
298 | break; | 354 | break; |
299 | case SNDRV_PCM_TRIGGER_START: | 355 | case SNDRV_PCM_TRIGGER_START: |
300 | case SNDRV_PCM_TRIGGER_RESUME: | 356 | case SNDRV_PCM_TRIGGER_RESUME: |
301 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 357 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
302 | if (playback) | 358 | if (playback) { |
303 | val = IC_HSLEN | IC_HSREN; | 359 | sirf_audio_codec_tx_enable(sirf_audio_codec); |
360 | snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, | ||
361 | IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN); | ||
362 | } else | ||
363 | sirf_audio_codec_rx_enable(sirf_audio_codec, | ||
364 | substream->runtime->channels); | ||
304 | break; | 365 | break; |
305 | default: | 366 | default: |
306 | return -EINVAL; | 367 | return -EINVAL; |
307 | } | 368 | } |
308 | 369 | ||
309 | if (playback) | ||
310 | snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0, | ||
311 | IC_HSLEN | IC_HSREN, val); | ||
312 | return 0; | 370 | return 0; |
313 | } | 371 | } |
314 | 372 | ||
@@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = { | |||
392 | .reg_bits = 32, | 450 | .reg_bits = 32, |
393 | .reg_stride = 4, | 451 | .reg_stride = 4, |
394 | .val_bits = 32, | 452 | .val_bits = 32, |
395 | .max_register = AUDIO_IC_CODEC_CTRL3, | 453 | .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, |
396 | .cache_type = REGCACHE_NONE, | 454 | .cache_type = REGCACHE_NONE, |
397 | }; | 455 | }; |
398 | 456 | ||
diff --git a/sound/soc/codecs/sirf-audio-codec.h b/sound/soc/codecs/sirf-audio-codec.h index d4c187b8e54a..ba1adc03839f 100644 --- a/sound/soc/codecs/sirf-audio-codec.h +++ b/sound/soc/codecs/sirf-audio-codec.h | |||
@@ -72,4 +72,54 @@ | |||
72 | #define IC_RXPGAR 0x7B | 72 | #define IC_RXPGAR 0x7B |
73 | #define IC_RXPGAL 0x7B | 73 | #define IC_RXPGAL 0x7B |
74 | 74 | ||
75 | #define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F | ||
76 | #define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 | ||
77 | #define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 | ||
78 | #define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 | ||
79 | |||
80 | #define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
81 | << AUDIO_PORT_TX_FIFO_SC_OFFSET) | ||
82 | #define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
83 | << AUDIO_PORT_TX_FIFO_LC_OFFSET) | ||
84 | #define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
85 | << AUDIO_PORT_TX_FIFO_HC_OFFSET) | ||
86 | |||
87 | #define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F | ||
88 | #define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 | ||
89 | #define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 | ||
90 | #define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 | ||
91 | |||
92 | #define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
93 | << AUDIO_PORT_RX_FIFO_SC_OFFSET) | ||
94 | #define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
95 | << AUDIO_PORT_RX_FIFO_LC_OFFSET) | ||
96 | #define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
97 | << AUDIO_PORT_RX_FIFO_HC_OFFSET) | ||
98 | #define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) | ||
99 | #define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) | ||
100 | |||
101 | #define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) | ||
102 | #define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) | ||
103 | #define AUDIO_PORT_IC_TXFIFO_STS (0x0104) | ||
104 | #define AUDIO_PORT_IC_TXFIFO_INT (0x0108) | ||
105 | #define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) | ||
106 | |||
107 | #define AUDIO_PORT_IC_RXFIFO_OP (0x0110) | ||
108 | #define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) | ||
109 | #define AUDIO_PORT_IC_RXFIFO_STS (0x0118) | ||
110 | #define AUDIO_PORT_IC_RXFIFO_INT (0x011C) | ||
111 | #define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) | ||
112 | |||
113 | #define AUDIO_FIFO_START (1 << 0) | ||
114 | #define AUDIO_FIFO_RESET (1 << 1) | ||
115 | |||
116 | #define AUDIO_FIFO_FULL (1 << 0) | ||
117 | #define AUDIO_FIFO_EMPTY (1 << 1) | ||
118 | #define AUDIO_FIFO_OFLOW (1 << 2) | ||
119 | #define AUDIO_FIFO_UFLOW (1 << 3) | ||
120 | |||
121 | #define IC_TX_ENABLE (0x03) | ||
122 | #define IC_RX_ENABLE_MONO (0x01) | ||
123 | #define IC_RX_ENABLE_STEREO (0x03) | ||
124 | |||
75 | #endif /*__SIRF_AUDIO_CODEC_H*/ | 125 | #endif /*__SIRF_AUDIO_CODEC_H*/ |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index 12577749b17b..0579d187135b 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -243,7 +243,7 @@ static int sta32x_coefficient_info(struct snd_kcontrol *kcontrol, | |||
243 | static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, | 243 | static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, |
244 | struct snd_ctl_elem_value *ucontrol) | 244 | struct snd_ctl_elem_value *ucontrol) |
245 | { | 245 | { |
246 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 246 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
247 | int numcoef = kcontrol->private_value >> 16; | 247 | int numcoef = kcontrol->private_value >> 16; |
248 | int index = kcontrol->private_value & 0xffff; | 248 | int index = kcontrol->private_value & 0xffff; |
249 | unsigned int cfud; | 249 | unsigned int cfud; |
@@ -272,7 +272,7 @@ static int sta32x_coefficient_get(struct snd_kcontrol *kcontrol, | |||
272 | static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, | 272 | static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, |
273 | struct snd_ctl_elem_value *ucontrol) | 273 | struct snd_ctl_elem_value *ucontrol) |
274 | { | 274 | { |
275 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 275 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
276 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 276 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
277 | int numcoef = kcontrol->private_value >> 16; | 277 | int numcoef = kcontrol->private_value >> 16; |
278 | int index = kcontrol->private_value & 0xffff; | 278 | int index = kcontrol->private_value & 0xffff; |
diff --git a/sound/soc/codecs/sta350.c b/sound/soc/codecs/sta350.c new file mode 100644 index 000000000000..cc97dd52aa9c --- /dev/null +++ b/sound/soc/codecs/sta350.c | |||
@@ -0,0 +1,1311 @@ | |||
1 | /* | ||
2 | * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system | ||
3 | * | ||
4 | * Copyright: 2014 Raumfeld GmbH | ||
5 | * Author: Sven Brandau <info@brandau.biz> | ||
6 | * | ||
7 | * based on code from: | ||
8 | * Raumfeld GmbH | ||
9 | * Johannes Stezenbach <js@sig21.net> | ||
10 | * Wolfson Microelectronics PLC. | ||
11 | * Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
12 | * Freescale Semiconductor, Inc. | ||
13 | * Timur Tabi <timur@freescale.com> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or modify it | ||
16 | * under the terms of the GNU General Public License as published by the | ||
17 | * Free Software Foundation; either version 2 of the License, or (at your | ||
18 | * option) any later version. | ||
19 | */ | ||
20 | |||
21 | #define pr_fmt(fmt) KBUILD_MODNAME ":%s:%d: " fmt, __func__, __LINE__ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/pm.h> | ||
28 | #include <linux/i2c.h> | ||
29 | #include <linux/of_device.h> | ||
30 | #include <linux/of_gpio.h> | ||
31 | #include <linux/regmap.h> | ||
32 | #include <linux/regulator/consumer.h> | ||
33 | #include <linux/gpio/consumer.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <sound/core.h> | ||
36 | #include <sound/pcm.h> | ||
37 | #include <sound/pcm_params.h> | ||
38 | #include <sound/soc.h> | ||
39 | #include <sound/soc-dapm.h> | ||
40 | #include <sound/initval.h> | ||
41 | #include <sound/tlv.h> | ||
42 | |||
43 | #include <sound/sta350.h> | ||
44 | #include "sta350.h" | ||
45 | |||
46 | #define STA350_RATES (SNDRV_PCM_RATE_32000 | \ | ||
47 | SNDRV_PCM_RATE_44100 | \ | ||
48 | SNDRV_PCM_RATE_48000 | \ | ||
49 | SNDRV_PCM_RATE_88200 | \ | ||
50 | SNDRV_PCM_RATE_96000 | \ | ||
51 | SNDRV_PCM_RATE_176400 | \ | ||
52 | SNDRV_PCM_RATE_192000) | ||
53 | |||
54 | #define STA350_FORMATS \ | ||
55 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ | ||
56 | SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE | \ | ||
57 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE | \ | ||
58 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | \ | ||
59 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ | ||
60 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE) | ||
61 | |||
62 | /* Power-up register defaults */ | ||
63 | static const struct reg_default sta350_regs[] = { | ||
64 | { 0x0, 0x63 }, | ||
65 | { 0x1, 0x80 }, | ||
66 | { 0x2, 0xdf }, | ||
67 | { 0x3, 0x40 }, | ||
68 | { 0x4, 0xc2 }, | ||
69 | { 0x5, 0x5c }, | ||
70 | { 0x6, 0x00 }, | ||
71 | { 0x7, 0xff }, | ||
72 | { 0x8, 0x60 }, | ||
73 | { 0x9, 0x60 }, | ||
74 | { 0xa, 0x60 }, | ||
75 | { 0xb, 0x00 }, | ||
76 | { 0xc, 0x00 }, | ||
77 | { 0xd, 0x00 }, | ||
78 | { 0xe, 0x00 }, | ||
79 | { 0xf, 0x40 }, | ||
80 | { 0x10, 0x80 }, | ||
81 | { 0x11, 0x77 }, | ||
82 | { 0x12, 0x6a }, | ||
83 | { 0x13, 0x69 }, | ||
84 | { 0x14, 0x6a }, | ||
85 | { 0x15, 0x69 }, | ||
86 | { 0x16, 0x00 }, | ||
87 | { 0x17, 0x00 }, | ||
88 | { 0x18, 0x00 }, | ||
89 | { 0x19, 0x00 }, | ||
90 | { 0x1a, 0x00 }, | ||
91 | { 0x1b, 0x00 }, | ||
92 | { 0x1c, 0x00 }, | ||
93 | { 0x1d, 0x00 }, | ||
94 | { 0x1e, 0x00 }, | ||
95 | { 0x1f, 0x00 }, | ||
96 | { 0x20, 0x00 }, | ||
97 | { 0x21, 0x00 }, | ||
98 | { 0x22, 0x00 }, | ||
99 | { 0x23, 0x00 }, | ||
100 | { 0x24, 0x00 }, | ||
101 | { 0x25, 0x00 }, | ||
102 | { 0x26, 0x00 }, | ||
103 | { 0x27, 0x2a }, | ||
104 | { 0x28, 0xc0 }, | ||
105 | { 0x29, 0xf3 }, | ||
106 | { 0x2a, 0x33 }, | ||
107 | { 0x2b, 0x00 }, | ||
108 | { 0x2c, 0x0c }, | ||
109 | { 0x31, 0x00 }, | ||
110 | { 0x36, 0x00 }, | ||
111 | { 0x37, 0x00 }, | ||
112 | { 0x38, 0x00 }, | ||
113 | { 0x39, 0x01 }, | ||
114 | { 0x3a, 0xee }, | ||
115 | { 0x3b, 0xff }, | ||
116 | { 0x3c, 0x7e }, | ||
117 | { 0x3d, 0xc0 }, | ||
118 | { 0x3e, 0x26 }, | ||
119 | { 0x3f, 0x00 }, | ||
120 | { 0x48, 0x00 }, | ||
121 | { 0x49, 0x00 }, | ||
122 | { 0x4a, 0x00 }, | ||
123 | { 0x4b, 0x04 }, | ||
124 | { 0x4c, 0x00 }, | ||
125 | }; | ||
126 | |||
127 | static const struct regmap_range sta350_write_regs_range[] = { | ||
128 | regmap_reg_range(STA350_CONFA, STA350_AUTO2), | ||
129 | regmap_reg_range(STA350_C1CFG, STA350_FDRC2), | ||
130 | regmap_reg_range(STA350_EQCFG, STA350_EVOLRES), | ||
131 | regmap_reg_range(STA350_NSHAPE, STA350_MISC2), | ||
132 | }; | ||
133 | |||
134 | static const struct regmap_range sta350_read_regs_range[] = { | ||
135 | regmap_reg_range(STA350_CONFA, STA350_AUTO2), | ||
136 | regmap_reg_range(STA350_C1CFG, STA350_STATUS), | ||
137 | regmap_reg_range(STA350_EQCFG, STA350_EVOLRES), | ||
138 | regmap_reg_range(STA350_NSHAPE, STA350_MISC2), | ||
139 | }; | ||
140 | |||
141 | static const struct regmap_range sta350_volatile_regs_range[] = { | ||
142 | regmap_reg_range(STA350_CFADDR2, STA350_CFUD), | ||
143 | regmap_reg_range(STA350_STATUS, STA350_STATUS), | ||
144 | }; | ||
145 | |||
146 | static const struct regmap_access_table sta350_write_regs = { | ||
147 | .yes_ranges = sta350_write_regs_range, | ||
148 | .n_yes_ranges = ARRAY_SIZE(sta350_write_regs_range), | ||
149 | }; | ||
150 | |||
151 | static const struct regmap_access_table sta350_read_regs = { | ||
152 | .yes_ranges = sta350_read_regs_range, | ||
153 | .n_yes_ranges = ARRAY_SIZE(sta350_read_regs_range), | ||
154 | }; | ||
155 | |||
156 | static const struct regmap_access_table sta350_volatile_regs = { | ||
157 | .yes_ranges = sta350_volatile_regs_range, | ||
158 | .n_yes_ranges = ARRAY_SIZE(sta350_volatile_regs_range), | ||
159 | }; | ||
160 | |||
161 | /* regulator power supply names */ | ||
162 | static const char * const sta350_supply_names[] = { | ||
163 | "vdd-dig", /* digital supply, 3.3V */ | ||
164 | "vdd-pll", /* pll supply, 3.3V */ | ||
165 | "vcc" /* power amp supply, 5V - 26V */ | ||
166 | }; | ||
167 | |||
168 | /* codec private data */ | ||
169 | struct sta350_priv { | ||
170 | struct regmap *regmap; | ||
171 | struct regulator_bulk_data supplies[ARRAY_SIZE(sta350_supply_names)]; | ||
172 | struct sta350_platform_data *pdata; | ||
173 | |||
174 | unsigned int mclk; | ||
175 | unsigned int format; | ||
176 | |||
177 | u32 coef_shadow[STA350_COEF_COUNT]; | ||
178 | int shutdown; | ||
179 | |||
180 | struct gpio_desc *gpiod_nreset; | ||
181 | struct gpio_desc *gpiod_power_down; | ||
182 | |||
183 | struct mutex coeff_lock; | ||
184 | }; | ||
185 | |||
186 | static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12750, 50, 1); | ||
187 | static const DECLARE_TLV_DB_SCALE(chvol_tlv, -7950, 50, 1); | ||
188 | static const DECLARE_TLV_DB_SCALE(tone_tlv, -1200, 200, 0); | ||
189 | |||
190 | static const char * const sta350_drc_ac[] = { | ||
191 | "Anti-Clipping", "Dynamic Range Compression" | ||
192 | }; | ||
193 | static const char * const sta350_auto_gc_mode[] = { | ||
194 | "User", "AC no clipping", "AC limited clipping (10%)", | ||
195 | "DRC nighttime listening mode" | ||
196 | }; | ||
197 | static const char * const sta350_auto_xo_mode[] = { | ||
198 | "User", "80Hz", "100Hz", "120Hz", "140Hz", "160Hz", "180Hz", | ||
199 | "200Hz", "220Hz", "240Hz", "260Hz", "280Hz", "300Hz", "320Hz", | ||
200 | "340Hz", "360Hz" | ||
201 | }; | ||
202 | static const char * const sta350_binary_output[] = { | ||
203 | "FFX 3-state output - normal operation", "Binary output" | ||
204 | }; | ||
205 | static const char * const sta350_limiter_select[] = { | ||
206 | "Limiter Disabled", "Limiter #1", "Limiter #2" | ||
207 | }; | ||
208 | static const char * const sta350_limiter_attack_rate[] = { | ||
209 | "3.1584", "2.7072", "2.2560", "1.8048", "1.3536", "0.9024", | ||
210 | "0.4512", "0.2256", "0.1504", "0.1123", "0.0902", "0.0752", | ||
211 | "0.0645", "0.0564", "0.0501", "0.0451" | ||
212 | }; | ||
213 | static const char * const sta350_limiter_release_rate[] = { | ||
214 | "0.5116", "0.1370", "0.0744", "0.0499", "0.0360", "0.0299", | ||
215 | "0.0264", "0.0208", "0.0198", "0.0172", "0.0147", "0.0137", | ||
216 | "0.0134", "0.0117", "0.0110", "0.0104" | ||
217 | }; | ||
218 | static const char * const sta350_noise_shaper_type[] = { | ||
219 | "Third order", "Fourth order" | ||
220 | }; | ||
221 | |||
222 | static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_attack_tlv, | ||
223 | 0, 7, TLV_DB_SCALE_ITEM(-1200, 200, 0), | ||
224 | 8, 16, TLV_DB_SCALE_ITEM(300, 100, 0), | ||
225 | ); | ||
226 | |||
227 | static DECLARE_TLV_DB_RANGE(sta350_limiter_ac_release_tlv, | ||
228 | 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), | ||
229 | 1, 1, TLV_DB_SCALE_ITEM(-2900, 0, 0), | ||
230 | 2, 2, TLV_DB_SCALE_ITEM(-2000, 0, 0), | ||
231 | 3, 8, TLV_DB_SCALE_ITEM(-1400, 200, 0), | ||
232 | 8, 16, TLV_DB_SCALE_ITEM(-700, 100, 0), | ||
233 | ); | ||
234 | |||
235 | static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_attack_tlv, | ||
236 | 0, 7, TLV_DB_SCALE_ITEM(-3100, 200, 0), | ||
237 | 8, 13, TLV_DB_SCALE_ITEM(-1600, 100, 0), | ||
238 | 14, 16, TLV_DB_SCALE_ITEM(-1000, 300, 0), | ||
239 | ); | ||
240 | |||
241 | static DECLARE_TLV_DB_RANGE(sta350_limiter_drc_release_tlv, | ||
242 | 0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 0), | ||
243 | 1, 2, TLV_DB_SCALE_ITEM(-3800, 200, 0), | ||
244 | 3, 4, TLV_DB_SCALE_ITEM(-3300, 200, 0), | ||
245 | 5, 12, TLV_DB_SCALE_ITEM(-3000, 200, 0), | ||
246 | 13, 16, TLV_DB_SCALE_ITEM(-1500, 300, 0), | ||
247 | ); | ||
248 | |||
249 | static SOC_ENUM_SINGLE_DECL(sta350_drc_ac_enum, | ||
250 | STA350_CONFD, STA350_CONFD_DRC_SHIFT, | ||
251 | sta350_drc_ac); | ||
252 | static SOC_ENUM_SINGLE_DECL(sta350_noise_shaper_enum, | ||
253 | STA350_CONFE, STA350_CONFE_NSBW_SHIFT, | ||
254 | sta350_noise_shaper_type); | ||
255 | static SOC_ENUM_SINGLE_DECL(sta350_auto_gc_enum, | ||
256 | STA350_AUTO1, STA350_AUTO1_AMGC_SHIFT, | ||
257 | sta350_auto_gc_mode); | ||
258 | static SOC_ENUM_SINGLE_DECL(sta350_auto_xo_enum, | ||
259 | STA350_AUTO2, STA350_AUTO2_XO_SHIFT, | ||
260 | sta350_auto_xo_mode); | ||
261 | static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch1_enum, | ||
262 | STA350_C1CFG, STA350_CxCFG_BO_SHIFT, | ||
263 | sta350_binary_output); | ||
264 | static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch2_enum, | ||
265 | STA350_C2CFG, STA350_CxCFG_BO_SHIFT, | ||
266 | sta350_binary_output); | ||
267 | static SOC_ENUM_SINGLE_DECL(sta350_binary_output_ch3_enum, | ||
268 | STA350_C3CFG, STA350_CxCFG_BO_SHIFT, | ||
269 | sta350_binary_output); | ||
270 | static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch1_enum, | ||
271 | STA350_C1CFG, STA350_CxCFG_LS_SHIFT, | ||
272 | sta350_limiter_select); | ||
273 | static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch2_enum, | ||
274 | STA350_C2CFG, STA350_CxCFG_LS_SHIFT, | ||
275 | sta350_limiter_select); | ||
276 | static SOC_ENUM_SINGLE_DECL(sta350_limiter_ch3_enum, | ||
277 | STA350_C3CFG, STA350_CxCFG_LS_SHIFT, | ||
278 | sta350_limiter_select); | ||
279 | static SOC_ENUM_SINGLE_DECL(sta350_limiter1_attack_rate_enum, | ||
280 | STA350_L1AR, STA350_LxA_SHIFT, | ||
281 | sta350_limiter_attack_rate); | ||
282 | static SOC_ENUM_SINGLE_DECL(sta350_limiter2_attack_rate_enum, | ||
283 | STA350_L2AR, STA350_LxA_SHIFT, | ||
284 | sta350_limiter_attack_rate); | ||
285 | static SOC_ENUM_SINGLE_DECL(sta350_limiter1_release_rate_enum, | ||
286 | STA350_L1AR, STA350_LxR_SHIFT, | ||
287 | sta350_limiter_release_rate); | ||
288 | static SOC_ENUM_SINGLE_DECL(sta350_limiter2_release_rate_enum, | ||
289 | STA350_L2AR, STA350_LxR_SHIFT, | ||
290 | sta350_limiter_release_rate); | ||
291 | |||
292 | /* | ||
293 | * byte array controls for setting biquad, mixer, scaling coefficients; | ||
294 | * for biquads all five coefficients need to be set in one go, | ||
295 | * mixer and pre/postscale coefs can be set individually; | ||
296 | * each coef is 24bit, the bytes are ordered in the same way | ||
297 | * as given in the STA350 data sheet (big endian; b1, b2, a1, a2, b0) | ||
298 | */ | ||
299 | |||
300 | static int sta350_coefficient_info(struct snd_kcontrol *kcontrol, | ||
301 | struct snd_ctl_elem_info *uinfo) | ||
302 | { | ||
303 | int numcoef = kcontrol->private_value >> 16; | ||
304 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
305 | uinfo->count = 3 * numcoef; | ||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static int sta350_coefficient_get(struct snd_kcontrol *kcontrol, | ||
310 | struct snd_ctl_elem_value *ucontrol) | ||
311 | { | ||
312 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
313 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
314 | int numcoef = kcontrol->private_value >> 16; | ||
315 | int index = kcontrol->private_value & 0xffff; | ||
316 | unsigned int cfud, val; | ||
317 | int i, ret = 0; | ||
318 | |||
319 | mutex_lock(&sta350->coeff_lock); | ||
320 | |||
321 | /* preserve reserved bits in STA350_CFUD */ | ||
322 | regmap_read(sta350->regmap, STA350_CFUD, &cfud); | ||
323 | cfud &= 0xf0; | ||
324 | /* | ||
325 | * chip documentation does not say if the bits are self clearing, | ||
326 | * so do it explicitly | ||
327 | */ | ||
328 | regmap_write(sta350->regmap, STA350_CFUD, cfud); | ||
329 | |||
330 | regmap_write(sta350->regmap, STA350_CFADDR2, index); | ||
331 | if (numcoef == 1) { | ||
332 | regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x04); | ||
333 | } else if (numcoef == 5) { | ||
334 | regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x08); | ||
335 | } else { | ||
336 | ret = -EINVAL; | ||
337 | goto exit_unlock; | ||
338 | } | ||
339 | |||
340 | for (i = 0; i < 3 * numcoef; i++) { | ||
341 | regmap_read(sta350->regmap, STA350_B1CF1 + i, &val); | ||
342 | ucontrol->value.bytes.data[i] = val; | ||
343 | } | ||
344 | |||
345 | exit_unlock: | ||
346 | mutex_unlock(&sta350->coeff_lock); | ||
347 | |||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static int sta350_coefficient_put(struct snd_kcontrol *kcontrol, | ||
352 | struct snd_ctl_elem_value *ucontrol) | ||
353 | { | ||
354 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); | ||
355 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
356 | int numcoef = kcontrol->private_value >> 16; | ||
357 | int index = kcontrol->private_value & 0xffff; | ||
358 | unsigned int cfud; | ||
359 | int i; | ||
360 | |||
361 | /* preserve reserved bits in STA350_CFUD */ | ||
362 | regmap_read(sta350->regmap, STA350_CFUD, &cfud); | ||
363 | cfud &= 0xf0; | ||
364 | /* | ||
365 | * chip documentation does not say if the bits are self clearing, | ||
366 | * so do it explicitly | ||
367 | */ | ||
368 | regmap_write(sta350->regmap, STA350_CFUD, cfud); | ||
369 | |||
370 | regmap_write(sta350->regmap, STA350_CFADDR2, index); | ||
371 | for (i = 0; i < numcoef && (index + i < STA350_COEF_COUNT); i++) | ||
372 | sta350->coef_shadow[index + i] = | ||
373 | (ucontrol->value.bytes.data[3 * i] << 16) | ||
374 | | (ucontrol->value.bytes.data[3 * i + 1] << 8) | ||
375 | | (ucontrol->value.bytes.data[3 * i + 2]); | ||
376 | for (i = 0; i < 3 * numcoef; i++) | ||
377 | regmap_write(sta350->regmap, STA350_B1CF1 + i, | ||
378 | ucontrol->value.bytes.data[i]); | ||
379 | if (numcoef == 1) | ||
380 | regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); | ||
381 | else if (numcoef == 5) | ||
382 | regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x02); | ||
383 | else | ||
384 | return -EINVAL; | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int sta350_sync_coef_shadow(struct snd_soc_codec *codec) | ||
390 | { | ||
391 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
392 | unsigned int cfud; | ||
393 | int i; | ||
394 | |||
395 | /* preserve reserved bits in STA350_CFUD */ | ||
396 | regmap_read(sta350->regmap, STA350_CFUD, &cfud); | ||
397 | cfud &= 0xf0; | ||
398 | |||
399 | for (i = 0; i < STA350_COEF_COUNT; i++) { | ||
400 | regmap_write(sta350->regmap, STA350_CFADDR2, i); | ||
401 | regmap_write(sta350->regmap, STA350_B1CF1, | ||
402 | (sta350->coef_shadow[i] >> 16) & 0xff); | ||
403 | regmap_write(sta350->regmap, STA350_B1CF2, | ||
404 | (sta350->coef_shadow[i] >> 8) & 0xff); | ||
405 | regmap_write(sta350->regmap, STA350_B1CF3, | ||
406 | (sta350->coef_shadow[i]) & 0xff); | ||
407 | /* | ||
408 | * chip documentation does not say if the bits are | ||
409 | * self-clearing, so do it explicitly | ||
410 | */ | ||
411 | regmap_write(sta350->regmap, STA350_CFUD, cfud); | ||
412 | regmap_write(sta350->regmap, STA350_CFUD, cfud | 0x01); | ||
413 | } | ||
414 | return 0; | ||
415 | } | ||
416 | |||
417 | static int sta350_cache_sync(struct snd_soc_codec *codec) | ||
418 | { | ||
419 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
420 | unsigned int mute; | ||
421 | int rc; | ||
422 | |||
423 | /* mute during register sync */ | ||
424 | regmap_read(sta350->regmap, STA350_CFUD, &mute); | ||
425 | regmap_write(sta350->regmap, STA350_MMUTE, mute | STA350_MMUTE_MMUTE); | ||
426 | sta350_sync_coef_shadow(codec); | ||
427 | rc = regcache_sync(sta350->regmap); | ||
428 | regmap_write(sta350->regmap, STA350_MMUTE, mute); | ||
429 | return rc; | ||
430 | } | ||
431 | |||
432 | #define SINGLE_COEF(xname, index) \ | ||
433 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
434 | .info = sta350_coefficient_info, \ | ||
435 | .get = sta350_coefficient_get,\ | ||
436 | .put = sta350_coefficient_put, \ | ||
437 | .private_value = index | (1 << 16) } | ||
438 | |||
439 | #define BIQUAD_COEFS(xname, index) \ | ||
440 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
441 | .info = sta350_coefficient_info, \ | ||
442 | .get = sta350_coefficient_get,\ | ||
443 | .put = sta350_coefficient_put, \ | ||
444 | .private_value = index | (5 << 16) } | ||
445 | |||
446 | static const struct snd_kcontrol_new sta350_snd_controls[] = { | ||
447 | SOC_SINGLE_TLV("Master Volume", STA350_MVOL, 0, 0xff, 1, mvol_tlv), | ||
448 | /* VOL */ | ||
449 | SOC_SINGLE_TLV("Ch1 Volume", STA350_C1VOL, 0, 0xff, 1, chvol_tlv), | ||
450 | SOC_SINGLE_TLV("Ch2 Volume", STA350_C2VOL, 0, 0xff, 1, chvol_tlv), | ||
451 | SOC_SINGLE_TLV("Ch3 Volume", STA350_C3VOL, 0, 0xff, 1, chvol_tlv), | ||
452 | /* CONFD */ | ||
453 | SOC_SINGLE("High Pass Filter Bypass Switch", | ||
454 | STA350_CONFD, STA350_CONFD_HPB_SHIFT, 1, 1), | ||
455 | SOC_SINGLE("De-emphasis Filter Switch", | ||
456 | STA350_CONFD, STA350_CONFD_DEMP_SHIFT, 1, 0), | ||
457 | SOC_SINGLE("DSP Bypass Switch", | ||
458 | STA350_CONFD, STA350_CONFD_DSPB_SHIFT, 1, 0), | ||
459 | SOC_SINGLE("Post-scale Link Switch", | ||
460 | STA350_CONFD, STA350_CONFD_PSL_SHIFT, 1, 0), | ||
461 | SOC_SINGLE("Biquad Coefficient Link Switch", | ||
462 | STA350_CONFD, STA350_CONFD_BQL_SHIFT, 1, 0), | ||
463 | SOC_ENUM("Compressor/Limiter Switch", sta350_drc_ac_enum), | ||
464 | SOC_ENUM("Noise Shaper Bandwidth", sta350_noise_shaper_enum), | ||
465 | SOC_SINGLE("Zero-detect Mute Enable Switch", | ||
466 | STA350_CONFD, STA350_CONFD_ZDE_SHIFT, 1, 0), | ||
467 | SOC_SINGLE("Submix Mode Switch", | ||
468 | STA350_CONFD, STA350_CONFD_SME_SHIFT, 1, 0), | ||
469 | /* CONFE */ | ||
470 | SOC_SINGLE("Zero Cross Switch", STA350_CONFE, STA350_CONFE_ZCE_SHIFT, 1, 0), | ||
471 | SOC_SINGLE("Soft Ramp Switch", STA350_CONFE, STA350_CONFE_SVE_SHIFT, 1, 0), | ||
472 | /* MUTE */ | ||
473 | SOC_SINGLE("Master Switch", STA350_MMUTE, STA350_MMUTE_MMUTE_SHIFT, 1, 1), | ||
474 | SOC_SINGLE("Ch1 Switch", STA350_MMUTE, STA350_MMUTE_C1M_SHIFT, 1, 1), | ||
475 | SOC_SINGLE("Ch2 Switch", STA350_MMUTE, STA350_MMUTE_C2M_SHIFT, 1, 1), | ||
476 | SOC_SINGLE("Ch3 Switch", STA350_MMUTE, STA350_MMUTE_C3M_SHIFT, 1, 1), | ||
477 | /* AUTOx */ | ||
478 | SOC_ENUM("Automode GC", sta350_auto_gc_enum), | ||
479 | SOC_ENUM("Automode XO", sta350_auto_xo_enum), | ||
480 | /* CxCFG */ | ||
481 | SOC_SINGLE("Ch1 Tone Control Bypass Switch", | ||
482 | STA350_C1CFG, STA350_CxCFG_TCB_SHIFT, 1, 0), | ||
483 | SOC_SINGLE("Ch2 Tone Control Bypass Switch", | ||
484 | STA350_C2CFG, STA350_CxCFG_TCB_SHIFT, 1, 0), | ||
485 | SOC_SINGLE("Ch1 EQ Bypass Switch", | ||
486 | STA350_C1CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0), | ||
487 | SOC_SINGLE("Ch2 EQ Bypass Switch", | ||
488 | STA350_C2CFG, STA350_CxCFG_EQBP_SHIFT, 1, 0), | ||
489 | SOC_SINGLE("Ch1 Master Volume Bypass Switch", | ||
490 | STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), | ||
491 | SOC_SINGLE("Ch2 Master Volume Bypass Switch", | ||
492 | STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), | ||
493 | SOC_SINGLE("Ch3 Master Volume Bypass Switch", | ||
494 | STA350_C1CFG, STA350_CxCFG_VBP_SHIFT, 1, 0), | ||
495 | SOC_ENUM("Ch1 Binary Output Select", sta350_binary_output_ch1_enum), | ||
496 | SOC_ENUM("Ch2 Binary Output Select", sta350_binary_output_ch2_enum), | ||
497 | SOC_ENUM("Ch3 Binary Output Select", sta350_binary_output_ch3_enum), | ||
498 | SOC_ENUM("Ch1 Limiter Select", sta350_limiter_ch1_enum), | ||
499 | SOC_ENUM("Ch2 Limiter Select", sta350_limiter_ch2_enum), | ||
500 | SOC_ENUM("Ch3 Limiter Select", sta350_limiter_ch3_enum), | ||
501 | /* TONE */ | ||
502 | SOC_SINGLE_RANGE_TLV("Bass Tone Control Volume", | ||
503 | STA350_TONE, STA350_TONE_BTC_SHIFT, 1, 13, 0, tone_tlv), | ||
504 | SOC_SINGLE_RANGE_TLV("Treble Tone Control Volume", | ||
505 | STA350_TONE, STA350_TONE_TTC_SHIFT, 1, 13, 0, tone_tlv), | ||
506 | SOC_ENUM("Limiter1 Attack Rate (dB/ms)", sta350_limiter1_attack_rate_enum), | ||
507 | SOC_ENUM("Limiter2 Attack Rate (dB/ms)", sta350_limiter2_attack_rate_enum), | ||
508 | SOC_ENUM("Limiter1 Release Rate (dB/ms)", sta350_limiter1_release_rate_enum), | ||
509 | SOC_ENUM("Limiter2 Release Rate (dB/ms)", sta350_limiter2_release_rate_enum), | ||
510 | |||
511 | /* | ||
512 | * depending on mode, the attack/release thresholds have | ||
513 | * two different enum definitions; provide both | ||
514 | */ | ||
515 | SOC_SINGLE_TLV("Limiter1 Attack Threshold (AC Mode)", | ||
516 | STA350_L1ATRT, STA350_LxA_SHIFT, | ||
517 | 16, 0, sta350_limiter_ac_attack_tlv), | ||
518 | SOC_SINGLE_TLV("Limiter2 Attack Threshold (AC Mode)", | ||
519 | STA350_L2ATRT, STA350_LxA_SHIFT, | ||
520 | 16, 0, sta350_limiter_ac_attack_tlv), | ||
521 | SOC_SINGLE_TLV("Limiter1 Release Threshold (AC Mode)", | ||
522 | STA350_L1ATRT, STA350_LxR_SHIFT, | ||
523 | 16, 0, sta350_limiter_ac_release_tlv), | ||
524 | SOC_SINGLE_TLV("Limiter2 Release Threshold (AC Mode)", | ||
525 | STA350_L2ATRT, STA350_LxR_SHIFT, | ||
526 | 16, 0, sta350_limiter_ac_release_tlv), | ||
527 | SOC_SINGLE_TLV("Limiter1 Attack Threshold (DRC Mode)", | ||
528 | STA350_L1ATRT, STA350_LxA_SHIFT, | ||
529 | 16, 0, sta350_limiter_drc_attack_tlv), | ||
530 | SOC_SINGLE_TLV("Limiter2 Attack Threshold (DRC Mode)", | ||
531 | STA350_L2ATRT, STA350_LxA_SHIFT, | ||
532 | 16, 0, sta350_limiter_drc_attack_tlv), | ||
533 | SOC_SINGLE_TLV("Limiter1 Release Threshold (DRC Mode)", | ||
534 | STA350_L1ATRT, STA350_LxR_SHIFT, | ||
535 | 16, 0, sta350_limiter_drc_release_tlv), | ||
536 | SOC_SINGLE_TLV("Limiter2 Release Threshold (DRC Mode)", | ||
537 | STA350_L2ATRT, STA350_LxR_SHIFT, | ||
538 | 16, 0, sta350_limiter_drc_release_tlv), | ||
539 | |||
540 | BIQUAD_COEFS("Ch1 - Biquad 1", 0), | ||
541 | BIQUAD_COEFS("Ch1 - Biquad 2", 5), | ||
542 | BIQUAD_COEFS("Ch1 - Biquad 3", 10), | ||
543 | BIQUAD_COEFS("Ch1 - Biquad 4", 15), | ||
544 | BIQUAD_COEFS("Ch2 - Biquad 1", 20), | ||
545 | BIQUAD_COEFS("Ch2 - Biquad 2", 25), | ||
546 | BIQUAD_COEFS("Ch2 - Biquad 3", 30), | ||
547 | BIQUAD_COEFS("Ch2 - Biquad 4", 35), | ||
548 | BIQUAD_COEFS("High-pass", 40), | ||
549 | BIQUAD_COEFS("Low-pass", 45), | ||
550 | SINGLE_COEF("Ch1 - Prescale", 50), | ||
551 | SINGLE_COEF("Ch2 - Prescale", 51), | ||
552 | SINGLE_COEF("Ch1 - Postscale", 52), | ||
553 | SINGLE_COEF("Ch2 - Postscale", 53), | ||
554 | SINGLE_COEF("Ch3 - Postscale", 54), | ||
555 | SINGLE_COEF("Thermal warning - Postscale", 55), | ||
556 | SINGLE_COEF("Ch1 - Mix 1", 56), | ||
557 | SINGLE_COEF("Ch1 - Mix 2", 57), | ||
558 | SINGLE_COEF("Ch2 - Mix 1", 58), | ||
559 | SINGLE_COEF("Ch2 - Mix 2", 59), | ||
560 | SINGLE_COEF("Ch3 - Mix 1", 60), | ||
561 | SINGLE_COEF("Ch3 - Mix 2", 61), | ||
562 | }; | ||
563 | |||
564 | static const struct snd_soc_dapm_widget sta350_dapm_widgets[] = { | ||
565 | SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), | ||
566 | SND_SOC_DAPM_OUTPUT("LEFT"), | ||
567 | SND_SOC_DAPM_OUTPUT("RIGHT"), | ||
568 | SND_SOC_DAPM_OUTPUT("SUB"), | ||
569 | }; | ||
570 | |||
571 | static const struct snd_soc_dapm_route sta350_dapm_routes[] = { | ||
572 | { "LEFT", NULL, "DAC" }, | ||
573 | { "RIGHT", NULL, "DAC" }, | ||
574 | { "SUB", NULL, "DAC" }, | ||
575 | { "DAC", NULL, "Playback" }, | ||
576 | }; | ||
577 | |||
578 | /* MCLK interpolation ratio per fs */ | ||
579 | static struct { | ||
580 | int fs; | ||
581 | int ir; | ||
582 | } interpolation_ratios[] = { | ||
583 | { 32000, 0 }, | ||
584 | { 44100, 0 }, | ||
585 | { 48000, 0 }, | ||
586 | { 88200, 1 }, | ||
587 | { 96000, 1 }, | ||
588 | { 176400, 2 }, | ||
589 | { 192000, 2 }, | ||
590 | }; | ||
591 | |||
592 | /* MCLK to fs clock ratios */ | ||
593 | static int mcs_ratio_table[3][6] = { | ||
594 | { 768, 512, 384, 256, 128, 576 }, | ||
595 | { 384, 256, 192, 128, 64, 0 }, | ||
596 | { 192, 128, 96, 64, 32, 0 }, | ||
597 | }; | ||
598 | |||
599 | /** | ||
600 | * sta350_set_dai_sysclk - configure MCLK | ||
601 | * @codec_dai: the codec DAI | ||
602 | * @clk_id: the clock ID (ignored) | ||
603 | * @freq: the MCLK input frequency | ||
604 | * @dir: the clock direction (ignored) | ||
605 | * | ||
606 | * The value of MCLK is used to determine which sample rates are supported | ||
607 | * by the STA350, based on the mcs_ratio_table. | ||
608 | * | ||
609 | * This function must be called by the machine driver's 'startup' function, | ||
610 | * otherwise the list of supported sample rates will not be available in | ||
611 | * time for ALSA. | ||
612 | */ | ||
613 | static int sta350_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
614 | int clk_id, unsigned int freq, int dir) | ||
615 | { | ||
616 | struct snd_soc_codec *codec = codec_dai->codec; | ||
617 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
618 | |||
619 | dev_dbg(codec->dev, "mclk=%u\n", freq); | ||
620 | sta350->mclk = freq; | ||
621 | |||
622 | return 0; | ||
623 | } | ||
624 | |||
625 | /** | ||
626 | * sta350_set_dai_fmt - configure the codec for the selected audio format | ||
627 | * @codec_dai: the codec DAI | ||
628 | * @fmt: a SND_SOC_DAIFMT_x value indicating the data format | ||
629 | * | ||
630 | * This function takes a bitmask of SND_SOC_DAIFMT_x bits and programs the | ||
631 | * codec accordingly. | ||
632 | */ | ||
633 | static int sta350_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
634 | unsigned int fmt) | ||
635 | { | ||
636 | struct snd_soc_codec *codec = codec_dai->codec; | ||
637 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
638 | unsigned int confb = 0; | ||
639 | |||
640 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
641 | case SND_SOC_DAIFMT_CBS_CFS: | ||
642 | break; | ||
643 | default: | ||
644 | return -EINVAL; | ||
645 | } | ||
646 | |||
647 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
648 | case SND_SOC_DAIFMT_I2S: | ||
649 | case SND_SOC_DAIFMT_RIGHT_J: | ||
650 | case SND_SOC_DAIFMT_LEFT_J: | ||
651 | sta350->format = fmt & SND_SOC_DAIFMT_FORMAT_MASK; | ||
652 | break; | ||
653 | default: | ||
654 | return -EINVAL; | ||
655 | } | ||
656 | |||
657 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
658 | case SND_SOC_DAIFMT_NB_NF: | ||
659 | confb |= STA350_CONFB_C2IM; | ||
660 | break; | ||
661 | case SND_SOC_DAIFMT_NB_IF: | ||
662 | confb |= STA350_CONFB_C1IM; | ||
663 | break; | ||
664 | default: | ||
665 | return -EINVAL; | ||
666 | } | ||
667 | |||
668 | return regmap_update_bits(sta350->regmap, STA350_CONFB, | ||
669 | STA350_CONFB_C1IM | STA350_CONFB_C2IM, confb); | ||
670 | } | ||
671 | |||
672 | /** | ||
673 | * sta350_hw_params - program the STA350 with the given hardware parameters. | ||
674 | * @substream: the audio stream | ||
675 | * @params: the hardware parameters to set | ||
676 | * @dai: the SOC DAI (ignored) | ||
677 | * | ||
678 | * This function programs the hardware with the values provided. | ||
679 | * Specifically, the sample rate and the data format. | ||
680 | */ | ||
681 | static int sta350_hw_params(struct snd_pcm_substream *substream, | ||
682 | struct snd_pcm_hw_params *params, | ||
683 | struct snd_soc_dai *dai) | ||
684 | { | ||
685 | struct snd_soc_codec *codec = dai->codec; | ||
686 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
687 | int i, mcs = -EINVAL, ir = -EINVAL; | ||
688 | unsigned int confa, confb; | ||
689 | unsigned int rate, ratio; | ||
690 | int ret; | ||
691 | |||
692 | if (!sta350->mclk) { | ||
693 | dev_err(codec->dev, | ||
694 | "sta350->mclk is unset. Unable to determine ratio\n"); | ||
695 | return -EIO; | ||
696 | } | ||
697 | |||
698 | rate = params_rate(params); | ||
699 | ratio = sta350->mclk / rate; | ||
700 | dev_dbg(codec->dev, "rate: %u, ratio: %u\n", rate, ratio); | ||
701 | |||
702 | for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) { | ||
703 | if (interpolation_ratios[i].fs == rate) { | ||
704 | ir = interpolation_ratios[i].ir; | ||
705 | break; | ||
706 | } | ||
707 | } | ||
708 | |||
709 | if (ir < 0) { | ||
710 | dev_err(codec->dev, "Unsupported samplerate: %u\n", rate); | ||
711 | return -EINVAL; | ||
712 | } | ||
713 | |||
714 | for (i = 0; i < 6; i++) { | ||
715 | if (mcs_ratio_table[ir][i] == ratio) { | ||
716 | mcs = i; | ||
717 | break; | ||
718 | } | ||
719 | } | ||
720 | |||
721 | if (mcs < 0) { | ||
722 | dev_err(codec->dev, "Unresolvable ratio: %u\n", ratio); | ||
723 | return -EINVAL; | ||
724 | } | ||
725 | |||
726 | confa = (ir << STA350_CONFA_IR_SHIFT) | | ||
727 | (mcs << STA350_CONFA_MCS_SHIFT); | ||
728 | confb = 0; | ||
729 | |||
730 | switch (params_width(params)) { | ||
731 | case 24: | ||
732 | dev_dbg(codec->dev, "24bit\n"); | ||
733 | /* fall through */ | ||
734 | case 32: | ||
735 | dev_dbg(codec->dev, "24bit or 32bit\n"); | ||
736 | switch (sta350->format) { | ||
737 | case SND_SOC_DAIFMT_I2S: | ||
738 | confb |= 0x0; | ||
739 | break; | ||
740 | case SND_SOC_DAIFMT_LEFT_J: | ||
741 | confb |= 0x1; | ||
742 | break; | ||
743 | case SND_SOC_DAIFMT_RIGHT_J: | ||
744 | confb |= 0x2; | ||
745 | break; | ||
746 | } | ||
747 | |||
748 | break; | ||
749 | case 20: | ||
750 | dev_dbg(codec->dev, "20bit\n"); | ||
751 | switch (sta350->format) { | ||
752 | case SND_SOC_DAIFMT_I2S: | ||
753 | confb |= 0x4; | ||
754 | break; | ||
755 | case SND_SOC_DAIFMT_LEFT_J: | ||
756 | confb |= 0x5; | ||
757 | break; | ||
758 | case SND_SOC_DAIFMT_RIGHT_J: | ||
759 | confb |= 0x6; | ||
760 | break; | ||
761 | } | ||
762 | |||
763 | break; | ||
764 | case 18: | ||
765 | dev_dbg(codec->dev, "18bit\n"); | ||
766 | switch (sta350->format) { | ||
767 | case SND_SOC_DAIFMT_I2S: | ||
768 | confb |= 0x8; | ||
769 | break; | ||
770 | case SND_SOC_DAIFMT_LEFT_J: | ||
771 | confb |= 0x9; | ||
772 | break; | ||
773 | case SND_SOC_DAIFMT_RIGHT_J: | ||
774 | confb |= 0xa; | ||
775 | break; | ||
776 | } | ||
777 | |||
778 | break; | ||
779 | case 16: | ||
780 | dev_dbg(codec->dev, "16bit\n"); | ||
781 | switch (sta350->format) { | ||
782 | case SND_SOC_DAIFMT_I2S: | ||
783 | confb |= 0x0; | ||
784 | break; | ||
785 | case SND_SOC_DAIFMT_LEFT_J: | ||
786 | confb |= 0xd; | ||
787 | break; | ||
788 | case SND_SOC_DAIFMT_RIGHT_J: | ||
789 | confb |= 0xe; | ||
790 | break; | ||
791 | } | ||
792 | |||
793 | break; | ||
794 | default: | ||
795 | return -EINVAL; | ||
796 | } | ||
797 | |||
798 | ret = regmap_update_bits(sta350->regmap, STA350_CONFA, | ||
799 | STA350_CONFA_MCS_MASK | STA350_CONFA_IR_MASK, | ||
800 | confa); | ||
801 | if (ret < 0) | ||
802 | return ret; | ||
803 | |||
804 | ret = regmap_update_bits(sta350->regmap, STA350_CONFB, | ||
805 | STA350_CONFB_SAI_MASK | STA350_CONFB_SAIFB, | ||
806 | confb); | ||
807 | if (ret < 0) | ||
808 | return ret; | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | static int sta350_startup_sequence(struct sta350_priv *sta350) | ||
814 | { | ||
815 | if (sta350->gpiod_power_down) | ||
816 | gpiod_set_value(sta350->gpiod_power_down, 1); | ||
817 | |||
818 | if (sta350->gpiod_nreset) { | ||
819 | gpiod_set_value(sta350->gpiod_nreset, 0); | ||
820 | mdelay(1); | ||
821 | gpiod_set_value(sta350->gpiod_nreset, 1); | ||
822 | mdelay(1); | ||
823 | } | ||
824 | |||
825 | return 0; | ||
826 | } | ||
827 | |||
828 | /** | ||
829 | * sta350_set_bias_level - DAPM callback | ||
830 | * @codec: the codec device | ||
831 | * @level: DAPM power level | ||
832 | * | ||
833 | * This is called by ALSA to put the codec into low power mode | ||
834 | * or to wake it up. If the codec is powered off completely | ||
835 | * all registers must be restored after power on. | ||
836 | */ | ||
837 | static int sta350_set_bias_level(struct snd_soc_codec *codec, | ||
838 | enum snd_soc_bias_level level) | ||
839 | { | ||
840 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
841 | int ret; | ||
842 | |||
843 | dev_dbg(codec->dev, "level = %d\n", level); | ||
844 | switch (level) { | ||
845 | case SND_SOC_BIAS_ON: | ||
846 | break; | ||
847 | |||
848 | case SND_SOC_BIAS_PREPARE: | ||
849 | /* Full power on */ | ||
850 | regmap_update_bits(sta350->regmap, STA350_CONFF, | ||
851 | STA350_CONFF_PWDN | STA350_CONFF_EAPD, | ||
852 | STA350_CONFF_PWDN | STA350_CONFF_EAPD); | ||
853 | break; | ||
854 | |||
855 | case SND_SOC_BIAS_STANDBY: | ||
856 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
857 | ret = regulator_bulk_enable( | ||
858 | ARRAY_SIZE(sta350->supplies), | ||
859 | sta350->supplies); | ||
860 | if (ret < 0) { | ||
861 | dev_err(codec->dev, | ||
862 | "Failed to enable supplies: %d\n", | ||
863 | ret); | ||
864 | return ret; | ||
865 | } | ||
866 | sta350_startup_sequence(sta350); | ||
867 | sta350_cache_sync(codec); | ||
868 | } | ||
869 | |||
870 | /* Power down */ | ||
871 | regmap_update_bits(sta350->regmap, STA350_CONFF, | ||
872 | STA350_CONFF_PWDN | STA350_CONFF_EAPD, | ||
873 | 0); | ||
874 | |||
875 | break; | ||
876 | |||
877 | case SND_SOC_BIAS_OFF: | ||
878 | /* The chip runs through the power down sequence for us */ | ||
879 | regmap_update_bits(sta350->regmap, STA350_CONFF, | ||
880 | STA350_CONFF_PWDN | STA350_CONFF_EAPD, 0); | ||
881 | |||
882 | /* power down: low */ | ||
883 | if (sta350->gpiod_power_down) | ||
884 | gpiod_set_value(sta350->gpiod_power_down, 0); | ||
885 | |||
886 | if (sta350->gpiod_nreset) | ||
887 | gpiod_set_value(sta350->gpiod_nreset, 0); | ||
888 | |||
889 | regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), | ||
890 | sta350->supplies); | ||
891 | break; | ||
892 | } | ||
893 | codec->dapm.bias_level = level; | ||
894 | return 0; | ||
895 | } | ||
896 | |||
897 | static const struct snd_soc_dai_ops sta350_dai_ops = { | ||
898 | .hw_params = sta350_hw_params, | ||
899 | .set_sysclk = sta350_set_dai_sysclk, | ||
900 | .set_fmt = sta350_set_dai_fmt, | ||
901 | }; | ||
902 | |||
903 | static struct snd_soc_dai_driver sta350_dai = { | ||
904 | .name = "sta350-hifi", | ||
905 | .playback = { | ||
906 | .stream_name = "Playback", | ||
907 | .channels_min = 2, | ||
908 | .channels_max = 2, | ||
909 | .rates = STA350_RATES, | ||
910 | .formats = STA350_FORMATS, | ||
911 | }, | ||
912 | .ops = &sta350_dai_ops, | ||
913 | }; | ||
914 | |||
915 | #ifdef CONFIG_PM | ||
916 | static int sta350_suspend(struct snd_soc_codec *codec) | ||
917 | { | ||
918 | sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
919 | return 0; | ||
920 | } | ||
921 | |||
922 | static int sta350_resume(struct snd_soc_codec *codec) | ||
923 | { | ||
924 | sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
925 | return 0; | ||
926 | } | ||
927 | #else | ||
928 | #define sta350_suspend NULL | ||
929 | #define sta350_resume NULL | ||
930 | #endif | ||
931 | |||
932 | static int sta350_probe(struct snd_soc_codec *codec) | ||
933 | { | ||
934 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
935 | struct sta350_platform_data *pdata = sta350->pdata; | ||
936 | int i, ret = 0, thermal = 0; | ||
937 | |||
938 | ret = regulator_bulk_enable(ARRAY_SIZE(sta350->supplies), | ||
939 | sta350->supplies); | ||
940 | if (ret < 0) { | ||
941 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
942 | return ret; | ||
943 | } | ||
944 | |||
945 | ret = sta350_startup_sequence(sta350); | ||
946 | if (ret < 0) { | ||
947 | dev_err(codec->dev, "Failed to startup device\n"); | ||
948 | return ret; | ||
949 | } | ||
950 | |||
951 | /* CONFA */ | ||
952 | if (!pdata->thermal_warning_recovery) | ||
953 | thermal |= STA350_CONFA_TWAB; | ||
954 | if (!pdata->thermal_warning_adjustment) | ||
955 | thermal |= STA350_CONFA_TWRB; | ||
956 | if (!pdata->fault_detect_recovery) | ||
957 | thermal |= STA350_CONFA_FDRB; | ||
958 | regmap_update_bits(sta350->regmap, STA350_CONFA, | ||
959 | STA350_CONFA_TWAB | STA350_CONFA_TWRB | | ||
960 | STA350_CONFA_FDRB, | ||
961 | thermal); | ||
962 | |||
963 | /* CONFC */ | ||
964 | regmap_update_bits(sta350->regmap, STA350_CONFC, | ||
965 | STA350_CONFC_OM_MASK, | ||
966 | pdata->ffx_power_output_mode | ||
967 | << STA350_CONFC_OM_SHIFT); | ||
968 | regmap_update_bits(sta350->regmap, STA350_CONFC, | ||
969 | STA350_CONFC_CSZ_MASK, | ||
970 | pdata->drop_compensation_ns | ||
971 | << STA350_CONFC_CSZ_SHIFT); | ||
972 | regmap_update_bits(sta350->regmap, | ||
973 | STA350_CONFC, | ||
974 | STA350_CONFC_OCRB, | ||
975 | pdata->oc_warning_adjustment ? | ||
976 | STA350_CONFC_OCRB : 0); | ||
977 | |||
978 | /* CONFE */ | ||
979 | regmap_update_bits(sta350->regmap, STA350_CONFE, | ||
980 | STA350_CONFE_MPCV, | ||
981 | pdata->max_power_use_mpcc ? | ||
982 | STA350_CONFE_MPCV : 0); | ||
983 | regmap_update_bits(sta350->regmap, STA350_CONFE, | ||
984 | STA350_CONFE_MPC, | ||
985 | pdata->max_power_correction ? | ||
986 | STA350_CONFE_MPC : 0); | ||
987 | regmap_update_bits(sta350->regmap, STA350_CONFE, | ||
988 | STA350_CONFE_AME, | ||
989 | pdata->am_reduction_mode ? | ||
990 | STA350_CONFE_AME : 0); | ||
991 | regmap_update_bits(sta350->regmap, STA350_CONFE, | ||
992 | STA350_CONFE_PWMS, | ||
993 | pdata->odd_pwm_speed_mode ? | ||
994 | STA350_CONFE_PWMS : 0); | ||
995 | regmap_update_bits(sta350->regmap, STA350_CONFE, | ||
996 | STA350_CONFE_DCCV, | ||
997 | pdata->distortion_compensation ? | ||
998 | STA350_CONFE_DCCV : 0); | ||
999 | /* CONFF */ | ||
1000 | regmap_update_bits(sta350->regmap, STA350_CONFF, | ||
1001 | STA350_CONFF_IDE, | ||
1002 | pdata->invalid_input_detect_mute ? | ||
1003 | STA350_CONFF_IDE : 0); | ||
1004 | regmap_update_bits(sta350->regmap, STA350_CONFF, | ||
1005 | STA350_CONFF_OCFG_MASK, | ||
1006 | pdata->output_conf | ||
1007 | << STA350_CONFF_OCFG_SHIFT); | ||
1008 | |||
1009 | /* channel to output mapping */ | ||
1010 | regmap_update_bits(sta350->regmap, STA350_C1CFG, | ||
1011 | STA350_CxCFG_OM_MASK, | ||
1012 | pdata->ch1_output_mapping | ||
1013 | << STA350_CxCFG_OM_SHIFT); | ||
1014 | regmap_update_bits(sta350->regmap, STA350_C2CFG, | ||
1015 | STA350_CxCFG_OM_MASK, | ||
1016 | pdata->ch2_output_mapping | ||
1017 | << STA350_CxCFG_OM_SHIFT); | ||
1018 | regmap_update_bits(sta350->regmap, STA350_C3CFG, | ||
1019 | STA350_CxCFG_OM_MASK, | ||
1020 | pdata->ch3_output_mapping | ||
1021 | << STA350_CxCFG_OM_SHIFT); | ||
1022 | |||
1023 | /* miscellaneous registers */ | ||
1024 | regmap_update_bits(sta350->regmap, STA350_MISC1, | ||
1025 | STA350_MISC1_CPWMEN, | ||
1026 | pdata->activate_mute_output ? | ||
1027 | STA350_MISC1_CPWMEN : 0); | ||
1028 | regmap_update_bits(sta350->regmap, STA350_MISC1, | ||
1029 | STA350_MISC1_BRIDGOFF, | ||
1030 | pdata->bridge_immediate_off ? | ||
1031 | STA350_MISC1_BRIDGOFF : 0); | ||
1032 | regmap_update_bits(sta350->regmap, STA350_MISC1, | ||
1033 | STA350_MISC1_NSHHPEN, | ||
1034 | pdata->noise_shape_dc_cut ? | ||
1035 | STA350_MISC1_NSHHPEN : 0); | ||
1036 | regmap_update_bits(sta350->regmap, STA350_MISC1, | ||
1037 | STA350_MISC1_RPDNEN, | ||
1038 | pdata->powerdown_master_vol ? | ||
1039 | STA350_MISC1_RPDNEN: 0); | ||
1040 | |||
1041 | regmap_update_bits(sta350->regmap, STA350_MISC2, | ||
1042 | STA350_MISC2_PNDLSL_MASK, | ||
1043 | pdata->powerdown_delay_divider | ||
1044 | << STA350_MISC2_PNDLSL_SHIFT); | ||
1045 | |||
1046 | /* initialize coefficient shadow RAM with reset values */ | ||
1047 | for (i = 4; i <= 49; i += 5) | ||
1048 | sta350->coef_shadow[i] = 0x400000; | ||
1049 | for (i = 50; i <= 54; i++) | ||
1050 | sta350->coef_shadow[i] = 0x7fffff; | ||
1051 | sta350->coef_shadow[55] = 0x5a9df7; | ||
1052 | sta350->coef_shadow[56] = 0x7fffff; | ||
1053 | sta350->coef_shadow[59] = 0x7fffff; | ||
1054 | sta350->coef_shadow[60] = 0x400000; | ||
1055 | sta350->coef_shadow[61] = 0x400000; | ||
1056 | |||
1057 | sta350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
1058 | /* Bias level configuration will have done an extra enable */ | ||
1059 | regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); | ||
1060 | |||
1061 | return 0; | ||
1062 | } | ||
1063 | |||
1064 | static int sta350_remove(struct snd_soc_codec *codec) | ||
1065 | { | ||
1066 | struct sta350_priv *sta350 = snd_soc_codec_get_drvdata(codec); | ||
1067 | |||
1068 | sta350_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1069 | regulator_bulk_disable(ARRAY_SIZE(sta350->supplies), sta350->supplies); | ||
1070 | |||
1071 | return 0; | ||
1072 | } | ||
1073 | |||
1074 | static const struct snd_soc_codec_driver sta350_codec = { | ||
1075 | .probe = sta350_probe, | ||
1076 | .remove = sta350_remove, | ||
1077 | .suspend = sta350_suspend, | ||
1078 | .resume = sta350_resume, | ||
1079 | .set_bias_level = sta350_set_bias_level, | ||
1080 | .controls = sta350_snd_controls, | ||
1081 | .num_controls = ARRAY_SIZE(sta350_snd_controls), | ||
1082 | .dapm_widgets = sta350_dapm_widgets, | ||
1083 | .num_dapm_widgets = ARRAY_SIZE(sta350_dapm_widgets), | ||
1084 | .dapm_routes = sta350_dapm_routes, | ||
1085 | .num_dapm_routes = ARRAY_SIZE(sta350_dapm_routes), | ||
1086 | }; | ||
1087 | |||
1088 | static const struct regmap_config sta350_regmap = { | ||
1089 | .reg_bits = 8, | ||
1090 | .val_bits = 8, | ||
1091 | .max_register = STA350_MISC2, | ||
1092 | .reg_defaults = sta350_regs, | ||
1093 | .num_reg_defaults = ARRAY_SIZE(sta350_regs), | ||
1094 | .cache_type = REGCACHE_RBTREE, | ||
1095 | .wr_table = &sta350_write_regs, | ||
1096 | .rd_table = &sta350_read_regs, | ||
1097 | .volatile_table = &sta350_volatile_regs, | ||
1098 | }; | ||
1099 | |||
1100 | #ifdef CONFIG_OF | ||
1101 | static const struct of_device_id st350_dt_ids[] = { | ||
1102 | { .compatible = "st,sta350", }, | ||
1103 | { } | ||
1104 | }; | ||
1105 | MODULE_DEVICE_TABLE(of, st350_dt_ids); | ||
1106 | |||
1107 | static const char * const sta350_ffx_modes[] = { | ||
1108 | [STA350_FFX_PM_DROP_COMP] = "drop-compensation", | ||
1109 | [STA350_FFX_PM_TAPERED_COMP] = "tapered-compensation", | ||
1110 | [STA350_FFX_PM_FULL_POWER] = "full-power-mode", | ||
1111 | [STA350_FFX_PM_VARIABLE_DROP_COMP] = "variable-drop-compensation", | ||
1112 | }; | ||
1113 | |||
1114 | static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) | ||
1115 | { | ||
1116 | struct device_node *np = dev->of_node; | ||
1117 | struct sta350_platform_data *pdata; | ||
1118 | const char *ffx_power_mode; | ||
1119 | u16 tmp; | ||
1120 | u8 tmp8; | ||
1121 | |||
1122 | pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); | ||
1123 | if (!pdata) | ||
1124 | return -ENOMEM; | ||
1125 | |||
1126 | of_property_read_u8(np, "st,output-conf", | ||
1127 | &pdata->output_conf); | ||
1128 | of_property_read_u8(np, "st,ch1-output-mapping", | ||
1129 | &pdata->ch1_output_mapping); | ||
1130 | of_property_read_u8(np, "st,ch2-output-mapping", | ||
1131 | &pdata->ch2_output_mapping); | ||
1132 | of_property_read_u8(np, "st,ch3-output-mapping", | ||
1133 | &pdata->ch3_output_mapping); | ||
1134 | |||
1135 | if (of_get_property(np, "st,thermal-warning-recovery", NULL)) | ||
1136 | pdata->thermal_warning_recovery = 1; | ||
1137 | if (of_get_property(np, "st,thermal-warning-adjustment", NULL)) | ||
1138 | pdata->thermal_warning_adjustment = 1; | ||
1139 | if (of_get_property(np, "st,fault-detect-recovery", NULL)) | ||
1140 | pdata->fault_detect_recovery = 1; | ||
1141 | |||
1142 | pdata->ffx_power_output_mode = STA350_FFX_PM_VARIABLE_DROP_COMP; | ||
1143 | if (!of_property_read_string(np, "st,ffx-power-output-mode", | ||
1144 | &ffx_power_mode)) { | ||
1145 | int i, mode = -EINVAL; | ||
1146 | |||
1147 | for (i = 0; i < ARRAY_SIZE(sta350_ffx_modes); i++) | ||
1148 | if (!strcasecmp(ffx_power_mode, sta350_ffx_modes[i])) | ||
1149 | mode = i; | ||
1150 | |||
1151 | if (mode < 0) | ||
1152 | dev_warn(dev, "Unsupported ffx output mode: %s\n", | ||
1153 | ffx_power_mode); | ||
1154 | else | ||
1155 | pdata->ffx_power_output_mode = mode; | ||
1156 | } | ||
1157 | |||
1158 | tmp = 140; | ||
1159 | of_property_read_u16(np, "st,drop-compensation-ns", &tmp); | ||
1160 | pdata->drop_compensation_ns = clamp_t(u16, tmp, 0, 300) / 20; | ||
1161 | |||
1162 | if (of_get_property(np, "st,overcurrent-warning-adjustment", NULL)) | ||
1163 | pdata->oc_warning_adjustment = 1; | ||
1164 | |||
1165 | /* CONFE */ | ||
1166 | if (of_get_property(np, "st,max-power-use-mpcc", NULL)) | ||
1167 | pdata->max_power_use_mpcc = 1; | ||
1168 | |||
1169 | if (of_get_property(np, "st,max-power-correction", NULL)) | ||
1170 | pdata->max_power_correction = 1; | ||
1171 | |||
1172 | if (of_get_property(np, "st,am-reduction-mode", NULL)) | ||
1173 | pdata->am_reduction_mode = 1; | ||
1174 | |||
1175 | if (of_get_property(np, "st,odd-pwm-speed-mode", NULL)) | ||
1176 | pdata->odd_pwm_speed_mode = 1; | ||
1177 | |||
1178 | if (of_get_property(np, "st,distortion-compensation", NULL)) | ||
1179 | pdata->distortion_compensation = 1; | ||
1180 | |||
1181 | /* CONFF */ | ||
1182 | if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) | ||
1183 | pdata->invalid_input_detect_mute = 1; | ||
1184 | |||
1185 | /* MISC */ | ||
1186 | if (of_get_property(np, "st,activate-mute-output", NULL)) | ||
1187 | pdata->activate_mute_output = 1; | ||
1188 | |||
1189 | if (of_get_property(np, "st,bridge-immediate-off", NULL)) | ||
1190 | pdata->bridge_immediate_off = 1; | ||
1191 | |||
1192 | if (of_get_property(np, "st,noise-shape-dc-cut", NULL)) | ||
1193 | pdata->noise_shape_dc_cut = 1; | ||
1194 | |||
1195 | if (of_get_property(np, "st,powerdown-master-volume", NULL)) | ||
1196 | pdata->powerdown_master_vol = 1; | ||
1197 | |||
1198 | if (!of_property_read_u8(np, "st,powerdown-delay-divider", &tmp8)) { | ||
1199 | if (is_power_of_2(tmp8) && tmp8 >= 1 && tmp8 <= 128) | ||
1200 | pdata->powerdown_delay_divider = ilog2(tmp8); | ||
1201 | else | ||
1202 | dev_warn(dev, "Unsupported powerdown delay divider %d\n", | ||
1203 | tmp8); | ||
1204 | } | ||
1205 | |||
1206 | sta350->pdata = pdata; | ||
1207 | |||
1208 | return 0; | ||
1209 | } | ||
1210 | #endif | ||
1211 | |||
1212 | static int sta350_i2c_probe(struct i2c_client *i2c, | ||
1213 | const struct i2c_device_id *id) | ||
1214 | { | ||
1215 | struct device *dev = &i2c->dev; | ||
1216 | struct sta350_priv *sta350; | ||
1217 | int ret, i; | ||
1218 | |||
1219 | sta350 = devm_kzalloc(dev, sizeof(struct sta350_priv), GFP_KERNEL); | ||
1220 | if (!sta350) | ||
1221 | return -ENOMEM; | ||
1222 | |||
1223 | mutex_init(&sta350->coeff_lock); | ||
1224 | sta350->pdata = dev_get_platdata(dev); | ||
1225 | |||
1226 | #ifdef CONFIG_OF | ||
1227 | if (dev->of_node) { | ||
1228 | ret = sta350_probe_dt(dev, sta350); | ||
1229 | if (ret < 0) | ||
1230 | return ret; | ||
1231 | } | ||
1232 | #endif | ||
1233 | |||
1234 | /* GPIOs */ | ||
1235 | sta350->gpiod_nreset = devm_gpiod_get(dev, "reset"); | ||
1236 | if (IS_ERR(sta350->gpiod_nreset)) { | ||
1237 | ret = PTR_ERR(sta350->gpiod_nreset); | ||
1238 | if (ret != -ENOENT && ret != -ENOSYS) | ||
1239 | return ret; | ||
1240 | |||
1241 | sta350->gpiod_nreset = NULL; | ||
1242 | } else { | ||
1243 | gpiod_direction_output(sta350->gpiod_nreset, 0); | ||
1244 | } | ||
1245 | |||
1246 | sta350->gpiod_power_down = devm_gpiod_get(dev, "power-down"); | ||
1247 | if (IS_ERR(sta350->gpiod_power_down)) { | ||
1248 | ret = PTR_ERR(sta350->gpiod_power_down); | ||
1249 | if (ret != -ENOENT && ret != -ENOSYS) | ||
1250 | return ret; | ||
1251 | |||
1252 | sta350->gpiod_power_down = NULL; | ||
1253 | } else { | ||
1254 | gpiod_direction_output(sta350->gpiod_power_down, 0); | ||
1255 | } | ||
1256 | |||
1257 | /* regulators */ | ||
1258 | for (i = 0; i < ARRAY_SIZE(sta350->supplies); i++) | ||
1259 | sta350->supplies[i].supply = sta350_supply_names[i]; | ||
1260 | |||
1261 | ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(sta350->supplies), | ||
1262 | sta350->supplies); | ||
1263 | if (ret < 0) { | ||
1264 | dev_err(dev, "Failed to request supplies: %d\n", ret); | ||
1265 | return ret; | ||
1266 | } | ||
1267 | |||
1268 | sta350->regmap = devm_regmap_init_i2c(i2c, &sta350_regmap); | ||
1269 | if (IS_ERR(sta350->regmap)) { | ||
1270 | ret = PTR_ERR(sta350->regmap); | ||
1271 | dev_err(dev, "Failed to init regmap: %d\n", ret); | ||
1272 | return ret; | ||
1273 | } | ||
1274 | |||
1275 | i2c_set_clientdata(i2c, sta350); | ||
1276 | |||
1277 | ret = snd_soc_register_codec(dev, &sta350_codec, &sta350_dai, 1); | ||
1278 | if (ret < 0) | ||
1279 | dev_err(dev, "Failed to register codec (%d)\n", ret); | ||
1280 | |||
1281 | return ret; | ||
1282 | } | ||
1283 | |||
1284 | static int sta350_i2c_remove(struct i2c_client *client) | ||
1285 | { | ||
1286 | snd_soc_unregister_codec(&client->dev); | ||
1287 | return 0; | ||
1288 | } | ||
1289 | |||
1290 | static const struct i2c_device_id sta350_i2c_id[] = { | ||
1291 | { "sta350", 0 }, | ||
1292 | { } | ||
1293 | }; | ||
1294 | MODULE_DEVICE_TABLE(i2c, sta350_i2c_id); | ||
1295 | |||
1296 | static struct i2c_driver sta350_i2c_driver = { | ||
1297 | .driver = { | ||
1298 | .name = "sta350", | ||
1299 | .owner = THIS_MODULE, | ||
1300 | .of_match_table = of_match_ptr(st350_dt_ids), | ||
1301 | }, | ||
1302 | .probe = sta350_i2c_probe, | ||
1303 | .remove = sta350_i2c_remove, | ||
1304 | .id_table = sta350_i2c_id, | ||
1305 | }; | ||
1306 | |||
1307 | module_i2c_driver(sta350_i2c_driver); | ||
1308 | |||
1309 | MODULE_DESCRIPTION("ASoC STA350 driver"); | ||
1310 | MODULE_AUTHOR("Sven Brandau <info@brandau.biz>"); | ||
1311 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/sta350.h b/sound/soc/codecs/sta350.h new file mode 100644 index 000000000000..fb7285290779 --- /dev/null +++ b/sound/soc/codecs/sta350.h | |||
@@ -0,0 +1,238 @@ | |||
1 | /* | ||
2 | * Codec driver for ST STA350 2.1-channel high-efficiency digital audio system | ||
3 | * | ||
4 | * Copyright: 2011 Raumfeld GmbH | ||
5 | * Author: Sven Brandau <info@brandau.biz> | ||
6 | * | ||
7 | * based on code from: | ||
8 | * Raumfeld GmbH | ||
9 | * Johannes Stezenbach <js@sig21.net> | ||
10 | * Wolfson Microelectronics PLC. | ||
11 | * Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the | ||
15 | * Free Software Foundation; either version 2 of the License, or (at your | ||
16 | * option) any later version. | ||
17 | */ | ||
18 | #ifndef _ASOC_STA_350_H | ||
19 | #define _ASOC_STA_350_H | ||
20 | |||
21 | /* STA50 register addresses */ | ||
22 | |||
23 | #define STA350_REGISTER_COUNT 0x4D | ||
24 | #define STA350_COEF_COUNT 62 | ||
25 | |||
26 | #define STA350_CONFA 0x00 | ||
27 | #define STA350_CONFB 0x01 | ||
28 | #define STA350_CONFC 0x02 | ||
29 | #define STA350_CONFD 0x03 | ||
30 | #define STA350_CONFE 0x04 | ||
31 | #define STA350_CONFF 0x05 | ||
32 | #define STA350_MMUTE 0x06 | ||
33 | #define STA350_MVOL 0x07 | ||
34 | #define STA350_C1VOL 0x08 | ||
35 | #define STA350_C2VOL 0x09 | ||
36 | #define STA350_C3VOL 0x0a | ||
37 | #define STA350_AUTO1 0x0b | ||
38 | #define STA350_AUTO2 0x0c | ||
39 | #define STA350_AUTO3 0x0d | ||
40 | #define STA350_C1CFG 0x0e | ||
41 | #define STA350_C2CFG 0x0f | ||
42 | #define STA350_C3CFG 0x10 | ||
43 | #define STA350_TONE 0x11 | ||
44 | #define STA350_L1AR 0x12 | ||
45 | #define STA350_L1ATRT 0x13 | ||
46 | #define STA350_L2AR 0x14 | ||
47 | #define STA350_L2ATRT 0x15 | ||
48 | #define STA350_CFADDR2 0x16 | ||
49 | #define STA350_B1CF1 0x17 | ||
50 | #define STA350_B1CF2 0x18 | ||
51 | #define STA350_B1CF3 0x19 | ||
52 | #define STA350_B2CF1 0x1a | ||
53 | #define STA350_B2CF2 0x1b | ||
54 | #define STA350_B2CF3 0x1c | ||
55 | #define STA350_A1CF1 0x1d | ||
56 | #define STA350_A1CF2 0x1e | ||
57 | #define STA350_A1CF3 0x1f | ||
58 | #define STA350_A2CF1 0x20 | ||
59 | #define STA350_A2CF2 0x21 | ||
60 | #define STA350_A2CF3 0x22 | ||
61 | #define STA350_B0CF1 0x23 | ||
62 | #define STA350_B0CF2 0x24 | ||
63 | #define STA350_B0CF3 0x25 | ||
64 | #define STA350_CFUD 0x26 | ||
65 | #define STA350_MPCC1 0x27 | ||
66 | #define STA350_MPCC2 0x28 | ||
67 | #define STA350_DCC1 0x29 | ||
68 | #define STA350_DCC2 0x2a | ||
69 | #define STA350_FDRC1 0x2b | ||
70 | #define STA350_FDRC2 0x2c | ||
71 | #define STA350_STATUS 0x2d | ||
72 | /* reserved: 0x2d - 0x30 */ | ||
73 | #define STA350_EQCFG 0x31 | ||
74 | #define STA350_EATH1 0x32 | ||
75 | #define STA350_ERTH1 0x33 | ||
76 | #define STA350_EATH2 0x34 | ||
77 | #define STA350_ERTH2 0x35 | ||
78 | #define STA350_CONFX 0x36 | ||
79 | #define STA350_SVCA 0x37 | ||
80 | #define STA350_SVCB 0x38 | ||
81 | #define STA350_RMS0A 0x39 | ||
82 | #define STA350_RMS0B 0x3a | ||
83 | #define STA350_RMS0C 0x3b | ||
84 | #define STA350_RMS1A 0x3c | ||
85 | #define STA350_RMS1B 0x3d | ||
86 | #define STA350_RMS1C 0x3e | ||
87 | #define STA350_EVOLRES 0x3f | ||
88 | /* reserved: 0x40 - 0x47 */ | ||
89 | #define STA350_NSHAPE 0x48 | ||
90 | #define STA350_CTXB4B1 0x49 | ||
91 | #define STA350_CTXB7B5 0x4a | ||
92 | #define STA350_MISC1 0x4b | ||
93 | #define STA350_MISC2 0x4c | ||
94 | |||
95 | /* 0x00 CONFA */ | ||
96 | #define STA350_CONFA_MCS_MASK 0x03 | ||
97 | #define STA350_CONFA_MCS_SHIFT 0 | ||
98 | #define STA350_CONFA_IR_MASK 0x18 | ||
99 | #define STA350_CONFA_IR_SHIFT 3 | ||
100 | #define STA350_CONFA_TWRB BIT(5) | ||
101 | #define STA350_CONFA_TWAB BIT(6) | ||
102 | #define STA350_CONFA_FDRB BIT(7) | ||
103 | |||
104 | /* 0x01 CONFB */ | ||
105 | #define STA350_CONFB_SAI_MASK 0x0f | ||
106 | #define STA350_CONFB_SAI_SHIFT 0 | ||
107 | #define STA350_CONFB_SAIFB BIT(4) | ||
108 | #define STA350_CONFB_DSCKE BIT(5) | ||
109 | #define STA350_CONFB_C1IM BIT(6) | ||
110 | #define STA350_CONFB_C2IM BIT(7) | ||
111 | |||
112 | /* 0x02 CONFC */ | ||
113 | #define STA350_CONFC_OM_MASK 0x03 | ||
114 | #define STA350_CONFC_OM_SHIFT 0 | ||
115 | #define STA350_CONFC_CSZ_MASK 0x3c | ||
116 | #define STA350_CONFC_CSZ_SHIFT 2 | ||
117 | #define STA350_CONFC_OCRB BIT(7) | ||
118 | |||
119 | /* 0x03 CONFD */ | ||
120 | #define STA350_CONFD_HPB_SHIFT 0 | ||
121 | #define STA350_CONFD_DEMP_SHIFT 1 | ||
122 | #define STA350_CONFD_DSPB_SHIFT 2 | ||
123 | #define STA350_CONFD_PSL_SHIFT 3 | ||
124 | #define STA350_CONFD_BQL_SHIFT 4 | ||
125 | #define STA350_CONFD_DRC_SHIFT 5 | ||
126 | #define STA350_CONFD_ZDE_SHIFT 6 | ||
127 | #define STA350_CONFD_SME_SHIFT 7 | ||
128 | |||
129 | /* 0x04 CONFE */ | ||
130 | #define STA350_CONFE_MPCV BIT(0) | ||
131 | #define STA350_CONFE_MPCV_SHIFT 0 | ||
132 | #define STA350_CONFE_MPC BIT(1) | ||
133 | #define STA350_CONFE_MPC_SHIFT 1 | ||
134 | #define STA350_CONFE_NSBW BIT(2) | ||
135 | #define STA350_CONFE_NSBW_SHIFT 2 | ||
136 | #define STA350_CONFE_AME BIT(3) | ||
137 | #define STA350_CONFE_AME_SHIFT 3 | ||
138 | #define STA350_CONFE_PWMS BIT(4) | ||
139 | #define STA350_CONFE_PWMS_SHIFT 4 | ||
140 | #define STA350_CONFE_DCCV BIT(5) | ||
141 | #define STA350_CONFE_DCCV_SHIFT 5 | ||
142 | #define STA350_CONFE_ZCE BIT(6) | ||
143 | #define STA350_CONFE_ZCE_SHIFT 6 | ||
144 | #define STA350_CONFE_SVE BIT(7) | ||
145 | #define STA350_CONFE_SVE_SHIFT 7 | ||
146 | |||
147 | /* 0x05 CONFF */ | ||
148 | #define STA350_CONFF_OCFG_MASK 0x03 | ||
149 | #define STA350_CONFF_OCFG_SHIFT 0 | ||
150 | #define STA350_CONFF_IDE BIT(2) | ||
151 | #define STA350_CONFF_BCLE BIT(3) | ||
152 | #define STA350_CONFF_LDTE BIT(4) | ||
153 | #define STA350_CONFF_ECLE BIT(5) | ||
154 | #define STA350_CONFF_PWDN BIT(6) | ||
155 | #define STA350_CONFF_EAPD BIT(7) | ||
156 | |||
157 | /* 0x06 MMUTE */ | ||
158 | #define STA350_MMUTE_MMUTE 0x01 | ||
159 | #define STA350_MMUTE_MMUTE_SHIFT 0 | ||
160 | #define STA350_MMUTE_C1M 0x02 | ||
161 | #define STA350_MMUTE_C1M_SHIFT 1 | ||
162 | #define STA350_MMUTE_C2M 0x04 | ||
163 | #define STA350_MMUTE_C2M_SHIFT 2 | ||
164 | #define STA350_MMUTE_C3M 0x08 | ||
165 | #define STA350_MMUTE_C3M_SHIFT 3 | ||
166 | #define STA350_MMUTE_LOC_MASK 0xC0 | ||
167 | #define STA350_MMUTE_LOC_SHIFT 6 | ||
168 | |||
169 | /* 0x0b AUTO1 */ | ||
170 | #define STA350_AUTO1_AMGC_MASK 0x30 | ||
171 | #define STA350_AUTO1_AMGC_SHIFT 4 | ||
172 | |||
173 | /* 0x0c AUTO2 */ | ||
174 | #define STA350_AUTO2_AMAME 0x01 | ||
175 | #define STA350_AUTO2_AMAM_MASK 0x0e | ||
176 | #define STA350_AUTO2_AMAM_SHIFT 1 | ||
177 | #define STA350_AUTO2_XO_MASK 0xf0 | ||
178 | #define STA350_AUTO2_XO_SHIFT 4 | ||
179 | |||
180 | /* 0x0d AUTO3 */ | ||
181 | #define STA350_AUTO3_PEQ_MASK 0x1f | ||
182 | #define STA350_AUTO3_PEQ_SHIFT 0 | ||
183 | |||
184 | /* 0x0e 0x0f 0x10 CxCFG */ | ||
185 | #define STA350_CxCFG_TCB_SHIFT 0 | ||
186 | #define STA350_CxCFG_EQBP_SHIFT 1 | ||
187 | #define STA350_CxCFG_VBP_SHIFT 2 | ||
188 | #define STA350_CxCFG_BO_SHIFT 3 | ||
189 | #define STA350_CxCFG_LS_SHIFT 4 | ||
190 | #define STA350_CxCFG_OM_MASK 0xc0 | ||
191 | #define STA350_CxCFG_OM_SHIFT 6 | ||
192 | |||
193 | /* 0x11 TONE */ | ||
194 | #define STA350_TONE_BTC_SHIFT 0 | ||
195 | #define STA350_TONE_TTC_SHIFT 4 | ||
196 | |||
197 | /* 0x12 0x13 0x14 0x15 limiter attack/release */ | ||
198 | #define STA350_LxA_SHIFT 0 | ||
199 | #define STA350_LxR_SHIFT 4 | ||
200 | |||
201 | /* 0x26 CFUD */ | ||
202 | #define STA350_CFUD_W1 0x01 | ||
203 | #define STA350_CFUD_WA 0x02 | ||
204 | #define STA350_CFUD_R1 0x04 | ||
205 | #define STA350_CFUD_RA 0x08 | ||
206 | |||
207 | |||
208 | /* biquad filter coefficient table offsets */ | ||
209 | #define STA350_C1_BQ_BASE 0 | ||
210 | #define STA350_C2_BQ_BASE 20 | ||
211 | #define STA350_CH_BQ_NUM 4 | ||
212 | #define STA350_BQ_NUM_COEF 5 | ||
213 | #define STA350_XO_HP_BQ_BASE 40 | ||
214 | #define STA350_XO_LP_BQ_BASE 45 | ||
215 | #define STA350_C1_PRESCALE 50 | ||
216 | #define STA350_C2_PRESCALE 51 | ||
217 | #define STA350_C1_POSTSCALE 52 | ||
218 | #define STA350_C2_POSTSCALE 53 | ||
219 | #define STA350_C3_POSTSCALE 54 | ||
220 | #define STA350_TW_POSTSCALE 55 | ||
221 | #define STA350_C1_MIX1 56 | ||
222 | #define STA350_C1_MIX2 57 | ||
223 | #define STA350_C2_MIX1 58 | ||
224 | #define STA350_C2_MIX2 59 | ||
225 | #define STA350_C3_MIX1 60 | ||
226 | #define STA350_C3_MIX2 61 | ||
227 | |||
228 | /* miscellaneous register 1 */ | ||
229 | #define STA350_MISC1_CPWMEN BIT(2) | ||
230 | #define STA350_MISC1_BRIDGOFF BIT(5) | ||
231 | #define STA350_MISC1_NSHHPEN BIT(6) | ||
232 | #define STA350_MISC1_RPDNEN BIT(7) | ||
233 | |||
234 | /* miscellaneous register 2 */ | ||
235 | #define STA350_MISC2_PNDLSL_MASK 0x1c | ||
236 | #define STA350_MISC2_PNDLSL_SHIFT 2 | ||
237 | |||
238 | #endif /* _ASOC_STA_350_H */ | ||
diff --git a/sound/soc/codecs/tas5086.c b/sound/soc/codecs/tas5086.c index a895a5e4bdf2..d48491a4a19d 100644 --- a/sound/soc/codecs/tas5086.c +++ b/sound/soc/codecs/tas5086.c | |||
@@ -272,7 +272,7 @@ static int tas5086_set_deemph(struct snd_soc_codec *codec) | |||
272 | static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, | 272 | static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, |
273 | struct snd_ctl_elem_value *ucontrol) | 273 | struct snd_ctl_elem_value *ucontrol) |
274 | { | 274 | { |
275 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 275 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
276 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | 276 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); |
277 | 277 | ||
278 | ucontrol->value.enumerated.item[0] = priv->deemph; | 278 | ucontrol->value.enumerated.item[0] = priv->deemph; |
@@ -283,7 +283,7 @@ static int tas5086_get_deemph(struct snd_kcontrol *kcontrol, | |||
283 | static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, | 283 | static int tas5086_put_deemph(struct snd_kcontrol *kcontrol, |
284 | struct snd_ctl_elem_value *ucontrol) | 284 | struct snd_ctl_elem_value *ucontrol) |
285 | { | 285 | { |
286 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 286 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
287 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); | 287 | struct tas5086_private *priv = snd_soc_codec_get_drvdata(codec); |
288 | 288 | ||
289 | priv->deemph = ucontrol->value.enumerated.item[0]; | 289 | priv->deemph = ucontrol->value.enumerated.item[0]; |
diff --git a/sound/soc/codecs/tlv320aic23-i2c.c b/sound/soc/codecs/tlv320aic23-i2c.c index b73c94ebcc2a..f13701995482 100644 --- a/sound/soc/codecs/tlv320aic23-i2c.c +++ b/sound/soc/codecs/tlv320aic23-i2c.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/of.h> | ||
16 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
17 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
18 | 19 | ||
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 20864ee8793b..686b8b85b956 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -82,7 +82,7 @@ static const DECLARE_TLV_DB_SCALE(sidetone_vol_tlv, -1800, 300, 0); | |||
82 | static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, | 82 | static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, |
83 | struct snd_ctl_elem_value *ucontrol) | 83 | struct snd_ctl_elem_value *ucontrol) |
84 | { | 84 | { |
85 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 85 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
86 | u16 val, reg; | 86 | u16 val, reg; |
87 | 87 | ||
88 | val = (ucontrol->value.integer.value[0] & 0x07); | 88 | val = (ucontrol->value.integer.value[0] & 0x07); |
@@ -105,7 +105,7 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, | |||
105 | static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, | 105 | static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, |
106 | struct snd_ctl_elem_value *ucontrol) | 106 | struct snd_ctl_elem_value *ucontrol) |
107 | { | 107 | { |
108 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 108 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
109 | u16 val; | 109 | u16 val; |
110 | 110 | ||
111 | val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0); | 111 | val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0); |
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c index d1929de641e2..23419109ecac 100644 --- a/sound/soc/codecs/tlv320aic31xx.c +++ b/sound/soc/codecs/tlv320aic31xx.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/i2c.h> | 28 | #include <linux/i2c.h> |
29 | #include <linux/gpio.h> | 29 | #include <linux/gpio.h> |
30 | #include <linux/regulator/consumer.h> | 30 | #include <linux/regulator/consumer.h> |
31 | #include <linux/of.h> | ||
31 | #include <linux/of_gpio.h> | 32 | #include <linux/of_gpio.h> |
32 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
33 | #include <sound/core.h> | 34 | #include <sound/core.h> |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 6bfc8a17331b..df3a7506c023 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
@@ -442,7 +442,7 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w, | |||
442 | static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, | 442 | static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, |
443 | struct snd_ctl_elem_value *ucontrol) | 443 | struct snd_ctl_elem_value *ucontrol) |
444 | { | 444 | { |
445 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 445 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
446 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 446 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
447 | 447 | ||
448 | ucontrol->value.integer.value[0] = dac33->fifo_mode; | 448 | ucontrol->value.integer.value[0] = dac33->fifo_mode; |
@@ -453,7 +453,7 @@ static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, | |||
453 | static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, | 453 | static int dac33_set_fifo_mode(struct snd_kcontrol *kcontrol, |
454 | struct snd_ctl_elem_value *ucontrol) | 454 | struct snd_ctl_elem_value *ucontrol) |
455 | { | 455 | { |
456 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 456 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
457 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); | 457 | struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); |
458 | int ret = 0; | 458 | int ret = 0; |
459 | 459 | ||
@@ -1540,7 +1540,7 @@ static int dac33_i2c_probe(struct i2c_client *client, | |||
1540 | for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++) | 1540 | for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++) |
1541 | dac33->supplies[i].supply = dac33_supply_names[i]; | 1541 | dac33->supplies[i].supply = dac33_supply_names[i]; |
1542 | 1542 | ||
1543 | ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies), | 1543 | ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies), |
1544 | dac33->supplies); | 1544 | dac33->supplies); |
1545 | 1545 | ||
1546 | if (ret != 0) { | 1546 | if (ret != 0) { |
@@ -1551,11 +1551,9 @@ static int dac33_i2c_probe(struct i2c_client *client, | |||
1551 | ret = snd_soc_register_codec(&client->dev, | 1551 | ret = snd_soc_register_codec(&client->dev, |
1552 | &soc_codec_dev_tlv320dac33, &dac33_dai, 1); | 1552 | &soc_codec_dev_tlv320dac33, &dac33_dai, 1); |
1553 | if (ret < 0) | 1553 | if (ret < 0) |
1554 | goto err_register; | 1554 | goto err_get; |
1555 | 1555 | ||
1556 | return ret; | 1556 | return ret; |
1557 | err_register: | ||
1558 | regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); | ||
1559 | err_get: | 1557 | err_get: |
1560 | if (dac33->power_gpio >= 0) | 1558 | if (dac33->power_gpio >= 0) |
1561 | gpio_free(dac33->power_gpio); | 1559 | gpio_free(dac33->power_gpio); |
@@ -1573,8 +1571,6 @@ static int dac33_i2c_remove(struct i2c_client *client) | |||
1573 | if (dac33->power_gpio >= 0) | 1571 | if (dac33->power_gpio >= 0) |
1574 | gpio_free(dac33->power_gpio); | 1572 | gpio_free(dac33->power_gpio); |
1575 | 1573 | ||
1576 | regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies); | ||
1577 | |||
1578 | snd_soc_unregister_codec(&client->dev); | 1574 | snd_soc_unregister_codec(&client->dev); |
1579 | return 0; | 1575 | return 0; |
1580 | } | 1576 | } |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index b27c396037d4..8fc5a647453b 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <sound/tpa6130a2-plat.h> | 30 | #include <sound/tpa6130a2-plat.h> |
31 | #include <sound/soc.h> | 31 | #include <sound/soc.h> |
32 | #include <sound/tlv.h> | 32 | #include <sound/tlv.h> |
33 | #include <linux/of.h> | ||
33 | #include <linux/of_gpio.h> | 34 | #include <linux/of_gpio.h> |
34 | 35 | ||
35 | #include "tpa6130a2.h" | 36 | #include "tpa6130a2.h" |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 975e0f760ac1..69e12a311ba2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -830,7 +830,7 @@ static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, | |||
830 | { | 830 | { |
831 | struct soc_mixer_control *mc = | 831 | struct soc_mixer_control *mc = |
832 | (struct soc_mixer_control *)kcontrol->private_value; | 832 | (struct soc_mixer_control *)kcontrol->private_value; |
833 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 833 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
834 | unsigned int reg = mc->reg; | 834 | unsigned int reg = mc->reg; |
835 | unsigned int shift = mc->shift; | 835 | unsigned int shift = mc->shift; |
836 | unsigned int rshift = mc->rshift; | 836 | unsigned int rshift = mc->rshift; |
@@ -859,7 +859,7 @@ static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol, | |||
859 | { | 859 | { |
860 | struct soc_mixer_control *mc = | 860 | struct soc_mixer_control *mc = |
861 | (struct soc_mixer_control *)kcontrol->private_value; | 861 | (struct soc_mixer_control *)kcontrol->private_value; |
862 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 862 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
863 | unsigned int reg = mc->reg; | 863 | unsigned int reg = mc->reg; |
864 | unsigned int shift = mc->shift; | 864 | unsigned int shift = mc->shift; |
865 | unsigned int rshift = mc->rshift; | 865 | unsigned int rshift = mc->rshift; |
@@ -888,7 +888,7 @@ static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, | |||
888 | { | 888 | { |
889 | struct soc_mixer_control *mc = | 889 | struct soc_mixer_control *mc = |
890 | (struct soc_mixer_control *)kcontrol->private_value; | 890 | (struct soc_mixer_control *)kcontrol->private_value; |
891 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 891 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
892 | unsigned int reg = mc->reg; | 892 | unsigned int reg = mc->reg; |
893 | unsigned int reg2 = mc->rreg; | 893 | unsigned int reg2 = mc->rreg; |
894 | unsigned int shift = mc->shift; | 894 | unsigned int shift = mc->shift; |
@@ -915,7 +915,7 @@ static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol, | |||
915 | { | 915 | { |
916 | struct soc_mixer_control *mc = | 916 | struct soc_mixer_control *mc = |
917 | (struct soc_mixer_control *)kcontrol->private_value; | 917 | (struct soc_mixer_control *)kcontrol->private_value; |
918 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 918 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
919 | unsigned int reg = mc->reg; | 919 | unsigned int reg = mc->reg; |
920 | unsigned int reg2 = mc->rreg; | 920 | unsigned int reg2 = mc->rreg; |
921 | unsigned int shift = mc->shift; | 921 | unsigned int shift = mc->shift; |
@@ -956,7 +956,7 @@ static SOC_ENUM_SINGLE_DECL(twl4030_op_modes_enum, | |||
956 | static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, | 956 | static int snd_soc_put_twl4030_opmode_enum_double(struct snd_kcontrol *kcontrol, |
957 | struct snd_ctl_elem_value *ucontrol) | 957 | struct snd_ctl_elem_value *ucontrol) |
958 | { | 958 | { |
959 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 959 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
960 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 960 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
961 | 961 | ||
962 | if (twl4030->configured) { | 962 | if (twl4030->configured) { |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index bd3a20647fdf..0f6067f04e29 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
@@ -484,7 +484,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(twl6040_power_mode_enum, | |||
484 | static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, | 484 | static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, |
485 | struct snd_ctl_elem_value *ucontrol) | 485 | struct snd_ctl_elem_value *ucontrol) |
486 | { | 486 | { |
487 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 487 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
488 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 488 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
489 | 489 | ||
490 | ucontrol->value.enumerated.item[0] = priv->hs_power_mode; | 490 | ucontrol->value.enumerated.item[0] = priv->hs_power_mode; |
@@ -495,7 +495,7 @@ static int twl6040_headset_power_get_enum(struct snd_kcontrol *kcontrol, | |||
495 | static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, | 495 | static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, |
496 | struct snd_ctl_elem_value *ucontrol) | 496 | struct snd_ctl_elem_value *ucontrol) |
497 | { | 497 | { |
498 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 498 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
499 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 499 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
500 | int high_perf = ucontrol->value.enumerated.item[0]; | 500 | int high_perf = ucontrol->value.enumerated.item[0]; |
501 | int ret = 0; | 501 | int ret = 0; |
@@ -512,7 +512,7 @@ static int twl6040_headset_power_put_enum(struct snd_kcontrol *kcontrol, | |||
512 | static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, | 512 | static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, |
513 | struct snd_ctl_elem_value *ucontrol) | 513 | struct snd_ctl_elem_value *ucontrol) |
514 | { | 514 | { |
515 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 515 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
516 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 516 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
517 | 517 | ||
518 | ucontrol->value.enumerated.item[0] = priv->pll_power_mode; | 518 | ucontrol->value.enumerated.item[0] = priv->pll_power_mode; |
@@ -523,7 +523,7 @@ static int twl6040_pll_get_enum(struct snd_kcontrol *kcontrol, | |||
523 | static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, | 523 | static int twl6040_pll_put_enum(struct snd_kcontrol *kcontrol, |
524 | struct snd_ctl_elem_value *ucontrol) | 524 | struct snd_ctl_elem_value *ucontrol) |
525 | { | 525 | { |
526 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 526 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
527 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 527 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
528 | 528 | ||
529 | priv->pll_power_mode = ucontrol->value.enumerated.item[0]; | 529 | priv->pll_power_mode = ucontrol->value.enumerated.item[0]; |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 6be5f80b65f1..4ead0dc02b87 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -172,7 +172,7 @@ out: | |||
172 | static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, | 172 | static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, |
173 | struct snd_ctl_elem_value *ucontrol) | 173 | struct snd_ctl_elem_value *ucontrol) |
174 | { | 174 | { |
175 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 175 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
176 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 176 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
177 | 177 | ||
178 | ucontrol->value.integer.value[0] = wl1273->mode; | 178 | ucontrol->value.integer.value[0] = wl1273->mode; |
@@ -190,7 +190,7 @@ static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" }; | |||
190 | static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, | 190 | static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, |
191 | struct snd_ctl_elem_value *ucontrol) | 191 | struct snd_ctl_elem_value *ucontrol) |
192 | { | 192 | { |
193 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 193 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
194 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 194 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
195 | 195 | ||
196 | if (wl1273->mode == ucontrol->value.integer.value[0]) | 196 | if (wl1273->mode == ucontrol->value.integer.value[0]) |
@@ -214,7 +214,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route); | |||
214 | static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, | 214 | static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, |
215 | struct snd_ctl_elem_value *ucontrol) | 215 | struct snd_ctl_elem_value *ucontrol) |
216 | { | 216 | { |
217 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 217 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
218 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 218 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
219 | 219 | ||
220 | dev_dbg(codec->dev, "%s: enter.\n", __func__); | 220 | dev_dbg(codec->dev, "%s: enter.\n", __func__); |
@@ -227,7 +227,7 @@ static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, | |||
227 | static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol, | 227 | static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol, |
228 | struct snd_ctl_elem_value *ucontrol) | 228 | struct snd_ctl_elem_value *ucontrol) |
229 | { | 229 | { |
230 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 230 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
231 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 231 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
232 | int val, r = 0; | 232 | int val, r = 0; |
233 | 233 | ||
@@ -251,7 +251,7 @@ static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings); | |||
251 | static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, | 251 | static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, |
252 | struct snd_ctl_elem_value *ucontrol) | 252 | struct snd_ctl_elem_value *ucontrol) |
253 | { | 253 | { |
254 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 254 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
255 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 255 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
256 | 256 | ||
257 | dev_dbg(codec->dev, "%s: enter.\n", __func__); | 257 | dev_dbg(codec->dev, "%s: enter.\n", __func__); |
@@ -264,7 +264,7 @@ static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, | |||
264 | static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, | 264 | static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, |
265 | struct snd_ctl_elem_value *ucontrol) | 265 | struct snd_ctl_elem_value *ucontrol) |
266 | { | 266 | { |
267 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 267 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
268 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); | 268 | struct wl1273_priv *wl1273 = snd_soc_codec_get_drvdata(codec); |
269 | int r; | 269 | int r; |
270 | 270 | ||
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 83a2c872925c..a4c352cc3464 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -607,7 +607,7 @@ static int wm2000_anc_set_mode(struct wm2000_priv *wm2000) | |||
607 | static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, | 607 | static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, |
608 | struct snd_ctl_elem_value *ucontrol) | 608 | struct snd_ctl_elem_value *ucontrol) |
609 | { | 609 | { |
610 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 610 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
611 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 611 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
612 | 612 | ||
613 | ucontrol->value.enumerated.item[0] = wm2000->anc_active; | 613 | ucontrol->value.enumerated.item[0] = wm2000->anc_active; |
@@ -618,7 +618,7 @@ static int wm2000_anc_mode_get(struct snd_kcontrol *kcontrol, | |||
618 | static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, | 618 | static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, |
619 | struct snd_ctl_elem_value *ucontrol) | 619 | struct snd_ctl_elem_value *ucontrol) |
620 | { | 620 | { |
621 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 621 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
622 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 622 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
623 | int anc_active = ucontrol->value.enumerated.item[0]; | 623 | int anc_active = ucontrol->value.enumerated.item[0]; |
624 | int ret; | 624 | int ret; |
@@ -640,7 +640,7 @@ static int wm2000_anc_mode_put(struct snd_kcontrol *kcontrol, | |||
640 | static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, | 640 | static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, |
641 | struct snd_ctl_elem_value *ucontrol) | 641 | struct snd_ctl_elem_value *ucontrol) |
642 | { | 642 | { |
643 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 643 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
644 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 644 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
645 | 645 | ||
646 | ucontrol->value.enumerated.item[0] = wm2000->spk_ena; | 646 | ucontrol->value.enumerated.item[0] = wm2000->spk_ena; |
@@ -651,7 +651,7 @@ static int wm2000_speaker_get(struct snd_kcontrol *kcontrol, | |||
651 | static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, | 651 | static int wm2000_speaker_put(struct snd_kcontrol *kcontrol, |
652 | struct snd_ctl_elem_value *ucontrol) | 652 | struct snd_ctl_elem_value *ucontrol) |
653 | { | 653 | { |
654 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 654 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
655 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); | 655 | struct wm2000_priv *wm2000 = dev_get_drvdata(codec->dev); |
656 | int val = ucontrol->value.enumerated.item[0]; | 656 | int val = ucontrol->value.enumerated.item[0]; |
657 | int ret; | 657 | int ret; |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index 2e721e06671b..cdea9d9c1631 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -1083,7 +1083,7 @@ static int wm2200_mixer_values[] = { | |||
1083 | 1083 | ||
1084 | #define WM2200_MUX_CTL_DECL(name) \ | 1084 | #define WM2200_MUX_CTL_DECL(name) \ |
1085 | const struct snd_kcontrol_new name##_mux = \ | 1085 | const struct snd_kcontrol_new name##_mux = \ |
1086 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | 1086 | SOC_DAPM_ENUM("Route", name##_enum) |
1087 | 1087 | ||
1088 | #define WM2200_MIXER_ENUMS(name, base_reg) \ | 1088 | #define WM2200_MIXER_ENUMS(name, base_reg) \ |
1089 | static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ | 1089 | static WM2200_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ |
@@ -1207,7 +1207,7 @@ WM2200_MIXER_ENUMS(LHPF1, WM2200_LHPF1MIX_INPUT_1_SOURCE); | |||
1207 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); | 1207 | WM2200_MIXER_ENUMS(LHPF2, WM2200_LHPF2MIX_INPUT_1_SOURCE); |
1208 | 1208 | ||
1209 | #define WM2200_MUX(name, ctrl) \ | 1209 | #define WM2200_MUX(name, ctrl) \ |
1210 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | 1210 | SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) |
1211 | 1211 | ||
1212 | #define WM2200_MIXER_WIDGETS(name, name_str) \ | 1212 | #define WM2200_MIXER_WIDGETS(name, name_str) \ |
1213 | WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ | 1213 | WM2200_MUX(name_str " Input 1", &name##_in1_mux), \ |
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c index eca983fad891..91a9ea2a2056 100644 --- a/sound/soc/codecs/wm5100.c +++ b/sound/soc/codecs/wm5100.c | |||
@@ -390,7 +390,7 @@ static int wm5100_mixer_values[] = { | |||
390 | 390 | ||
391 | #define WM5100_MUX_CTL_DECL(name) \ | 391 | #define WM5100_MUX_CTL_DECL(name) \ |
392 | const struct snd_kcontrol_new name##_mux = \ | 392 | const struct snd_kcontrol_new name##_mux = \ |
393 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | 393 | SOC_DAPM_ENUM("Route", name##_enum) |
394 | 394 | ||
395 | #define WM5100_MIXER_ENUMS(name, base_reg) \ | 395 | #define WM5100_MIXER_ENUMS(name, base_reg) \ |
396 | static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ | 396 | static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ |
@@ -448,7 +448,7 @@ WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE); | |||
448 | WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE); | 448 | WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE); |
449 | 449 | ||
450 | #define WM5100_MUX(name, ctrl) \ | 450 | #define WM5100_MUX(name, ctrl) \ |
451 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | 451 | SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) |
452 | 452 | ||
453 | #define WM5100_MIXER_WIDGETS(name, name_str) \ | 453 | #define WM5100_MIXER_WIDGETS(name, name_str) \ |
454 | WM5100_MUX(name_str " Input 1", &name##_in1_mux), \ | 454 | WM5100_MUX(name_str " Input 1", &name##_in1_mux), \ |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index dcf1d12cfef8..289b64d89abd 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -764,8 +764,8 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | |||
764 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 764 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
765 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), | 765 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), |
766 | 766 | ||
767 | SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), | 767 | SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), |
768 | SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), | 768 | SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), |
769 | 769 | ||
770 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), | 770 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), |
771 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), | 771 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), |
@@ -814,9 +814,9 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, | |||
814 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, | 814 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, |
815 | 0xbf, 0, digital_tlv), | 815 | 0xbf, 0, digital_tlv), |
816 | 816 | ||
817 | SOC_VALUE_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), | 817 | SOC_ENUM("HPOUT1 OSR", wm5102_hpout_osr[0]), |
818 | SOC_VALUE_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), | 818 | SOC_ENUM("HPOUT2 OSR", wm5102_hpout_osr[1]), |
819 | SOC_VALUE_ENUM("EPOUT OSR", wm5102_hpout_osr[2]), | 819 | SOC_ENUM("EPOUT OSR", wm5102_hpout_osr[2]), |
820 | 820 | ||
821 | SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE, | 821 | SOC_DOUBLE("HPOUT1 DRE Switch", ARIZONA_DRE_ENABLE, |
822 | ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0), | 822 | ARIZONA_DRE1L_ENA_SHIFT, ARIZONA_DRE1R_ENA_SHIFT, 1, 0), |
@@ -970,7 +970,7 @@ static const struct soc_enum wm5102_aec_loopback = | |||
970 | wm5102_aec_loopback_values); | 970 | wm5102_aec_loopback_values); |
971 | 971 | ||
972 | static const struct snd_kcontrol_new wm5102_aec_loopback_mux = | 972 | static const struct snd_kcontrol_new wm5102_aec_loopback_mux = |
973 | SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5102_aec_loopback); | 973 | SOC_DAPM_ENUM("AEC Loopback", wm5102_aec_loopback); |
974 | 974 | ||
975 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { | 975 | static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = { |
976 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 976 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
@@ -1204,7 +1204,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, | |||
1204 | 1204 | ||
1205 | ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), | 1205 | ARIZONA_DSP_WIDGETS(DSP1, "DSP1"), |
1206 | 1206 | ||
1207 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | 1207 | SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, |
1208 | ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, | 1208 | ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, |
1209 | &wm5102_aec_loopback_mux), | 1209 | &wm5102_aec_loopback_mux), |
1210 | 1210 | ||
@@ -1760,10 +1760,6 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec) | |||
1760 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); | 1760 | struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec); |
1761 | int ret; | 1761 | int ret; |
1762 | 1762 | ||
1763 | ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); | ||
1764 | if (ret != 0) | ||
1765 | return ret; | ||
1766 | |||
1767 | ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); | 1763 | ret = snd_soc_add_codec_controls(codec, wm_adsp2_fw_controls, 2); |
1768 | if (ret != 0) | 1764 | if (ret != 0) |
1769 | return ret; | 1765 | return ret; |
@@ -1802,9 +1798,17 @@ static unsigned int wm5102_digital_vu[] = { | |||
1802 | ARIZONA_DAC_DIGITAL_VOLUME_5R, | 1798 | ARIZONA_DAC_DIGITAL_VOLUME_5R, |
1803 | }; | 1799 | }; |
1804 | 1800 | ||
1801 | static struct regmap *wm5102_get_regmap(struct device *dev) | ||
1802 | { | ||
1803 | struct wm5102_priv *priv = dev_get_drvdata(dev); | ||
1804 | |||
1805 | return priv->core.arizona->regmap; | ||
1806 | } | ||
1807 | |||
1805 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { | 1808 | static struct snd_soc_codec_driver soc_codec_dev_wm5102 = { |
1806 | .probe = wm5102_codec_probe, | 1809 | .probe = wm5102_codec_probe, |
1807 | .remove = wm5102_codec_remove, | 1810 | .remove = wm5102_codec_remove, |
1811 | .get_regmap = wm5102_get_regmap, | ||
1808 | 1812 | ||
1809 | .idle_bias_off = true, | 1813 | .idle_bias_off = true, |
1810 | 1814 | ||
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index df5a38dd8328..2e5fcb559e90 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -324,13 +324,13 @@ SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode), | |||
324 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), | 324 | SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode), |
325 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), | 325 | SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode), |
326 | 326 | ||
327 | SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), | 327 | SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), |
328 | SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), | 328 | SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), |
329 | SOC_VALUE_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), | 329 | SOC_ENUM("ISRC3 FSL", arizona_isrc_fsl[2]), |
330 | SOC_VALUE_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), | 330 | SOC_ENUM("ISRC1 FSH", arizona_isrc_fsh[0]), |
331 | SOC_VALUE_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), | 331 | SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]), |
332 | SOC_VALUE_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), | 332 | SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]), |
333 | SOC_VALUE_ENUM("ASRC RATE 1", arizona_asrc_rate1), | 333 | SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1), |
334 | 334 | ||
335 | ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), | 335 | ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE), |
336 | ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), | 336 | ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE), |
@@ -367,6 +367,11 @@ SOC_SINGLE("HPOUT2 SC Protect Switch", ARIZONA_HP2_SHORT_CIRCUIT_CTRL, | |||
367 | SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL, | 367 | SOC_SINGLE("HPOUT3 SC Protect Switch", ARIZONA_HP3_SHORT_CIRCUIT_CTRL, |
368 | ARIZONA_HP3_SC_ENA_SHIFT, 1, 0), | 368 | ARIZONA_HP3_SC_ENA_SHIFT, 1, 0), |
369 | 369 | ||
370 | SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L, | ||
371 | ARIZONA_OUT5_OSR_SHIFT, 1, 0), | ||
372 | SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L, | ||
373 | ARIZONA_OUT6_OSR_SHIFT, 1, 0), | ||
374 | |||
370 | SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, | 375 | SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L, |
371 | ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), | 376 | ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1), |
372 | SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, | 377 | SOC_DOUBLE_R("HPOUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L, |
@@ -592,7 +597,7 @@ static const struct soc_enum wm5110_aec_loopback = | |||
592 | wm5110_aec_loopback_values); | 597 | wm5110_aec_loopback_values); |
593 | 598 | ||
594 | static const struct snd_kcontrol_new wm5110_aec_loopback_mux = | 599 | static const struct snd_kcontrol_new wm5110_aec_loopback_mux = |
595 | SOC_DAPM_VALUE_ENUM("AEC Loopback", wm5110_aec_loopback); | 600 | SOC_DAPM_ENUM("AEC Loopback", wm5110_aec_loopback); |
596 | 601 | ||
597 | static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { | 602 | static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = { |
598 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 603 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
@@ -774,7 +779,7 @@ SND_SOC_DAPM_PGA("ISRC3DEC3", ARIZONA_ISRC_3_CTRL_3, | |||
774 | SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3, | 779 | SND_SOC_DAPM_PGA("ISRC3DEC4", ARIZONA_ISRC_3_CTRL_3, |
775 | ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0), | 780 | ARIZONA_ISRC3_DEC3_ENA_SHIFT, 0, NULL, 0), |
776 | 781 | ||
777 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | 782 | SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, |
778 | ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, | 783 | ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, |
779 | &wm5110_aec_loopback_mux), | 784 | &wm5110_aec_loopback_mux), |
780 | 785 | ||
@@ -1589,10 +1594,6 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec) | |||
1589 | 1594 | ||
1590 | priv->core.arizona->dapm = &codec->dapm; | 1595 | priv->core.arizona->dapm = &codec->dapm; |
1591 | 1596 | ||
1592 | ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); | ||
1593 | if (ret != 0) | ||
1594 | return ret; | ||
1595 | |||
1596 | arizona_init_spk(codec); | 1597 | arizona_init_spk(codec); |
1597 | arizona_init_gpio(codec); | 1598 | arizona_init_gpio(codec); |
1598 | 1599 | ||
@@ -1633,9 +1634,17 @@ static unsigned int wm5110_digital_vu[] = { | |||
1633 | ARIZONA_DAC_DIGITAL_VOLUME_6R, | 1634 | ARIZONA_DAC_DIGITAL_VOLUME_6R, |
1634 | }; | 1635 | }; |
1635 | 1636 | ||
1637 | static struct regmap *wm5110_get_regmap(struct device *dev) | ||
1638 | { | ||
1639 | struct wm5110_priv *priv = dev_get_drvdata(dev); | ||
1640 | |||
1641 | return priv->core.arizona->regmap; | ||
1642 | } | ||
1643 | |||
1636 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { | 1644 | static struct snd_soc_codec_driver soc_codec_dev_wm5110 = { |
1637 | .probe = wm5110_codec_probe, | 1645 | .probe = wm5110_codec_probe, |
1638 | .remove = wm5110_codec_remove, | 1646 | .remove = wm5110_codec_remove, |
1647 | .get_regmap = wm5110_get_regmap, | ||
1639 | 1648 | ||
1640 | .idle_bias_off = true, | 1649 | .idle_bias_off = true, |
1641 | 1650 | ||
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 757256bf7672..392285edb595 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -302,7 +302,7 @@ static int pga_event(struct snd_soc_dapm_widget *w, | |||
302 | static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, | 302 | static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, |
303 | struct snd_ctl_elem_value *ucontrol) | 303 | struct snd_ctl_elem_value *ucontrol) |
304 | { | 304 | { |
305 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 305 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
306 | struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); | 306 | struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); |
307 | struct wm8350_output *out = NULL; | 307 | struct wm8350_output *out = NULL; |
308 | struct soc_mixer_control *mc = | 308 | struct soc_mixer_control *mc = |
@@ -345,7 +345,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, | |||
345 | static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol, | 345 | static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol, |
346 | struct snd_ctl_elem_value *ucontrol) | 346 | struct snd_ctl_elem_value *ucontrol) |
347 | { | 347 | { |
348 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 348 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
349 | struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); | 349 | struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); |
350 | struct wm8350_output *out1 = &wm8350_priv->out1; | 350 | struct wm8350_output *out1 = &wm8350_priv->out1; |
351 | struct wm8350_output *out2 = &wm8350_priv->out2; | 351 | struct wm8350_output *out2 = &wm8350_priv->out2; |
@@ -1505,8 +1505,6 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) | |||
1505 | if (ret != 0) | 1505 | if (ret != 0) |
1506 | return ret; | 1506 | return ret; |
1507 | 1507 | ||
1508 | snd_soc_codec_set_cache_io(codec, wm8350->regmap); | ||
1509 | |||
1510 | /* Put the codec into reset if it wasn't already */ | 1508 | /* Put the codec into reset if it wasn't already */ |
1511 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); | 1509 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); |
1512 | 1510 | ||
@@ -1608,11 +1606,19 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) | |||
1608 | return 0; | 1606 | return 0; |
1609 | } | 1607 | } |
1610 | 1608 | ||
1609 | static struct regmap *wm8350_get_regmap(struct device *dev) | ||
1610 | { | ||
1611 | struct wm8350 *wm8350 = dev_get_platdata(dev); | ||
1612 | |||
1613 | return wm8350->regmap; | ||
1614 | } | ||
1615 | |||
1611 | static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { | 1616 | static struct snd_soc_codec_driver soc_codec_dev_wm8350 = { |
1612 | .probe = wm8350_codec_probe, | 1617 | .probe = wm8350_codec_probe, |
1613 | .remove = wm8350_codec_remove, | 1618 | .remove = wm8350_codec_remove, |
1614 | .suspend = wm8350_suspend, | 1619 | .suspend = wm8350_suspend, |
1615 | .resume = wm8350_resume, | 1620 | .resume = wm8350_resume, |
1621 | .get_regmap = wm8350_get_regmap, | ||
1616 | .set_bias_level = wm8350_set_bias_level, | 1622 | .set_bias_level = wm8350_set_bias_level, |
1617 | 1623 | ||
1618 | .controls = wm8350_snd_controls, | 1624 | .controls = wm8350_snd_controls, |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 146564feaea0..06e913d3fea1 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -93,7 +93,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); | |||
93 | static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 93 | static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
94 | struct snd_ctl_elem_value *ucontrol) | 94 | struct snd_ctl_elem_value *ucontrol) |
95 | { | 95 | { |
96 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 96 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
97 | struct soc_mixer_control *mc = | 97 | struct soc_mixer_control *mc = |
98 | (struct soc_mixer_control *)kcontrol->private_value; | 98 | (struct soc_mixer_control *)kcontrol->private_value; |
99 | int reg = mc->reg; | 99 | int reg = mc->reg; |
@@ -1318,8 +1318,6 @@ static int wm8400_codec_probe(struct snd_soc_codec *codec) | |||
1318 | priv->wm8400 = wm8400; | 1318 | priv->wm8400 = wm8400; |
1319 | priv->codec = codec; | 1319 | priv->codec = codec; |
1320 | 1320 | ||
1321 | snd_soc_codec_set_cache_io(codec, wm8400->regmap); | ||
1322 | |||
1323 | ret = devm_regulator_bulk_get(wm8400->dev, | 1321 | ret = devm_regulator_bulk_get(wm8400->dev, |
1324 | ARRAY_SIZE(power), &power[0]); | 1322 | ARRAY_SIZE(power), &power[0]); |
1325 | if (ret != 0) { | 1323 | if (ret != 0) { |
@@ -1361,11 +1359,19 @@ static int wm8400_codec_remove(struct snd_soc_codec *codec) | |||
1361 | return 0; | 1359 | return 0; |
1362 | } | 1360 | } |
1363 | 1361 | ||
1362 | static struct regmap *wm8400_get_regmap(struct device *dev) | ||
1363 | { | ||
1364 | struct wm8400 *wm8400 = dev_get_platdata(dev); | ||
1365 | |||
1366 | return wm8400->regmap; | ||
1367 | } | ||
1368 | |||
1364 | static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { | 1369 | static struct snd_soc_codec_driver soc_codec_dev_wm8400 = { |
1365 | .probe = wm8400_codec_probe, | 1370 | .probe = wm8400_codec_probe, |
1366 | .remove = wm8400_codec_remove, | 1371 | .remove = wm8400_codec_remove, |
1367 | .suspend = wm8400_suspend, | 1372 | .suspend = wm8400_suspend, |
1368 | .resume = wm8400_resume, | 1373 | .resume = wm8400_resume, |
1374 | .get_regmap = wm8400_get_regmap, | ||
1369 | .set_bias_level = wm8400_set_bias_level, | 1375 | .set_bias_level = wm8400_set_bias_level, |
1370 | 1376 | ||
1371 | .controls = wm8400_snd_controls, | 1377 | .controls = wm8400_snd_controls, |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index af7ed8b5d4e1..7665ff6aea6d 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -252,7 +252,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, | |||
252 | { | 252 | { |
253 | struct soc_mixer_control *mc = | 253 | struct soc_mixer_control *mc = |
254 | (struct soc_mixer_control *)kcontrol->private_value; | 254 | (struct soc_mixer_control *)kcontrol->private_value; |
255 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 255 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
256 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); | 256 | struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); |
257 | unsigned int reg = mc->reg; | 257 | unsigned int reg = mc->reg; |
258 | unsigned int reg2 = mc->rreg; | 258 | unsigned int reg2 = mc->rreg; |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index d74f43975b90..5ada61611324 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -119,7 +119,7 @@ static int wm8731_set_deemph(struct snd_soc_codec *codec) | |||
119 | static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, | 119 | static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, |
120 | struct snd_ctl_elem_value *ucontrol) | 120 | struct snd_ctl_elem_value *ucontrol) |
121 | { | 121 | { |
122 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 122 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
123 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 123 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
124 | 124 | ||
125 | ucontrol->value.enumerated.item[0] = wm8731->deemph; | 125 | ucontrol->value.enumerated.item[0] = wm8731->deemph; |
@@ -130,7 +130,7 @@ static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, | |||
130 | static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, | 130 | static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, |
131 | struct snd_ctl_elem_value *ucontrol) | 131 | struct snd_ctl_elem_value *ucontrol) |
132 | { | 132 | { |
133 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 133 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
134 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 134 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
135 | int deemph = ucontrol->value.enumerated.item[0]; | 135 | int deemph = ucontrol->value.enumerated.item[0]; |
136 | int ret = 0; | 136 | int ret = 0; |
@@ -586,7 +586,7 @@ static int wm8731_probe(struct snd_soc_codec *codec) | |||
586 | for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) | 586 | for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++) |
587 | wm8731->supplies[i].supply = wm8731_supply_names[i]; | 587 | wm8731->supplies[i].supply = wm8731_supply_names[i]; |
588 | 588 | ||
589 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies), | 589 | ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies), |
590 | wm8731->supplies); | 590 | wm8731->supplies); |
591 | if (ret != 0) { | 591 | if (ret != 0) { |
592 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 592 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); |
@@ -597,7 +597,7 @@ static int wm8731_probe(struct snd_soc_codec *codec) | |||
597 | wm8731->supplies); | 597 | wm8731->supplies); |
598 | if (ret != 0) { | 598 | if (ret != 0) { |
599 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 599 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
600 | goto err_regulator_get; | 600 | return ret; |
601 | } | 601 | } |
602 | 602 | ||
603 | ret = wm8731_reset(codec); | 603 | ret = wm8731_reset(codec); |
@@ -624,8 +624,6 @@ static int wm8731_probe(struct snd_soc_codec *codec) | |||
624 | 624 | ||
625 | err_regulator_enable: | 625 | err_regulator_enable: |
626 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 626 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
627 | err_regulator_get: | ||
628 | regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | ||
629 | 627 | ||
630 | return ret; | 628 | return ret; |
631 | } | 629 | } |
@@ -638,7 +636,6 @@ static int wm8731_remove(struct snd_soc_codec *codec) | |||
638 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); | 636 | wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); |
639 | 637 | ||
640 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 638 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
641 | regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | ||
642 | 639 | ||
643 | return 0; | 640 | return 0; |
644 | } | 641 | } |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index cbb8d55052a4..53e57b4049a8 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -234,7 +234,7 @@ SOC_ENUM_SINGLE(WM8753_OUTCTL, 2, 2, wm8753_rout2_phase), | |||
234 | static int wm8753_get_dai(struct snd_kcontrol *kcontrol, | 234 | static int wm8753_get_dai(struct snd_kcontrol *kcontrol, |
235 | struct snd_ctl_elem_value *ucontrol) | 235 | struct snd_ctl_elem_value *ucontrol) |
236 | { | 236 | { |
237 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 237 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
238 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 238 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
239 | 239 | ||
240 | ucontrol->value.integer.value[0] = wm8753->dai_func; | 240 | ucontrol->value.integer.value[0] = wm8753->dai_func; |
@@ -244,7 +244,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol, | |||
244 | static int wm8753_set_dai(struct snd_kcontrol *kcontrol, | 244 | static int wm8753_set_dai(struct snd_kcontrol *kcontrol, |
245 | struct snd_ctl_elem_value *ucontrol) | 245 | struct snd_ctl_elem_value *ucontrol) |
246 | { | 246 | { |
247 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 247 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
248 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 248 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
249 | u16 ioctl; | 249 | u16 ioctl; |
250 | 250 | ||
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index ee76f0fb4299..bbcad9ff3c98 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
@@ -106,7 +106,7 @@ static int txsrc_get(struct snd_kcontrol *kcontrol, | |||
106 | struct snd_soc_codec *codec; | 106 | struct snd_soc_codec *codec; |
107 | unsigned int src; | 107 | unsigned int src; |
108 | 108 | ||
109 | codec = snd_kcontrol_chip(kcontrol); | 109 | codec = snd_soc_kcontrol_codec(kcontrol); |
110 | src = snd_soc_read(codec, WM8804_SPDTX4); | 110 | src = snd_soc_read(codec, WM8804_SPDTX4); |
111 | if (src & 0x40) | 111 | if (src & 0x40) |
112 | ucontrol->value.integer.value[0] = 1; | 112 | ucontrol->value.integer.value[0] = 1; |
@@ -122,7 +122,7 @@ static int txsrc_put(struct snd_kcontrol *kcontrol, | |||
122 | struct snd_soc_codec *codec; | 122 | struct snd_soc_codec *codec; |
123 | unsigned int src, txpwr; | 123 | unsigned int src, txpwr; |
124 | 124 | ||
125 | codec = snd_kcontrol_chip(kcontrol); | 125 | codec = snd_soc_kcontrol_codec(kcontrol); |
126 | 126 | ||
127 | if (ucontrol->value.integer.value[0] != 0 | 127 | if (ucontrol->value.integer.value[0] != 0 |
128 | && ucontrol->value.integer.value[0] != 1) | 128 | && ucontrol->value.integer.value[0] != 1) |
@@ -535,7 +535,6 @@ static int wm8804_remove(struct snd_soc_codec *codec) | |||
535 | for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) | 535 | for (i = 0; i < ARRAY_SIZE(wm8804->supplies); ++i) |
536 | regulator_unregister_notifier(wm8804->supplies[i].consumer, | 536 | regulator_unregister_notifier(wm8804->supplies[i].consumer, |
537 | &wm8804->disable_nb[i]); | 537 | &wm8804->disable_nb[i]); |
538 | regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); | ||
539 | return 0; | 538 | return 0; |
540 | } | 539 | } |
541 | 540 | ||
@@ -549,7 +548,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) | |||
549 | for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) | 548 | for (i = 0; i < ARRAY_SIZE(wm8804->supplies); i++) |
550 | wm8804->supplies[i].supply = wm8804_supply_names[i]; | 549 | wm8804->supplies[i].supply = wm8804_supply_names[i]; |
551 | 550 | ||
552 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies), | 551 | ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8804->supplies), |
553 | wm8804->supplies); | 552 | wm8804->supplies); |
554 | if (ret) { | 553 | if (ret) { |
555 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 554 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); |
@@ -574,7 +573,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) | |||
574 | wm8804->supplies); | 573 | wm8804->supplies); |
575 | if (ret) { | 574 | if (ret) { |
576 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 575 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
577 | goto err_reg_get; | 576 | return ret; |
578 | } | 577 | } |
579 | 578 | ||
580 | id1 = snd_soc_read(codec, WM8804_RST_DEVID1); | 579 | id1 = snd_soc_read(codec, WM8804_RST_DEVID1); |
@@ -619,8 +618,6 @@ static int wm8804_probe(struct snd_soc_codec *codec) | |||
619 | 618 | ||
620 | err_reg_enable: | 619 | err_reg_enable: |
621 | regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); | 620 | regulator_bulk_disable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); |
622 | err_reg_get: | ||
623 | regulator_bulk_free(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); | ||
624 | return ret; | 621 | return ret; |
625 | } | 622 | } |
626 | 623 | ||
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b0084a127d18..b84940c359a1 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -439,7 +439,7 @@ static int wm8903_set_deemph(struct snd_soc_codec *codec) | |||
439 | static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, | 439 | static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, |
440 | struct snd_ctl_elem_value *ucontrol) | 440 | struct snd_ctl_elem_value *ucontrol) |
441 | { | 441 | { |
442 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 442 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
443 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 443 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
444 | 444 | ||
445 | ucontrol->value.enumerated.item[0] = wm8903->deemph; | 445 | ucontrol->value.enumerated.item[0] = wm8903->deemph; |
@@ -450,7 +450,7 @@ static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, | |||
450 | static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, | 450 | static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, |
451 | struct snd_ctl_elem_value *ucontrol) | 451 | struct snd_ctl_elem_value *ucontrol) |
452 | { | 452 | { |
453 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 453 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
454 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 454 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
455 | int deemph = ucontrol->value.enumerated.item[0]; | 455 | int deemph = ucontrol->value.enumerated.item[0]; |
456 | int ret = 0; | 456 | int ret = 0; |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 49c35c36935e..f7c549949c54 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -391,7 +391,7 @@ static void wm8904_set_drc(struct snd_soc_codec *codec) | |||
391 | static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, | 391 | static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, |
392 | struct snd_ctl_elem_value *ucontrol) | 392 | struct snd_ctl_elem_value *ucontrol) |
393 | { | 393 | { |
394 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 394 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
395 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 395 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
396 | struct wm8904_pdata *pdata = wm8904->pdata; | 396 | struct wm8904_pdata *pdata = wm8904->pdata; |
397 | int value = ucontrol->value.integer.value[0]; | 397 | int value = ucontrol->value.integer.value[0]; |
@@ -409,7 +409,7 @@ static int wm8904_put_drc_enum(struct snd_kcontrol *kcontrol, | |||
409 | static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol, | 409 | static int wm8904_get_drc_enum(struct snd_kcontrol *kcontrol, |
410 | struct snd_ctl_elem_value *ucontrol) | 410 | struct snd_ctl_elem_value *ucontrol) |
411 | { | 411 | { |
412 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 412 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
413 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 413 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
414 | 414 | ||
415 | ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; | 415 | ucontrol->value.enumerated.item[0] = wm8904->drc_cfg; |
@@ -462,7 +462,7 @@ static void wm8904_set_retune_mobile(struct snd_soc_codec *codec) | |||
462 | static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | 462 | static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, |
463 | struct snd_ctl_elem_value *ucontrol) | 463 | struct snd_ctl_elem_value *ucontrol) |
464 | { | 464 | { |
465 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 465 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
466 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 466 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
467 | struct wm8904_pdata *pdata = wm8904->pdata; | 467 | struct wm8904_pdata *pdata = wm8904->pdata; |
468 | int value = ucontrol->value.integer.value[0]; | 468 | int value = ucontrol->value.integer.value[0]; |
@@ -480,7 +480,7 @@ static int wm8904_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
480 | static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, | 480 | static int wm8904_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, |
481 | struct snd_ctl_elem_value *ucontrol) | 481 | struct snd_ctl_elem_value *ucontrol) |
482 | { | 482 | { |
483 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 483 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
484 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 484 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
485 | 485 | ||
486 | ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; | 486 | ucontrol->value.enumerated.item[0] = wm8904->retune_mobile_cfg; |
@@ -520,7 +520,7 @@ static int wm8904_set_deemph(struct snd_soc_codec *codec) | |||
520 | static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, | 520 | static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, |
521 | struct snd_ctl_elem_value *ucontrol) | 521 | struct snd_ctl_elem_value *ucontrol) |
522 | { | 522 | { |
523 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 523 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
524 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 524 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
525 | 525 | ||
526 | ucontrol->value.enumerated.item[0] = wm8904->deemph; | 526 | ucontrol->value.enumerated.item[0] = wm8904->deemph; |
@@ -530,7 +530,7 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, | |||
530 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, | 530 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, |
531 | struct snd_ctl_elem_value *ucontrol) | 531 | struct snd_ctl_elem_value *ucontrol) |
532 | { | 532 | { |
533 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 533 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
534 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 534 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
535 | int deemph = ucontrol->value.enumerated.item[0]; | 535 | int deemph = ucontrol->value.enumerated.item[0]; |
536 | 536 | ||
@@ -570,7 +570,7 @@ static SOC_ENUM_SINGLE_DECL(hpf_mode, WM8904_ADC_DIGITAL_0, 5, | |||
570 | static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, | 570 | static int wm8904_adc_osr_put(struct snd_kcontrol *kcontrol, |
571 | struct snd_ctl_elem_value *ucontrol) | 571 | struct snd_ctl_elem_value *ucontrol) |
572 | { | 572 | { |
573 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 573 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
574 | unsigned int val; | 574 | unsigned int val; |
575 | int ret; | 575 | int ret; |
576 | 576 | ||
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index fecd4e4f4c57..2a35108f233d 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -390,7 +390,7 @@ static int wm8955_set_deemph(struct snd_soc_codec *codec) | |||
390 | static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, | 390 | static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, |
391 | struct snd_ctl_elem_value *ucontrol) | 391 | struct snd_ctl_elem_value *ucontrol) |
392 | { | 392 | { |
393 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 393 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
394 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 394 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
395 | 395 | ||
396 | ucontrol->value.enumerated.item[0] = wm8955->deemph; | 396 | ucontrol->value.enumerated.item[0] = wm8955->deemph; |
@@ -400,7 +400,7 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, | |||
400 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, | 400 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, |
401 | struct snd_ctl_elem_value *ucontrol) | 401 | struct snd_ctl_elem_value *ucontrol) |
402 | { | 402 | { |
403 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 403 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
404 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 404 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
405 | int deemph = ucontrol->value.enumerated.item[0]; | 405 | int deemph = ucontrol->value.enumerated.item[0]; |
406 | 406 | ||
@@ -898,7 +898,7 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
898 | for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) | 898 | for (i = 0; i < ARRAY_SIZE(wm8955->supplies); i++) |
899 | wm8955->supplies[i].supply = wm8955_supply_names[i]; | 899 | wm8955->supplies[i].supply = wm8955_supply_names[i]; |
900 | 900 | ||
901 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies), | 901 | ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8955->supplies), |
902 | wm8955->supplies); | 902 | wm8955->supplies); |
903 | if (ret != 0) { | 903 | if (ret != 0) { |
904 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 904 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); |
@@ -909,7 +909,7 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
909 | wm8955->supplies); | 909 | wm8955->supplies); |
910 | if (ret != 0) { | 910 | if (ret != 0) { |
911 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 911 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
912 | goto err_get; | 912 | return ret; |
913 | } | 913 | } |
914 | 914 | ||
915 | ret = wm8955_reset(codec); | 915 | ret = wm8955_reset(codec); |
@@ -961,17 +961,12 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
961 | 961 | ||
962 | err_enable: | 962 | err_enable: |
963 | regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); | 963 | regulator_bulk_disable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); |
964 | err_get: | ||
965 | regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); | ||
966 | return ret; | 964 | return ret; |
967 | } | 965 | } |
968 | 966 | ||
969 | static int wm8955_remove(struct snd_soc_codec *codec) | 967 | static int wm8955_remove(struct snd_soc_codec *codec) |
970 | { | 968 | { |
971 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | ||
972 | |||
973 | wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); | 969 | wm8955_set_bias_level(codec, SND_SOC_BIAS_OFF); |
974 | regulator_bulk_free(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); | ||
975 | return 0; | 970 | return 0; |
976 | } | 971 | } |
977 | 972 | ||
diff --git a/sound/soc/codecs/wm8958-dsp2.c b/sound/soc/codecs/wm8958-dsp2.c index 7ac2e511403c..b2ebb104d879 100644 --- a/sound/soc/codecs/wm8958-dsp2.c +++ b/sound/soc/codecs/wm8958-dsp2.c | |||
@@ -456,7 +456,7 @@ static int wm8958_dsp2_busy(struct wm8994_priv *wm8994, int aif) | |||
456 | static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, | 456 | static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, |
457 | struct snd_ctl_elem_value *ucontrol) | 457 | struct snd_ctl_elem_value *ucontrol) |
458 | { | 458 | { |
459 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 459 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
460 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 460 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
461 | struct wm8994 *control = wm8994->wm8994; | 461 | struct wm8994 *control = wm8994->wm8994; |
462 | int value = ucontrol->value.integer.value[0]; | 462 | int value = ucontrol->value.integer.value[0]; |
@@ -478,7 +478,7 @@ static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol, | |||
478 | static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, | 478 | static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol, |
479 | struct snd_ctl_elem_value *ucontrol) | 479 | struct snd_ctl_elem_value *ucontrol) |
480 | { | 480 | { |
481 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 481 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
482 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 482 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
483 | 483 | ||
484 | ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; | 484 | ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; |
@@ -500,7 +500,7 @@ static int wm8958_mbc_get(struct snd_kcontrol *kcontrol, | |||
500 | struct snd_ctl_elem_value *ucontrol) | 500 | struct snd_ctl_elem_value *ucontrol) |
501 | { | 501 | { |
502 | int mbc = kcontrol->private_value; | 502 | int mbc = kcontrol->private_value; |
503 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 503 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
504 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 504 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
505 | 505 | ||
506 | ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; | 506 | ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; |
@@ -512,7 +512,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, | |||
512 | struct snd_ctl_elem_value *ucontrol) | 512 | struct snd_ctl_elem_value *ucontrol) |
513 | { | 513 | { |
514 | int mbc = kcontrol->private_value; | 514 | int mbc = kcontrol->private_value; |
515 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 515 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
516 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 516 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
517 | 517 | ||
518 | if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0]) | 518 | if (wm8994->mbc_ena[mbc] == ucontrol->value.integer.value[0]) |
@@ -546,7 +546,7 @@ static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, | |||
546 | static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, | 546 | static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, |
547 | struct snd_ctl_elem_value *ucontrol) | 547 | struct snd_ctl_elem_value *ucontrol) |
548 | { | 548 | { |
549 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 549 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
550 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 550 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
551 | struct wm8994 *control = wm8994->wm8994; | 551 | struct wm8994 *control = wm8994->wm8994; |
552 | int value = ucontrol->value.integer.value[0]; | 552 | int value = ucontrol->value.integer.value[0]; |
@@ -568,7 +568,7 @@ static int wm8958_put_vss_enum(struct snd_kcontrol *kcontrol, | |||
568 | static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, | 568 | static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, |
569 | struct snd_ctl_elem_value *ucontrol) | 569 | struct snd_ctl_elem_value *ucontrol) |
570 | { | 570 | { |
571 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 571 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
572 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 572 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
573 | 573 | ||
574 | ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; | 574 | ucontrol->value.enumerated.item[0] = wm8994->vss_cfg; |
@@ -579,7 +579,7 @@ static int wm8958_get_vss_enum(struct snd_kcontrol *kcontrol, | |||
579 | static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, | 579 | static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, |
580 | struct snd_ctl_elem_value *ucontrol) | 580 | struct snd_ctl_elem_value *ucontrol) |
581 | { | 581 | { |
582 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 582 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
583 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 583 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
584 | struct wm8994 *control = wm8994->wm8994; | 584 | struct wm8994 *control = wm8994->wm8994; |
585 | int value = ucontrol->value.integer.value[0]; | 585 | int value = ucontrol->value.integer.value[0]; |
@@ -601,7 +601,7 @@ static int wm8958_put_vss_hpf_enum(struct snd_kcontrol *kcontrol, | |||
601 | static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, | 601 | static int wm8958_get_vss_hpf_enum(struct snd_kcontrol *kcontrol, |
602 | struct snd_ctl_elem_value *ucontrol) | 602 | struct snd_ctl_elem_value *ucontrol) |
603 | { | 603 | { |
604 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 604 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
605 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 605 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
606 | 606 | ||
607 | ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; | 607 | ucontrol->value.enumerated.item[0] = wm8994->vss_hpf_cfg; |
@@ -623,7 +623,7 @@ static int wm8958_vss_get(struct snd_kcontrol *kcontrol, | |||
623 | struct snd_ctl_elem_value *ucontrol) | 623 | struct snd_ctl_elem_value *ucontrol) |
624 | { | 624 | { |
625 | int vss = kcontrol->private_value; | 625 | int vss = kcontrol->private_value; |
626 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 626 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
627 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 627 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
628 | 628 | ||
629 | ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; | 629 | ucontrol->value.integer.value[0] = wm8994->vss_ena[vss]; |
@@ -635,7 +635,7 @@ static int wm8958_vss_put(struct snd_kcontrol *kcontrol, | |||
635 | struct snd_ctl_elem_value *ucontrol) | 635 | struct snd_ctl_elem_value *ucontrol) |
636 | { | 636 | { |
637 | int vss = kcontrol->private_value; | 637 | int vss = kcontrol->private_value; |
638 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 638 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
639 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 639 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
640 | 640 | ||
641 | if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0]) | 641 | if (wm8994->vss_ena[vss] == ucontrol->value.integer.value[0]) |
@@ -684,7 +684,7 @@ static int wm8958_hpf_get(struct snd_kcontrol *kcontrol, | |||
684 | struct snd_ctl_elem_value *ucontrol) | 684 | struct snd_ctl_elem_value *ucontrol) |
685 | { | 685 | { |
686 | int hpf = kcontrol->private_value; | 686 | int hpf = kcontrol->private_value; |
687 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 687 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
688 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 688 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
689 | 689 | ||
690 | if (hpf < 3) | 690 | if (hpf < 3) |
@@ -699,7 +699,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, | |||
699 | struct snd_ctl_elem_value *ucontrol) | 699 | struct snd_ctl_elem_value *ucontrol) |
700 | { | 700 | { |
701 | int hpf = kcontrol->private_value; | 701 | int hpf = kcontrol->private_value; |
702 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 702 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
703 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 703 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
704 | 704 | ||
705 | if (hpf < 3) { | 705 | if (hpf < 3) { |
@@ -746,7 +746,7 @@ static int wm8958_hpf_put(struct snd_kcontrol *kcontrol, | |||
746 | static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, | 746 | static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, |
747 | struct snd_ctl_elem_value *ucontrol) | 747 | struct snd_ctl_elem_value *ucontrol) |
748 | { | 748 | { |
749 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 749 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
750 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 750 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
751 | struct wm8994 *control = wm8994->wm8994; | 751 | struct wm8994 *control = wm8994->wm8994; |
752 | int value = ucontrol->value.integer.value[0]; | 752 | int value = ucontrol->value.integer.value[0]; |
@@ -768,7 +768,7 @@ static int wm8958_put_enh_eq_enum(struct snd_kcontrol *kcontrol, | |||
768 | static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, | 768 | static int wm8958_get_enh_eq_enum(struct snd_kcontrol *kcontrol, |
769 | struct snd_ctl_elem_value *ucontrol) | 769 | struct snd_ctl_elem_value *ucontrol) |
770 | { | 770 | { |
771 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 771 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
772 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 772 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
773 | 773 | ||
774 | ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; | 774 | ucontrol->value.enumerated.item[0] = wm8994->enh_eq_cfg; |
@@ -790,7 +790,7 @@ static int wm8958_enh_eq_get(struct snd_kcontrol *kcontrol, | |||
790 | struct snd_ctl_elem_value *ucontrol) | 790 | struct snd_ctl_elem_value *ucontrol) |
791 | { | 791 | { |
792 | int eq = kcontrol->private_value; | 792 | int eq = kcontrol->private_value; |
793 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 793 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
794 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 794 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
795 | 795 | ||
796 | ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; | 796 | ucontrol->value.integer.value[0] = wm8994->enh_eq_ena[eq]; |
@@ -802,7 +802,7 @@ static int wm8958_enh_eq_put(struct snd_kcontrol *kcontrol, | |||
802 | struct snd_ctl_elem_value *ucontrol) | 802 | struct snd_ctl_elem_value *ucontrol) |
803 | { | 803 | { |
804 | int eq = kcontrol->private_value; | 804 | int eq = kcontrol->private_value; |
805 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 805 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
806 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 806 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
807 | 807 | ||
808 | if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0]) | 808 | if (wm8994->enh_eq_ena[eq] == ucontrol->value.integer.value[0]) |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index d04e9cad445c..a145d0431b63 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -178,7 +178,7 @@ static int wm8960_set_deemph(struct snd_soc_codec *codec) | |||
178 | static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, | 178 | static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, |
179 | struct snd_ctl_elem_value *ucontrol) | 179 | struct snd_ctl_elem_value *ucontrol) |
180 | { | 180 | { |
181 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 181 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
182 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 182 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
183 | 183 | ||
184 | ucontrol->value.enumerated.item[0] = wm8960->deemph; | 184 | ucontrol->value.enumerated.item[0] = wm8960->deemph; |
@@ -188,7 +188,7 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, | |||
188 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, | 188 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, |
189 | struct snd_ctl_elem_value *ucontrol) | 189 | struct snd_ctl_elem_value *ucontrol) |
190 | { | 190 | { |
191 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 191 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
192 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 192 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
193 | int deemph = ucontrol->value.enumerated.item[0]; | 193 | int deemph = ucontrol->value.enumerated.item[0]; |
194 | 194 | ||
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index ecd26dd2e442..ca2fda9d72be 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -74,11 +74,9 @@ struct wm8962_priv { | |||
74 | struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES]; | 74 | struct regulator_bulk_data supplies[WM8962_NUM_SUPPLIES]; |
75 | struct notifier_block disable_nb[WM8962_NUM_SUPPLIES]; | 75 | struct notifier_block disable_nb[WM8962_NUM_SUPPLIES]; |
76 | 76 | ||
77 | #if IS_ENABLED(CONFIG_INPUT) | ||
78 | struct input_dev *beep; | 77 | struct input_dev *beep; |
79 | struct work_struct beep_work; | 78 | struct work_struct beep_work; |
80 | int beep_rate; | 79 | int beep_rate; |
81 | #endif | ||
82 | 80 | ||
83 | #ifdef CONFIG_GPIOLIB | 81 | #ifdef CONFIG_GPIOLIB |
84 | struct gpio_chip gpio_chip; | 82 | struct gpio_chip gpio_chip; |
@@ -1552,7 +1550,7 @@ static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol, | |||
1552 | struct snd_ctl_elem_value *ucontrol) | 1550 | struct snd_ctl_elem_value *ucontrol) |
1553 | { | 1551 | { |
1554 | int shift = kcontrol->private_value; | 1552 | int shift = kcontrol->private_value; |
1555 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1553 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1556 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 1554 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
1557 | 1555 | ||
1558 | ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift); | 1556 | ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift); |
@@ -1564,7 +1562,7 @@ static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol, | |||
1564 | struct snd_ctl_elem_value *ucontrol) | 1562 | struct snd_ctl_elem_value *ucontrol) |
1565 | { | 1563 | { |
1566 | int shift = kcontrol->private_value; | 1564 | int shift = kcontrol->private_value; |
1567 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1565 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1568 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 1566 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
1569 | int old = wm8962->dsp2_ena; | 1567 | int old = wm8962->dsp2_ena; |
1570 | int ret = 0; | 1568 | int ret = 0; |
@@ -1602,7 +1600,7 @@ out: | |||
1602 | static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, | 1600 | static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, |
1603 | struct snd_ctl_elem_value *ucontrol) | 1601 | struct snd_ctl_elem_value *ucontrol) |
1604 | { | 1602 | { |
1605 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1603 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1606 | int ret; | 1604 | int ret; |
1607 | 1605 | ||
1608 | /* Apply the update (if any) */ | 1606 | /* Apply the update (if any) */ |
@@ -1632,7 +1630,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, | |||
1632 | static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, | 1630 | static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, |
1633 | struct snd_ctl_elem_value *ucontrol) | 1631 | struct snd_ctl_elem_value *ucontrol) |
1634 | { | 1632 | { |
1635 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1633 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
1636 | int ret; | 1634 | int ret; |
1637 | 1635 | ||
1638 | /* Apply the update (if any) */ | 1636 | /* Apply the update (if any) */ |
@@ -3154,7 +3152,6 @@ int wm8962_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | |||
3154 | } | 3152 | } |
3155 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); | 3153 | EXPORT_SYMBOL_GPL(wm8962_mic_detect); |
3156 | 3154 | ||
3157 | #if IS_ENABLED(CONFIG_INPUT) | ||
3158 | static int beep_rates[] = { | 3155 | static int beep_rates[] = { |
3159 | 500, 1000, 2000, 4000, | 3156 | 500, 1000, 2000, 4000, |
3160 | }; | 3157 | }; |
@@ -3286,15 +3283,6 @@ static void wm8962_free_beep(struct snd_soc_codec *codec) | |||
3286 | 3283 | ||
3287 | snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0); | 3284 | snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA,0); |
3288 | } | 3285 | } |
3289 | #else | ||
3290 | static void wm8962_init_beep(struct snd_soc_codec *codec) | ||
3291 | { | ||
3292 | } | ||
3293 | |||
3294 | static void wm8962_free_beep(struct snd_soc_codec *codec) | ||
3295 | { | ||
3296 | } | ||
3297 | #endif | ||
3298 | 3286 | ||
3299 | static void wm8962_set_gpio_mode(struct wm8962_priv *wm8962, int gpio) | 3287 | static void wm8962_set_gpio_mode(struct wm8962_priv *wm8962, int gpio) |
3300 | { | 3288 | { |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 2b9bfa53efbf..19d5baa38f5c 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
@@ -552,7 +552,7 @@ static const struct snd_soc_dapm_route wm8983_audio_map[] = { | |||
552 | static int eqmode_get(struct snd_kcontrol *kcontrol, | 552 | static int eqmode_get(struct snd_kcontrol *kcontrol, |
553 | struct snd_ctl_elem_value *ucontrol) | 553 | struct snd_ctl_elem_value *ucontrol) |
554 | { | 554 | { |
555 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 555 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
556 | unsigned int reg; | 556 | unsigned int reg; |
557 | 557 | ||
558 | reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF); | 558 | reg = snd_soc_read(codec, WM8983_EQ1_LOW_SHELF); |
@@ -567,7 +567,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol, | |||
567 | static int eqmode_put(struct snd_kcontrol *kcontrol, | 567 | static int eqmode_put(struct snd_kcontrol *kcontrol, |
568 | struct snd_ctl_elem_value *ucontrol) | 568 | struct snd_ctl_elem_value *ucontrol) |
569 | { | 569 | { |
570 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 570 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
571 | unsigned int regpwr2, regpwr3; | 571 | unsigned int regpwr2, regpwr3; |
572 | unsigned int reg_eq; | 572 | unsigned int reg_eq; |
573 | 573 | ||
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index 5473dc969585..0f5780c09f3a 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c | |||
@@ -526,7 +526,7 @@ static const struct snd_soc_dapm_route wm8985_dapm_routes[] = { | |||
526 | static int eqmode_get(struct snd_kcontrol *kcontrol, | 526 | static int eqmode_get(struct snd_kcontrol *kcontrol, |
527 | struct snd_ctl_elem_value *ucontrol) | 527 | struct snd_ctl_elem_value *ucontrol) |
528 | { | 528 | { |
529 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 529 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
530 | unsigned int reg; | 530 | unsigned int reg; |
531 | 531 | ||
532 | reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF); | 532 | reg = snd_soc_read(codec, WM8985_EQ1_LOW_SHELF); |
@@ -541,7 +541,7 @@ static int eqmode_get(struct snd_kcontrol *kcontrol, | |||
541 | static int eqmode_put(struct snd_kcontrol *kcontrol, | 541 | static int eqmode_put(struct snd_kcontrol *kcontrol, |
542 | struct snd_ctl_elem_value *ucontrol) | 542 | struct snd_ctl_elem_value *ucontrol) |
543 | { | 543 | { |
544 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 544 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
545 | unsigned int regpwr2, regpwr3; | 545 | unsigned int regpwr2, regpwr3; |
546 | unsigned int reg_eq; | 546 | unsigned int reg_eq; |
547 | 547 | ||
@@ -984,7 +984,6 @@ static int wm8985_remove(struct snd_soc_codec *codec) | |||
984 | 984 | ||
985 | wm8985 = snd_soc_codec_get_drvdata(codec); | 985 | wm8985 = snd_soc_codec_get_drvdata(codec); |
986 | wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); | 986 | wm8985_set_bias_level(codec, SND_SOC_BIAS_OFF); |
987 | regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); | ||
988 | return 0; | 987 | return 0; |
989 | } | 988 | } |
990 | 989 | ||
@@ -999,7 +998,7 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
999 | for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++) | 998 | for (i = 0; i < ARRAY_SIZE(wm8985->supplies); i++) |
1000 | wm8985->supplies[i].supply = wm8985_supply_names[i]; | 999 | wm8985->supplies[i].supply = wm8985_supply_names[i]; |
1001 | 1000 | ||
1002 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8985->supplies), | 1001 | ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8985->supplies), |
1003 | wm8985->supplies); | 1002 | wm8985->supplies); |
1004 | if (ret) { | 1003 | if (ret) { |
1005 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | 1004 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); |
@@ -1010,7 +1009,7 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
1010 | wm8985->supplies); | 1009 | wm8985->supplies); |
1011 | if (ret) { | 1010 | if (ret) { |
1012 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 1011 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
1013 | goto err_reg_get; | 1012 | return ret; |
1014 | } | 1013 | } |
1015 | 1014 | ||
1016 | ret = wm8985_reset(codec); | 1015 | ret = wm8985_reset(codec); |
@@ -1032,8 +1031,6 @@ static int wm8985_probe(struct snd_soc_codec *codec) | |||
1032 | 1031 | ||
1033 | err_reg_enable: | 1032 | err_reg_enable: |
1034 | regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); | 1033 | regulator_bulk_disable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); |
1035 | err_reg_get: | ||
1036 | regulator_bulk_free(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); | ||
1037 | return ret; | 1034 | return ret; |
1038 | } | 1035 | } |
1039 | 1036 | ||
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 3a1ae4f5164d..d3fea46d58e8 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
@@ -268,7 +268,7 @@ static const struct soc_enum wm8988_lline_enum = | |||
268 | wm8988_line_texts, | 268 | wm8988_line_texts, |
269 | wm8988_line_values); | 269 | wm8988_line_values); |
270 | static const struct snd_kcontrol_new wm8988_left_line_controls = | 270 | static const struct snd_kcontrol_new wm8988_left_line_controls = |
271 | SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); | 271 | SOC_DAPM_ENUM("Route", wm8988_lline_enum); |
272 | 272 | ||
273 | static const struct soc_enum wm8988_rline_enum = | 273 | static const struct soc_enum wm8988_rline_enum = |
274 | SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, | 274 | SOC_VALUE_ENUM_SINGLE(WM8988_ROUTM1, 0, 7, |
@@ -276,7 +276,7 @@ static const struct soc_enum wm8988_rline_enum = | |||
276 | wm8988_line_texts, | 276 | wm8988_line_texts, |
277 | wm8988_line_values); | 277 | wm8988_line_values); |
278 | static const struct snd_kcontrol_new wm8988_right_line_controls = | 278 | static const struct snd_kcontrol_new wm8988_right_line_controls = |
279 | SOC_DAPM_VALUE_ENUM("Route", wm8988_lline_enum); | 279 | SOC_DAPM_ENUM("Route", wm8988_lline_enum); |
280 | 280 | ||
281 | /* Left Mixer */ | 281 | /* Left Mixer */ |
282 | static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { | 282 | static const struct snd_kcontrol_new wm8988_left_mixer_controls[] = { |
@@ -304,7 +304,7 @@ static const struct soc_enum wm8988_lpga_enum = | |||
304 | wm8988_pga_sel, | 304 | wm8988_pga_sel, |
305 | wm8988_pga_val); | 305 | wm8988_pga_val); |
306 | static const struct snd_kcontrol_new wm8988_left_pga_controls = | 306 | static const struct snd_kcontrol_new wm8988_left_pga_controls = |
307 | SOC_DAPM_VALUE_ENUM("Route", wm8988_lpga_enum); | 307 | SOC_DAPM_ENUM("Route", wm8988_lpga_enum); |
308 | 308 | ||
309 | /* Right PGA Mux */ | 309 | /* Right PGA Mux */ |
310 | static const struct soc_enum wm8988_rpga_enum = | 310 | static const struct soc_enum wm8988_rpga_enum = |
@@ -313,7 +313,7 @@ static const struct soc_enum wm8988_rpga_enum = | |||
313 | wm8988_pga_sel, | 313 | wm8988_pga_sel, |
314 | wm8988_pga_val); | 314 | wm8988_pga_val); |
315 | static const struct snd_kcontrol_new wm8988_right_pga_controls = | 315 | static const struct snd_kcontrol_new wm8988_right_pga_controls = |
316 | SOC_DAPM_VALUE_ENUM("Route", wm8988_rpga_enum); | 316 | SOC_DAPM_ENUM("Route", wm8988_rpga_enum); |
317 | 317 | ||
318 | /* Differential Mux */ | 318 | /* Differential Mux */ |
319 | static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; | 319 | static const char *wm8988_diff_sel[] = {"Line 1", "Line 2"}; |
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index c413c1991453..b5c1f0f07058 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
@@ -132,7 +132,7 @@ static const DECLARE_TLV_DB_SCALE(out_sidetone_tlv, -3600, 0, 0); | |||
132 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 132 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
133 | struct snd_ctl_elem_value *ucontrol) | 133 | struct snd_ctl_elem_value *ucontrol) |
134 | { | 134 | { |
135 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 135 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
136 | struct soc_mixer_control *mc = | 136 | struct soc_mixer_control *mc = |
137 | (struct soc_mixer_control *)kcontrol->private_value; | 137 | (struct soc_mixer_control *)kcontrol->private_value; |
138 | int reg = mc->reg; | 138 | int reg = mc->reg; |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 844cc4a60d66..b8fd284fc0c0 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
@@ -154,7 +154,7 @@ static const unsigned int out_sidetone_tlv[] = { | |||
154 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, | 154 | static int wm899x_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol, |
155 | struct snd_ctl_elem_value *ucontrol) | 155 | struct snd_ctl_elem_value *ucontrol) |
156 | { | 156 | { |
157 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 157 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
158 | int reg = kcontrol->private_value & 0xff; | 158 | int reg = kcontrol->private_value & 0xff; |
159 | int ret; | 159 | int ret; |
160 | u16 val; | 160 | u16 val; |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 6303537f54c6..247b39013fba 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -298,7 +298,7 @@ static int wm8994_put_drc_sw(struct snd_kcontrol *kcontrol, | |||
298 | { | 298 | { |
299 | struct soc_mixer_control *mc = | 299 | struct soc_mixer_control *mc = |
300 | (struct soc_mixer_control *)kcontrol->private_value; | 300 | (struct soc_mixer_control *)kcontrol->private_value; |
301 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 301 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
302 | int mask, ret; | 302 | int mask, ret; |
303 | 303 | ||
304 | /* Can't enable both ADC and DAC paths simultaneously */ | 304 | /* Can't enable both ADC and DAC paths simultaneously */ |
@@ -355,7 +355,7 @@ static int wm8994_get_drc(const char *name) | |||
355 | static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, | 355 | static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, |
356 | struct snd_ctl_elem_value *ucontrol) | 356 | struct snd_ctl_elem_value *ucontrol) |
357 | { | 357 | { |
358 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 358 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
359 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 359 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
360 | struct wm8994 *control = wm8994->wm8994; | 360 | struct wm8994 *control = wm8994->wm8994; |
361 | struct wm8994_pdata *pdata = &control->pdata; | 361 | struct wm8994_pdata *pdata = &control->pdata; |
@@ -378,7 +378,7 @@ static int wm8994_put_drc_enum(struct snd_kcontrol *kcontrol, | |||
378 | static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, | 378 | static int wm8994_get_drc_enum(struct snd_kcontrol *kcontrol, |
379 | struct snd_ctl_elem_value *ucontrol) | 379 | struct snd_ctl_elem_value *ucontrol) |
380 | { | 380 | { |
381 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 381 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
382 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 382 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
383 | int drc = wm8994_get_drc(kcontrol->id.name); | 383 | int drc = wm8994_get_drc(kcontrol->id.name); |
384 | 384 | ||
@@ -462,7 +462,7 @@ static int wm8994_get_retune_mobile_block(const char *name) | |||
462 | static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | 462 | static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, |
463 | struct snd_ctl_elem_value *ucontrol) | 463 | struct snd_ctl_elem_value *ucontrol) |
464 | { | 464 | { |
465 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 465 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
466 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 466 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
467 | struct wm8994 *control = wm8994->wm8994; | 467 | struct wm8994 *control = wm8994->wm8994; |
468 | struct wm8994_pdata *pdata = &control->pdata; | 468 | struct wm8994_pdata *pdata = &control->pdata; |
@@ -485,7 +485,7 @@ static int wm8994_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
485 | static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, | 485 | static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, |
486 | struct snd_ctl_elem_value *ucontrol) | 486 | struct snd_ctl_elem_value *ucontrol) |
487 | { | 487 | { |
488 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 488 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
489 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 489 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
490 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); | 490 | int block = wm8994_get_retune_mobile_block(kcontrol->id.name); |
491 | 491 | ||
@@ -1347,10 +1347,10 @@ static const char *adc_mux_text[] = { | |||
1347 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); | 1347 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); |
1348 | 1348 | ||
1349 | static const struct snd_kcontrol_new adcl_mux = | 1349 | static const struct snd_kcontrol_new adcl_mux = |
1350 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 1350 | SOC_DAPM_ENUM("ADCL Mux", adc_enum); |
1351 | 1351 | ||
1352 | static const struct snd_kcontrol_new adcr_mux = | 1352 | static const struct snd_kcontrol_new adcr_mux = |
1353 | SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); | 1353 | SOC_DAPM_ENUM("ADCR Mux", adc_enum); |
1354 | 1354 | ||
1355 | static const struct snd_kcontrol_new left_speaker_mixer[] = { | 1355 | static const struct snd_kcontrol_new left_speaker_mixer[] = { |
1356 | SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0), | 1356 | SOC_DAPM_SINGLE("DAC2 Switch", WM8994_SPEAKER_MIXER, 9, 1, 0), |
@@ -1651,15 +1651,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), | |||
1651 | }; | 1651 | }; |
1652 | 1652 | ||
1653 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { | 1653 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { |
1654 | SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, | 1654 | SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, |
1655 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1655 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1656 | SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, | 1656 | SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, |
1657 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1657 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1658 | }; | 1658 | }; |
1659 | 1659 | ||
1660 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { | 1660 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { |
1661 | SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), | 1661 | SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), |
1662 | SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), | 1662 | SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), |
1663 | }; | 1663 | }; |
1664 | 1664 | ||
1665 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { | 1665 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { |
@@ -3999,8 +3999,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3999 | 3999 | ||
4000 | wm8994->hubs.codec = codec; | 4000 | wm8994->hubs.codec = codec; |
4001 | 4001 | ||
4002 | snd_soc_codec_set_cache_io(codec, control->regmap); | ||
4003 | |||
4004 | mutex_init(&wm8994->accdet_lock); | 4002 | mutex_init(&wm8994->accdet_lock); |
4005 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, | 4003 | INIT_DELAYED_WORK(&wm8994->jackdet_bootstrap, |
4006 | wm1811_jackdet_bootstrap); | 4004 | wm1811_jackdet_bootstrap); |
@@ -4434,11 +4432,19 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
4434 | return 0; | 4432 | return 0; |
4435 | } | 4433 | } |
4436 | 4434 | ||
4435 | static struct regmap *wm8994_get_regmap(struct device *dev) | ||
4436 | { | ||
4437 | struct wm8994 *control = dev_get_drvdata(dev->parent); | ||
4438 | |||
4439 | return control->regmap; | ||
4440 | } | ||
4441 | |||
4437 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { | 4442 | static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { |
4438 | .probe = wm8994_codec_probe, | 4443 | .probe = wm8994_codec_probe, |
4439 | .remove = wm8994_codec_remove, | 4444 | .remove = wm8994_codec_remove, |
4440 | .suspend = wm8994_codec_suspend, | 4445 | .suspend = wm8994_codec_suspend, |
4441 | .resume = wm8994_codec_resume, | 4446 | .resume = wm8994_codec_resume, |
4447 | .get_regmap = wm8994_get_regmap, | ||
4442 | .set_bias_level = wm8994_set_bias_level, | 4448 | .set_bias_level = wm8994_set_bias_level, |
4443 | }; | 4449 | }; |
4444 | 4450 | ||
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index d3152cf5bd56..863a2c38bcb5 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
@@ -885,10 +885,10 @@ static const char *adc_mux_text[] = { | |||
885 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); | 885 | static SOC_ENUM_SINGLE_VIRT_DECL(adc_enum, adc_mux_text); |
886 | 886 | ||
887 | static const struct snd_kcontrol_new adcl_mux = | 887 | static const struct snd_kcontrol_new adcl_mux = |
888 | SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); | 888 | SOC_DAPM_ENUM("ADCL Mux", adc_enum); |
889 | 889 | ||
890 | static const struct snd_kcontrol_new adcr_mux = | 890 | static const struct snd_kcontrol_new adcr_mux = |
891 | SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); | 891 | SOC_DAPM_ENUM("ADCR Mux", adc_enum); |
892 | 892 | ||
893 | static const char *spk_src_text[] = { | 893 | static const char *spk_src_text[] = { |
894 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" | 894 | "DAC1L", "DAC1R", "DAC2L", "DAC2R" |
@@ -948,10 +948,8 @@ static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = { | |||
948 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", | 948 | SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", |
949 | 0, WM8995_POWER_MANAGEMENT_3, 10, 0), | 949 | 0, WM8995_POWER_MANAGEMENT_3, 10, 0), |
950 | 950 | ||
951 | SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0, | 951 | SND_SOC_DAPM_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0, &adcl_mux), |
952 | &adcl_mux), | 952 | SND_SOC_DAPM_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), |
953 | SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0, | ||
954 | &adcr_mux), | ||
955 | 953 | ||
956 | SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0), | 954 | SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0), |
957 | SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0), | 955 | SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0), |
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index c6cbb3b8ace9..69266332760e 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
@@ -412,7 +412,7 @@ static int wm8996_get_retune_mobile_block(const char *name) | |||
412 | static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | 412 | static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, |
413 | struct snd_ctl_elem_value *ucontrol) | 413 | struct snd_ctl_elem_value *ucontrol) |
414 | { | 414 | { |
415 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 415 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
416 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 416 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
417 | struct wm8996_pdata *pdata = &wm8996->pdata; | 417 | struct wm8996_pdata *pdata = &wm8996->pdata; |
418 | int block = wm8996_get_retune_mobile_block(kcontrol->id.name); | 418 | int block = wm8996_get_retune_mobile_block(kcontrol->id.name); |
@@ -434,7 +434,7 @@ static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol, | |||
434 | static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, | 434 | static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, |
435 | struct snd_ctl_elem_value *ucontrol) | 435 | struct snd_ctl_elem_value *ucontrol) |
436 | { | 436 | { |
437 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 437 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
438 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 438 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
439 | int block = wm8996_get_retune_mobile_block(kcontrol->id.name); | 439 | int block = wm8996_get_retune_mobile_block(kcontrol->id.name); |
440 | 440 | ||
diff --git a/sound/soc/codecs/wm8997.c b/sound/soc/codecs/wm8997.c index 004186b6bd48..bb9b47b956aa 100644 --- a/sound/soc/codecs/wm8997.c +++ b/sound/soc/codecs/wm8997.c | |||
@@ -245,8 +245,8 @@ SND_SOC_BYTES("LHPF2 Coefficients", ARIZONA_HPLPF2_2, 1), | |||
245 | SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), | 245 | SND_SOC_BYTES("LHPF3 Coefficients", ARIZONA_HPLPF3_2, 1), |
246 | SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), | 246 | SND_SOC_BYTES("LHPF4 Coefficients", ARIZONA_HPLPF4_2, 1), |
247 | 247 | ||
248 | SOC_VALUE_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), | 248 | SOC_ENUM("ISRC1 FSL", arizona_isrc_fsl[0]), |
249 | SOC_VALUE_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), | 249 | SOC_ENUM("ISRC2 FSL", arizona_isrc_fsl[1]), |
250 | 250 | ||
251 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), | 251 | ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE), |
252 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), | 252 | ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE), |
@@ -286,8 +286,8 @@ SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L, | |||
286 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, | 286 | ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT, |
287 | 0xbf, 0, digital_tlv), | 287 | 0xbf, 0, digital_tlv), |
288 | 288 | ||
289 | SOC_VALUE_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]), | 289 | SOC_ENUM("HPOUT1 OSR", wm8997_hpout_osr[0]), |
290 | SOC_VALUE_ENUM("EPOUT OSR", wm8997_hpout_osr[1]), | 290 | SOC_ENUM("EPOUT OSR", wm8997_hpout_osr[1]), |
291 | 291 | ||
292 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), | 292 | SOC_ENUM("Output Ramp Up", arizona_out_vi_ramp), |
293 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), | 293 | SOC_ENUM("Output Ramp Down", arizona_out_vd_ramp), |
@@ -405,7 +405,7 @@ static const struct soc_enum wm8997_aec_loopback = | |||
405 | wm8997_aec_loopback_values); | 405 | wm8997_aec_loopback_values); |
406 | 406 | ||
407 | static const struct snd_kcontrol_new wm8997_aec_loopback_mux = | 407 | static const struct snd_kcontrol_new wm8997_aec_loopback_mux = |
408 | SOC_DAPM_VALUE_ENUM("AEC Loopback", wm8997_aec_loopback); | 408 | SOC_DAPM_ENUM("AEC Loopback", wm8997_aec_loopback); |
409 | 409 | ||
410 | static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = { | 410 | static const struct snd_soc_dapm_widget wm8997_dapm_widgets[] = { |
411 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, | 411 | SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT, |
@@ -604,7 +604,7 @@ SND_SOC_DAPM_AIF_IN("SLIMRX8", NULL, 0, | |||
604 | ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE, | 604 | ARIZONA_SLIMBUS_RX_CHANNEL_ENABLE, |
605 | ARIZONA_SLIMRX8_ENA_SHIFT, 0), | 605 | ARIZONA_SLIMRX8_ENA_SHIFT, 0), |
606 | 606 | ||
607 | SND_SOC_DAPM_VALUE_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, | 607 | SND_SOC_DAPM_MUX("AEC Loopback", ARIZONA_DAC_AEC_CONTROL_1, |
608 | ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, | 608 | ARIZONA_AEC_LOOPBACK_ENA_SHIFT, 0, |
609 | &wm8997_aec_loopback_mux), | 609 | &wm8997_aec_loopback_mux), |
610 | 610 | ||
@@ -1051,11 +1051,6 @@ static struct snd_soc_dai_driver wm8997_dai[] = { | |||
1051 | static int wm8997_codec_probe(struct snd_soc_codec *codec) | 1051 | static int wm8997_codec_probe(struct snd_soc_codec *codec) |
1052 | { | 1052 | { |
1053 | struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); | 1053 | struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec); |
1054 | int ret; | ||
1055 | |||
1056 | ret = snd_soc_codec_set_cache_io(codec, priv->core.arizona->regmap); | ||
1057 | if (ret != 0) | ||
1058 | return ret; | ||
1059 | 1054 | ||
1060 | arizona_init_spk(codec); | 1055 | arizona_init_spk(codec); |
1061 | 1056 | ||
@@ -1086,9 +1081,17 @@ static unsigned int wm8997_digital_vu[] = { | |||
1086 | ARIZONA_DAC_DIGITAL_VOLUME_5R, | 1081 | ARIZONA_DAC_DIGITAL_VOLUME_5R, |
1087 | }; | 1082 | }; |
1088 | 1083 | ||
1084 | static struct regmap *wm8997_get_regmap(struct device *dev) | ||
1085 | { | ||
1086 | struct wm8997_priv *priv = dev_get_drvdata(dev); | ||
1087 | |||
1088 | return priv->core.arizona->regmap; | ||
1089 | } | ||
1090 | |||
1089 | static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { | 1091 | static struct snd_soc_codec_driver soc_codec_dev_wm8997 = { |
1090 | .probe = wm8997_codec_probe, | 1092 | .probe = wm8997_codec_probe, |
1091 | .remove = wm8997_codec_remove, | 1093 | .remove = wm8997_codec_remove, |
1094 | .get_regmap = wm8997_get_regmap, | ||
1092 | 1095 | ||
1093 | .idle_bias_off = true, | 1096 | .idle_bias_off = true, |
1094 | 1097 | ||
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index d18eff31fbbc..185eb97769e7 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -340,7 +340,7 @@ static SOC_ENUM_SINGLE_DECL(speaker_mode, WM9081_ANALOGUE_SPEAKER_2, 6, | |||
340 | static int speaker_mode_get(struct snd_kcontrol *kcontrol, | 340 | static int speaker_mode_get(struct snd_kcontrol *kcontrol, |
341 | struct snd_ctl_elem_value *ucontrol) | 341 | struct snd_ctl_elem_value *ucontrol) |
342 | { | 342 | { |
343 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 343 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
344 | unsigned int reg; | 344 | unsigned int reg; |
345 | 345 | ||
346 | reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); | 346 | reg = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); |
@@ -361,7 +361,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol, | |||
361 | static int speaker_mode_put(struct snd_kcontrol *kcontrol, | 361 | static int speaker_mode_put(struct snd_kcontrol *kcontrol, |
362 | struct snd_ctl_elem_value *ucontrol) | 362 | struct snd_ctl_elem_value *ucontrol) |
363 | { | 363 | { |
364 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 364 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
365 | unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT); | 365 | unsigned int reg_pwr = snd_soc_read(codec, WM9081_POWER_MANAGEMENT); |
366 | unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); | 366 | unsigned int reg2 = snd_soc_read(codec, WM9081_ANALOGUE_SPEAKER_2); |
367 | 367 | ||
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index bb5f7b4e3ebb..ff15eec3ab2f 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c | |||
@@ -242,7 +242,7 @@ struct wm_coeff_ctl { | |||
242 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, | 242 | static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, |
243 | struct snd_ctl_elem_value *ucontrol) | 243 | struct snd_ctl_elem_value *ucontrol) |
244 | { | 244 | { |
245 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 245 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
246 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 246 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
247 | struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); | 247 | struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); |
248 | 248 | ||
@@ -254,7 +254,7 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, | |||
254 | static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, | 254 | static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, |
255 | struct snd_ctl_elem_value *ucontrol) | 255 | struct snd_ctl_elem_value *ucontrol) |
256 | { | 256 | { |
257 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 257 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
258 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 258 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
259 | struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); | 259 | struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); |
260 | 260 | ||
@@ -1625,7 +1625,7 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, | |||
1625 | break; | 1625 | break; |
1626 | default: | 1626 | default: |
1627 | break; | 1627 | break; |
1628 | }; | 1628 | } |
1629 | 1629 | ||
1630 | return 0; | 1630 | return 0; |
1631 | } | 1631 | } |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index b6209662ab13..916817fe6632 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -337,7 +337,7 @@ static void enable_dc_servo(struct snd_soc_codec *codec) | |||
337 | static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, | 337 | static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, |
338 | struct snd_ctl_elem_value *ucontrol) | 338 | struct snd_ctl_elem_value *ucontrol) |
339 | { | 339 | { |
340 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 340 | struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); |
341 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 341 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
342 | int ret; | 342 | int ret; |
343 | 343 | ||
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig index a8ec1fc3e4d0..50a098749b9e 100644 --- a/sound/soc/davinci/Kconfig +++ b/sound/soc/davinci/Kconfig | |||
@@ -18,7 +18,7 @@ config SND_DAVINCI_SOC_GENERIC_EVM | |||
18 | 18 | ||
19 | config SND_AM33XX_SOC_EVM | 19 | config SND_AM33XX_SOC_EVM |
20 | tristate "SoC Audio for the AM33XX chip based boards" | 20 | tristate "SoC Audio for the AM33XX chip based boards" |
21 | depends on SND_DAVINCI_SOC && SOC_AM33XX | 21 | depends on SND_DAVINCI_SOC && SOC_AM33XX && I2C |
22 | select SND_DAVINCI_SOC_GENERIC_EVM | 22 | select SND_DAVINCI_SOC_GENERIC_EVM |
23 | help | 23 | help |
24 | Say Y or M if you want to add support for SoC audio on AM33XX | 24 | Say Y or M if you want to add support for SoC audio on AM33XX |
@@ -28,7 +28,7 @@ config SND_AM33XX_SOC_EVM | |||
28 | 28 | ||
29 | config SND_DAVINCI_SOC_EVM | 29 | config SND_DAVINCI_SOC_EVM |
30 | tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" | 30 | tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM" |
31 | depends on SND_DAVINCI_SOC | 31 | depends on SND_DAVINCI_SOC && I2C |
32 | depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM | 32 | depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM |
33 | select SND_DAVINCI_SOC_GENERIC_EVM | 33 | select SND_DAVINCI_SOC_GENERIC_EVM |
34 | help | 34 | help |
@@ -56,7 +56,7 @@ endchoice | |||
56 | 56 | ||
57 | config SND_DM6467_SOC_EVM | 57 | config SND_DM6467_SOC_EVM |
58 | tristate "SoC Audio support for DaVinci DM6467 EVM" | 58 | tristate "SoC Audio support for DaVinci DM6467 EVM" |
59 | depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM | 59 | depends on SND_DAVINCI_SOC && MACH_DAVINCI_DM6467_EVM && I2C |
60 | select SND_DAVINCI_SOC_GENERIC_EVM | 60 | select SND_DAVINCI_SOC_GENERIC_EVM |
61 | select SND_SOC_SPDIF | 61 | select SND_SOC_SPDIF |
62 | 62 | ||
@@ -65,7 +65,7 @@ config SND_DM6467_SOC_EVM | |||
65 | 65 | ||
66 | config SND_DA830_SOC_EVM | 66 | config SND_DA830_SOC_EVM |
67 | tristate "SoC Audio support for DA830/OMAP-L137 EVM" | 67 | tristate "SoC Audio support for DA830/OMAP-L137 EVM" |
68 | depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM | 68 | depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA830_EVM && I2C |
69 | select SND_DAVINCI_SOC_GENERIC_EVM | 69 | select SND_DAVINCI_SOC_GENERIC_EVM |
70 | 70 | ||
71 | help | 71 | help |
@@ -74,7 +74,7 @@ config SND_DA830_SOC_EVM | |||
74 | 74 | ||
75 | config SND_DA850_SOC_EVM | 75 | config SND_DA850_SOC_EVM |
76 | tristate "SoC Audio support for DA850/OMAP-L138 EVM" | 76 | tristate "SoC Audio support for DA850/OMAP-L138 EVM" |
77 | depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM | 77 | depends on SND_DAVINCI_SOC && MACH_DAVINCI_DA850_EVM && I2C |
78 | select SND_DAVINCI_SOC_GENERIC_EVM | 78 | select SND_DAVINCI_SOC_GENERIC_EVM |
79 | help | 79 | help |
80 | Say Y if you want to add support for SoC audio on TI | 80 | Say Y if you want to add support for SoC audio on TI |
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index ebe82947bab3..7682af31d6e6 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
@@ -757,7 +757,6 @@ static int davinci_i2s_remove(struct platform_device *pdev) | |||
757 | struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); | 757 | struct davinci_mcbsp_dev *dev = dev_get_drvdata(&pdev->dev); |
758 | 758 | ||
759 | snd_soc_unregister_component(&pdev->dev); | 759 | snd_soc_unregister_component(&pdev->dev); |
760 | davinci_soc_platform_unregister(&pdev->dev); | ||
761 | 760 | ||
762 | clk_disable(dev->clk); | 761 | clk_disable(dev->clk); |
763 | clk_put(dev->clk); | 762 | clk_put(dev->clk); |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 4f75cac462d1..14058dc6eaf8 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -36,6 +36,9 @@ | |||
36 | 36 | ||
37 | #include "davinci-pcm.h" | 37 | #include "davinci-pcm.h" |
38 | #include "davinci-mcasp.h" | 38 | #include "davinci-mcasp.h" |
39 | #include "../omap/omap-pcm.h" | ||
40 | |||
41 | #define MCASP_MAX_AFIFO_DEPTH 64 | ||
39 | 42 | ||
40 | struct davinci_mcasp_context { | 43 | struct davinci_mcasp_context { |
41 | u32 txfmtctl; | 44 | u32 txfmtctl; |
@@ -269,25 +272,51 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
269 | { | 272 | { |
270 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 273 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
271 | int ret = 0; | 274 | int ret = 0; |
275 | u32 data_delay; | ||
276 | bool fs_pol_rising; | ||
277 | bool inv_fs = false; | ||
272 | 278 | ||
273 | pm_runtime_get_sync(mcasp->dev); | 279 | pm_runtime_get_sync(mcasp->dev); |
274 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 280 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
281 | case SND_SOC_DAIFMT_DSP_A: | ||
282 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
283 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
284 | /* 1st data bit occur one ACLK cycle after the frame sync */ | ||
285 | data_delay = 1; | ||
286 | break; | ||
275 | case SND_SOC_DAIFMT_DSP_B: | 287 | case SND_SOC_DAIFMT_DSP_B: |
276 | case SND_SOC_DAIFMT_AC97: | 288 | case SND_SOC_DAIFMT_AC97: |
277 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | 289 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); |
278 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | 290 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); |
291 | /* No delay after FS */ | ||
292 | data_delay = 0; | ||
279 | break; | 293 | break; |
280 | default: | 294 | case SND_SOC_DAIFMT_I2S: |
281 | /* configure a full-word SYNC pulse (LRCLK) */ | 295 | /* configure a full-word SYNC pulse (LRCLK) */ |
282 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | 296 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); |
283 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | 297 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); |
284 | 298 | /* 1st data bit occur one ACLK cycle after the frame sync */ | |
285 | /* make 1st data bit occur one ACLK cycle after the frame sync */ | 299 | data_delay = 1; |
286 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(1)); | 300 | /* FS need to be inverted */ |
287 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(1)); | 301 | inv_fs = true; |
288 | break; | 302 | break; |
303 | case SND_SOC_DAIFMT_LEFT_J: | ||
304 | /* configure a full-word SYNC pulse (LRCLK) */ | ||
305 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXDUR); | ||
306 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRDUR); | ||
307 | /* No delay after FS */ | ||
308 | data_delay = 0; | ||
309 | break; | ||
310 | default: | ||
311 | ret = -EINVAL; | ||
312 | goto out; | ||
289 | } | 313 | } |
290 | 314 | ||
315 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_TXFMT_REG, FSXDLY(data_delay), | ||
316 | FSXDLY(3)); | ||
317 | mcasp_mod_bits(mcasp, DAVINCI_MCASP_RXFMT_REG, FSRDLY(data_delay), | ||
318 | FSRDLY(3)); | ||
319 | |||
291 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 320 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
292 | case SND_SOC_DAIFMT_CBS_CFS: | 321 | case SND_SOC_DAIFMT_CBS_CFS: |
293 | /* codec is clock and frame slave */ | 322 | /* codec is clock and frame slave */ |
@@ -325,7 +354,6 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
325 | ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); | 354 | ACLKX | AHCLKX | AFSX | ACLKR | AHCLKR | AFSR); |
326 | mcasp->bclk_master = 0; | 355 | mcasp->bclk_master = 0; |
327 | break; | 356 | break; |
328 | |||
329 | default: | 357 | default: |
330 | ret = -EINVAL; | 358 | ret = -EINVAL; |
331 | goto out; | 359 | goto out; |
@@ -334,39 +362,38 @@ static int davinci_mcasp_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
334 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 362 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
335 | case SND_SOC_DAIFMT_IB_NF: | 363 | case SND_SOC_DAIFMT_IB_NF: |
336 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); | 364 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); |
337 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); | ||
338 | |||
339 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); | 365 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); |
340 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | 366 | fs_pol_rising = true; |
341 | break; | 367 | break; |
342 | |||
343 | case SND_SOC_DAIFMT_NB_IF: | 368 | case SND_SOC_DAIFMT_NB_IF: |
344 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); | 369 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); |
345 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); | ||
346 | |||
347 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); | 370 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); |
348 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | 371 | fs_pol_rising = false; |
349 | break; | 372 | break; |
350 | |||
351 | case SND_SOC_DAIFMT_IB_IF: | 373 | case SND_SOC_DAIFMT_IB_IF: |
352 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); | 374 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); |
353 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); | ||
354 | |||
355 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); | 375 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); |
356 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | 376 | fs_pol_rising = false; |
357 | break; | 377 | break; |
358 | |||
359 | case SND_SOC_DAIFMT_NB_NF: | 378 | case SND_SOC_DAIFMT_NB_NF: |
360 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); | 379 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKXCTL_REG, ACLKXPOL); |
361 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); | ||
362 | |||
363 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); | 380 | mcasp_set_bits(mcasp, DAVINCI_MCASP_ACLKRCTL_REG, ACLKRPOL); |
364 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | 381 | fs_pol_rising = true; |
365 | break; | 382 | break; |
366 | |||
367 | default: | 383 | default: |
368 | ret = -EINVAL; | 384 | ret = -EINVAL; |
369 | break; | 385 | goto out; |
386 | } | ||
387 | |||
388 | if (inv_fs) | ||
389 | fs_pol_rising = !fs_pol_rising; | ||
390 | |||
391 | if (fs_pol_rising) { | ||
392 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); | ||
393 | mcasp_clr_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | ||
394 | } else { | ||
395 | mcasp_set_bits(mcasp, DAVINCI_MCASP_TXFMCTL_REG, FSXPOL); | ||
396 | mcasp_set_bits(mcasp, DAVINCI_MCASP_RXFMCTL_REG, FSRPOL); | ||
370 | } | 397 | } |
371 | out: | 398 | out: |
372 | pm_runtime_put_sync(mcasp->dev); | 399 | pm_runtime_put_sync(mcasp->dev); |
@@ -464,17 +491,19 @@ static int davinci_config_channel_size(struct davinci_mcasp *mcasp, | |||
464 | } | 491 | } |
465 | 492 | ||
466 | static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, | 493 | static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, |
467 | int channels) | 494 | int period_words, int channels) |
468 | { | 495 | { |
496 | struct davinci_pcm_dma_params *dma_params = &mcasp->dma_params[stream]; | ||
497 | struct snd_dmaengine_dai_dma_data *dma_data = &mcasp->dma_data[stream]; | ||
469 | int i; | 498 | int i; |
470 | u8 tx_ser = 0; | 499 | u8 tx_ser = 0; |
471 | u8 rx_ser = 0; | 500 | u8 rx_ser = 0; |
472 | u8 ser; | ||
473 | u8 slots = mcasp->tdm_slots; | 501 | u8 slots = mcasp->tdm_slots; |
474 | u8 max_active_serializers = (channels + slots - 1) / slots; | 502 | u8 max_active_serializers = (channels + slots - 1) / slots; |
503 | int active_serializers, numevt, n; | ||
475 | u32 reg; | 504 | u32 reg; |
476 | /* Default configuration */ | 505 | /* Default configuration */ |
477 | if (mcasp->version != MCASP_VERSION_4) | 506 | if (mcasp->version < MCASP_VERSION_3) |
478 | mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); | 507 | mcasp_set_bits(mcasp, DAVINCI_MCASP_PWREMUMGT_REG, MCASP_SOFT); |
479 | 508 | ||
480 | /* All PINS as McASP */ | 509 | /* All PINS as McASP */ |
@@ -505,37 +534,71 @@ static int mcasp_common_hw_param(struct davinci_mcasp *mcasp, int stream, | |||
505 | } | 534 | } |
506 | } | 535 | } |
507 | 536 | ||
508 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | 537 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
509 | ser = tx_ser; | 538 | active_serializers = tx_ser; |
510 | else | 539 | numevt = mcasp->txnumevt; |
511 | ser = rx_ser; | 540 | reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; |
541 | } else { | ||
542 | active_serializers = rx_ser; | ||
543 | numevt = mcasp->rxnumevt; | ||
544 | reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; | ||
545 | } | ||
512 | 546 | ||
513 | if (ser < max_active_serializers) { | 547 | if (active_serializers < max_active_serializers) { |
514 | dev_warn(mcasp->dev, "stream has more channels (%d) than are " | 548 | dev_warn(mcasp->dev, "stream has more channels (%d) than are " |
515 | "enabled in mcasp (%d)\n", channels, ser * slots); | 549 | "enabled in mcasp (%d)\n", channels, |
550 | active_serializers * slots); | ||
516 | return -EINVAL; | 551 | return -EINVAL; |
517 | } | 552 | } |
518 | 553 | ||
519 | if (mcasp->txnumevt && stream == SNDRV_PCM_STREAM_PLAYBACK) { | 554 | /* AFIFO is not in use */ |
520 | if (mcasp->txnumevt * tx_ser > 64) | 555 | if (!numevt) { |
521 | mcasp->txnumevt = 1; | 556 | /* Configure the burst size for platform drivers */ |
522 | 557 | if (active_serializers > 1) { | |
523 | reg = mcasp->fifo_base + MCASP_WFIFOCTL_OFFSET; | 558 | /* |
524 | mcasp_mod_bits(mcasp, reg, tx_ser, NUMDMA_MASK); | 559 | * If more than one serializers are in use we have one |
525 | mcasp_mod_bits(mcasp, reg, ((mcasp->txnumevt * tx_ser) << 8), | 560 | * DMA request to provide data for all serializers. |
526 | NUMEVT_MASK); | 561 | * For example if three serializers are enabled the DMA |
562 | * need to transfer three words per DMA request. | ||
563 | */ | ||
564 | dma_params->fifo_level = active_serializers; | ||
565 | dma_data->maxburst = active_serializers; | ||
566 | } else { | ||
567 | dma_params->fifo_level = 0; | ||
568 | dma_data->maxburst = 0; | ||
569 | } | ||
570 | return 0; | ||
527 | } | 571 | } |
528 | 572 | ||
529 | if (mcasp->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { | 573 | if (period_words % active_serializers) { |
530 | if (mcasp->rxnumevt * rx_ser > 64) | 574 | dev_err(mcasp->dev, "Invalid combination of period words and " |
531 | mcasp->rxnumevt = 1; | 575 | "active serializers: %d, %d\n", period_words, |
532 | 576 | active_serializers); | |
533 | reg = mcasp->fifo_base + MCASP_RFIFOCTL_OFFSET; | 577 | return -EINVAL; |
534 | mcasp_mod_bits(mcasp, reg, rx_ser, NUMDMA_MASK); | ||
535 | mcasp_mod_bits(mcasp, reg, ((mcasp->rxnumevt * rx_ser) << 8), | ||
536 | NUMEVT_MASK); | ||
537 | } | 578 | } |
538 | 579 | ||
580 | /* | ||
581 | * Calculate the optimal AFIFO depth for platform side: | ||
582 | * The number of words for numevt need to be in steps of active | ||
583 | * serializers. | ||
584 | */ | ||
585 | n = numevt % active_serializers; | ||
586 | if (n) | ||
587 | numevt += (active_serializers - n); | ||
588 | while (period_words % numevt && numevt > 0) | ||
589 | numevt -= active_serializers; | ||
590 | if (numevt <= 0) | ||
591 | numevt = active_serializers; | ||
592 | |||
593 | mcasp_mod_bits(mcasp, reg, active_serializers, NUMDMA_MASK); | ||
594 | mcasp_mod_bits(mcasp, reg, NUMEVT(numevt), NUMEVT_MASK); | ||
595 | |||
596 | /* Configure the burst size for platform drivers */ | ||
597 | if (numevt == 1) | ||
598 | numevt = 0; | ||
599 | dma_params->fifo_level = numevt; | ||
600 | dma_data->maxburst = numevt; | ||
601 | |||
539 | return 0; | 602 | return 0; |
540 | } | 603 | } |
541 | 604 | ||
@@ -607,27 +670,24 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
607 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); | 670 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(cpu_dai); |
608 | struct davinci_pcm_dma_params *dma_params = | 671 | struct davinci_pcm_dma_params *dma_params = |
609 | &mcasp->dma_params[substream->stream]; | 672 | &mcasp->dma_params[substream->stream]; |
610 | struct snd_dmaengine_dai_dma_data *dma_data = | ||
611 | &mcasp->dma_data[substream->stream]; | ||
612 | int word_length; | 673 | int word_length; |
613 | u8 fifo_level; | ||
614 | u8 slots = mcasp->tdm_slots; | ||
615 | u8 active_serializers; | ||
616 | int channels = params_channels(params); | 674 | int channels = params_channels(params); |
675 | int period_size = params_period_size(params); | ||
617 | int ret; | 676 | int ret; |
618 | 677 | ||
619 | /* If mcasp is BCLK master we need to set BCLK divider */ | 678 | /* If mcasp is BCLK master we need to set BCLK divider */ |
620 | if (mcasp->bclk_master) { | 679 | if (mcasp->bclk_master) { |
621 | unsigned int bclk_freq = snd_soc_params_to_bclk(params); | 680 | unsigned int bclk_freq = snd_soc_params_to_bclk(params); |
622 | if (mcasp->sysclk_freq % bclk_freq != 0) { | 681 | if (mcasp->sysclk_freq % bclk_freq != 0) { |
623 | dev_err(mcasp->dev, "Can't produce requred BCLK\n"); | 682 | dev_err(mcasp->dev, "Can't produce required BCLK\n"); |
624 | return -EINVAL; | 683 | return -EINVAL; |
625 | } | 684 | } |
626 | davinci_mcasp_set_clkdiv( | 685 | davinci_mcasp_set_clkdiv( |
627 | cpu_dai, 1, mcasp->sysclk_freq / bclk_freq); | 686 | cpu_dai, 1, mcasp->sysclk_freq / bclk_freq); |
628 | } | 687 | } |
629 | 688 | ||
630 | ret = mcasp_common_hw_param(mcasp, substream->stream, channels); | 689 | ret = mcasp_common_hw_param(mcasp, substream->stream, |
690 | period_size * channels, channels); | ||
631 | if (ret) | 691 | if (ret) |
632 | return ret; | 692 | return ret; |
633 | 693 | ||
@@ -671,21 +731,11 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
671 | return -EINVAL; | 731 | return -EINVAL; |
672 | } | 732 | } |
673 | 733 | ||
674 | /* Calculate FIFO level */ | 734 | if (mcasp->version == MCASP_VERSION_2 && !dma_params->fifo_level) |
675 | active_serializers = (channels + slots - 1) / slots; | ||
676 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
677 | fifo_level = mcasp->txnumevt * active_serializers; | ||
678 | else | ||
679 | fifo_level = mcasp->rxnumevt * active_serializers; | ||
680 | |||
681 | if (mcasp->version == MCASP_VERSION_2 && !fifo_level) | ||
682 | dma_params->acnt = 4; | 735 | dma_params->acnt = 4; |
683 | else | 736 | else |
684 | dma_params->acnt = dma_params->data_type; | 737 | dma_params->acnt = dma_params->data_type; |
685 | 738 | ||
686 | dma_params->fifo_level = fifo_level; | ||
687 | dma_data->maxburst = fifo_level; | ||
688 | |||
689 | davinci_config_channel_size(mcasp, word_length); | 739 | davinci_config_channel_size(mcasp, word_length); |
690 | 740 | ||
691 | return 0; | 741 | return 0; |
@@ -716,22 +766,7 @@ static int davinci_mcasp_trigger(struct snd_pcm_substream *substream, | |||
716 | return ret; | 766 | return ret; |
717 | } | 767 | } |
718 | 768 | ||
719 | static int davinci_mcasp_startup(struct snd_pcm_substream *substream, | ||
720 | struct snd_soc_dai *dai) | ||
721 | { | ||
722 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | ||
723 | |||
724 | if (mcasp->version == MCASP_VERSION_4) | ||
725 | snd_soc_dai_set_dma_data(dai, substream, | ||
726 | &mcasp->dma_data[substream->stream]); | ||
727 | else | ||
728 | snd_soc_dai_set_dma_data(dai, substream, mcasp->dma_params); | ||
729 | |||
730 | return 0; | ||
731 | } | ||
732 | |||
733 | static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | 769 | static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { |
734 | .startup = davinci_mcasp_startup, | ||
735 | .trigger = davinci_mcasp_trigger, | 770 | .trigger = davinci_mcasp_trigger, |
736 | .hw_params = davinci_mcasp_hw_params, | 771 | .hw_params = davinci_mcasp_hw_params, |
737 | .set_fmt = davinci_mcasp_set_dai_fmt, | 772 | .set_fmt = davinci_mcasp_set_dai_fmt, |
@@ -739,6 +774,25 @@ static const struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | |||
739 | .set_sysclk = davinci_mcasp_set_sysclk, | 774 | .set_sysclk = davinci_mcasp_set_sysclk, |
740 | }; | 775 | }; |
741 | 776 | ||
777 | static int davinci_mcasp_dai_probe(struct snd_soc_dai *dai) | ||
778 | { | ||
779 | struct davinci_mcasp *mcasp = snd_soc_dai_get_drvdata(dai); | ||
780 | |||
781 | if (mcasp->version == MCASP_VERSION_4) { | ||
782 | /* Using dmaengine PCM */ | ||
783 | dai->playback_dma_data = | ||
784 | &mcasp->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; | ||
785 | dai->capture_dma_data = | ||
786 | &mcasp->dma_data[SNDRV_PCM_STREAM_CAPTURE]; | ||
787 | } else { | ||
788 | /* Using davinci-pcm */ | ||
789 | dai->playback_dma_data = mcasp->dma_params; | ||
790 | dai->capture_dma_data = mcasp->dma_params; | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
742 | #ifdef CONFIG_PM_SLEEP | 796 | #ifdef CONFIG_PM_SLEEP |
743 | static int davinci_mcasp_suspend(struct snd_soc_dai *dai) | 797 | static int davinci_mcasp_suspend(struct snd_soc_dai *dai) |
744 | { | 798 | { |
@@ -792,6 +846,7 @@ static int davinci_mcasp_resume(struct snd_soc_dai *dai) | |||
792 | static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | 846 | static struct snd_soc_dai_driver davinci_mcasp_dai[] = { |
793 | { | 847 | { |
794 | .name = "davinci-mcasp.0", | 848 | .name = "davinci-mcasp.0", |
849 | .probe = davinci_mcasp_dai_probe, | ||
795 | .suspend = davinci_mcasp_suspend, | 850 | .suspend = davinci_mcasp_suspend, |
796 | .resume = davinci_mcasp_resume, | 851 | .resume = davinci_mcasp_resume, |
797 | .playback = { | 852 | .playback = { |
@@ -811,6 +866,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
811 | }, | 866 | }, |
812 | { | 867 | { |
813 | .name = "davinci-mcasp.1", | 868 | .name = "davinci-mcasp.1", |
869 | .probe = davinci_mcasp_dai_probe, | ||
814 | .playback = { | 870 | .playback = { |
815 | .channels_min = 1, | 871 | .channels_min = 1, |
816 | .channels_max = 384, | 872 | .channels_max = 384, |
@@ -1078,7 +1134,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1078 | if (!mcasp->base) { | 1134 | if (!mcasp->base) { |
1079 | dev_err(&pdev->dev, "ioremap failed\n"); | 1135 | dev_err(&pdev->dev, "ioremap failed\n"); |
1080 | ret = -ENOMEM; | 1136 | ret = -ENOMEM; |
1081 | goto err_release_clk; | 1137 | goto err; |
1082 | } | 1138 | } |
1083 | 1139 | ||
1084 | mcasp->op_mode = pdata->op_mode; | 1140 | mcasp->op_mode = pdata->op_mode; |
@@ -1159,25 +1215,37 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
1159 | 1215 | ||
1160 | mcasp_reparent_fck(pdev); | 1216 | mcasp_reparent_fck(pdev); |
1161 | 1217 | ||
1162 | ret = snd_soc_register_component(&pdev->dev, &davinci_mcasp_component, | 1218 | ret = devm_snd_soc_register_component(&pdev->dev, |
1163 | &davinci_mcasp_dai[pdata->op_mode], 1); | 1219 | &davinci_mcasp_component, |
1220 | &davinci_mcasp_dai[pdata->op_mode], 1); | ||
1164 | 1221 | ||
1165 | if (ret != 0) | 1222 | if (ret != 0) |
1166 | goto err_release_clk; | 1223 | goto err; |
1167 | 1224 | ||
1168 | if (mcasp->version != MCASP_VERSION_4) { | 1225 | switch (mcasp->version) { |
1226 | case MCASP_VERSION_1: | ||
1227 | case MCASP_VERSION_2: | ||
1228 | case MCASP_VERSION_3: | ||
1169 | ret = davinci_soc_platform_register(&pdev->dev); | 1229 | ret = davinci_soc_platform_register(&pdev->dev); |
1170 | if (ret) { | 1230 | break; |
1171 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | 1231 | case MCASP_VERSION_4: |
1172 | goto err_unregister_component; | 1232 | ret = omap_pcm_platform_register(&pdev->dev); |
1173 | } | 1233 | break; |
1234 | default: | ||
1235 | dev_err(&pdev->dev, "Invalid McASP version: %d\n", | ||
1236 | mcasp->version); | ||
1237 | ret = -EINVAL; | ||
1238 | break; | ||
1239 | } | ||
1240 | |||
1241 | if (ret) { | ||
1242 | dev_err(&pdev->dev, "register PCM failed: %d\n", ret); | ||
1243 | goto err; | ||
1174 | } | 1244 | } |
1175 | 1245 | ||
1176 | return 0; | 1246 | return 0; |
1177 | 1247 | ||
1178 | err_unregister_component: | 1248 | err: |
1179 | snd_soc_unregister_component(&pdev->dev); | ||
1180 | err_release_clk: | ||
1181 | pm_runtime_put_sync(&pdev->dev); | 1249 | pm_runtime_put_sync(&pdev->dev); |
1182 | pm_runtime_disable(&pdev->dev); | 1250 | pm_runtime_disable(&pdev->dev); |
1183 | return ret; | 1251 | return ret; |
@@ -1185,12 +1253,6 @@ err_release_clk: | |||
1185 | 1253 | ||
1186 | static int davinci_mcasp_remove(struct platform_device *pdev) | 1254 | static int davinci_mcasp_remove(struct platform_device *pdev) |
1187 | { | 1255 | { |
1188 | struct davinci_mcasp *mcasp = dev_get_drvdata(&pdev->dev); | ||
1189 | |||
1190 | snd_soc_unregister_component(&pdev->dev); | ||
1191 | if (mcasp->version != MCASP_VERSION_4) | ||
1192 | davinci_soc_platform_unregister(&pdev->dev); | ||
1193 | |||
1194 | pm_runtime_put_sync(&pdev->dev); | 1256 | pm_runtime_put_sync(&pdev->dev); |
1195 | pm_runtime_disable(&pdev->dev); | 1257 | pm_runtime_disable(&pdev->dev); |
1196 | 1258 | ||
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h index 8fed757d6087..98fbc451892a 100644 --- a/sound/soc/davinci/davinci-mcasp.h +++ b/sound/soc/davinci/davinci-mcasp.h | |||
@@ -283,6 +283,7 @@ | |||
283 | */ | 283 | */ |
284 | #define FIFO_ENABLE BIT(16) | 284 | #define FIFO_ENABLE BIT(16) |
285 | #define NUMEVT_MASK (0xFF << 8) | 285 | #define NUMEVT_MASK (0xFF << 8) |
286 | #define NUMEVT(x) (((x) & 0xFF) << 8) | ||
286 | #define NUMDMA_MASK (0xFF) | 287 | #define NUMDMA_MASK (0xFF) |
287 | 288 | ||
288 | #endif /* DAVINCI_MCASP_H */ | 289 | #endif /* DAVINCI_MCASP_H */ |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 14145cdf8a11..7809e9d935fc 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -852,16 +852,10 @@ static struct snd_soc_platform_driver davinci_soc_platform = { | |||
852 | 852 | ||
853 | int davinci_soc_platform_register(struct device *dev) | 853 | int davinci_soc_platform_register(struct device *dev) |
854 | { | 854 | { |
855 | return snd_soc_register_platform(dev, &davinci_soc_platform); | 855 | return devm_snd_soc_register_platform(dev, &davinci_soc_platform); |
856 | } | 856 | } |
857 | EXPORT_SYMBOL_GPL(davinci_soc_platform_register); | 857 | EXPORT_SYMBOL_GPL(davinci_soc_platform_register); |
858 | 858 | ||
859 | void davinci_soc_platform_unregister(struct device *dev) | ||
860 | { | ||
861 | snd_soc_unregister_platform(dev); | ||
862 | } | ||
863 | EXPORT_SYMBOL_GPL(davinci_soc_platform_unregister); | ||
864 | |||
865 | MODULE_AUTHOR("Vladimir Barinov"); | 859 | MODULE_AUTHOR("Vladimir Barinov"); |
866 | MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); | 860 | MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); |
867 | MODULE_LICENSE("GPL"); | 861 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h index fbb710c76c08..0fe2346a9aa2 100644 --- a/sound/soc/davinci/davinci-pcm.h +++ b/sound/soc/davinci/davinci-pcm.h | |||
@@ -29,7 +29,13 @@ struct davinci_pcm_dma_params { | |||
29 | unsigned int fifo_level; | 29 | unsigned int fifo_level; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | #if IS_ENABLED(CONFIG_SND_DAVINCI_SOC) | ||
32 | int davinci_soc_platform_register(struct device *dev); | 33 | int davinci_soc_platform_register(struct device *dev); |
33 | void davinci_soc_platform_unregister(struct device *dev); | 34 | #else |
35 | static inline int davinci_soc_platform_register(struct device *dev) | ||
36 | { | ||
37 | return 0; | ||
38 | } | ||
39 | #endif /* CONFIG_SND_DAVINCI_SOC */ | ||
34 | 40 | ||
35 | #endif | 41 | #endif |
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 30587c0cdbd2..77aef05588c3 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c | |||
@@ -258,7 +258,6 @@ static int davinci_vcif_probe(struct platform_device *pdev) | |||
258 | static int davinci_vcif_remove(struct platform_device *pdev) | 258 | static int davinci_vcif_remove(struct platform_device *pdev) |
259 | { | 259 | { |
260 | snd_soc_unregister_component(&pdev->dev); | 260 | snd_soc_unregister_component(&pdev->dev); |
261 | davinci_soc_platform_unregister(&pdev->dev); | ||
262 | 261 | ||
263 | return 0; | 262 | return 0; |
264 | } | 263 | } |
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index 338a91642471..d262ec0653d3 100644 --- a/sound/soc/fsl/Kconfig +++ b/sound/soc/fsl/Kconfig | |||
@@ -1,30 +1,77 @@ | |||
1 | menu "SoC Audio for Freescale CPUs" | ||
2 | |||
3 | comment "Common SoC Audio options for Freescale CPUs:" | ||
4 | |||
1 | config SND_SOC_FSL_SAI | 5 | config SND_SOC_FSL_SAI |
2 | tristate | 6 | tristate "Synchronous Audio Interface (SAI) module support" |
3 | select REGMAP_MMIO | 7 | select REGMAP_MMIO |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | 8 | select SND_SOC_GENERIC_DMAENGINE_PCM |
9 | help | ||
10 | Say Y if you want to add Synchronous Audio Interface (SAI) | ||
11 | support for the Freescale CPUs. | ||
12 | This option is only useful for out-of-tree drivers since | ||
13 | in-tree drivers select it automatically. | ||
5 | 14 | ||
6 | config SND_SOC_FSL_SSI | 15 | config SND_SOC_FSL_SSI |
7 | tristate | 16 | tristate "Synchronous Serial Interface module support" |
17 | select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n | ||
18 | select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && ARCH_MXC | ||
19 | help | ||
20 | Say Y if you want to add Synchronous Serial Interface (SSI) | ||
21 | support for the Freescale CPUs. | ||
22 | This option is only useful for out-of-tree drivers since | ||
23 | in-tree drivers select it automatically. | ||
8 | 24 | ||
9 | config SND_SOC_FSL_SPDIF | 25 | config SND_SOC_FSL_SPDIF |
10 | tristate | 26 | tristate "Sony/Philips Digital Interface module support" |
11 | select REGMAP_MMIO | 27 | select REGMAP_MMIO |
28 | select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n | ||
29 | select SND_SOC_IMX_PCM_FIQ if SND_IMX_SOC != n && ARCH_MXC | ||
30 | help | ||
31 | Say Y if you want to add Sony/Philips Digital Interface (SPDIF) | ||
32 | support for the Freescale CPUs. | ||
33 | This option is only useful for out-of-tree drivers since | ||
34 | in-tree drivers select it automatically. | ||
12 | 35 | ||
13 | config SND_SOC_FSL_ESAI | 36 | config SND_SOC_FSL_ESAI |
14 | tristate | 37 | tristate "Enhanced Serial Audio Interface (ESAI) module support" |
15 | select REGMAP_MMIO | 38 | select REGMAP_MMIO |
16 | select SND_SOC_FSL_UTILS | 39 | select SND_SOC_FSL_UTILS |
40 | help | ||
41 | Say Y if you want to add Enhanced Synchronous Audio Interface | ||
42 | (ESAI) support for the Freescale CPUs. | ||
43 | This option is only useful for out-of-tree drivers since | ||
44 | in-tree drivers select it automatically. | ||
17 | 45 | ||
18 | config SND_SOC_FSL_UTILS | 46 | config SND_SOC_FSL_UTILS |
19 | tristate | 47 | tristate |
20 | 48 | ||
21 | menuconfig SND_POWERPC_SOC | 49 | config SND_SOC_IMX_PCM_DMA |
50 | tristate | ||
51 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
52 | |||
53 | config SND_SOC_IMX_AUDMUX | ||
54 | tristate "Digital Audio Mux module support" | ||
55 | help | ||
56 | Say Y if you want to add Digital Audio Mux (AUDMUX) support | ||
57 | for the ARM i.MX CPUs. | ||
58 | This option is only useful for out-of-tree drivers since | ||
59 | in-tree drivers select it automatically. | ||
60 | |||
61 | config SND_POWERPC_SOC | ||
22 | tristate "SoC Audio for Freescale PowerPC CPUs" | 62 | tristate "SoC Audio for Freescale PowerPC CPUs" |
23 | depends on FSL_SOC || PPC_MPC52xx | 63 | depends on FSL_SOC || PPC_MPC52xx |
24 | help | 64 | help |
25 | Say Y or M if you want to add support for codecs attached to | 65 | Say Y or M if you want to add support for codecs attached to |
26 | the PowerPC CPUs. | 66 | the PowerPC CPUs. |
27 | 67 | ||
68 | config SND_IMX_SOC | ||
69 | tristate "SoC Audio for Freescale i.MX CPUs" | ||
70 | depends on ARCH_MXC || COMPILE_TEST | ||
71 | help | ||
72 | Say Y or M if you want to add support for codecs attached to | ||
73 | the i.MX CPUs. | ||
74 | |||
28 | if SND_POWERPC_SOC | 75 | if SND_POWERPC_SOC |
29 | 76 | ||
30 | config SND_MPC52xx_DMA | 77 | config SND_MPC52xx_DMA |
@@ -33,6 +80,8 @@ config SND_MPC52xx_DMA | |||
33 | config SND_SOC_POWERPC_DMA | 80 | config SND_SOC_POWERPC_DMA |
34 | tristate | 81 | tristate |
35 | 82 | ||
83 | comment "SoC Audio support for Freescale PPC boards:" | ||
84 | |||
36 | config SND_SOC_MPC8610_HPCD | 85 | config SND_SOC_MPC8610_HPCD |
37 | tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" | 86 | tristate "ALSA SoC support for the Freescale MPC8610 HPCD board" |
38 | # I2C is necessary for the CS4270 driver | 87 | # I2C is necessary for the CS4270 driver |
@@ -110,13 +159,6 @@ config SND_MPC52xx_SOC_EFIKA | |||
110 | 159 | ||
111 | endif # SND_POWERPC_SOC | 160 | endif # SND_POWERPC_SOC |
112 | 161 | ||
113 | menuconfig SND_IMX_SOC | ||
114 | tristate "SoC Audio for Freescale i.MX CPUs" | ||
115 | depends on ARCH_MXC || COMPILE_TEST | ||
116 | help | ||
117 | Say Y or M if you want to add support for codecs attached to | ||
118 | the i.MX CPUs. | ||
119 | |||
120 | if SND_IMX_SOC | 162 | if SND_IMX_SOC |
121 | 163 | ||
122 | config SND_SOC_IMX_SSI | 164 | config SND_SOC_IMX_SSI |
@@ -127,12 +169,7 @@ config SND_SOC_IMX_PCM_FIQ | |||
127 | tristate | 169 | tristate |
128 | select FIQ | 170 | select FIQ |
129 | 171 | ||
130 | config SND_SOC_IMX_PCM_DMA | 172 | comment "SoC Audio support for Freescale i.MX boards:" |
131 | tristate | ||
132 | select SND_SOC_GENERIC_DMAENGINE_PCM | ||
133 | |||
134 | config SND_SOC_IMX_AUDMUX | ||
135 | tristate | ||
136 | 173 | ||
137 | config SND_MXC_SOC_WM1133_EV1 | 174 | config SND_MXC_SOC_WM1133_EV1 |
138 | tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" | 175 | tristate "Audio on the i.MX31ADS with WM1133-EV1 fitted" |
@@ -187,7 +224,7 @@ config SND_SOC_EUKREA_TLV320 | |||
187 | 224 | ||
188 | config SND_SOC_IMX_WM8962 | 225 | config SND_SOC_IMX_WM8962 |
189 | tristate "SoC Audio support for i.MX boards with wm8962" | 226 | tristate "SoC Audio support for i.MX boards with wm8962" |
190 | depends on OF && I2C | 227 | depends on OF && I2C && INPUT |
191 | select SND_SOC_WM8962 | 228 | select SND_SOC_WM8962 |
192 | select SND_SOC_IMX_PCM_DMA | 229 | select SND_SOC_IMX_PCM_DMA |
193 | select SND_SOC_IMX_AUDMUX | 230 | select SND_SOC_IMX_AUDMUX |
@@ -225,3 +262,5 @@ config SND_SOC_IMX_MC13783 | |||
225 | select SND_SOC_IMX_PCM_DMA | 262 | select SND_SOC_IMX_PCM_DMA |
226 | 263 | ||
227 | endif # SND_IMX_SOC | 264 | endif # SND_IMX_SOC |
265 | |||
266 | endmenu | ||
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index b12ad4b9b4da..db254e358c18 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile | |||
@@ -12,7 +12,8 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o | |||
12 | 12 | ||
13 | # Freescale SSI/DMA/SAI/SPDIF Support | 13 | # Freescale SSI/DMA/SAI/SPDIF Support |
14 | snd-soc-fsl-sai-objs := fsl_sai.o | 14 | snd-soc-fsl-sai-objs := fsl_sai.o |
15 | snd-soc-fsl-ssi-objs := fsl_ssi.o | 15 | snd-soc-fsl-ssi-y := fsl_ssi.o |
16 | snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o | ||
16 | snd-soc-fsl-spdif-objs := fsl_spdif.o | 17 | snd-soc-fsl-spdif-objs := fsl_spdif.o |
17 | snd-soc-fsl-esai-objs := fsl_esai.o | 18 | snd-soc-fsl-esai-objs := fsl_esai.o |
18 | snd-soc-fsl-utils-objs := fsl_utils.o | 19 | snd-soc-fsl-utils-objs := fsl_utils.o |
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 496ce2eb2f1f..d719caf26dc2 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -39,6 +39,8 @@ | |||
39 | * @fifo_depth: depth of tx/rx FIFO | 39 | * @fifo_depth: depth of tx/rx FIFO |
40 | * @slot_width: width of each DAI slot | 40 | * @slot_width: width of each DAI slot |
41 | * @hck_rate: clock rate of desired HCKx clock | 41 | * @hck_rate: clock rate of desired HCKx clock |
42 | * @sck_rate: clock rate of desired SCKx clock | ||
43 | * @hck_dir: the direction of HCKx pads | ||
42 | * @sck_div: if using PSR/PM dividers for SCKx clock | 44 | * @sck_div: if using PSR/PM dividers for SCKx clock |
43 | * @slave_mode: if fully using DAI slave mode | 45 | * @slave_mode: if fully using DAI slave mode |
44 | * @synchronous: if using tx/rx synchronous mode | 46 | * @synchronous: if using tx/rx synchronous mode |
@@ -55,6 +57,8 @@ struct fsl_esai { | |||
55 | u32 fifo_depth; | 57 | u32 fifo_depth; |
56 | u32 slot_width; | 58 | u32 slot_width; |
57 | u32 hck_rate[2]; | 59 | u32 hck_rate[2]; |
60 | u32 sck_rate[2]; | ||
61 | bool hck_dir[2]; | ||
58 | bool sck_div[2]; | 62 | bool sck_div[2]; |
59 | bool slave_mode; | 63 | bool slave_mode; |
60 | bool synchronous; | 64 | bool synchronous; |
@@ -209,8 +213,13 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
209 | struct clk *clksrc = esai_priv->extalclk; | 213 | struct clk *clksrc = esai_priv->extalclk; |
210 | bool tx = clk_id <= ESAI_HCKT_EXTAL; | 214 | bool tx = clk_id <= ESAI_HCKT_EXTAL; |
211 | bool in = dir == SND_SOC_CLOCK_IN; | 215 | bool in = dir == SND_SOC_CLOCK_IN; |
212 | u32 ret, ratio, ecr = 0; | 216 | u32 ratio, ecr = 0; |
213 | unsigned long clk_rate; | 217 | unsigned long clk_rate; |
218 | int ret; | ||
219 | |||
220 | /* Bypass divider settings if the requirement doesn't change */ | ||
221 | if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx]) | ||
222 | return 0; | ||
214 | 223 | ||
215 | /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ | 224 | /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */ |
216 | esai_priv->sck_div[tx] = true; | 225 | esai_priv->sck_div[tx] = true; |
@@ -277,6 +286,7 @@ static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
277 | esai_priv->sck_div[tx] = false; | 286 | esai_priv->sck_div[tx] = false; |
278 | 287 | ||
279 | out: | 288 | out: |
289 | esai_priv->hck_dir[tx] = dir; | ||
280 | esai_priv->hck_rate[tx] = freq; | 290 | esai_priv->hck_rate[tx] = freq; |
281 | 291 | ||
282 | regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, | 292 | regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR, |
@@ -294,9 +304,10 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) | |||
294 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); | 304 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
295 | u32 hck_rate = esai_priv->hck_rate[tx]; | 305 | u32 hck_rate = esai_priv->hck_rate[tx]; |
296 | u32 sub, ratio = hck_rate / freq; | 306 | u32 sub, ratio = hck_rate / freq; |
307 | int ret; | ||
297 | 308 | ||
298 | /* Don't apply for fully slave mode*/ | 309 | /* Don't apply for fully slave mode or unchanged bclk */ |
299 | if (esai_priv->slave_mode) | 310 | if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq) |
300 | return 0; | 311 | return 0; |
301 | 312 | ||
302 | if (ratio * freq > hck_rate) | 313 | if (ratio * freq > hck_rate) |
@@ -319,8 +330,15 @@ static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) | |||
319 | return -EINVAL; | 330 | return -EINVAL; |
320 | } | 331 | } |
321 | 332 | ||
322 | return fsl_esai_divisor_cal(dai, tx, ratio, true, | 333 | ret = fsl_esai_divisor_cal(dai, tx, ratio, true, |
323 | esai_priv->sck_div[tx] ? 0 : ratio); | 334 | esai_priv->sck_div[tx] ? 0 : ratio); |
335 | if (ret) | ||
336 | return ret; | ||
337 | |||
338 | /* Save current bclk rate */ | ||
339 | esai_priv->sck_rate[tx] = freq; | ||
340 | |||
341 | return 0; | ||
324 | } | 342 | } |
325 | 343 | ||
326 | static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | 344 | static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, |
@@ -439,8 +457,8 @@ static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
439 | static int fsl_esai_startup(struct snd_pcm_substream *substream, | 457 | static int fsl_esai_startup(struct snd_pcm_substream *substream, |
440 | struct snd_soc_dai *dai) | 458 | struct snd_soc_dai *dai) |
441 | { | 459 | { |
442 | int ret; | ||
443 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); | 460 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
461 | int ret; | ||
444 | 462 | ||
445 | /* | 463 | /* |
446 | * Some platforms might use the same bit to gate all three or two of | 464 | * Some platforms might use the same bit to gate all three or two of |
@@ -492,7 +510,8 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, | |||
492 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 510 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
493 | u32 width = snd_pcm_format_width(params_format(params)); | 511 | u32 width = snd_pcm_format_width(params_format(params)); |
494 | u32 channels = params_channels(params); | 512 | u32 channels = params_channels(params); |
495 | u32 bclk, mask, val, ret; | 513 | u32 bclk, mask, val; |
514 | int ret; | ||
496 | 515 | ||
497 | bclk = params_rate(params) * esai_priv->slot_width * 2; | 516 | bclk = params_rate(params) * esai_priv->slot_width * 2; |
498 | 517 | ||
@@ -822,6 +841,7 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
822 | 841 | ||
823 | static const struct of_device_id fsl_esai_dt_ids[] = { | 842 | static const struct of_device_id fsl_esai_dt_ids[] = { |
824 | { .compatible = "fsl,imx35-esai", }, | 843 | { .compatible = "fsl,imx35-esai", }, |
844 | { .compatible = "fsl,vf610-esai", }, | ||
825 | {} | 845 | {} |
826 | }; | 846 | }; |
827 | MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); | 847 | MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids); |
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 56da8c8c5960..c5a0e8af8226 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <sound/pcm_params.h> | 22 | #include <sound/pcm_params.h> |
23 | 23 | ||
24 | #include "fsl_sai.h" | 24 | #include "fsl_sai.h" |
25 | #include "imx-pcm.h" | ||
25 | 26 | ||
26 | #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ | 27 | #define FSL_SAI_FLAGS (FSL_SAI_CSR_SEIE |\ |
27 | FSL_SAI_CSR_FEIE) | 28 | FSL_SAI_CSR_FEIE) |
@@ -30,78 +31,96 @@ static irqreturn_t fsl_sai_isr(int irq, void *devid) | |||
30 | { | 31 | { |
31 | struct fsl_sai *sai = (struct fsl_sai *)devid; | 32 | struct fsl_sai *sai = (struct fsl_sai *)devid; |
32 | struct device *dev = &sai->pdev->dev; | 33 | struct device *dev = &sai->pdev->dev; |
33 | u32 xcsr, mask; | 34 | u32 flags, xcsr, mask; |
35 | bool irq_none = true; | ||
34 | 36 | ||
35 | /* Only handle those what we enabled */ | 37 | /* |
38 | * Both IRQ status bits and IRQ mask bits are in the xCSR but | ||
39 | * different shifts. And we here create a mask only for those | ||
40 | * IRQs that we activated. | ||
41 | */ | ||
36 | mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; | 42 | mask = (FSL_SAI_FLAGS >> FSL_SAI_CSR_xIE_SHIFT) << FSL_SAI_CSR_xF_SHIFT; |
37 | 43 | ||
38 | /* Tx IRQ */ | 44 | /* Tx IRQ */ |
39 | regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); | 45 | regmap_read(sai->regmap, FSL_SAI_TCSR, &xcsr); |
40 | xcsr &= mask; | 46 | flags = xcsr & mask; |
47 | |||
48 | if (flags) | ||
49 | irq_none = false; | ||
50 | else | ||
51 | goto irq_rx; | ||
41 | 52 | ||
42 | if (xcsr & FSL_SAI_CSR_WSF) | 53 | if (flags & FSL_SAI_CSR_WSF) |
43 | dev_dbg(dev, "isr: Start of Tx word detected\n"); | 54 | dev_dbg(dev, "isr: Start of Tx word detected\n"); |
44 | 55 | ||
45 | if (xcsr & FSL_SAI_CSR_SEF) | 56 | if (flags & FSL_SAI_CSR_SEF) |
46 | dev_warn(dev, "isr: Tx Frame sync error detected\n"); | 57 | dev_warn(dev, "isr: Tx Frame sync error detected\n"); |
47 | 58 | ||
48 | if (xcsr & FSL_SAI_CSR_FEF) { | 59 | if (flags & FSL_SAI_CSR_FEF) { |
49 | dev_warn(dev, "isr: Transmit underrun detected\n"); | 60 | dev_warn(dev, "isr: Transmit underrun detected\n"); |
50 | /* FIFO reset for safety */ | 61 | /* FIFO reset for safety */ |
51 | xcsr |= FSL_SAI_CSR_FR; | 62 | xcsr |= FSL_SAI_CSR_FR; |
52 | } | 63 | } |
53 | 64 | ||
54 | if (xcsr & FSL_SAI_CSR_FWF) | 65 | if (flags & FSL_SAI_CSR_FWF) |
55 | dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); | 66 | dev_dbg(dev, "isr: Enabled transmit FIFO is empty\n"); |
56 | 67 | ||
57 | if (xcsr & FSL_SAI_CSR_FRF) | 68 | if (flags & FSL_SAI_CSR_FRF) |
58 | dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n"); | 69 | dev_dbg(dev, "isr: Transmit FIFO watermark has been reached\n"); |
59 | 70 | ||
60 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | 71 | flags &= FSL_SAI_CSR_xF_W_MASK; |
61 | FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); | 72 | xcsr &= ~FSL_SAI_CSR_xF_MASK; |
73 | |||
74 | if (flags) | ||
75 | regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); | ||
62 | 76 | ||
77 | irq_rx: | ||
63 | /* Rx IRQ */ | 78 | /* Rx IRQ */ |
64 | regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); | 79 | regmap_read(sai->regmap, FSL_SAI_RCSR, &xcsr); |
65 | xcsr &= mask; | 80 | flags = xcsr & mask; |
66 | 81 | ||
67 | if (xcsr & FSL_SAI_CSR_WSF) | 82 | if (flags) |
83 | irq_none = false; | ||
84 | else | ||
85 | goto out; | ||
86 | |||
87 | if (flags & FSL_SAI_CSR_WSF) | ||
68 | dev_dbg(dev, "isr: Start of Rx word detected\n"); | 88 | dev_dbg(dev, "isr: Start of Rx word detected\n"); |
69 | 89 | ||
70 | if (xcsr & FSL_SAI_CSR_SEF) | 90 | if (flags & FSL_SAI_CSR_SEF) |
71 | dev_warn(dev, "isr: Rx Frame sync error detected\n"); | 91 | dev_warn(dev, "isr: Rx Frame sync error detected\n"); |
72 | 92 | ||
73 | if (xcsr & FSL_SAI_CSR_FEF) { | 93 | if (flags & FSL_SAI_CSR_FEF) { |
74 | dev_warn(dev, "isr: Receive overflow detected\n"); | 94 | dev_warn(dev, "isr: Receive overflow detected\n"); |
75 | /* FIFO reset for safety */ | 95 | /* FIFO reset for safety */ |
76 | xcsr |= FSL_SAI_CSR_FR; | 96 | xcsr |= FSL_SAI_CSR_FR; |
77 | } | 97 | } |
78 | 98 | ||
79 | if (xcsr & FSL_SAI_CSR_FWF) | 99 | if (flags & FSL_SAI_CSR_FWF) |
80 | dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); | 100 | dev_dbg(dev, "isr: Enabled receive FIFO is full\n"); |
81 | 101 | ||
82 | if (xcsr & FSL_SAI_CSR_FRF) | 102 | if (flags & FSL_SAI_CSR_FRF) |
83 | dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n"); | 103 | dev_dbg(dev, "isr: Receive FIFO watermark has been reached\n"); |
84 | 104 | ||
85 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | 105 | flags &= FSL_SAI_CSR_xF_W_MASK; |
86 | FSL_SAI_CSR_xF_W_MASK | FSL_SAI_CSR_FR, xcsr); | 106 | xcsr &= ~FSL_SAI_CSR_xF_MASK; |
107 | |||
108 | if (flags) | ||
109 | regmap_write(sai->regmap, FSL_SAI_TCSR, flags | xcsr); | ||
87 | 110 | ||
88 | return IRQ_HANDLED; | 111 | out: |
112 | if (irq_none) | ||
113 | return IRQ_NONE; | ||
114 | else | ||
115 | return IRQ_HANDLED; | ||
89 | } | 116 | } |
90 | 117 | ||
91 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | 118 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, |
92 | int clk_id, unsigned int freq, int fsl_dir) | 119 | int clk_id, unsigned int freq, int fsl_dir) |
93 | { | 120 | { |
94 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 121 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
95 | u32 val_cr2, reg_cr2; | 122 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; |
96 | 123 | u32 val_cr2 = 0; | |
97 | if (fsl_dir == FSL_FMT_TRANSMITTER) | ||
98 | reg_cr2 = FSL_SAI_TCR2; | ||
99 | else | ||
100 | reg_cr2 = FSL_SAI_RCR2; | ||
101 | |||
102 | regmap_read(sai->regmap, reg_cr2, &val_cr2); | ||
103 | |||
104 | val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK; | ||
105 | 124 | ||
106 | switch (clk_id) { | 125 | switch (clk_id) { |
107 | case FSL_SAI_CLK_BUS: | 126 | case FSL_SAI_CLK_BUS: |
@@ -120,7 +139,8 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | |||
120 | return -EINVAL; | 139 | return -EINVAL; |
121 | } | 140 | } |
122 | 141 | ||
123 | regmap_write(sai->regmap, reg_cr2, val_cr2); | 142 | regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), |
143 | FSL_SAI_CR2_MSEL_MASK, val_cr2); | ||
124 | 144 | ||
125 | return 0; | 145 | return 0; |
126 | } | 146 | } |
@@ -152,22 +172,10 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
152 | unsigned int fmt, int fsl_dir) | 172 | unsigned int fmt, int fsl_dir) |
153 | { | 173 | { |
154 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 174 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
155 | u32 val_cr2, val_cr4, reg_cr2, reg_cr4; | 175 | bool tx = fsl_dir == FSL_FMT_TRANSMITTER; |
156 | 176 | u32 val_cr2 = 0, val_cr4 = 0; | |
157 | if (fsl_dir == FSL_FMT_TRANSMITTER) { | ||
158 | reg_cr2 = FSL_SAI_TCR2; | ||
159 | reg_cr4 = FSL_SAI_TCR4; | ||
160 | } else { | ||
161 | reg_cr2 = FSL_SAI_RCR2; | ||
162 | reg_cr4 = FSL_SAI_RCR4; | ||
163 | } | ||
164 | 177 | ||
165 | regmap_read(sai->regmap, reg_cr2, &val_cr2); | 178 | if (!sai->big_endian_data) |
166 | regmap_read(sai->regmap, reg_cr4, &val_cr4); | ||
167 | |||
168 | if (sai->big_endian_data) | ||
169 | val_cr4 &= ~FSL_SAI_CR4_MF; | ||
170 | else | ||
171 | val_cr4 |= FSL_SAI_CR4_MF; | 179 | val_cr4 |= FSL_SAI_CR4_MF; |
172 | 180 | ||
173 | /* DAI mode */ | 181 | /* DAI mode */ |
@@ -188,7 +196,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
188 | * frame sync asserts with the first bit of the frame. | 196 | * frame sync asserts with the first bit of the frame. |
189 | */ | 197 | */ |
190 | val_cr2 |= FSL_SAI_CR2_BCP; | 198 | val_cr2 |= FSL_SAI_CR2_BCP; |
191 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); | ||
192 | break; | 199 | break; |
193 | case SND_SOC_DAIFMT_DSP_A: | 200 | case SND_SOC_DAIFMT_DSP_A: |
194 | /* | 201 | /* |
@@ -198,7 +205,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
198 | * data word. | 205 | * data word. |
199 | */ | 206 | */ |
200 | val_cr2 |= FSL_SAI_CR2_BCP; | 207 | val_cr2 |= FSL_SAI_CR2_BCP; |
201 | val_cr4 &= ~FSL_SAI_CR4_FSP; | ||
202 | val_cr4 |= FSL_SAI_CR4_FSE; | 208 | val_cr4 |= FSL_SAI_CR4_FSE; |
203 | sai->is_dsp_mode = true; | 209 | sai->is_dsp_mode = true; |
204 | break; | 210 | break; |
@@ -208,7 +214,6 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
208 | * frame sync asserts with the first bit of the frame. | 214 | * frame sync asserts with the first bit of the frame. |
209 | */ | 215 | */ |
210 | val_cr2 |= FSL_SAI_CR2_BCP; | 216 | val_cr2 |= FSL_SAI_CR2_BCP; |
211 | val_cr4 &= ~(FSL_SAI_CR4_FSE | FSL_SAI_CR4_FSP); | ||
212 | sai->is_dsp_mode = true; | 217 | sai->is_dsp_mode = true; |
213 | break; | 218 | break; |
214 | case SND_SOC_DAIFMT_RIGHT_J: | 219 | case SND_SOC_DAIFMT_RIGHT_J: |
@@ -246,23 +251,22 @@ static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai, | |||
246 | val_cr4 |= FSL_SAI_CR4_FSD_MSTR; | 251 | val_cr4 |= FSL_SAI_CR4_FSD_MSTR; |
247 | break; | 252 | break; |
248 | case SND_SOC_DAIFMT_CBM_CFM: | 253 | case SND_SOC_DAIFMT_CBM_CFM: |
249 | val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; | ||
250 | val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; | ||
251 | break; | 254 | break; |
252 | case SND_SOC_DAIFMT_CBS_CFM: | 255 | case SND_SOC_DAIFMT_CBS_CFM: |
253 | val_cr2 |= FSL_SAI_CR2_BCD_MSTR; | 256 | val_cr2 |= FSL_SAI_CR2_BCD_MSTR; |
254 | val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR; | ||
255 | break; | 257 | break; |
256 | case SND_SOC_DAIFMT_CBM_CFS: | 258 | case SND_SOC_DAIFMT_CBM_CFS: |
257 | val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR; | ||
258 | val_cr4 |= FSL_SAI_CR4_FSD_MSTR; | 259 | val_cr4 |= FSL_SAI_CR4_FSD_MSTR; |
259 | break; | 260 | break; |
260 | default: | 261 | default: |
261 | return -EINVAL; | 262 | return -EINVAL; |
262 | } | 263 | } |
263 | 264 | ||
264 | regmap_write(sai->regmap, reg_cr2, val_cr2); | 265 | regmap_update_bits(sai->regmap, FSL_SAI_xCR2(tx), |
265 | regmap_write(sai->regmap, reg_cr4, val_cr4); | 266 | FSL_SAI_CR2_BCP | FSL_SAI_CR2_BCD_MSTR, val_cr2); |
267 | regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), | ||
268 | FSL_SAI_CR4_MF | FSL_SAI_CR4_FSE | | ||
269 | FSL_SAI_CR4_FSP | FSL_SAI_CR4_FSD_MSTR, val_cr4); | ||
266 | 270 | ||
267 | return 0; | 271 | return 0; |
268 | } | 272 | } |
@@ -289,29 +293,10 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
289 | struct snd_soc_dai *cpu_dai) | 293 | struct snd_soc_dai *cpu_dai) |
290 | { | 294 | { |
291 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 295 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
292 | u32 val_cr4, val_cr5, val_mr, reg_cr4, reg_cr5, reg_mr; | 296 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
293 | unsigned int channels = params_channels(params); | 297 | unsigned int channels = params_channels(params); |
294 | u32 word_width = snd_pcm_format_width(params_format(params)); | 298 | u32 word_width = snd_pcm_format_width(params_format(params)); |
295 | 299 | u32 val_cr4 = 0, val_cr5 = 0; | |
296 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
297 | reg_cr4 = FSL_SAI_TCR4; | ||
298 | reg_cr5 = FSL_SAI_TCR5; | ||
299 | reg_mr = FSL_SAI_TMR; | ||
300 | } else { | ||
301 | reg_cr4 = FSL_SAI_RCR4; | ||
302 | reg_cr5 = FSL_SAI_RCR5; | ||
303 | reg_mr = FSL_SAI_RMR; | ||
304 | } | ||
305 | |||
306 | regmap_read(sai->regmap, reg_cr4, &val_cr4); | ||
307 | regmap_read(sai->regmap, reg_cr4, &val_cr5); | ||
308 | |||
309 | val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK; | ||
310 | val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK; | ||
311 | |||
312 | val_cr5 &= ~FSL_SAI_CR5_WNW_MASK; | ||
313 | val_cr5 &= ~FSL_SAI_CR5_W0W_MASK; | ||
314 | val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; | ||
315 | 300 | ||
316 | if (!sai->is_dsp_mode) | 301 | if (!sai->is_dsp_mode) |
317 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); | 302 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); |
@@ -319,18 +304,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
319 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); | 304 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); |
320 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); | 305 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); |
321 | 306 | ||
322 | val_cr5 &= ~FSL_SAI_CR5_FBT_MASK; | ||
323 | if (sai->big_endian_data) | 307 | if (sai->big_endian_data) |
324 | val_cr5 |= FSL_SAI_CR5_FBT(0); | 308 | val_cr5 |= FSL_SAI_CR5_FBT(0); |
325 | else | 309 | else |
326 | val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); | 310 | val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); |
327 | 311 | ||
328 | val_cr4 |= FSL_SAI_CR4_FRSZ(channels); | 312 | val_cr4 |= FSL_SAI_CR4_FRSZ(channels); |
329 | val_mr = ~0UL - ((1 << channels) - 1); | ||
330 | 313 | ||
331 | regmap_write(sai->regmap, reg_cr4, val_cr4); | 314 | regmap_update_bits(sai->regmap, FSL_SAI_xCR4(tx), |
332 | regmap_write(sai->regmap, reg_cr5, val_cr5); | 315 | FSL_SAI_CR4_SYWD_MASK | FSL_SAI_CR4_FRSZ_MASK, |
333 | regmap_write(sai->regmap, reg_mr, val_mr); | 316 | val_cr4); |
317 | regmap_update_bits(sai->regmap, FSL_SAI_xCR5(tx), | ||
318 | FSL_SAI_CR5_WNW_MASK | FSL_SAI_CR5_W0W_MASK | | ||
319 | FSL_SAI_CR5_FBT_MASK, val_cr5); | ||
320 | regmap_write(sai->regmap, FSL_SAI_xMR(tx), ~0UL - ((1 << channels) - 1)); | ||
334 | 321 | ||
335 | return 0; | 322 | return 0; |
336 | } | 323 | } |
@@ -339,6 +326,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
339 | struct snd_soc_dai *cpu_dai) | 326 | struct snd_soc_dai *cpu_dai) |
340 | { | 327 | { |
341 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 328 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
329 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
342 | u32 tcsr, rcsr; | 330 | u32 tcsr, rcsr; |
343 | 331 | ||
344 | /* | 332 | /* |
@@ -353,14 +341,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
353 | regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); | 341 | regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr); |
354 | regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); | 342 | regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr); |
355 | 343 | ||
356 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
357 | tcsr |= FSL_SAI_CSR_FRDE; | ||
358 | rcsr &= ~FSL_SAI_CSR_FRDE; | ||
359 | } else { | ||
360 | rcsr |= FSL_SAI_CSR_FRDE; | ||
361 | tcsr &= ~FSL_SAI_CSR_FRDE; | ||
362 | } | ||
363 | |||
364 | /* | 344 | /* |
365 | * It is recommended that the transmitter is the last enabled | 345 | * It is recommended that the transmitter is the last enabled |
366 | * and the first disabled. | 346 | * and the first disabled. |
@@ -369,22 +349,33 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
369 | case SNDRV_PCM_TRIGGER_START: | 349 | case SNDRV_PCM_TRIGGER_START: |
370 | case SNDRV_PCM_TRIGGER_RESUME: | 350 | case SNDRV_PCM_TRIGGER_RESUME: |
371 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 351 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
372 | tcsr |= FSL_SAI_CSR_TERE; | 352 | if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { |
373 | rcsr |= FSL_SAI_CSR_TERE; | 353 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, |
354 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | ||
355 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | ||
356 | FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); | ||
357 | } | ||
374 | 358 | ||
375 | regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); | 359 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), |
376 | regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); | 360 | FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); |
361 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), | ||
362 | FSL_SAI_CSR_FRDE, FSL_SAI_CSR_FRDE); | ||
377 | break; | 363 | break; |
378 | case SNDRV_PCM_TRIGGER_STOP: | 364 | case SNDRV_PCM_TRIGGER_STOP: |
379 | case SNDRV_PCM_TRIGGER_SUSPEND: | 365 | case SNDRV_PCM_TRIGGER_SUSPEND: |
380 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 366 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
381 | if (!(cpu_dai->playback_active || cpu_dai->capture_active)) { | 367 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), |
382 | tcsr &= ~FSL_SAI_CSR_TERE; | 368 | FSL_SAI_CSR_FRDE, 0); |
383 | rcsr &= ~FSL_SAI_CSR_TERE; | 369 | regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), |
370 | FSL_SAI_CSR_xIE_MASK, 0); | ||
371 | |||
372 | /* Check if the opposite FRDE is also disabled */ | ||
373 | if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { | ||
374 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, | ||
375 | FSL_SAI_CSR_TERE, 0); | ||
376 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, | ||
377 | FSL_SAI_CSR_TERE, 0); | ||
384 | } | 378 | } |
385 | |||
386 | regmap_write(sai->regmap, FSL_SAI_TCSR, tcsr); | ||
387 | regmap_write(sai->regmap, FSL_SAI_RCSR, rcsr); | ||
388 | break; | 379 | break; |
389 | default: | 380 | default: |
390 | return -EINVAL; | 381 | return -EINVAL; |
@@ -397,14 +388,17 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream, | |||
397 | struct snd_soc_dai *cpu_dai) | 388 | struct snd_soc_dai *cpu_dai) |
398 | { | 389 | { |
399 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 390 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
400 | u32 reg; | 391 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
392 | struct device *dev = &sai->pdev->dev; | ||
393 | int ret; | ||
401 | 394 | ||
402 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 395 | ret = clk_prepare_enable(sai->bus_clk); |
403 | reg = FSL_SAI_TCR3; | 396 | if (ret) { |
404 | else | 397 | dev_err(dev, "failed to enable bus clock: %d\n", ret); |
405 | reg = FSL_SAI_RCR3; | 398 | return ret; |
399 | } | ||
406 | 400 | ||
407 | regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, | 401 | regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, |
408 | FSL_SAI_CR3_TRCE); | 402 | FSL_SAI_CR3_TRCE); |
409 | 403 | ||
410 | return 0; | 404 | return 0; |
@@ -414,15 +408,11 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, | |||
414 | struct snd_soc_dai *cpu_dai) | 408 | struct snd_soc_dai *cpu_dai) |
415 | { | 409 | { |
416 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | 410 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); |
417 | u32 reg; | 411 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
418 | 412 | ||
419 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 413 | regmap_update_bits(sai->regmap, FSL_SAI_xCR3(tx), FSL_SAI_CR3_TRCE, 0); |
420 | reg = FSL_SAI_TCR3; | ||
421 | else | ||
422 | reg = FSL_SAI_RCR3; | ||
423 | 414 | ||
424 | regmap_update_bits(sai->regmap, reg, FSL_SAI_CR3_TRCE, | 415 | clk_disable_unprepare(sai->bus_clk); |
425 | ~FSL_SAI_CR3_TRCE); | ||
426 | } | 416 | } |
427 | 417 | ||
428 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { | 418 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { |
@@ -438,8 +428,8 @@ static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai) | |||
438 | { | 428 | { |
439 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); | 429 | struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev); |
440 | 430 | ||
441 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, FSL_SAI_FLAGS); | 431 | regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 0xffffffff, 0x0); |
442 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, FSL_SAI_FLAGS); | 432 | regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 0xffffffff, 0x0); |
443 | regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, | 433 | regmap_update_bits(sai->regmap, FSL_SAI_TCR1, FSL_SAI_CR1_RFW_MASK, |
444 | FSL_SAI_MAXBURST_TX * 2); | 434 | FSL_SAI_MAXBURST_TX * 2); |
445 | regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, | 435 | regmap_update_bits(sai->regmap, FSL_SAI_RCR1, FSL_SAI_CR1_RFW_MASK, |
@@ -555,7 +545,8 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
555 | struct fsl_sai *sai; | 545 | struct fsl_sai *sai; |
556 | struct resource *res; | 546 | struct resource *res; |
557 | void __iomem *base; | 547 | void __iomem *base; |
558 | int irq, ret; | 548 | char tmp[8]; |
549 | int irq, ret, i; | ||
559 | 550 | ||
560 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); | 551 | sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL); |
561 | if (!sai) | 552 | if (!sai) |
@@ -563,6 +554,9 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
563 | 554 | ||
564 | sai->pdev = pdev; | 555 | sai->pdev = pdev; |
565 | 556 | ||
557 | if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx6sx-sai")) | ||
558 | sai->sai_on_imx = true; | ||
559 | |||
566 | sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); | 560 | sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs"); |
567 | if (sai->big_endian_regs) | 561 | if (sai->big_endian_regs) |
568 | fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; | 562 | fsl_sai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG; |
@@ -575,12 +569,35 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
575 | return PTR_ERR(base); | 569 | return PTR_ERR(base); |
576 | 570 | ||
577 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, | 571 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, |
578 | "sai", base, &fsl_sai_regmap_config); | 572 | "bus", base, &fsl_sai_regmap_config); |
573 | |||
574 | /* Compatible with old DTB cases */ | ||
575 | if (IS_ERR(sai->regmap)) | ||
576 | sai->regmap = devm_regmap_init_mmio_clk(&pdev->dev, | ||
577 | "sai", base, &fsl_sai_regmap_config); | ||
579 | if (IS_ERR(sai->regmap)) { | 578 | if (IS_ERR(sai->regmap)) { |
580 | dev_err(&pdev->dev, "regmap init failed\n"); | 579 | dev_err(&pdev->dev, "regmap init failed\n"); |
581 | return PTR_ERR(sai->regmap); | 580 | return PTR_ERR(sai->regmap); |
582 | } | 581 | } |
583 | 582 | ||
583 | /* No error out for old DTB cases but only mark the clock NULL */ | ||
584 | sai->bus_clk = devm_clk_get(&pdev->dev, "bus"); | ||
585 | if (IS_ERR(sai->bus_clk)) { | ||
586 | dev_err(&pdev->dev, "failed to get bus clock: %ld\n", | ||
587 | PTR_ERR(sai->bus_clk)); | ||
588 | sai->bus_clk = NULL; | ||
589 | } | ||
590 | |||
591 | for (i = 0; i < FSL_SAI_MCLK_MAX; i++) { | ||
592 | sprintf(tmp, "mclk%d", i + 1); | ||
593 | sai->mclk_clk[i] = devm_clk_get(&pdev->dev, tmp); | ||
594 | if (IS_ERR(sai->mclk_clk[i])) { | ||
595 | dev_err(&pdev->dev, "failed to get mclk%d clock: %ld\n", | ||
596 | i + 1, PTR_ERR(sai->mclk_clk[i])); | ||
597 | sai->mclk_clk[i] = NULL; | ||
598 | } | ||
599 | } | ||
600 | |||
584 | irq = platform_get_irq(pdev, 0); | 601 | irq = platform_get_irq(pdev, 0); |
585 | if (irq < 0) { | 602 | if (irq < 0) { |
586 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | 603 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); |
@@ -605,12 +622,16 @@ static int fsl_sai_probe(struct platform_device *pdev) | |||
605 | if (ret) | 622 | if (ret) |
606 | return ret; | 623 | return ret; |
607 | 624 | ||
608 | return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, | 625 | if (sai->sai_on_imx) |
609 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); | 626 | return imx_pcm_dma_init(pdev); |
627 | else | ||
628 | return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, | ||
629 | SND_DMAENGINE_PCM_FLAG_NO_RESIDUE); | ||
610 | } | 630 | } |
611 | 631 | ||
612 | static const struct of_device_id fsl_sai_ids[] = { | 632 | static const struct of_device_id fsl_sai_ids[] = { |
613 | { .compatible = "fsl,vf610-sai", }, | 633 | { .compatible = "fsl,vf610-sai", }, |
634 | { .compatible = "fsl,imx6sx-sai", }, | ||
614 | { /* sentinel */ } | 635 | { /* sentinel */ } |
615 | }; | 636 | }; |
616 | 637 | ||
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index a264185c7138..0e6c9f595d75 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h | |||
@@ -35,6 +35,16 @@ | |||
35 | #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ | 35 | #define FSL_SAI_RFR 0xc0 /* SAI Receive FIFO */ |
36 | #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ | 36 | #define FSL_SAI_RMR 0xe0 /* SAI Receive Mask */ |
37 | 37 | ||
38 | #define FSL_SAI_xCSR(tx) (tx ? FSL_SAI_TCSR : FSL_SAI_RCSR) | ||
39 | #define FSL_SAI_xCR1(tx) (tx ? FSL_SAI_TCR1 : FSL_SAI_RCR1) | ||
40 | #define FSL_SAI_xCR2(tx) (tx ? FSL_SAI_TCR2 : FSL_SAI_RCR2) | ||
41 | #define FSL_SAI_xCR3(tx) (tx ? FSL_SAI_TCR3 : FSL_SAI_RCR3) | ||
42 | #define FSL_SAI_xCR4(tx) (tx ? FSL_SAI_TCR4 : FSL_SAI_RCR4) | ||
43 | #define FSL_SAI_xCR5(tx) (tx ? FSL_SAI_TCR5 : FSL_SAI_RCR5) | ||
44 | #define FSL_SAI_xDR(tx) (tx ? FSL_SAI_TDR : FSL_SAI_RDR) | ||
45 | #define FSL_SAI_xFR(tx) (tx ? FSL_SAI_TFR : FSL_SAI_RFR) | ||
46 | #define FSL_SAI_xMR(tx) (tx ? FSL_SAI_TMR : FSL_SAI_RMR) | ||
47 | |||
38 | /* SAI Transmit/Recieve Control Register */ | 48 | /* SAI Transmit/Recieve Control Register */ |
39 | #define FSL_SAI_CSR_TERE BIT(31) | 49 | #define FSL_SAI_CSR_TERE BIT(31) |
40 | #define FSL_SAI_CSR_FR BIT(25) | 50 | #define FSL_SAI_CSR_FR BIT(25) |
@@ -48,6 +58,7 @@ | |||
48 | #define FSL_SAI_CSR_FWF BIT(17) | 58 | #define FSL_SAI_CSR_FWF BIT(17) |
49 | #define FSL_SAI_CSR_FRF BIT(16) | 59 | #define FSL_SAI_CSR_FRF BIT(16) |
50 | #define FSL_SAI_CSR_xIE_SHIFT 8 | 60 | #define FSL_SAI_CSR_xIE_SHIFT 8 |
61 | #define FSL_SAI_CSR_xIE_MASK (0x1f << FSL_SAI_CSR_xIE_SHIFT) | ||
51 | #define FSL_SAI_CSR_WSIE BIT(12) | 62 | #define FSL_SAI_CSR_WSIE BIT(12) |
52 | #define FSL_SAI_CSR_SEIE BIT(11) | 63 | #define FSL_SAI_CSR_SEIE BIT(11) |
53 | #define FSL_SAI_CSR_FEIE BIT(10) | 64 | #define FSL_SAI_CSR_FEIE BIT(10) |
@@ -108,6 +119,8 @@ | |||
108 | #define FSL_SAI_CLK_MAST2 2 | 119 | #define FSL_SAI_CLK_MAST2 2 |
109 | #define FSL_SAI_CLK_MAST3 3 | 120 | #define FSL_SAI_CLK_MAST3 3 |
110 | 121 | ||
122 | #define FSL_SAI_MCLK_MAX 3 | ||
123 | |||
111 | /* SAI data transfer numbers per DMA request */ | 124 | /* SAI data transfer numbers per DMA request */ |
112 | #define FSL_SAI_MAXBURST_TX 6 | 125 | #define FSL_SAI_MAXBURST_TX 6 |
113 | #define FSL_SAI_MAXBURST_RX 6 | 126 | #define FSL_SAI_MAXBURST_RX 6 |
@@ -115,10 +128,13 @@ | |||
115 | struct fsl_sai { | 128 | struct fsl_sai { |
116 | struct platform_device *pdev; | 129 | struct platform_device *pdev; |
117 | struct regmap *regmap; | 130 | struct regmap *regmap; |
131 | struct clk *bus_clk; | ||
132 | struct clk *mclk_clk[FSL_SAI_MCLK_MAX]; | ||
118 | 133 | ||
119 | bool big_endian_regs; | 134 | bool big_endian_regs; |
120 | bool big_endian_data; | 135 | bool big_endian_data; |
121 | bool is_dsp_mode; | 136 | bool is_dsp_mode; |
137 | bool sai_on_imx; | ||
122 | 138 | ||
123 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 139 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
124 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 140 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c index 6452ca83d889..b912d45a2a4c 100644 --- a/sound/soc/fsl/fsl_spdif.c +++ b/sound/soc/fsl/fsl_spdif.c | |||
@@ -13,18 +13,18 @@ | |||
13 | * kind, whether express or implied. | 13 | * kind, whether express or implied. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/bitrev.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/clk-private.h> | 18 | #include <linux/clk-private.h> |
19 | #include <linux/bitrev.h> | 19 | #include <linux/module.h> |
20 | #include <linux/regmap.h> | ||
21 | #include <linux/of_address.h> | 20 | #include <linux/of_address.h> |
22 | #include <linux/of_device.h> | 21 | #include <linux/of_device.h> |
23 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
23 | #include <linux/regmap.h> | ||
24 | 24 | ||
25 | #include <sound/asoundef.h> | 25 | #include <sound/asoundef.h> |
26 | #include <sound/soc.h> | ||
27 | #include <sound/dmaengine_pcm.h> | 26 | #include <sound/dmaengine_pcm.h> |
27 | #include <sound/soc.h> | ||
28 | 28 | ||
29 | #include "fsl_spdif.h" | 29 | #include "fsl_spdif.h" |
30 | #include "imx-pcm.h" | 30 | #include "imx-pcm.h" |
@@ -69,17 +69,42 @@ struct spdif_mixer_control { | |||
69 | u32 ready_buf; | 69 | u32 ready_buf; |
70 | }; | 70 | }; |
71 | 71 | ||
72 | /** | ||
73 | * fsl_spdif_priv: Freescale SPDIF private data | ||
74 | * | ||
75 | * @fsl_spdif_control: SPDIF control data | ||
76 | * @cpu_dai_drv: cpu dai driver | ||
77 | * @pdev: platform device pointer | ||
78 | * @regmap: regmap handler | ||
79 | * @dpll_locked: dpll lock flag | ||
80 | * @txrate: the best rates for playback | ||
81 | * @txclk_df: STC_TXCLK_DF dividers value for playback | ||
82 | * @sysclk_df: STC_SYSCLK_DF dividers value for playback | ||
83 | * @txclk_src: STC_TXCLK_SRC values for playback | ||
84 | * @rxclk_src: SRPC_CLKSRC_SEL values for capture | ||
85 | * @txclk: tx clock sources for playback | ||
86 | * @rxclk: rx clock sources for capture | ||
87 | * @coreclk: core clock for register access via DMA | ||
88 | * @sysclk: system clock for rx clock rate measurement | ||
89 | * @dma_params_tx: DMA parameters for transmit channel | ||
90 | * @dma_params_rx: DMA parameters for receive channel | ||
91 | * @name: driver name | ||
92 | */ | ||
72 | struct fsl_spdif_priv { | 93 | struct fsl_spdif_priv { |
73 | struct spdif_mixer_control fsl_spdif_control; | 94 | struct spdif_mixer_control fsl_spdif_control; |
74 | struct snd_soc_dai_driver cpu_dai_drv; | 95 | struct snd_soc_dai_driver cpu_dai_drv; |
75 | struct platform_device *pdev; | 96 | struct platform_device *pdev; |
76 | struct regmap *regmap; | 97 | struct regmap *regmap; |
77 | bool dpll_locked; | 98 | bool dpll_locked; |
78 | u8 txclk_div[SPDIF_TXRATE_MAX]; | 99 | u16 txrate[SPDIF_TXRATE_MAX]; |
100 | u8 txclk_df[SPDIF_TXRATE_MAX]; | ||
101 | u8 sysclk_df[SPDIF_TXRATE_MAX]; | ||
79 | u8 txclk_src[SPDIF_TXRATE_MAX]; | 102 | u8 txclk_src[SPDIF_TXRATE_MAX]; |
80 | u8 rxclk_src; | 103 | u8 rxclk_src; |
81 | struct clk *txclk[SPDIF_TXRATE_MAX]; | 104 | struct clk *txclk[SPDIF_TXRATE_MAX]; |
82 | struct clk *rxclk; | 105 | struct clk *rxclk; |
106 | struct clk *coreclk; | ||
107 | struct clk *sysclk; | ||
83 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 108 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
84 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 109 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
85 | 110 | ||
@@ -349,7 +374,7 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, | |||
349 | struct platform_device *pdev = spdif_priv->pdev; | 374 | struct platform_device *pdev = spdif_priv->pdev; |
350 | unsigned long csfs = 0; | 375 | unsigned long csfs = 0; |
351 | u32 stc, mask, rate; | 376 | u32 stc, mask, rate; |
352 | u8 clk, div; | 377 | u8 clk, txclk_df, sysclk_df; |
353 | int ret; | 378 | int ret; |
354 | 379 | ||
355 | switch (sample_rate) { | 380 | switch (sample_rate) { |
@@ -376,25 +401,31 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, | |||
376 | return -EINVAL; | 401 | return -EINVAL; |
377 | } | 402 | } |
378 | 403 | ||
379 | div = spdif_priv->txclk_div[rate]; | 404 | txclk_df = spdif_priv->txclk_df[rate]; |
380 | if (div == 0) { | 405 | if (txclk_df == 0) { |
381 | dev_err(&pdev->dev, "the divisor can't be zero\n"); | 406 | dev_err(&pdev->dev, "the txclk_df can't be zero\n"); |
382 | return -EINVAL; | 407 | return -EINVAL; |
383 | } | 408 | } |
384 | 409 | ||
410 | sysclk_df = spdif_priv->sysclk_df[rate]; | ||
411 | |||
412 | /* Don't mess up the clocks from other modules */ | ||
413 | if (clk != STC_TXCLK_SPDIF_ROOT) | ||
414 | goto clk_set_bypass; | ||
415 | |||
385 | /* | 416 | /* |
386 | * The S/PDIF block needs a clock of 64 * fs * div. The S/PDIF block | 417 | * The S/PDIF block needs a clock of 64 * fs * txclk_df. |
387 | * will divide by (div). So request 64 * fs * (div+1) which will | 418 | * So request 64 * fs * (txclk_df + 1) to get rounded. |
388 | * get rounded. | ||
389 | */ | 419 | */ |
390 | ret = clk_set_rate(spdif_priv->txclk[rate], 64 * sample_rate * (div + 1)); | 420 | ret = clk_set_rate(spdif_priv->txclk[rate], 64 * sample_rate * (txclk_df + 1)); |
391 | if (ret) { | 421 | if (ret) { |
392 | dev_err(&pdev->dev, "failed to set tx clock rate\n"); | 422 | dev_err(&pdev->dev, "failed to set tx clock rate\n"); |
393 | return ret; | 423 | return ret; |
394 | } | 424 | } |
395 | 425 | ||
426 | clk_set_bypass: | ||
396 | dev_dbg(&pdev->dev, "expected clock rate = %d\n", | 427 | dev_dbg(&pdev->dev, "expected clock rate = %d\n", |
397 | (64 * sample_rate * div)); | 428 | (64 * sample_rate * txclk_df * sysclk_df)); |
398 | dev_dbg(&pdev->dev, "actual clock rate = %ld\n", | 429 | dev_dbg(&pdev->dev, "actual clock rate = %ld\n", |
399 | clk_get_rate(spdif_priv->txclk[rate])); | 430 | clk_get_rate(spdif_priv->txclk[rate])); |
400 | 431 | ||
@@ -402,11 +433,15 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream, | |||
402 | spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs); | 433 | spdif_set_cstatus(ctrl, IEC958_AES3_CON_FS, csfs); |
403 | 434 | ||
404 | /* select clock source and divisor */ | 435 | /* select clock source and divisor */ |
405 | stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DIV(div); | 436 | stc = STC_TXCLK_ALL_EN | STC_TXCLK_SRC_SET(clk) | STC_TXCLK_DF(txclk_df); |
406 | mask = STC_TXCLK_ALL_EN_MASK | STC_TXCLK_SRC_MASK | STC_TXCLK_DIV_MASK; | 437 | mask = STC_TXCLK_ALL_EN_MASK | STC_TXCLK_SRC_MASK | STC_TXCLK_DF_MASK; |
407 | regmap_update_bits(regmap, REG_SPDIF_STC, mask, stc); | 438 | regmap_update_bits(regmap, REG_SPDIF_STC, mask, stc); |
408 | 439 | ||
409 | dev_dbg(&pdev->dev, "set sample rate to %d\n", sample_rate); | 440 | regmap_update_bits(regmap, REG_SPDIF_STC, |
441 | STC_SYSCLK_DF_MASK, STC_SYSCLK_DF(sysclk_df)); | ||
442 | |||
443 | dev_dbg(&pdev->dev, "set sample rate to %dHz for %dHz playback\n", | ||
444 | spdif_priv->txrate[rate], sample_rate); | ||
410 | 445 | ||
411 | return 0; | 446 | return 0; |
412 | } | 447 | } |
@@ -423,10 +458,16 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream, | |||
423 | 458 | ||
424 | /* Reset module and interrupts only for first initialization */ | 459 | /* Reset module and interrupts only for first initialization */ |
425 | if (!cpu_dai->active) { | 460 | if (!cpu_dai->active) { |
461 | ret = clk_prepare_enable(spdif_priv->coreclk); | ||
462 | if (ret) { | ||
463 | dev_err(&pdev->dev, "failed to enable core clock\n"); | ||
464 | return ret; | ||
465 | } | ||
466 | |||
426 | ret = spdif_softreset(spdif_priv); | 467 | ret = spdif_softreset(spdif_priv); |
427 | if (ret) { | 468 | if (ret) { |
428 | dev_err(&pdev->dev, "failed to soft reset\n"); | 469 | dev_err(&pdev->dev, "failed to soft reset\n"); |
429 | return ret; | 470 | goto err; |
430 | } | 471 | } |
431 | 472 | ||
432 | /* Disable all the interrupts */ | 473 | /* Disable all the interrupts */ |
@@ -454,6 +495,11 @@ static int fsl_spdif_startup(struct snd_pcm_substream *substream, | |||
454 | regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0); | 495 | regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0); |
455 | 496 | ||
456 | return 0; | 497 | return 0; |
498 | |||
499 | err: | ||
500 | clk_disable_unprepare(spdif_priv->coreclk); | ||
501 | |||
502 | return ret; | ||
457 | } | 503 | } |
458 | 504 | ||
459 | static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, | 505 | static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, |
@@ -484,6 +530,7 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream *substream, | |||
484 | spdif_intr_status_clear(spdif_priv); | 530 | spdif_intr_status_clear(spdif_priv); |
485 | regmap_update_bits(regmap, REG_SPDIF_SCR, | 531 | regmap_update_bits(regmap, REG_SPDIF_SCR, |
486 | SCR_LOW_POWER, SCR_LOW_POWER); | 532 | SCR_LOW_POWER, SCR_LOW_POWER); |
533 | clk_disable_unprepare(spdif_priv->coreclk); | ||
487 | } | 534 | } |
488 | } | 535 | } |
489 | 536 | ||
@@ -754,7 +801,7 @@ static int spdif_get_rxclk_rate(struct fsl_spdif_priv *spdif_priv, | |||
754 | clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf; | 801 | clksrc = (phaseconf >> SRPC_CLKSRC_SEL_OFFSET) & 0xf; |
755 | if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) { | 802 | if (srpc_dpll_locked[clksrc] && (phaseconf & SRPC_DPLL_LOCKED)) { |
756 | /* Get bus clock from system */ | 803 | /* Get bus clock from system */ |
757 | busclk_freq = clk_get_rate(spdif_priv->rxclk); | 804 | busclk_freq = clk_get_rate(spdif_priv->sysclk); |
758 | } | 805 | } |
759 | 806 | ||
760 | /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */ | 807 | /* FreqMeas_CLK = (BUS_CLK * FreqMeas) / 2 ^ 10 / GAINSEL / 128 */ |
@@ -997,43 +1044,61 @@ static struct regmap_config fsl_spdif_regmap_config = { | |||
997 | 1044 | ||
998 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, | 1045 | static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv *spdif_priv, |
999 | struct clk *clk, u64 savesub, | 1046 | struct clk *clk, u64 savesub, |
1000 | enum spdif_txrate index) | 1047 | enum spdif_txrate index, bool round) |
1001 | { | 1048 | { |
1002 | const u32 rate[] = { 32000, 44100, 48000 }; | 1049 | const u32 rate[] = { 32000, 44100, 48000 }; |
1050 | bool is_sysclk = clk == spdif_priv->sysclk; | ||
1003 | u64 rate_ideal, rate_actual, sub; | 1051 | u64 rate_ideal, rate_actual, sub; |
1004 | u32 div, arate; | 1052 | u32 sysclk_dfmin, sysclk_dfmax; |
1005 | 1053 | u32 txclk_df, sysclk_df, arate; | |
1006 | for (div = 1; div <= 128; div++) { | 1054 | |
1007 | rate_ideal = rate[index] * (div + 1) * 64; | 1055 | /* The sysclk has an extra divisor [2, 512] */ |
1008 | rate_actual = clk_round_rate(clk, rate_ideal); | 1056 | sysclk_dfmin = is_sysclk ? 2 : 1; |
1009 | 1057 | sysclk_dfmax = is_sysclk ? 512 : 1; | |
1010 | arate = rate_actual / 64; | 1058 | |
1011 | arate /= div; | 1059 | for (sysclk_df = sysclk_dfmin; sysclk_df <= sysclk_dfmax; sysclk_df++) { |
1012 | 1060 | for (txclk_df = 1; txclk_df <= 128; txclk_df++) { | |
1013 | if (arate == rate[index]) { | 1061 | rate_ideal = rate[index] * (txclk_df + 1) * 64; |
1014 | /* We are lucky */ | 1062 | if (round) |
1015 | savesub = 0; | 1063 | rate_actual = clk_round_rate(clk, rate_ideal); |
1016 | spdif_priv->txclk_div[index] = div; | 1064 | else |
1017 | break; | 1065 | rate_actual = clk_get_rate(clk); |
1018 | } else if (arate / rate[index] == 1) { | 1066 | |
1019 | /* A little bigger than expect */ | 1067 | arate = rate_actual / 64; |
1020 | sub = (arate - rate[index]) * 100000; | 1068 | arate /= txclk_df * sysclk_df; |
1021 | do_div(sub, rate[index]); | 1069 | |
1022 | if (sub < savesub) { | 1070 | if (arate == rate[index]) { |
1071 | /* We are lucky */ | ||
1072 | savesub = 0; | ||
1073 | spdif_priv->txclk_df[index] = txclk_df; | ||
1074 | spdif_priv->sysclk_df[index] = sysclk_df; | ||
1075 | spdif_priv->txrate[index] = arate; | ||
1076 | goto out; | ||
1077 | } else if (arate / rate[index] == 1) { | ||
1078 | /* A little bigger than expect */ | ||
1079 | sub = (arate - rate[index]) * 100000; | ||
1080 | do_div(sub, rate[index]); | ||
1081 | if (sub >= savesub) | ||
1082 | continue; | ||
1023 | savesub = sub; | 1083 | savesub = sub; |
1024 | spdif_priv->txclk_div[index] = div; | 1084 | spdif_priv->txclk_df[index] = txclk_df; |
1025 | } | 1085 | spdif_priv->sysclk_df[index] = sysclk_df; |
1026 | } else if (rate[index] / arate == 1) { | 1086 | spdif_priv->txrate[index] = arate; |
1027 | /* A little smaller than expect */ | 1087 | } else if (rate[index] / arate == 1) { |
1028 | sub = (rate[index] - arate) * 100000; | 1088 | /* A little smaller than expect */ |
1029 | do_div(sub, rate[index]); | 1089 | sub = (rate[index] - arate) * 100000; |
1030 | if (sub < savesub) { | 1090 | do_div(sub, rate[index]); |
1091 | if (sub >= savesub) | ||
1092 | continue; | ||
1031 | savesub = sub; | 1093 | savesub = sub; |
1032 | spdif_priv->txclk_div[index] = div; | 1094 | spdif_priv->txclk_df[index] = txclk_df; |
1095 | spdif_priv->sysclk_df[index] = sysclk_df; | ||
1096 | spdif_priv->txrate[index] = arate; | ||
1033 | } | 1097 | } |
1034 | } | 1098 | } |
1035 | } | 1099 | } |
1036 | 1100 | ||
1101 | out: | ||
1037 | return savesub; | 1102 | return savesub; |
1038 | } | 1103 | } |
1039 | 1104 | ||
@@ -1058,7 +1123,8 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, | |||
1058 | if (!clk_get_rate(clk)) | 1123 | if (!clk_get_rate(clk)) |
1059 | continue; | 1124 | continue; |
1060 | 1125 | ||
1061 | ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index); | 1126 | ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index, |
1127 | i == STC_TXCLK_SPDIF_ROOT); | ||
1062 | if (savesub == ret) | 1128 | if (savesub == ret) |
1063 | continue; | 1129 | continue; |
1064 | 1130 | ||
@@ -1073,8 +1139,13 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv, | |||
1073 | 1139 | ||
1074 | dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", | 1140 | dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", |
1075 | spdif_priv->txclk_src[index], rate[index]); | 1141 | spdif_priv->txclk_src[index], rate[index]); |
1076 | dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate\n", | 1142 | dev_dbg(&pdev->dev, "use txclk df %d for %dHz sample rate\n", |
1077 | spdif_priv->txclk_div[index], rate[index]); | 1143 | spdif_priv->txclk_df[index], rate[index]); |
1144 | if (spdif_priv->txclk[index] == spdif_priv->sysclk) | ||
1145 | dev_dbg(&pdev->dev, "use sysclk df %d for %dHz sample rate\n", | ||
1146 | spdif_priv->sysclk_df[index], rate[index]); | ||
1147 | dev_dbg(&pdev->dev, "the best rate for %dHz sample rate is %dHz\n", | ||
1148 | rate[index], spdif_priv->txrate[index]); | ||
1078 | 1149 | ||
1079 | return 0; | 1150 | return 0; |
1080 | } | 1151 | } |
@@ -1134,6 +1205,20 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1134 | return ret; | 1205 | return ret; |
1135 | } | 1206 | } |
1136 | 1207 | ||
1208 | /* Get system clock for rx clock rate calculation */ | ||
1209 | spdif_priv->sysclk = devm_clk_get(&pdev->dev, "rxtx5"); | ||
1210 | if (IS_ERR(spdif_priv->sysclk)) { | ||
1211 | dev_err(&pdev->dev, "no sys clock (rxtx5) in devicetree\n"); | ||
1212 | return PTR_ERR(spdif_priv->sysclk); | ||
1213 | } | ||
1214 | |||
1215 | /* Get core clock for data register access via DMA */ | ||
1216 | spdif_priv->coreclk = devm_clk_get(&pdev->dev, "core"); | ||
1217 | if (IS_ERR(spdif_priv->coreclk)) { | ||
1218 | dev_err(&pdev->dev, "no core clock in devicetree\n"); | ||
1219 | return PTR_ERR(spdif_priv->coreclk); | ||
1220 | } | ||
1221 | |||
1137 | /* Select clock source for rx/tx clock */ | 1222 | /* Select clock source for rx/tx clock */ |
1138 | spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); | 1223 | spdif_priv->rxclk = devm_clk_get(&pdev->dev, "rxtx1"); |
1139 | if (IS_ERR(spdif_priv->rxclk)) { | 1224 | if (IS_ERR(spdif_priv->rxclk)) { |
@@ -1186,6 +1271,7 @@ static int fsl_spdif_probe(struct platform_device *pdev) | |||
1186 | 1271 | ||
1187 | static const struct of_device_id fsl_spdif_dt_ids[] = { | 1272 | static const struct of_device_id fsl_spdif_dt_ids[] = { |
1188 | { .compatible = "fsl,imx35-spdif", }, | 1273 | { .compatible = "fsl,imx35-spdif", }, |
1274 | { .compatible = "fsl,vf610-spdif", }, | ||
1189 | {} | 1275 | {} |
1190 | }; | 1276 | }; |
1191 | MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids); | 1277 | MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids); |
diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h index 605a10b2112b..16fde4b927d3 100644 --- a/sound/soc/fsl/fsl_spdif.h +++ b/sound/soc/fsl/fsl_spdif.h | |||
@@ -143,20 +143,22 @@ enum spdif_gainsel { | |||
143 | #define INT_RXFIFO_FUL (1 << 0) | 143 | #define INT_RXFIFO_FUL (1 << 0) |
144 | 144 | ||
145 | /* SPDIF Clock register */ | 145 | /* SPDIF Clock register */ |
146 | #define STC_SYSCLK_DIV_OFFSET 11 | 146 | #define STC_SYSCLK_DF_OFFSET 11 |
147 | #define STC_SYSCLK_DIV_MASK (0x1ff << STC_SYSCLK_DIV_OFFSET) | 147 | #define STC_SYSCLK_DF_MASK (0x1ff << STC_SYSCLK_DF_OFFSET) |
148 | #define STC_SYSCLK_DIV(x) ((((x) - 1) << STC_SYSCLK_DIV_OFFSET) & STC_SYSCLK_DIV_MASK) | 148 | #define STC_SYSCLK_DF(x) ((((x) - 1) << STC_SYSCLK_DF_OFFSET) & STC_SYSCLK_DF_MASK) |
149 | #define STC_TXCLK_SRC_OFFSET 8 | 149 | #define STC_TXCLK_SRC_OFFSET 8 |
150 | #define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET) | 150 | #define STC_TXCLK_SRC_MASK (0x7 << STC_TXCLK_SRC_OFFSET) |
151 | #define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK) | 151 | #define STC_TXCLK_SRC_SET(x) ((x << STC_TXCLK_SRC_OFFSET) & STC_TXCLK_SRC_MASK) |
152 | #define STC_TXCLK_ALL_EN_OFFSET 7 | 152 | #define STC_TXCLK_ALL_EN_OFFSET 7 |
153 | #define STC_TXCLK_ALL_EN_MASK (1 << STC_TXCLK_ALL_EN_OFFSET) | 153 | #define STC_TXCLK_ALL_EN_MASK (1 << STC_TXCLK_ALL_EN_OFFSET) |
154 | #define STC_TXCLK_ALL_EN (1 << STC_TXCLK_ALL_EN_OFFSET) | 154 | #define STC_TXCLK_ALL_EN (1 << STC_TXCLK_ALL_EN_OFFSET) |
155 | #define STC_TXCLK_DIV_OFFSET 0 | 155 | #define STC_TXCLK_DF_OFFSET 0 |
156 | #define STC_TXCLK_DIV_MASK (0x7ff << STC_TXCLK_DIV_OFFSET) | 156 | #define STC_TXCLK_DF_MASK (0x7ff << STC_TXCLK_DF_OFFSET) |
157 | #define STC_TXCLK_DIV(x) ((((x) - 1) << STC_TXCLK_DIV_OFFSET) & STC_TXCLK_DIV_MASK) | 157 | #define STC_TXCLK_DF(x) ((((x) - 1) << STC_TXCLK_DF_OFFSET) & STC_TXCLK_DF_MASK) |
158 | #define STC_TXCLK_SRC_MAX 8 | 158 | #define STC_TXCLK_SRC_MAX 8 |
159 | 159 | ||
160 | #define STC_TXCLK_SPDIF_ROOT 1 | ||
161 | |||
160 | /* SPDIF tx rate */ | 162 | /* SPDIF tx rate */ |
161 | enum spdif_txrate { | 163 | enum spdif_txrate { |
162 | SPDIF_TXRATE_32000 = 0, | 164 | SPDIF_TXRATE_32000 = 0, |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 5428a1fda260..f233d915b7e4 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -35,11 +35,11 @@ | |||
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
37 | #include <linux/clk.h> | 37 | #include <linux/clk.h> |
38 | #include <linux/debugfs.h> | ||
39 | #include <linux/device.h> | 38 | #include <linux/device.h> |
40 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
41 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
42 | #include <linux/spinlock.h> | 41 | #include <linux/spinlock.h> |
42 | #include <linux/of.h> | ||
43 | #include <linux/of_address.h> | 43 | #include <linux/of_address.h> |
44 | #include <linux/of_irq.h> | 44 | #include <linux/of_irq.h> |
45 | #include <linux/of_platform.h> | 45 | #include <linux/of_platform.h> |
@@ -113,8 +113,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set) | |||
113 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ | 113 | #define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \ |
114 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ | 114 | CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \ |
115 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) | 115 | CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN) |
116 | #define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS) | ||
117 | |||
118 | 116 | ||
119 | enum fsl_ssi_type { | 117 | enum fsl_ssi_type { |
120 | FSL_SSI_MCP8610, | 118 | FSL_SSI_MCP8610, |
@@ -146,7 +144,6 @@ struct fsl_ssi_rxtx_reg_val { | |||
146 | * @cpu_dai: the CPU DAI for this device | 144 | * @cpu_dai: the CPU DAI for this device |
147 | * @dev_attr: the sysfs device attribute structure | 145 | * @dev_attr: the sysfs device attribute structure |
148 | * @stats: SSI statistics | 146 | * @stats: SSI statistics |
149 | * @name: name for this device | ||
150 | */ | 147 | */ |
151 | struct fsl_ssi_private { | 148 | struct fsl_ssi_private { |
152 | struct ccsr_ssi __iomem *ssi; | 149 | struct ccsr_ssi __iomem *ssi; |
@@ -155,15 +152,11 @@ struct fsl_ssi_private { | |||
155 | unsigned int fifo_depth; | 152 | unsigned int fifo_depth; |
156 | struct snd_soc_dai_driver cpu_dai_drv; | 153 | struct snd_soc_dai_driver cpu_dai_drv; |
157 | struct platform_device *pdev; | 154 | struct platform_device *pdev; |
155 | unsigned int dai_fmt; | ||
158 | 156 | ||
159 | enum fsl_ssi_type hw_type; | 157 | enum fsl_ssi_type hw_type; |
160 | bool new_binding; | ||
161 | bool ssi_on_imx; | ||
162 | bool imx_ac97; | ||
163 | bool use_dma; | 158 | bool use_dma; |
164 | bool baudclk_locked; | 159 | bool baudclk_locked; |
165 | bool irq_stats; | ||
166 | bool offline_config; | ||
167 | bool use_dual_fifo; | 160 | bool use_dual_fifo; |
168 | u8 i2s_mode; | 161 | u8 i2s_mode; |
169 | spinlock_t baudclk_lock; | 162 | spinlock_t baudclk_lock; |
@@ -171,39 +164,11 @@ struct fsl_ssi_private { | |||
171 | struct clk *clk; | 164 | struct clk *clk; |
172 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 165 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
173 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 166 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
174 | struct imx_dma_data filter_data_tx; | ||
175 | struct imx_dma_data filter_data_rx; | ||
176 | struct imx_pcm_fiq_params fiq_params; | 167 | struct imx_pcm_fiq_params fiq_params; |
177 | /* Register values for rx/tx configuration */ | 168 | /* Register values for rx/tx configuration */ |
178 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; | 169 | struct fsl_ssi_rxtx_reg_val rxtx_reg_val; |
179 | 170 | ||
180 | struct { | 171 | struct fsl_ssi_dbg dbg_stats; |
181 | unsigned int rfrc; | ||
182 | unsigned int tfrc; | ||
183 | unsigned int cmdau; | ||
184 | unsigned int cmddu; | ||
185 | unsigned int rxt; | ||
186 | unsigned int rdr1; | ||
187 | unsigned int rdr0; | ||
188 | unsigned int tde1; | ||
189 | unsigned int tde0; | ||
190 | unsigned int roe1; | ||
191 | unsigned int roe0; | ||
192 | unsigned int tue1; | ||
193 | unsigned int tue0; | ||
194 | unsigned int tfs; | ||
195 | unsigned int rfs; | ||
196 | unsigned int tls; | ||
197 | unsigned int rls; | ||
198 | unsigned int rff1; | ||
199 | unsigned int rff0; | ||
200 | unsigned int tfe1; | ||
201 | unsigned int tfe0; | ||
202 | } stats; | ||
203 | struct dentry *dbg_dir; | ||
204 | struct dentry *dbg_stats; | ||
205 | |||
206 | char name[1]; | ||
207 | }; | 172 | }; |
208 | 173 | ||
209 | static const struct of_device_id fsl_ssi_ids[] = { | 174 | static const struct of_device_id fsl_ssi_ids[] = { |
@@ -215,6 +180,54 @@ static const struct of_device_id fsl_ssi_ids[] = { | |||
215 | }; | 180 | }; |
216 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); | 181 | MODULE_DEVICE_TABLE(of, fsl_ssi_ids); |
217 | 182 | ||
183 | static bool fsl_ssi_is_ac97(struct fsl_ssi_private *ssi_private) | ||
184 | { | ||
185 | return !!(ssi_private->dai_fmt & SND_SOC_DAIFMT_AC97); | ||
186 | } | ||
187 | |||
188 | static bool fsl_ssi_on_imx(struct fsl_ssi_private *ssi_private) | ||
189 | { | ||
190 | switch (ssi_private->hw_type) { | ||
191 | case FSL_SSI_MX21: | ||
192 | case FSL_SSI_MX35: | ||
193 | case FSL_SSI_MX51: | ||
194 | return true; | ||
195 | case FSL_SSI_MCP8610: | ||
196 | return false; | ||
197 | } | ||
198 | |||
199 | return false; | ||
200 | } | ||
201 | |||
202 | /* | ||
203 | * imx51 and later SoCs have a slightly different IP that allows the | ||
204 | * SSI configuration while the SSI unit is running. | ||
205 | * | ||
206 | * More important, it is necessary on those SoCs to configure the | ||
207 | * sperate TX/RX DMA bits just before starting the stream | ||
208 | * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi | ||
209 | * sends any DMA requests to the SDMA unit, otherwise it is not defined | ||
210 | * how the SDMA unit handles the DMA request. | ||
211 | * | ||
212 | * SDMA units are present on devices starting at imx35 but the imx35 | ||
213 | * reference manual states that the DMA bits should not be changed | ||
214 | * while the SSI unit is running (SSIEN). So we support the necessary | ||
215 | * online configuration of fsl-ssi starting at imx51. | ||
216 | */ | ||
217 | static bool fsl_ssi_offline_config(struct fsl_ssi_private *ssi_private) | ||
218 | { | ||
219 | switch (ssi_private->hw_type) { | ||
220 | case FSL_SSI_MCP8610: | ||
221 | case FSL_SSI_MX21: | ||
222 | case FSL_SSI_MX35: | ||
223 | return true; | ||
224 | case FSL_SSI_MX51: | ||
225 | return false; | ||
226 | } | ||
227 | |||
228 | return true; | ||
229 | } | ||
230 | |||
218 | /** | 231 | /** |
219 | * fsl_ssi_isr: SSI interrupt handler | 232 | * fsl_ssi_isr: SSI interrupt handler |
220 | * | 233 | * |
@@ -231,7 +244,6 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
231 | { | 244 | { |
232 | struct fsl_ssi_private *ssi_private = dev_id; | 245 | struct fsl_ssi_private *ssi_private = dev_id; |
233 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 246 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
234 | irqreturn_t ret = IRQ_NONE; | ||
235 | __be32 sisr; | 247 | __be32 sisr; |
236 | __be32 sisr2; | 248 | __be32 sisr2; |
237 | __be32 sisr_write_mask = 0; | 249 | __be32 sisr_write_mask = 0; |
@@ -258,217 +270,18 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id) | |||
258 | were interrupted for. We mask it with the Interrupt Enable register | 270 | were interrupted for. We mask it with the Interrupt Enable register |
259 | so that we only check for events that we're interested in. | 271 | so that we only check for events that we're interested in. |
260 | */ | 272 | */ |
261 | sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK; | 273 | sisr = read_ssi(&ssi->sisr); |
262 | |||
263 | if (sisr & CCSR_SSI_SISR_RFRC) { | ||
264 | ssi_private->stats.rfrc++; | ||
265 | ret = IRQ_HANDLED; | ||
266 | } | ||
267 | |||
268 | if (sisr & CCSR_SSI_SISR_TFRC) { | ||
269 | ssi_private->stats.tfrc++; | ||
270 | ret = IRQ_HANDLED; | ||
271 | } | ||
272 | |||
273 | if (sisr & CCSR_SSI_SISR_CMDAU) { | ||
274 | ssi_private->stats.cmdau++; | ||
275 | ret = IRQ_HANDLED; | ||
276 | } | ||
277 | |||
278 | if (sisr & CCSR_SSI_SISR_CMDDU) { | ||
279 | ssi_private->stats.cmddu++; | ||
280 | ret = IRQ_HANDLED; | ||
281 | } | ||
282 | |||
283 | if (sisr & CCSR_SSI_SISR_RXT) { | ||
284 | ssi_private->stats.rxt++; | ||
285 | ret = IRQ_HANDLED; | ||
286 | } | ||
287 | |||
288 | if (sisr & CCSR_SSI_SISR_RDR1) { | ||
289 | ssi_private->stats.rdr1++; | ||
290 | ret = IRQ_HANDLED; | ||
291 | } | ||
292 | |||
293 | if (sisr & CCSR_SSI_SISR_RDR0) { | ||
294 | ssi_private->stats.rdr0++; | ||
295 | ret = IRQ_HANDLED; | ||
296 | } | ||
297 | |||
298 | if (sisr & CCSR_SSI_SISR_TDE1) { | ||
299 | ssi_private->stats.tde1++; | ||
300 | ret = IRQ_HANDLED; | ||
301 | } | ||
302 | |||
303 | if (sisr & CCSR_SSI_SISR_TDE0) { | ||
304 | ssi_private->stats.tde0++; | ||
305 | ret = IRQ_HANDLED; | ||
306 | } | ||
307 | |||
308 | if (sisr & CCSR_SSI_SISR_ROE1) { | ||
309 | ssi_private->stats.roe1++; | ||
310 | ret = IRQ_HANDLED; | ||
311 | } | ||
312 | |||
313 | if (sisr & CCSR_SSI_SISR_ROE0) { | ||
314 | ssi_private->stats.roe0++; | ||
315 | ret = IRQ_HANDLED; | ||
316 | } | ||
317 | |||
318 | if (sisr & CCSR_SSI_SISR_TUE1) { | ||
319 | ssi_private->stats.tue1++; | ||
320 | ret = IRQ_HANDLED; | ||
321 | } | ||
322 | |||
323 | if (sisr & CCSR_SSI_SISR_TUE0) { | ||
324 | ssi_private->stats.tue0++; | ||
325 | ret = IRQ_HANDLED; | ||
326 | } | ||
327 | |||
328 | if (sisr & CCSR_SSI_SISR_TFS) { | ||
329 | ssi_private->stats.tfs++; | ||
330 | ret = IRQ_HANDLED; | ||
331 | } | ||
332 | |||
333 | if (sisr & CCSR_SSI_SISR_RFS) { | ||
334 | ssi_private->stats.rfs++; | ||
335 | ret = IRQ_HANDLED; | ||
336 | } | ||
337 | |||
338 | if (sisr & CCSR_SSI_SISR_TLS) { | ||
339 | ssi_private->stats.tls++; | ||
340 | ret = IRQ_HANDLED; | ||
341 | } | ||
342 | |||
343 | if (sisr & CCSR_SSI_SISR_RLS) { | ||
344 | ssi_private->stats.rls++; | ||
345 | ret = IRQ_HANDLED; | ||
346 | } | ||
347 | |||
348 | if (sisr & CCSR_SSI_SISR_RFF1) { | ||
349 | ssi_private->stats.rff1++; | ||
350 | ret = IRQ_HANDLED; | ||
351 | } | ||
352 | |||
353 | if (sisr & CCSR_SSI_SISR_RFF0) { | ||
354 | ssi_private->stats.rff0++; | ||
355 | ret = IRQ_HANDLED; | ||
356 | } | ||
357 | |||
358 | if (sisr & CCSR_SSI_SISR_TFE1) { | ||
359 | ssi_private->stats.tfe1++; | ||
360 | ret = IRQ_HANDLED; | ||
361 | } | ||
362 | |||
363 | if (sisr & CCSR_SSI_SISR_TFE0) { | ||
364 | ssi_private->stats.tfe0++; | ||
365 | ret = IRQ_HANDLED; | ||
366 | } | ||
367 | 274 | ||
368 | sisr2 = sisr & sisr_write_mask; | 275 | sisr2 = sisr & sisr_write_mask; |
369 | /* Clear the bits that we set */ | 276 | /* Clear the bits that we set */ |
370 | if (sisr2) | 277 | if (sisr2) |
371 | write_ssi(sisr2, &ssi->sisr); | 278 | write_ssi(sisr2, &ssi->sisr); |
372 | 279 | ||
373 | return ret; | 280 | fsl_ssi_dbg_isr(&ssi_private->dbg_stats, sisr); |
374 | } | ||
375 | |||
376 | #if IS_ENABLED(CONFIG_DEBUG_FS) | ||
377 | /* Show the statistics of a flag only if its interrupt is enabled. The | ||
378 | * compiler will optimze this code to a no-op if the interrupt is not | ||
379 | * enabled. | ||
380 | */ | ||
381 | #define SIER_SHOW(flag, name) \ | ||
382 | do { \ | ||
383 | if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \ | ||
384 | seq_printf(s, #name "=%u\n", ssi_private->stats.name); \ | ||
385 | } while (0) | ||
386 | |||
387 | |||
388 | /** | ||
389 | * fsl_sysfs_ssi_show: display SSI statistics | ||
390 | * | ||
391 | * Display the statistics for the current SSI device. To avoid confusion, | ||
392 | * we only show those counts that are enabled. | ||
393 | */ | ||
394 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) | ||
395 | { | ||
396 | struct fsl_ssi_private *ssi_private = s->private; | ||
397 | |||
398 | SIER_SHOW(RFRC_EN, rfrc); | ||
399 | SIER_SHOW(TFRC_EN, tfrc); | ||
400 | SIER_SHOW(CMDAU_EN, cmdau); | ||
401 | SIER_SHOW(CMDDU_EN, cmddu); | ||
402 | SIER_SHOW(RXT_EN, rxt); | ||
403 | SIER_SHOW(RDR1_EN, rdr1); | ||
404 | SIER_SHOW(RDR0_EN, rdr0); | ||
405 | SIER_SHOW(TDE1_EN, tde1); | ||
406 | SIER_SHOW(TDE0_EN, tde0); | ||
407 | SIER_SHOW(ROE1_EN, roe1); | ||
408 | SIER_SHOW(ROE0_EN, roe0); | ||
409 | SIER_SHOW(TUE1_EN, tue1); | ||
410 | SIER_SHOW(TUE0_EN, tue0); | ||
411 | SIER_SHOW(TFS_EN, tfs); | ||
412 | SIER_SHOW(RFS_EN, rfs); | ||
413 | SIER_SHOW(TLS_EN, tls); | ||
414 | SIER_SHOW(RLS_EN, rls); | ||
415 | SIER_SHOW(RFF1_EN, rff1); | ||
416 | SIER_SHOW(RFF0_EN, rff0); | ||
417 | SIER_SHOW(TFE1_EN, tfe1); | ||
418 | SIER_SHOW(TFE0_EN, tfe0); | ||
419 | 281 | ||
420 | return 0; | 282 | return IRQ_HANDLED; |
421 | } | 283 | } |
422 | 284 | ||
423 | static int fsl_ssi_stats_open(struct inode *inode, struct file *file) | ||
424 | { | ||
425 | return single_open(file, fsl_ssi_stats_show, inode->i_private); | ||
426 | } | ||
427 | |||
428 | static const struct file_operations fsl_ssi_stats_ops = { | ||
429 | .open = fsl_ssi_stats_open, | ||
430 | .read = seq_read, | ||
431 | .llseek = seq_lseek, | ||
432 | .release = single_release, | ||
433 | }; | ||
434 | |||
435 | static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, | ||
436 | struct device *dev) | ||
437 | { | ||
438 | ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL); | ||
439 | if (!ssi_private->dbg_dir) | ||
440 | return -ENOMEM; | ||
441 | |||
442 | ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO, | ||
443 | ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops); | ||
444 | if (!ssi_private->dbg_stats) { | ||
445 | debugfs_remove(ssi_private->dbg_dir); | ||
446 | return -ENOMEM; | ||
447 | } | ||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) | ||
453 | { | ||
454 | debugfs_remove(ssi_private->dbg_stats); | ||
455 | debugfs_remove(ssi_private->dbg_dir); | ||
456 | } | ||
457 | |||
458 | #else | ||
459 | |||
460 | static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private, | ||
461 | struct device *dev) | ||
462 | { | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private) | ||
467 | { | ||
468 | } | ||
469 | |||
470 | #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ | ||
471 | |||
472 | /* | 285 | /* |
473 | * Enable/Disable all rx/tx config flags at once. | 286 | * Enable/Disable all rx/tx config flags at once. |
474 | */ | 287 | */ |
@@ -490,6 +303,26 @@ static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private, | |||
490 | } | 303 | } |
491 | 304 | ||
492 | /* | 305 | /* |
306 | * Calculate the bits that have to be disabled for the current stream that is | ||
307 | * getting disabled. This keeps the bits enabled that are necessary for the | ||
308 | * second stream to work if 'stream_active' is true. | ||
309 | * | ||
310 | * Detailed calculation: | ||
311 | * These are the values that need to be active after disabling. For non-active | ||
312 | * second stream, this is 0: | ||
313 | * vals_stream * !!stream_active | ||
314 | * | ||
315 | * The following computes the overall differences between the setup for the | ||
316 | * to-disable stream and the active stream, a simple XOR: | ||
317 | * vals_disable ^ (vals_stream * !!(stream_active)) | ||
318 | * | ||
319 | * The full expression adds a mask on all values we care about | ||
320 | */ | ||
321 | #define fsl_ssi_disable_val(vals_disable, vals_stream, stream_active) \ | ||
322 | ((vals_disable) & \ | ||
323 | ((vals_disable) ^ ((vals_stream) * (u32)!!(stream_active)))) | ||
324 | |||
325 | /* | ||
493 | * Enable/Disable a ssi configuration. You have to pass either | 326 | * Enable/Disable a ssi configuration. You have to pass either |
494 | * ssi_private->rxtx_reg_val.rx or tx as vals parameter. | 327 | * ssi_private->rxtx_reg_val.rx or tx as vals parameter. |
495 | */ | 328 | */ |
@@ -501,6 +334,12 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
501 | u32 scr_val = read_ssi(&ssi->scr); | 334 | u32 scr_val = read_ssi(&ssi->scr); |
502 | int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + | 335 | int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) + |
503 | !!(scr_val & CCSR_SSI_SCR_RE); | 336 | !!(scr_val & CCSR_SSI_SCR_RE); |
337 | int keep_active; | ||
338 | |||
339 | if (nr_active_streams - 1 > 0) | ||
340 | keep_active = 1; | ||
341 | else | ||
342 | keep_active = 0; | ||
504 | 343 | ||
505 | /* Find the other direction values rx or tx which we do not want to | 344 | /* Find the other direction values rx or tx which we do not want to |
506 | * modify */ | 345 | * modify */ |
@@ -511,7 +350,8 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
511 | 350 | ||
512 | /* If vals should be disabled, start with disabling the unit */ | 351 | /* If vals should be disabled, start with disabling the unit */ |
513 | if (!enable) { | 352 | if (!enable) { |
514 | u32 scr = vals->scr & (vals->scr ^ avals->scr); | 353 | u32 scr = fsl_ssi_disable_val(vals->scr, avals->scr, |
354 | keep_active); | ||
515 | write_ssi_mask(&ssi->scr, scr, 0); | 355 | write_ssi_mask(&ssi->scr, scr, 0); |
516 | } | 356 | } |
517 | 357 | ||
@@ -520,9 +360,9 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
520 | * reconfiguration, so we have to enable all necessary flags at once | 360 | * reconfiguration, so we have to enable all necessary flags at once |
521 | * even if we do not use them later (capture and playback configuration) | 361 | * even if we do not use them later (capture and playback configuration) |
522 | */ | 362 | */ |
523 | if (ssi_private->offline_config) { | 363 | if (fsl_ssi_offline_config(ssi_private)) { |
524 | if ((enable && !nr_active_streams) || | 364 | if ((enable && !nr_active_streams) || |
525 | (!enable && nr_active_streams == 1)) | 365 | (!enable && !keep_active)) |
526 | fsl_ssi_rxtx_config(ssi_private, enable); | 366 | fsl_ssi_rxtx_config(ssi_private, enable); |
527 | 367 | ||
528 | goto config_done; | 368 | goto config_done; |
@@ -551,9 +391,12 @@ static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable, | |||
551 | */ | 391 | */ |
552 | 392 | ||
553 | /* These assignments are simply vals without bits set in avals*/ | 393 | /* These assignments are simply vals without bits set in avals*/ |
554 | sier = vals->sier & (vals->sier ^ avals->sier); | 394 | sier = fsl_ssi_disable_val(vals->sier, avals->sier, |
555 | srcr = vals->srcr & (vals->srcr ^ avals->srcr); | 395 | keep_active); |
556 | stcr = vals->stcr & (vals->stcr ^ avals->stcr); | 396 | srcr = fsl_ssi_disable_val(vals->srcr, avals->srcr, |
397 | keep_active); | ||
398 | stcr = fsl_ssi_disable_val(vals->stcr, avals->stcr, | ||
399 | keep_active); | ||
557 | 400 | ||
558 | write_ssi_mask(&ssi->srcr, srcr, 0); | 401 | write_ssi_mask(&ssi->srcr, srcr, 0); |
559 | write_ssi_mask(&ssi->stcr, stcr, 0); | 402 | write_ssi_mask(&ssi->stcr, stcr, 0); |
@@ -593,7 +436,7 @@ static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private) | |||
593 | reg->tx.stcr = CCSR_SSI_STCR_TFEN0; | 436 | reg->tx.stcr = CCSR_SSI_STCR_TFEN0; |
594 | reg->tx.scr = 0; | 437 | reg->tx.scr = 0; |
595 | 438 | ||
596 | if (!ssi_private->imx_ac97) { | 439 | if (!fsl_ssi_is_ac97(ssi_private)) { |
597 | reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE; | 440 | reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE; |
598 | reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN; | 441 | reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN; |
599 | reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE; | 442 | reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE; |
@@ -642,96 +485,6 @@ static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) | |||
642 | write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); | 485 | write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); |
643 | } | 486 | } |
644 | 487 | ||
645 | static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) | ||
646 | { | ||
647 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
648 | u8 wm; | ||
649 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; | ||
650 | |||
651 | fsl_ssi_setup_reg_vals(ssi_private); | ||
652 | |||
653 | if (ssi_private->imx_ac97) | ||
654 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; | ||
655 | else | ||
656 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; | ||
657 | |||
658 | /* | ||
659 | * Section 16.5 of the MPC8610 reference manual says that the SSI needs | ||
660 | * to be disabled before updating the registers we set here. | ||
661 | */ | ||
662 | write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); | ||
663 | |||
664 | /* | ||
665 | * Program the SSI into I2S Slave Non-Network Synchronous mode. Also | ||
666 | * enable the transmit and receive FIFO. | ||
667 | * | ||
668 | * FIXME: Little-endian samples require a different shift dir | ||
669 | */ | ||
670 | write_ssi_mask(&ssi->scr, | ||
671 | CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, | ||
672 | CCSR_SSI_SCR_TFR_CLK_DIS | | ||
673 | ssi_private->i2s_mode | | ||
674 | (synchronous ? CCSR_SSI_SCR_SYN : 0)); | ||
675 | |||
676 | write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI | | ||
677 | CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr); | ||
678 | |||
679 | write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI | | ||
680 | CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr); | ||
681 | |||
682 | /* | ||
683 | * The DC and PM bits are only used if the SSI is the clock master. | ||
684 | */ | ||
685 | |||
686 | /* | ||
687 | * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't | ||
688 | * use FIFO 1. We program the transmit water to signal a DMA transfer | ||
689 | * if there are only two (or fewer) elements left in the FIFO. Two | ||
690 | * elements equals one frame (left channel, right channel). This value, | ||
691 | * however, depends on the depth of the transmit buffer. | ||
692 | * | ||
693 | * We set the watermark on the same level as the DMA burstsize. For | ||
694 | * fiq it is probably better to use the biggest possible watermark | ||
695 | * size. | ||
696 | */ | ||
697 | if (ssi_private->use_dma) | ||
698 | wm = ssi_private->fifo_depth - 2; | ||
699 | else | ||
700 | wm = ssi_private->fifo_depth; | ||
701 | |||
702 | write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | | ||
703 | CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), | ||
704 | &ssi->sfcsr); | ||
705 | |||
706 | /* | ||
707 | * For ac97 interrupts are enabled with the startup of the substream | ||
708 | * because it is also running without an active substream. Normally SSI | ||
709 | * is only enabled when there is a substream. | ||
710 | */ | ||
711 | if (ssi_private->imx_ac97) | ||
712 | fsl_ssi_setup_ac97(ssi_private); | ||
713 | |||
714 | /* | ||
715 | * Set a default slot number so that there is no need for those common | ||
716 | * cases like I2S mode to call the extra set_tdm_slot() any more. | ||
717 | */ | ||
718 | if (!ssi_private->imx_ac97) { | ||
719 | write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK, | ||
720 | CCSR_SSI_SxCCR_DC(2)); | ||
721 | write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK, | ||
722 | CCSR_SSI_SxCCR_DC(2)); | ||
723 | } | ||
724 | |||
725 | if (ssi_private->use_dual_fifo) { | ||
726 | write_ssi_mask(&ssi->srcr, 0, CCSR_SSI_SRCR_RFEN1); | ||
727 | write_ssi_mask(&ssi->stcr, 0, CCSR_SSI_STCR_TFEN1); | ||
728 | write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_TCH_EN); | ||
729 | } | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | |||
735 | /** | 488 | /** |
736 | * fsl_ssi_startup: create a new substream | 489 | * fsl_ssi_startup: create a new substream |
737 | * | 490 | * |
@@ -748,12 +501,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
748 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | 501 | snd_soc_dai_get_drvdata(rtd->cpu_dai); |
749 | unsigned long flags; | 502 | unsigned long flags; |
750 | 503 | ||
751 | /* First, we only do fsl_ssi_setup() when SSI is going to be active. | 504 | if (!dai->active && !fsl_ssi_is_ac97(ssi_private)) { |
752 | * Second, fsl_ssi_setup was already called by ac97_init earlier if | ||
753 | * the driver is in ac97 mode. | ||
754 | */ | ||
755 | if (!dai->active && !ssi_private->imx_ac97) { | ||
756 | fsl_ssi_setup(ssi_private); | ||
757 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | 505 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); |
758 | ssi_private->baudclk_locked = false; | 506 | ssi_private->baudclk_locked = false; |
759 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | 507 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); |
@@ -772,6 +520,102 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
772 | } | 520 | } |
773 | 521 | ||
774 | /** | 522 | /** |
523 | * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock | ||
524 | * | ||
525 | * Note: This function can be only called when using SSI as DAI master | ||
526 | * | ||
527 | * Quick instruction for parameters: | ||
528 | * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels | ||
529 | * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. | ||
530 | */ | ||
531 | static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | ||
532 | int clk_id, unsigned int freq, int dir) | ||
533 | { | ||
534 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | ||
535 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
536 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; | ||
537 | u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; | ||
538 | unsigned long flags, clkrate, baudrate, tmprate; | ||
539 | u64 sub, savesub = 100000; | ||
540 | |||
541 | /* Don't apply it to any non-baudclk circumstance */ | ||
542 | if (IS_ERR(ssi_private->baudclk)) | ||
543 | return -EINVAL; | ||
544 | |||
545 | /* It should be already enough to divide clock by setting pm alone */ | ||
546 | psr = 0; | ||
547 | div2 = 0; | ||
548 | |||
549 | factor = (div2 + 1) * (7 * psr + 1) * 2; | ||
550 | |||
551 | for (i = 0; i < 255; i++) { | ||
552 | /* The bclk rate must be smaller than 1/5 sysclk rate */ | ||
553 | if (factor * (i + 1) < 5) | ||
554 | continue; | ||
555 | |||
556 | tmprate = freq * factor * (i + 2); | ||
557 | clkrate = clk_round_rate(ssi_private->baudclk, tmprate); | ||
558 | |||
559 | do_div(clkrate, factor); | ||
560 | afreq = (u32)clkrate / (i + 1); | ||
561 | |||
562 | if (freq == afreq) | ||
563 | sub = 0; | ||
564 | else if (freq / afreq == 1) | ||
565 | sub = freq - afreq; | ||
566 | else if (afreq / freq == 1) | ||
567 | sub = afreq - freq; | ||
568 | else | ||
569 | continue; | ||
570 | |||
571 | /* Calculate the fraction */ | ||
572 | sub *= 100000; | ||
573 | do_div(sub, freq); | ||
574 | |||
575 | if (sub < savesub) { | ||
576 | baudrate = tmprate; | ||
577 | savesub = sub; | ||
578 | pm = i; | ||
579 | } | ||
580 | |||
581 | /* We are lucky */ | ||
582 | if (savesub == 0) | ||
583 | break; | ||
584 | } | ||
585 | |||
586 | /* No proper pm found if it is still remaining the initial value */ | ||
587 | if (pm == 999) { | ||
588 | dev_err(cpu_dai->dev, "failed to handle the required sysclk\n"); | ||
589 | return -EINVAL; | ||
590 | } | ||
591 | |||
592 | stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) | | ||
593 | (psr ? CCSR_SSI_SxCCR_PSR : 0); | ||
594 | mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | | ||
595 | CCSR_SSI_SxCCR_PSR; | ||
596 | |||
597 | if (dir == SND_SOC_CLOCK_OUT || synchronous) | ||
598 | write_ssi_mask(&ssi->stccr, mask, stccr); | ||
599 | else | ||
600 | write_ssi_mask(&ssi->srccr, mask, stccr); | ||
601 | |||
602 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | ||
603 | if (!ssi_private->baudclk_locked) { | ||
604 | ret = clk_set_rate(ssi_private->baudclk, baudrate); | ||
605 | if (ret) { | ||
606 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, | ||
607 | flags); | ||
608 | dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); | ||
609 | return -EINVAL; | ||
610 | } | ||
611 | ssi_private->baudclk_locked = true; | ||
612 | } | ||
613 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | ||
614 | |||
615 | return 0; | ||
616 | } | ||
617 | |||
618 | /** | ||
775 | * fsl_ssi_hw_params - program the sample size | 619 | * fsl_ssi_hw_params - program the sample size |
776 | * | 620 | * |
777 | * Most of the SSI registers have been programmed in the startup function, | 621 | * Most of the SSI registers have been programmed in the startup function, |
@@ -819,7 +663,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
819 | else | 663 | else |
820 | write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); | 664 | write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); |
821 | 665 | ||
822 | if (!ssi_private->imx_ac97) | 666 | if (!fsl_ssi_is_ac97(ssi_private)) |
823 | write_ssi_mask(&ssi->scr, | 667 | write_ssi_mask(&ssi->scr, |
824 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, | 668 | CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK, |
825 | channels == 1 ? 0 : ssi_private->i2s_mode); | 669 | channels == 1 ? 0 : ssi_private->i2s_mode); |
@@ -835,9 +679,14 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
835 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 679 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); |
836 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 680 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
837 | u32 strcr = 0, stcr, srcr, scr, mask; | 681 | u32 strcr = 0, stcr, srcr, scr, mask; |
682 | u8 wm; | ||
683 | |||
684 | ssi_private->dai_fmt = fmt; | ||
685 | |||
686 | fsl_ssi_setup_reg_vals(ssi_private); | ||
838 | 687 | ||
839 | scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); | 688 | scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK); |
840 | scr |= CCSR_SSI_SCR_NET; | 689 | scr |= CCSR_SSI_SCR_SYNC_TX_FS; |
841 | 690 | ||
842 | mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | | 691 | mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR | |
843 | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | | 692 | CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL | |
@@ -845,19 +694,19 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
845 | stcr = read_ssi(&ssi->stcr) & ~mask; | 694 | stcr = read_ssi(&ssi->stcr) & ~mask; |
846 | srcr = read_ssi(&ssi->srcr) & ~mask; | 695 | srcr = read_ssi(&ssi->srcr) & ~mask; |
847 | 696 | ||
697 | ssi_private->i2s_mode = CCSR_SSI_SCR_NET; | ||
848 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 698 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
849 | case SND_SOC_DAIFMT_I2S: | 699 | case SND_SOC_DAIFMT_I2S: |
850 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 700 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
851 | case SND_SOC_DAIFMT_CBS_CFS: | 701 | case SND_SOC_DAIFMT_CBS_CFS: |
852 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER; | 702 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_MASTER; |
853 | break; | 703 | break; |
854 | case SND_SOC_DAIFMT_CBM_CFM: | 704 | case SND_SOC_DAIFMT_CBM_CFM: |
855 | ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; | 705 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_SLAVE; |
856 | break; | 706 | break; |
857 | default: | 707 | default: |
858 | return -EINVAL; | 708 | return -EINVAL; |
859 | } | 709 | } |
860 | scr |= ssi_private->i2s_mode; | ||
861 | 710 | ||
862 | /* Data on rising edge of bclk, frame low, 1clk before data */ | 711 | /* Data on rising edge of bclk, frame low, 1clk before data */ |
863 | strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | | 712 | strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP | |
@@ -877,9 +726,13 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
877 | strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | | 726 | strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP | |
878 | CCSR_SSI_STCR_TXBIT0; | 727 | CCSR_SSI_STCR_TXBIT0; |
879 | break; | 728 | break; |
729 | case SND_SOC_DAIFMT_AC97: | ||
730 | ssi_private->i2s_mode |= CCSR_SSI_SCR_I2S_MODE_NORMAL; | ||
731 | break; | ||
880 | default: | 732 | default: |
881 | return -EINVAL; | 733 | return -EINVAL; |
882 | } | 734 | } |
735 | scr |= ssi_private->i2s_mode; | ||
883 | 736 | ||
884 | /* DAI clock inversion */ | 737 | /* DAI clock inversion */ |
885 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 738 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
@@ -929,99 +782,37 @@ static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | |||
929 | write_ssi(srcr, &ssi->srcr); | 782 | write_ssi(srcr, &ssi->srcr); |
930 | write_ssi(scr, &ssi->scr); | 783 | write_ssi(scr, &ssi->scr); |
931 | 784 | ||
932 | return 0; | 785 | /* |
933 | } | 786 | * Set the watermark for transmit FIFI 0 and receive FIFO 0. We don't |
934 | 787 | * use FIFO 1. We program the transmit water to signal a DMA transfer | |
935 | /** | 788 | * if there are only two (or fewer) elements left in the FIFO. Two |
936 | * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock | 789 | * elements equals one frame (left channel, right channel). This value, |
937 | * | 790 | * however, depends on the depth of the transmit buffer. |
938 | * Note: This function can be only called when using SSI as DAI master | 791 | * |
939 | * | 792 | * We set the watermark on the same level as the DMA burstsize. For |
940 | * Quick instruction for parameters: | 793 | * fiq it is probably better to use the biggest possible watermark |
941 | * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels | 794 | * size. |
942 | * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK. | 795 | */ |
943 | */ | 796 | if (ssi_private->use_dma) |
944 | static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | 797 | wm = ssi_private->fifo_depth - 2; |
945 | int clk_id, unsigned int freq, int dir) | 798 | else |
946 | { | 799 | wm = ssi_private->fifo_depth; |
947 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | ||
948 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
949 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret; | ||
950 | u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i; | ||
951 | unsigned long flags, clkrate, baudrate, tmprate; | ||
952 | u64 sub, savesub = 100000; | ||
953 | |||
954 | /* Don't apply it to any non-baudclk circumstance */ | ||
955 | if (IS_ERR(ssi_private->baudclk)) | ||
956 | return -EINVAL; | ||
957 | |||
958 | /* It should be already enough to divide clock by setting pm alone */ | ||
959 | psr = 0; | ||
960 | div2 = 0; | ||
961 | |||
962 | factor = (div2 + 1) * (7 * psr + 1) * 2; | ||
963 | |||
964 | for (i = 0; i < 255; i++) { | ||
965 | /* The bclk rate must be smaller than 1/5 sysclk rate */ | ||
966 | if (factor * (i + 1) < 5) | ||
967 | continue; | ||
968 | |||
969 | tmprate = freq * factor * (i + 2); | ||
970 | clkrate = clk_round_rate(ssi_private->baudclk, tmprate); | ||
971 | |||
972 | do_div(clkrate, factor); | ||
973 | afreq = (u32)clkrate / (i + 1); | ||
974 | |||
975 | if (freq == afreq) | ||
976 | sub = 0; | ||
977 | else if (freq / afreq == 1) | ||
978 | sub = freq - afreq; | ||
979 | else if (afreq / freq == 1) | ||
980 | sub = afreq - freq; | ||
981 | else | ||
982 | continue; | ||
983 | |||
984 | /* Calculate the fraction */ | ||
985 | sub *= 100000; | ||
986 | do_div(sub, freq); | ||
987 | |||
988 | if (sub < savesub) { | ||
989 | baudrate = tmprate; | ||
990 | savesub = sub; | ||
991 | pm = i; | ||
992 | } | ||
993 | 800 | ||
994 | /* We are lucky */ | 801 | write_ssi(CCSR_SSI_SFCSR_TFWM0(wm) | CCSR_SSI_SFCSR_RFWM0(wm) | |
995 | if (savesub == 0) | 802 | CCSR_SSI_SFCSR_TFWM1(wm) | CCSR_SSI_SFCSR_RFWM1(wm), |
996 | break; | 803 | &ssi->sfcsr); |
997 | } | ||
998 | 804 | ||
999 | /* No proper pm found if it is still remaining the initial value */ | 805 | if (ssi_private->use_dual_fifo) { |
1000 | if (pm == 999) { | 806 | write_ssi_mask(&ssi->srcr, CCSR_SSI_SRCR_RFEN1, |
1001 | dev_err(cpu_dai->dev, "failed to handle the required sysclk\n"); | 807 | CCSR_SSI_SRCR_RFEN1); |
1002 | return -EINVAL; | 808 | write_ssi_mask(&ssi->stcr, CCSR_SSI_STCR_TFEN1, |
809 | CCSR_SSI_STCR_TFEN1); | ||
810 | write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TCH_EN, | ||
811 | CCSR_SSI_SCR_TCH_EN); | ||
1003 | } | 812 | } |
1004 | 813 | ||
1005 | stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) | | 814 | if (fmt & SND_SOC_DAIFMT_AC97) |
1006 | (psr ? CCSR_SSI_SxCCR_PSR : 0); | 815 | fsl_ssi_setup_ac97(ssi_private); |
1007 | mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR; | ||
1008 | |||
1009 | if (dir == SND_SOC_CLOCK_OUT || synchronous) | ||
1010 | write_ssi_mask(&ssi->stccr, mask, stccr); | ||
1011 | else | ||
1012 | write_ssi_mask(&ssi->srccr, mask, stccr); | ||
1013 | |||
1014 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | ||
1015 | if (!ssi_private->baudclk_locked) { | ||
1016 | ret = clk_set_rate(ssi_private->baudclk, baudrate); | ||
1017 | if (ret) { | ||
1018 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | ||
1019 | dev_err(cpu_dai->dev, "failed to set baudclk rate\n"); | ||
1020 | return -EINVAL; | ||
1021 | } | ||
1022 | ssi_private->baudclk_locked = true; | ||
1023 | } | ||
1024 | spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); | ||
1025 | 816 | ||
1026 | return 0; | 817 | return 0; |
1027 | } | 818 | } |
@@ -1097,7 +888,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1097 | else | 888 | else |
1098 | fsl_ssi_rx_config(ssi_private, false); | 889 | fsl_ssi_rx_config(ssi_private, false); |
1099 | 890 | ||
1100 | if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & | 891 | if (!fsl_ssi_is_ac97(ssi_private) && (read_ssi(&ssi->scr) & |
1101 | (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { | 892 | (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { |
1102 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); | 893 | spin_lock_irqsave(&ssi_private->baudclk_lock, flags); |
1103 | ssi_private->baudclk_locked = false; | 894 | ssi_private->baudclk_locked = false; |
@@ -1109,7 +900,7 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
1109 | return -EINVAL; | 900 | return -EINVAL; |
1110 | } | 901 | } |
1111 | 902 | ||
1112 | if (ssi_private->imx_ac97) { | 903 | if (fsl_ssi_is_ac97(ssi_private)) { |
1113 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 904 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
1114 | write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor); | 905 | write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor); |
1115 | else | 906 | else |
@@ -1123,7 +914,7 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) | |||
1123 | { | 914 | { |
1124 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); | 915 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); |
1125 | 916 | ||
1126 | if (ssi_private->ssi_on_imx && ssi_private->use_dma) { | 917 | if (fsl_ssi_on_imx(ssi_private) && ssi_private->use_dma) { |
1127 | dai->playback_dma_data = &ssi_private->dma_params_tx; | 918 | dai->playback_dma_data = &ssi_private->dma_params_tx; |
1128 | dai->capture_dma_data = &ssi_private->dma_params_rx; | 919 | dai->capture_dma_data = &ssi_private->dma_params_rx; |
1129 | } | 920 | } |
@@ -1184,11 +975,6 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { | |||
1184 | 975 | ||
1185 | static struct fsl_ssi_private *fsl_ac97_data; | 976 | static struct fsl_ssi_private *fsl_ac97_data; |
1186 | 977 | ||
1187 | static void fsl_ssi_ac97_init(void) | ||
1188 | { | ||
1189 | fsl_ssi_setup(fsl_ac97_data); | ||
1190 | } | ||
1191 | |||
1192 | static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, | 978 | static void fsl_ssi_ac97_write(struct snd_ac97 *ac97, unsigned short reg, |
1193 | unsigned short val) | 979 | unsigned short val) |
1194 | { | 980 | { |
@@ -1251,11 +1037,107 @@ static void make_lowercase(char *s) | |||
1251 | } | 1037 | } |
1252 | } | 1038 | } |
1253 | 1039 | ||
1040 | static int fsl_ssi_imx_probe(struct platform_device *pdev, | ||
1041 | struct fsl_ssi_private *ssi_private, void __iomem *iomem) | ||
1042 | { | ||
1043 | struct device_node *np = pdev->dev.of_node; | ||
1044 | u32 dmas[4]; | ||
1045 | int ret; | ||
1046 | |||
1047 | ssi_private->clk = devm_clk_get(&pdev->dev, NULL); | ||
1048 | if (IS_ERR(ssi_private->clk)) { | ||
1049 | ret = PTR_ERR(ssi_private->clk); | ||
1050 | dev_err(&pdev->dev, "could not get clock: %d\n", ret); | ||
1051 | return ret; | ||
1052 | } | ||
1053 | |||
1054 | ret = clk_prepare_enable(ssi_private->clk); | ||
1055 | if (ret) { | ||
1056 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); | ||
1057 | return ret; | ||
1058 | } | ||
1059 | |||
1060 | /* For those SLAVE implementations, we ingore non-baudclk cases | ||
1061 | * and, instead, abandon MASTER mode that needs baud clock. | ||
1062 | */ | ||
1063 | ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); | ||
1064 | if (IS_ERR(ssi_private->baudclk)) | ||
1065 | dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", | ||
1066 | PTR_ERR(ssi_private->baudclk)); | ||
1067 | else | ||
1068 | clk_prepare_enable(ssi_private->baudclk); | ||
1069 | |||
1070 | /* | ||
1071 | * We have burstsize be "fifo_depth - 2" to match the SSI | ||
1072 | * watermark setting in fsl_ssi_startup(). | ||
1073 | */ | ||
1074 | ssi_private->dma_params_tx.maxburst = ssi_private->fifo_depth - 2; | ||
1075 | ssi_private->dma_params_rx.maxburst = ssi_private->fifo_depth - 2; | ||
1076 | ssi_private->dma_params_tx.addr = ssi_private->ssi_phys + | ||
1077 | offsetof(struct ccsr_ssi, stx0); | ||
1078 | ssi_private->dma_params_rx.addr = ssi_private->ssi_phys + | ||
1079 | offsetof(struct ccsr_ssi, srx0); | ||
1080 | |||
1081 | ret = !of_property_read_u32_array(np, "dmas", dmas, 4); | ||
1082 | if (ssi_private->use_dma && !ret && dmas[2] == IMX_DMATYPE_SSI_DUAL) { | ||
1083 | ssi_private->use_dual_fifo = true; | ||
1084 | /* When using dual fifo mode, we need to keep watermark | ||
1085 | * as even numbers due to dma script limitation. | ||
1086 | */ | ||
1087 | ssi_private->dma_params_tx.maxburst &= ~0x1; | ||
1088 | ssi_private->dma_params_rx.maxburst &= ~0x1; | ||
1089 | } | ||
1090 | |||
1091 | if (!ssi_private->use_dma) { | ||
1092 | |||
1093 | /* | ||
1094 | * Some boards use an incompatible codec. To get it | ||
1095 | * working, we are using imx-fiq-pcm-audio, that | ||
1096 | * can handle those codecs. DMA is not possible in this | ||
1097 | * situation. | ||
1098 | */ | ||
1099 | |||
1100 | ssi_private->fiq_params.irq = ssi_private->irq; | ||
1101 | ssi_private->fiq_params.base = iomem; | ||
1102 | ssi_private->fiq_params.dma_params_rx = | ||
1103 | &ssi_private->dma_params_rx; | ||
1104 | ssi_private->fiq_params.dma_params_tx = | ||
1105 | &ssi_private->dma_params_tx; | ||
1106 | |||
1107 | ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); | ||
1108 | if (ret) | ||
1109 | goto error_pcm; | ||
1110 | } else { | ||
1111 | ret = imx_pcm_dma_init(pdev); | ||
1112 | if (ret) | ||
1113 | goto error_pcm; | ||
1114 | } | ||
1115 | |||
1116 | return 0; | ||
1117 | |||
1118 | error_pcm: | ||
1119 | if (!IS_ERR(ssi_private->baudclk)) | ||
1120 | clk_disable_unprepare(ssi_private->baudclk); | ||
1121 | |||
1122 | clk_disable_unprepare(ssi_private->clk); | ||
1123 | |||
1124 | return ret; | ||
1125 | } | ||
1126 | |||
1127 | static void fsl_ssi_imx_clean(struct platform_device *pdev, | ||
1128 | struct fsl_ssi_private *ssi_private) | ||
1129 | { | ||
1130 | if (!ssi_private->use_dma) | ||
1131 | imx_pcm_fiq_exit(pdev); | ||
1132 | if (!IS_ERR(ssi_private->baudclk)) | ||
1133 | clk_disable_unprepare(ssi_private->baudclk); | ||
1134 | clk_disable_unprepare(ssi_private->clk); | ||
1135 | } | ||
1136 | |||
1254 | static int fsl_ssi_probe(struct platform_device *pdev) | 1137 | static int fsl_ssi_probe(struct platform_device *pdev) |
1255 | { | 1138 | { |
1256 | struct fsl_ssi_private *ssi_private; | 1139 | struct fsl_ssi_private *ssi_private; |
1257 | int ret = 0; | 1140 | int ret = 0; |
1258 | struct device_attribute *dev_attr = NULL; | ||
1259 | struct device_node *np = pdev->dev.of_node; | 1141 | struct device_node *np = pdev->dev.of_node; |
1260 | const struct of_device_id *of_id; | 1142 | const struct of_device_id *of_id; |
1261 | enum fsl_ssi_type hw_type; | 1143 | enum fsl_ssi_type hw_type; |
@@ -1263,7 +1145,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1263 | const uint32_t *iprop; | 1145 | const uint32_t *iprop; |
1264 | struct resource res; | 1146 | struct resource res; |
1265 | char name[64]; | 1147 | char name[64]; |
1266 | bool shared; | ||
1267 | bool ac97 = false; | 1148 | bool ac97 = false; |
1268 | 1149 | ||
1269 | /* SSIs that are not connected on the board should have a | 1150 | /* SSIs that are not connected on the board should have a |
@@ -1286,17 +1167,13 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1286 | if (!strcmp(sprop, "ac97-slave")) | 1167 | if (!strcmp(sprop, "ac97-slave")) |
1287 | ac97 = true; | 1168 | ac97 = true; |
1288 | 1169 | ||
1289 | /* The DAI name is the last part of the full name of the node. */ | 1170 | ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private), |
1290 | p = strrchr(np->full_name, '/') + 1; | 1171 | GFP_KERNEL); |
1291 | ssi_private = devm_kzalloc(&pdev->dev, sizeof(*ssi_private) + strlen(p), | ||
1292 | GFP_KERNEL); | ||
1293 | if (!ssi_private) { | 1172 | if (!ssi_private) { |
1294 | dev_err(&pdev->dev, "could not allocate DAI object\n"); | 1173 | dev_err(&pdev->dev, "could not allocate DAI object\n"); |
1295 | return -ENOMEM; | 1174 | return -ENOMEM; |
1296 | } | 1175 | } |
1297 | 1176 | ||
1298 | strcpy(ssi_private->name, p); | ||
1299 | |||
1300 | ssi_private->use_dma = !of_property_read_bool(np, | 1177 | ssi_private->use_dma = !of_property_read_bool(np, |
1301 | "fsl,fiq-stream-filter"); | 1178 | "fsl,fiq-stream-filter"); |
1302 | ssi_private->hw_type = hw_type; | 1179 | ssi_private->hw_type = hw_type; |
@@ -1306,7 +1183,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1306 | sizeof(fsl_ssi_ac97_dai)); | 1183 | sizeof(fsl_ssi_ac97_dai)); |
1307 | 1184 | ||
1308 | fsl_ac97_data = ssi_private; | 1185 | fsl_ac97_data = ssi_private; |
1309 | ssi_private->imx_ac97 = true; | ||
1310 | 1186 | ||
1311 | snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); | 1187 | snd_soc_set_ac97_ops_of_reset(&fsl_ssi_ac97_ops, pdev); |
1312 | } else { | 1188 | } else { |
@@ -1314,7 +1190,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1314 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, | 1190 | memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_dai_template, |
1315 | sizeof(fsl_ssi_dai_template)); | 1191 | sizeof(fsl_ssi_dai_template)); |
1316 | } | 1192 | } |
1317 | ssi_private->cpu_dai_drv.name = ssi_private->name; | 1193 | ssi_private->cpu_dai_drv.name = dev_name(&pdev->dev); |
1318 | 1194 | ||
1319 | /* Get the addresses and IRQ */ | 1195 | /* Get the addresses and IRQ */ |
1320 | ret = of_address_to_resource(np, 0, &res); | 1196 | ret = of_address_to_resource(np, 0, &res); |
@@ -1353,177 +1229,43 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1353 | ssi_private->baudclk_locked = false; | 1229 | ssi_private->baudclk_locked = false; |
1354 | spin_lock_init(&ssi_private->baudclk_lock); | 1230 | spin_lock_init(&ssi_private->baudclk_lock); |
1355 | 1231 | ||
1356 | /* | 1232 | dev_set_drvdata(&pdev->dev, ssi_private); |
1357 | * imx51 and later SoCs have a slightly different IP that allows the | ||
1358 | * SSI configuration while the SSI unit is running. | ||
1359 | * | ||
1360 | * More important, it is necessary on those SoCs to configure the | ||
1361 | * sperate TX/RX DMA bits just before starting the stream | ||
1362 | * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi | ||
1363 | * sends any DMA requests to the SDMA unit, otherwise it is not defined | ||
1364 | * how the SDMA unit handles the DMA request. | ||
1365 | * | ||
1366 | * SDMA units are present on devices starting at imx35 but the imx35 | ||
1367 | * reference manual states that the DMA bits should not be changed | ||
1368 | * while the SSI unit is running (SSIEN). So we support the necessary | ||
1369 | * online configuration of fsl-ssi starting at imx51. | ||
1370 | */ | ||
1371 | switch (hw_type) { | ||
1372 | case FSL_SSI_MCP8610: | ||
1373 | case FSL_SSI_MX21: | ||
1374 | case FSL_SSI_MX35: | ||
1375 | ssi_private->offline_config = true; | ||
1376 | break; | ||
1377 | case FSL_SSI_MX51: | ||
1378 | ssi_private->offline_config = false; | ||
1379 | break; | ||
1380 | } | ||
1381 | |||
1382 | if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 || | ||
1383 | hw_type == FSL_SSI_MX35) { | ||
1384 | u32 dma_events[2], dmas[4]; | ||
1385 | ssi_private->ssi_on_imx = true; | ||
1386 | 1233 | ||
1387 | ssi_private->clk = devm_clk_get(&pdev->dev, NULL); | 1234 | if (fsl_ssi_on_imx(ssi_private)) { |
1388 | if (IS_ERR(ssi_private->clk)) { | 1235 | ret = fsl_ssi_imx_probe(pdev, ssi_private, ssi_private->ssi); |
1389 | ret = PTR_ERR(ssi_private->clk); | 1236 | if (ret) |
1390 | dev_err(&pdev->dev, "could not get clock: %d\n", ret); | ||
1391 | goto error_irqmap; | ||
1392 | } | ||
1393 | ret = clk_prepare_enable(ssi_private->clk); | ||
1394 | if (ret) { | ||
1395 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", | ||
1396 | ret); | ||
1397 | goto error_irqmap; | 1237 | goto error_irqmap; |
1398 | } | 1238 | } |
1399 | |||
1400 | /* For those SLAVE implementations, we ingore non-baudclk cases | ||
1401 | * and, instead, abandon MASTER mode that needs baud clock. | ||
1402 | */ | ||
1403 | ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); | ||
1404 | if (IS_ERR(ssi_private->baudclk)) | ||
1405 | dev_dbg(&pdev->dev, "could not get baud clock: %ld\n", | ||
1406 | PTR_ERR(ssi_private->baudclk)); | ||
1407 | else | ||
1408 | clk_prepare_enable(ssi_private->baudclk); | ||
1409 | |||
1410 | /* | ||
1411 | * We have burstsize be "fifo_depth - 2" to match the SSI | ||
1412 | * watermark setting in fsl_ssi_startup(). | ||
1413 | */ | ||
1414 | ssi_private->dma_params_tx.maxburst = | ||
1415 | ssi_private->fifo_depth - 2; | ||
1416 | ssi_private->dma_params_rx.maxburst = | ||
1417 | ssi_private->fifo_depth - 2; | ||
1418 | ssi_private->dma_params_tx.addr = | ||
1419 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, stx0); | ||
1420 | ssi_private->dma_params_rx.addr = | ||
1421 | ssi_private->ssi_phys + offsetof(struct ccsr_ssi, srx0); | ||
1422 | ssi_private->dma_params_tx.filter_data = | ||
1423 | &ssi_private->filter_data_tx; | ||
1424 | ssi_private->dma_params_rx.filter_data = | ||
1425 | &ssi_private->filter_data_rx; | ||
1426 | if (!of_property_read_bool(pdev->dev.of_node, "dmas") && | ||
1427 | ssi_private->use_dma) { | ||
1428 | /* | ||
1429 | * FIXME: This is a temporary solution until all | ||
1430 | * necessary dma drivers support the generic dma | ||
1431 | * bindings. | ||
1432 | */ | ||
1433 | ret = of_property_read_u32_array(pdev->dev.of_node, | ||
1434 | "fsl,ssi-dma-events", dma_events, 2); | ||
1435 | if (ret && ssi_private->use_dma) { | ||
1436 | dev_err(&pdev->dev, "could not get dma events but fsl-ssi is configured to use DMA\n"); | ||
1437 | goto error_clk; | ||
1438 | } | ||
1439 | } | ||
1440 | /* Should this be merge with the above? */ | ||
1441 | if (!of_property_read_u32_array(pdev->dev.of_node, "dmas", dmas, 4) | ||
1442 | && dmas[2] == IMX_DMATYPE_SSI_DUAL) { | ||
1443 | ssi_private->use_dual_fifo = true; | ||
1444 | /* When using dual fifo mode, we need to keep watermark | ||
1445 | * as even numbers due to dma script limitation. | ||
1446 | */ | ||
1447 | ssi_private->dma_params_tx.maxburst &= ~0x1; | ||
1448 | ssi_private->dma_params_rx.maxburst &= ~0x1; | ||
1449 | } | ||
1450 | |||
1451 | shared = of_device_is_compatible(of_get_parent(np), | ||
1452 | "fsl,spba-bus"); | ||
1453 | 1239 | ||
1454 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_tx, | 1240 | ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, |
1455 | dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1241 | &ssi_private->cpu_dai_drv, 1); |
1456 | imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, | 1242 | if (ret) { |
1457 | dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); | 1243 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); |
1244 | goto error_asoc_register; | ||
1458 | } | 1245 | } |
1459 | 1246 | ||
1460 | /* | ||
1461 | * Enable interrupts only for MCP8610 and MX51. The other MXs have | ||
1462 | * different writeable interrupt status registers. | ||
1463 | */ | ||
1464 | if (ssi_private->use_dma) { | 1247 | if (ssi_private->use_dma) { |
1465 | /* The 'name' should not have any slashes in it. */ | ||
1466 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, | 1248 | ret = devm_request_irq(&pdev->dev, ssi_private->irq, |
1467 | fsl_ssi_isr, 0, ssi_private->name, | 1249 | fsl_ssi_isr, 0, dev_name(&pdev->dev), |
1468 | ssi_private); | 1250 | ssi_private); |
1469 | ssi_private->irq_stats = true; | ||
1470 | if (ret < 0) { | 1251 | if (ret < 0) { |
1471 | dev_err(&pdev->dev, "could not claim irq %u\n", | 1252 | dev_err(&pdev->dev, "could not claim irq %u\n", |
1472 | ssi_private->irq); | 1253 | ssi_private->irq); |
1473 | goto error_clk; | 1254 | goto error_irq; |
1474 | } | 1255 | } |
1475 | } | 1256 | } |
1476 | 1257 | ||
1477 | /* Register with ASoC */ | 1258 | ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); |
1478 | dev_set_drvdata(&pdev->dev, ssi_private); | ||
1479 | |||
1480 | ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, | ||
1481 | &ssi_private->cpu_dai_drv, 1); | ||
1482 | if (ret) { | ||
1483 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | ||
1484 | goto error_dev; | ||
1485 | } | ||
1486 | |||
1487 | ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev); | ||
1488 | if (ret) | 1259 | if (ret) |
1489 | goto error_dbgfs; | 1260 | goto error_asoc_register; |
1490 | |||
1491 | if (ssi_private->ssi_on_imx) { | ||
1492 | if (!ssi_private->use_dma) { | ||
1493 | |||
1494 | /* | ||
1495 | * Some boards use an incompatible codec. To get it | ||
1496 | * working, we are using imx-fiq-pcm-audio, that | ||
1497 | * can handle those codecs. DMA is not possible in this | ||
1498 | * situation. | ||
1499 | */ | ||
1500 | |||
1501 | ssi_private->fiq_params.irq = ssi_private->irq; | ||
1502 | ssi_private->fiq_params.base = ssi_private->ssi; | ||
1503 | ssi_private->fiq_params.dma_params_rx = | ||
1504 | &ssi_private->dma_params_rx; | ||
1505 | ssi_private->fiq_params.dma_params_tx = | ||
1506 | &ssi_private->dma_params_tx; | ||
1507 | |||
1508 | ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); | ||
1509 | if (ret) | ||
1510 | goto error_pcm; | ||
1511 | } else { | ||
1512 | ret = imx_pcm_dma_init(pdev); | ||
1513 | if (ret) | ||
1514 | goto error_pcm; | ||
1515 | } | ||
1516 | } | ||
1517 | 1261 | ||
1518 | /* | 1262 | /* |
1519 | * If codec-handle property is missing from SSI node, we assume | 1263 | * If codec-handle property is missing from SSI node, we assume |
1520 | * that the machine driver uses new binding which does not require | 1264 | * that the machine driver uses new binding which does not require |
1521 | * SSI driver to trigger machine driver's probe. | 1265 | * SSI driver to trigger machine driver's probe. |
1522 | */ | 1266 | */ |
1523 | if (!of_get_property(np, "codec-handle", NULL)) { | 1267 | if (!of_get_property(np, "codec-handle", NULL)) |
1524 | ssi_private->new_binding = true; | ||
1525 | goto done; | 1268 | goto done; |
1526 | } | ||
1527 | 1269 | ||
1528 | /* Trigger the machine driver's probe function. The platform driver | 1270 | /* Trigger the machine driver's probe function. The platform driver |
1529 | * name of the machine driver is taken from /compatible property of the | 1271 | * name of the machine driver is taken from /compatible property of the |
@@ -1543,37 +1285,24 @@ static int fsl_ssi_probe(struct platform_device *pdev) | |||
1543 | if (IS_ERR(ssi_private->pdev)) { | 1285 | if (IS_ERR(ssi_private->pdev)) { |
1544 | ret = PTR_ERR(ssi_private->pdev); | 1286 | ret = PTR_ERR(ssi_private->pdev); |
1545 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); | 1287 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); |
1546 | goto error_dai; | 1288 | goto error_sound_card; |
1547 | } | 1289 | } |
1548 | 1290 | ||
1549 | done: | 1291 | done: |
1550 | if (ssi_private->imx_ac97) | ||
1551 | fsl_ssi_ac97_init(); | ||
1552 | |||
1553 | return 0; | 1292 | return 0; |
1554 | 1293 | ||
1555 | error_dai: | 1294 | error_sound_card: |
1556 | if (ssi_private->ssi_on_imx && !ssi_private->use_dma) | 1295 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1557 | imx_pcm_fiq_exit(pdev); | ||
1558 | |||
1559 | error_pcm: | ||
1560 | fsl_ssi_debugfs_remove(ssi_private); | ||
1561 | 1296 | ||
1562 | error_dbgfs: | 1297 | error_irq: |
1563 | snd_soc_unregister_component(&pdev->dev); | 1298 | snd_soc_unregister_component(&pdev->dev); |
1564 | 1299 | ||
1565 | error_dev: | 1300 | error_asoc_register: |
1566 | device_remove_file(&pdev->dev, dev_attr); | 1301 | if (fsl_ssi_on_imx(ssi_private)) |
1567 | 1302 | fsl_ssi_imx_clean(pdev, ssi_private); | |
1568 | error_clk: | ||
1569 | if (ssi_private->ssi_on_imx) { | ||
1570 | if (!IS_ERR(ssi_private->baudclk)) | ||
1571 | clk_disable_unprepare(ssi_private->baudclk); | ||
1572 | clk_disable_unprepare(ssi_private->clk); | ||
1573 | } | ||
1574 | 1303 | ||
1575 | error_irqmap: | 1304 | error_irqmap: |
1576 | if (ssi_private->irq_stats) | 1305 | if (ssi_private->use_dma) |
1577 | irq_dispose_mapping(ssi_private->irq); | 1306 | irq_dispose_mapping(ssi_private->irq); |
1578 | 1307 | ||
1579 | return ret; | 1308 | return ret; |
@@ -1583,17 +1312,16 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
1583 | { | 1312 | { |
1584 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); | 1313 | struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); |
1585 | 1314 | ||
1586 | fsl_ssi_debugfs_remove(ssi_private); | 1315 | fsl_ssi_debugfs_remove(&ssi_private->dbg_stats); |
1587 | 1316 | ||
1588 | if (!ssi_private->new_binding) | 1317 | if (ssi_private->pdev) |
1589 | platform_device_unregister(ssi_private->pdev); | 1318 | platform_device_unregister(ssi_private->pdev); |
1590 | snd_soc_unregister_component(&pdev->dev); | 1319 | snd_soc_unregister_component(&pdev->dev); |
1591 | if (ssi_private->ssi_on_imx) { | 1320 | |
1592 | if (!IS_ERR(ssi_private->baudclk)) | 1321 | if (fsl_ssi_on_imx(ssi_private)) |
1593 | clk_disable_unprepare(ssi_private->baudclk); | 1322 | fsl_ssi_imx_clean(pdev, ssi_private); |
1594 | clk_disable_unprepare(ssi_private->clk); | 1323 | |
1595 | } | 1324 | if (ssi_private->use_dma) |
1596 | if (ssi_private->irq_stats) | ||
1597 | irq_dispose_mapping(ssi_private->irq); | 1325 | irq_dispose_mapping(ssi_private->irq); |
1598 | 1326 | ||
1599 | return 0; | 1327 | return 0; |
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h index e6b63240a3d7..71c3e7e4340d 100644 --- a/sound/soc/fsl/fsl_ssi.h +++ b/sound/soc/fsl/fsl_ssi.h | |||
@@ -39,6 +39,7 @@ struct ccsr_ssi { | |||
39 | __be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */ | 39 | __be32 saccdis; /* 0x.0058 - SSI AC97 Channel Disable Register */ |
40 | }; | 40 | }; |
41 | 41 | ||
42 | #define CCSR_SSI_SCR_SYNC_TX_FS 0x00001000 | ||
42 | #define CCSR_SSI_SCR_RFR_CLK_DIS 0x00000800 | 43 | #define CCSR_SSI_SCR_RFR_CLK_DIS 0x00000800 |
43 | #define CCSR_SSI_SCR_TFR_CLK_DIS 0x00000400 | 44 | #define CCSR_SSI_SCR_TFR_CLK_DIS 0x00000400 |
44 | #define CCSR_SSI_SCR_TCH_EN 0x00000100 | 45 | #define CCSR_SSI_SCR_TCH_EN 0x00000100 |
@@ -206,5 +207,64 @@ struct ccsr_ssi { | |||
206 | #define CCSR_SSI_SACNT_FV 0x00000002 | 207 | #define CCSR_SSI_SACNT_FV 0x00000002 |
207 | #define CCSR_SSI_SACNT_AC97EN 0x00000001 | 208 | #define CCSR_SSI_SACNT_AC97EN 0x00000001 |
208 | 209 | ||
209 | #endif | ||
210 | 210 | ||
211 | struct device; | ||
212 | |||
213 | #if IS_ENABLED(CONFIG_DEBUG_FS) | ||
214 | |||
215 | struct fsl_ssi_dbg { | ||
216 | struct dentry *dbg_dir; | ||
217 | struct dentry *dbg_stats; | ||
218 | |||
219 | struct { | ||
220 | unsigned int rfrc; | ||
221 | unsigned int tfrc; | ||
222 | unsigned int cmdau; | ||
223 | unsigned int cmddu; | ||
224 | unsigned int rxt; | ||
225 | unsigned int rdr1; | ||
226 | unsigned int rdr0; | ||
227 | unsigned int tde1; | ||
228 | unsigned int tde0; | ||
229 | unsigned int roe1; | ||
230 | unsigned int roe0; | ||
231 | unsigned int tue1; | ||
232 | unsigned int tue0; | ||
233 | unsigned int tfs; | ||
234 | unsigned int rfs; | ||
235 | unsigned int tls; | ||
236 | unsigned int rls; | ||
237 | unsigned int rff1; | ||
238 | unsigned int rff0; | ||
239 | unsigned int tfe1; | ||
240 | unsigned int tfe0; | ||
241 | } stats; | ||
242 | }; | ||
243 | |||
244 | void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *ssi_dbg, u32 sisr); | ||
245 | |||
246 | int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev); | ||
247 | |||
248 | void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg); | ||
249 | |||
250 | #else | ||
251 | |||
252 | struct fsl_ssi_dbg { | ||
253 | }; | ||
254 | |||
255 | static inline void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *stats, u32 sisr) | ||
256 | { | ||
257 | } | ||
258 | |||
259 | static inline int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, | ||
260 | struct device *dev) | ||
261 | { | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | static inline void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg) | ||
266 | { | ||
267 | } | ||
268 | #endif /* ! IS_ENABLED(CONFIG_DEBUG_FS) */ | ||
269 | |||
270 | #endif | ||
diff --git a/sound/soc/fsl/fsl_ssi_dbg.c b/sound/soc/fsl/fsl_ssi_dbg.c new file mode 100644 index 000000000000..5469ffbc0253 --- /dev/null +++ b/sound/soc/fsl/fsl_ssi_dbg.c | |||
@@ -0,0 +1,163 @@ | |||
1 | /* | ||
2 | * Freescale SSI ALSA SoC Digital Audio Interface (DAI) debugging functions | ||
3 | * | ||
4 | * Copyright 2014 Markus Pargmann <mpa@pengutronix.de>, Pengutronix | ||
5 | * | ||
6 | * Splitted from fsl_ssi.c | ||
7 | * | ||
8 | * This file is licensed under the terms of the GNU General Public License | ||
9 | * version 2. This program is licensed "as is" without any warranty of any | ||
10 | * kind, whether express or implied. | ||
11 | */ | ||
12 | |||
13 | #include <linux/debugfs.h> | ||
14 | #include <linux/device.h> | ||
15 | #include <linux/kernel.h> | ||
16 | |||
17 | #include "fsl_ssi.h" | ||
18 | |||
19 | void fsl_ssi_dbg_isr(struct fsl_ssi_dbg *dbg, u32 sisr) | ||
20 | { | ||
21 | if (sisr & CCSR_SSI_SISR_RFRC) | ||
22 | dbg->stats.rfrc++; | ||
23 | |||
24 | if (sisr & CCSR_SSI_SISR_TFRC) | ||
25 | dbg->stats.tfrc++; | ||
26 | |||
27 | if (sisr & CCSR_SSI_SISR_CMDAU) | ||
28 | dbg->stats.cmdau++; | ||
29 | |||
30 | if (sisr & CCSR_SSI_SISR_CMDDU) | ||
31 | dbg->stats.cmddu++; | ||
32 | |||
33 | if (sisr & CCSR_SSI_SISR_RXT) | ||
34 | dbg->stats.rxt++; | ||
35 | |||
36 | if (sisr & CCSR_SSI_SISR_RDR1) | ||
37 | dbg->stats.rdr1++; | ||
38 | |||
39 | if (sisr & CCSR_SSI_SISR_RDR0) | ||
40 | dbg->stats.rdr0++; | ||
41 | |||
42 | if (sisr & CCSR_SSI_SISR_TDE1) | ||
43 | dbg->stats.tde1++; | ||
44 | |||
45 | if (sisr & CCSR_SSI_SISR_TDE0) | ||
46 | dbg->stats.tde0++; | ||
47 | |||
48 | if (sisr & CCSR_SSI_SISR_ROE1) | ||
49 | dbg->stats.roe1++; | ||
50 | |||
51 | if (sisr & CCSR_SSI_SISR_ROE0) | ||
52 | dbg->stats.roe0++; | ||
53 | |||
54 | if (sisr & CCSR_SSI_SISR_TUE1) | ||
55 | dbg->stats.tue1++; | ||
56 | |||
57 | if (sisr & CCSR_SSI_SISR_TUE0) | ||
58 | dbg->stats.tue0++; | ||
59 | |||
60 | if (sisr & CCSR_SSI_SISR_TFS) | ||
61 | dbg->stats.tfs++; | ||
62 | |||
63 | if (sisr & CCSR_SSI_SISR_RFS) | ||
64 | dbg->stats.rfs++; | ||
65 | |||
66 | if (sisr & CCSR_SSI_SISR_TLS) | ||
67 | dbg->stats.tls++; | ||
68 | |||
69 | if (sisr & CCSR_SSI_SISR_RLS) | ||
70 | dbg->stats.rls++; | ||
71 | |||
72 | if (sisr & CCSR_SSI_SISR_RFF1) | ||
73 | dbg->stats.rff1++; | ||
74 | |||
75 | if (sisr & CCSR_SSI_SISR_RFF0) | ||
76 | dbg->stats.rff0++; | ||
77 | |||
78 | if (sisr & CCSR_SSI_SISR_TFE1) | ||
79 | dbg->stats.tfe1++; | ||
80 | |||
81 | if (sisr & CCSR_SSI_SISR_TFE0) | ||
82 | dbg->stats.tfe0++; | ||
83 | } | ||
84 | |||
85 | /* Show the statistics of a flag only if its interrupt is enabled. The | ||
86 | * compiler will optimze this code to a no-op if the interrupt is not | ||
87 | * enabled. | ||
88 | */ | ||
89 | #define SIER_SHOW(flag, name) \ | ||
90 | do { \ | ||
91 | if (CCSR_SSI_SIER_##flag) \ | ||
92 | seq_printf(s, #name "=%u\n", ssi_dbg->stats.name); \ | ||
93 | } while (0) | ||
94 | |||
95 | |||
96 | /** | ||
97 | * fsl_sysfs_ssi_show: display SSI statistics | ||
98 | * | ||
99 | * Display the statistics for the current SSI device. To avoid confusion, | ||
100 | * we only show those counts that are enabled. | ||
101 | */ | ||
102 | static int fsl_ssi_stats_show(struct seq_file *s, void *unused) | ||
103 | { | ||
104 | struct fsl_ssi_dbg *ssi_dbg = s->private; | ||
105 | |||
106 | SIER_SHOW(RFRC_EN, rfrc); | ||
107 | SIER_SHOW(TFRC_EN, tfrc); | ||
108 | SIER_SHOW(CMDAU_EN, cmdau); | ||
109 | SIER_SHOW(CMDDU_EN, cmddu); | ||
110 | SIER_SHOW(RXT_EN, rxt); | ||
111 | SIER_SHOW(RDR1_EN, rdr1); | ||
112 | SIER_SHOW(RDR0_EN, rdr0); | ||
113 | SIER_SHOW(TDE1_EN, tde1); | ||
114 | SIER_SHOW(TDE0_EN, tde0); | ||
115 | SIER_SHOW(ROE1_EN, roe1); | ||
116 | SIER_SHOW(ROE0_EN, roe0); | ||
117 | SIER_SHOW(TUE1_EN, tue1); | ||
118 | SIER_SHOW(TUE0_EN, tue0); | ||
119 | SIER_SHOW(TFS_EN, tfs); | ||
120 | SIER_SHOW(RFS_EN, rfs); | ||
121 | SIER_SHOW(TLS_EN, tls); | ||
122 | SIER_SHOW(RLS_EN, rls); | ||
123 | SIER_SHOW(RFF1_EN, rff1); | ||
124 | SIER_SHOW(RFF0_EN, rff0); | ||
125 | SIER_SHOW(TFE1_EN, tfe1); | ||
126 | SIER_SHOW(TFE0_EN, tfe0); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | static int fsl_ssi_stats_open(struct inode *inode, struct file *file) | ||
132 | { | ||
133 | return single_open(file, fsl_ssi_stats_show, inode->i_private); | ||
134 | } | ||
135 | |||
136 | static const struct file_operations fsl_ssi_stats_ops = { | ||
137 | .open = fsl_ssi_stats_open, | ||
138 | .read = seq_read, | ||
139 | .llseek = seq_lseek, | ||
140 | .release = single_release, | ||
141 | }; | ||
142 | |||
143 | int fsl_ssi_debugfs_create(struct fsl_ssi_dbg *ssi_dbg, struct device *dev) | ||
144 | { | ||
145 | ssi_dbg->dbg_dir = debugfs_create_dir(dev_name(dev), NULL); | ||
146 | if (!ssi_dbg->dbg_dir) | ||
147 | return -ENOMEM; | ||
148 | |||
149 | ssi_dbg->dbg_stats = debugfs_create_file("stats", S_IRUGO, | ||
150 | ssi_dbg->dbg_dir, ssi_dbg, &fsl_ssi_stats_ops); | ||
151 | if (!ssi_dbg->dbg_stats) { | ||
152 | debugfs_remove(ssi_dbg->dbg_dir); | ||
153 | return -ENOMEM; | ||
154 | } | ||
155 | |||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | void fsl_ssi_debugfs_remove(struct fsl_ssi_dbg *ssi_dbg) | ||
160 | { | ||
161 | debugfs_remove(ssi_dbg->dbg_stats); | ||
162 | debugfs_remove(ssi_dbg->dbg_dir); | ||
163 | } | ||
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c index 2585ae44e634..0849b7b83f0a 100644 --- a/sound/soc/fsl/imx-pcm-dma.c +++ b/sound/soc/fsl/imx-pcm-dma.c | |||
@@ -40,7 +40,6 @@ static const struct snd_pcm_hardware imx_pcm_hardware = { | |||
40 | SNDRV_PCM_INFO_MMAP_VALID | | 40 | SNDRV_PCM_INFO_MMAP_VALID | |
41 | SNDRV_PCM_INFO_PAUSE | | 41 | SNDRV_PCM_INFO_PAUSE | |
42 | SNDRV_PCM_INFO_RESUME, | 42 | SNDRV_PCM_INFO_RESUME, |
43 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
44 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, | 43 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, |
45 | .period_bytes_min = 128, | 44 | .period_bytes_min = 128, |
46 | .period_bytes_max = 65535, /* Limited by SDMA engine */ | 45 | .period_bytes_max = 65535, /* Limited by SDMA engine */ |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index 21f1ccbdf582..98f97e543c29 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
@@ -66,8 +66,7 @@ err: | |||
66 | 66 | ||
67 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | 67 | static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) |
68 | { | 68 | { |
69 | struct simple_card_data *priv = | 69 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
70 | snd_soc_card_get_drvdata(rtd->card); | ||
71 | struct snd_soc_dai *codec = rtd->codec_dai; | 70 | struct snd_soc_dai *codec = rtd->codec_dai; |
72 | struct snd_soc_dai *cpu = rtd->cpu_dai; | 71 | struct snd_soc_dai *cpu = rtd->cpu_dai; |
73 | struct simple_dai_props *dai_props; | 72 | struct simple_dai_props *dai_props; |
@@ -88,7 +87,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
88 | 87 | ||
89 | static int | 88 | static int |
90 | asoc_simple_card_sub_parse_of(struct device_node *np, | 89 | asoc_simple_card_sub_parse_of(struct device_node *np, |
91 | unsigned int daifmt, | ||
92 | struct asoc_simple_dai *dai, | 90 | struct asoc_simple_dai *dai, |
93 | const struct device_node **p_node, | 91 | const struct device_node **p_node, |
94 | const char **name) | 92 | const char **name) |
@@ -117,14 +115,6 @@ asoc_simple_card_sub_parse_of(struct device_node *np, | |||
117 | return ret; | 115 | return ret; |
118 | 116 | ||
119 | /* | 117 | /* |
120 | * bitclock-inversion, frame-inversion | ||
121 | * bitclock-master, frame-master | ||
122 | * and specific "format" if it has | ||
123 | */ | ||
124 | dai->fmt = snd_soc_of_parse_daifmt(np, NULL); | ||
125 | dai->fmt |= daifmt; | ||
126 | |||
127 | /* | ||
128 | * dai->sysclk come from | 118 | * dai->sysclk come from |
129 | * "clocks = <&xxx>" (if system has common clock) | 119 | * "clocks = <&xxx>" (if system has common clock) |
130 | * or "system-clock-frequency = <xxx>" | 120 | * or "system-clock-frequency = <xxx>" |
@@ -151,37 +141,132 @@ asoc_simple_card_sub_parse_of(struct device_node *np, | |||
151 | return 0; | 141 | return 0; |
152 | } | 142 | } |
153 | 143 | ||
154 | static int simple_card_cpu_codec_of(struct device_node *node, | 144 | static int simple_card_dai_link_of(struct device_node *node, |
155 | int daifmt, | 145 | struct device *dev, |
156 | struct snd_soc_dai_link *dai_link, | 146 | struct snd_soc_dai_link *dai_link, |
157 | struct simple_dai_props *dai_props) | 147 | struct simple_dai_props *dai_props) |
158 | { | 148 | { |
159 | struct device_node *np; | 149 | struct device_node *np = NULL; |
150 | struct device_node *bitclkmaster = NULL; | ||
151 | struct device_node *framemaster = NULL; | ||
152 | unsigned int daifmt; | ||
153 | char *name; | ||
154 | char prop[128]; | ||
155 | char *prefix = ""; | ||
160 | int ret; | 156 | int ret; |
161 | 157 | ||
162 | /* CPU sub-node */ | 158 | prefix = "simple-audio-card,"; |
163 | ret = -EINVAL; | 159 | |
164 | np = of_get_child_by_name(node, "simple-audio-card,cpu"); | 160 | daifmt = snd_soc_of_parse_daifmt(node, prefix, |
165 | if (np) { | 161 | &bitclkmaster, &framemaster); |
166 | ret = asoc_simple_card_sub_parse_of(np, daifmt, | 162 | daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK; |
167 | &dai_props->cpu_dai, | 163 | |
168 | &dai_link->cpu_of_node, | 164 | snprintf(prop, sizeof(prop), "%scpu", prefix); |
169 | &dai_link->cpu_dai_name); | 165 | np = of_get_child_by_name(node, prop); |
170 | of_node_put(np); | 166 | if (!np) { |
167 | ret = -EINVAL; | ||
168 | dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); | ||
169 | goto dai_link_of_err; | ||
171 | } | 170 | } |
171 | |||
172 | ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai, | ||
173 | &dai_link->cpu_of_node, | ||
174 | &dai_link->cpu_dai_name); | ||
172 | if (ret < 0) | 175 | if (ret < 0) |
173 | return ret; | 176 | goto dai_link_of_err; |
177 | |||
178 | dai_props->cpu_dai.fmt = daifmt; | ||
179 | switch (((np == bitclkmaster) << 4) | (np == framemaster)) { | ||
180 | case 0x11: | ||
181 | dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS; | ||
182 | break; | ||
183 | case 0x10: | ||
184 | dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM; | ||
185 | break; | ||
186 | case 0x01: | ||
187 | dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS; | ||
188 | break; | ||
189 | default: | ||
190 | dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM; | ||
191 | break; | ||
192 | } | ||
174 | 193 | ||
175 | /* CODEC sub-node */ | 194 | of_node_put(np); |
176 | ret = -EINVAL; | 195 | snprintf(prop, sizeof(prop), "%scodec", prefix); |
177 | np = of_get_child_by_name(node, "simple-audio-card,codec"); | 196 | np = of_get_child_by_name(node, prop); |
178 | if (np) { | 197 | if (!np) { |
179 | ret = asoc_simple_card_sub_parse_of(np, daifmt, | 198 | ret = -EINVAL; |
180 | &dai_props->codec_dai, | 199 | dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop); |
181 | &dai_link->codec_of_node, | 200 | goto dai_link_of_err; |
182 | &dai_link->codec_dai_name); | ||
183 | of_node_put(np); | ||
184 | } | 201 | } |
202 | |||
203 | ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai, | ||
204 | &dai_link->codec_of_node, | ||
205 | &dai_link->codec_dai_name); | ||
206 | if (ret < 0) | ||
207 | goto dai_link_of_err; | ||
208 | |||
209 | if (strlen(prefix) && !bitclkmaster && !framemaster) { | ||
210 | /* No dai-link level and master setting was not found from | ||
211 | sound node level, revert back to legacy DT parsing and | ||
212 | take the settings from codec node. */ | ||
213 | dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n", | ||
214 | __func__); | ||
215 | dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt = | ||
216 | snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) | | ||
217 | (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK); | ||
218 | } else { | ||
219 | dai_props->codec_dai.fmt = daifmt; | ||
220 | switch (((np == bitclkmaster) << 4) | (np == framemaster)) { | ||
221 | case 0x11: | ||
222 | dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM; | ||
223 | break; | ||
224 | case 0x10: | ||
225 | dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS; | ||
226 | break; | ||
227 | case 0x01: | ||
228 | dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM; | ||
229 | break; | ||
230 | default: | ||
231 | dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS; | ||
232 | break; | ||
233 | } | ||
234 | } | ||
235 | |||
236 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | ||
237 | ret = -EINVAL; | ||
238 | goto dai_link_of_err; | ||
239 | } | ||
240 | |||
241 | /* simple-card assumes platform == cpu */ | ||
242 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
243 | |||
244 | /* Link name is created from CPU/CODEC dai name */ | ||
245 | name = devm_kzalloc(dev, | ||
246 | strlen(dai_link->cpu_dai_name) + | ||
247 | strlen(dai_link->codec_dai_name) + 2, | ||
248 | GFP_KERNEL); | ||
249 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, | ||
250 | dai_link->codec_dai_name); | ||
251 | dai_link->name = dai_link->stream_name = name; | ||
252 | |||
253 | dev_dbg(dev, "\tname : %s\n", dai_link->stream_name); | ||
254 | dev_dbg(dev, "\tcpu : %s / %04x / %d\n", | ||
255 | dai_link->cpu_dai_name, | ||
256 | dai_props->cpu_dai.fmt, | ||
257 | dai_props->cpu_dai.sysclk); | ||
258 | dev_dbg(dev, "\tcodec : %s / %04x / %d\n", | ||
259 | dai_link->codec_dai_name, | ||
260 | dai_props->codec_dai.fmt, | ||
261 | dai_props->codec_dai.sysclk); | ||
262 | |||
263 | dai_link_of_err: | ||
264 | if (np) | ||
265 | of_node_put(np); | ||
266 | if (bitclkmaster) | ||
267 | of_node_put(bitclkmaster); | ||
268 | if (framemaster) | ||
269 | of_node_put(framemaster); | ||
185 | return ret; | 270 | return ret; |
186 | } | 271 | } |
187 | 272 | ||
@@ -192,18 +277,11 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
192 | { | 277 | { |
193 | struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; | 278 | struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; |
194 | struct simple_dai_props *dai_props = priv->dai_props; | 279 | struct simple_dai_props *dai_props = priv->dai_props; |
195 | struct device_node *np; | ||
196 | char *name; | ||
197 | unsigned int daifmt; | ||
198 | int ret; | 280 | int ret; |
199 | 281 | ||
200 | /* parsing the card name from DT */ | 282 | /* parsing the card name from DT */ |
201 | snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); | 283 | snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); |
202 | 284 | ||
203 | /* get CPU/CODEC common format via simple-audio-card,format */ | ||
204 | daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") & | ||
205 | (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK); | ||
206 | |||
207 | /* off-codec widgets */ | 285 | /* off-codec widgets */ |
208 | if (of_property_read_bool(node, "simple-audio-card,widgets")) { | 286 | if (of_property_read_bool(node, "simple-audio-card,widgets")) { |
209 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, | 287 | ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, |
@@ -220,71 +298,31 @@ static int asoc_simple_card_parse_of(struct device_node *node, | |||
220 | return ret; | 298 | return ret; |
221 | } | 299 | } |
222 | 300 | ||
223 | /* loop on the DAI links */ | 301 | dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ? |
224 | np = NULL; | 302 | priv->snd_card.name : ""); |
225 | for (;;) { | 303 | |
226 | if (multi) { | 304 | if (multi) { |
227 | np = of_get_next_child(node, np); | 305 | struct device_node *np = NULL; |
228 | if (!np) | 306 | int i; |
229 | break; | 307 | for (i = 0; (np = of_get_next_child(node, np)); i++) { |
308 | dev_dbg(dev, "\tlink %d:\n", i); | ||
309 | ret = simple_card_dai_link_of(np, dev, dai_link + i, | ||
310 | dai_props + i); | ||
311 | if (ret < 0) { | ||
312 | of_node_put(np); | ||
313 | return ret; | ||
314 | } | ||
230 | } | 315 | } |
231 | 316 | } else { | |
232 | ret = simple_card_cpu_codec_of(multi ? np : node, | 317 | ret = simple_card_dai_link_of(node, dev, dai_link, dai_props); |
233 | daifmt, dai_link, dai_props); | ||
234 | if (ret < 0) | 318 | if (ret < 0) |
235 | goto err; | 319 | return ret; |
236 | |||
237 | /* | ||
238 | * overwrite cpu_dai->fmt as its DAIFMT_MASTER bit is based on CODEC | ||
239 | * while the other bits should be identical unless buggy SW/HW design. | ||
240 | */ | ||
241 | dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt; | ||
242 | |||
243 | if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) { | ||
244 | ret = -EINVAL; | ||
245 | goto err; | ||
246 | } | ||
247 | |||
248 | /* simple-card assumes platform == cpu */ | ||
249 | dai_link->platform_of_node = dai_link->cpu_of_node; | ||
250 | |||
251 | name = devm_kzalloc(dev, | ||
252 | strlen(dai_link->cpu_dai_name) + | ||
253 | strlen(dai_link->codec_dai_name) + 2, | ||
254 | GFP_KERNEL); | ||
255 | sprintf(name, "%s-%s", dai_link->cpu_dai_name, | ||
256 | dai_link->codec_dai_name); | ||
257 | dai_link->name = dai_link->stream_name = name; | ||
258 | |||
259 | if (!multi) | ||
260 | break; | ||
261 | |||
262 | dai_link++; | ||
263 | dai_props++; | ||
264 | } | 320 | } |
265 | 321 | ||
266 | /* card name is created from CPU/CODEC dai name */ | ||
267 | dai_link = priv->snd_card.dai_link; | ||
268 | if (!priv->snd_card.name) | 322 | if (!priv->snd_card.name) |
269 | priv->snd_card.name = dai_link->name; | 323 | priv->snd_card.name = priv->snd_card.dai_link->name; |
270 | |||
271 | dev_dbg(dev, "card-name : %s\n", priv->snd_card.name); | ||
272 | dev_dbg(dev, "platform : %04x\n", daifmt); | ||
273 | dai_props = priv->dai_props; | ||
274 | dev_dbg(dev, "cpu : %s / %04x / %d\n", | ||
275 | dai_link->cpu_dai_name, | ||
276 | dai_props->cpu_dai.fmt, | ||
277 | dai_props->cpu_dai.sysclk); | ||
278 | dev_dbg(dev, "codec : %s / %04x / %d\n", | ||
279 | dai_link->codec_dai_name, | ||
280 | dai_props->codec_dai.fmt, | ||
281 | dai_props->codec_dai.sysclk); | ||
282 | 324 | ||
283 | return 0; | 325 | return 0; |
284 | |||
285 | err: | ||
286 | of_node_put(np); | ||
287 | return ret; | ||
288 | } | 326 | } |
289 | 327 | ||
290 | /* update the reference count of the devices nodes at end of probe */ | 328 | /* update the reference count of the devices nodes at end of probe */ |
@@ -378,10 +416,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev) | |||
378 | return -EINVAL; | 416 | return -EINVAL; |
379 | } | 417 | } |
380 | 418 | ||
381 | if (!cinfo->name || | 419 | if (!cinfo->name || |
382 | !cinfo->codec_dai.name || | 420 | !cinfo->codec_dai.name || |
383 | !cinfo->codec || | 421 | !cinfo->codec || |
384 | !cinfo->platform || | 422 | !cinfo->platform || |
385 | !cinfo->cpu_dai.name) { | 423 | !cinfo->cpu_dai.name) { |
386 | dev_err(dev, "insufficient asoc_simple_card_info settings\n"); | 424 | dev_err(dev, "insufficient asoc_simple_card_info settings\n"); |
387 | return -EINVAL; | 425 | return -EINVAL; |
@@ -425,11 +463,11 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match); | |||
425 | 463 | ||
426 | static struct platform_driver asoc_simple_card = { | 464 | static struct platform_driver asoc_simple_card = { |
427 | .driver = { | 465 | .driver = { |
428 | .name = "asoc-simple-card", | 466 | .name = "asoc-simple-card", |
429 | .owner = THIS_MODULE, | 467 | .owner = THIS_MODULE, |
430 | .of_match_table = asoc_simple_of_match, | 468 | .of_match_table = asoc_simple_of_match, |
431 | }, | 469 | }, |
432 | .probe = asoc_simple_card_probe, | 470 | .probe = asoc_simple_card_probe, |
433 | }; | 471 | }; |
434 | 472 | ||
435 | module_platform_driver(asoc_simple_card); | 473 | module_platform_driver(asoc_simple_card); |
diff --git a/sound/soc/intel/Makefile b/sound/soc/intel/Makefile index edeb79ae3dff..0db4e2f336dc 100644 --- a/sound/soc/intel/Makefile +++ b/sound/soc/intel/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o | 2 | snd-soc-sst-dsp-objs := sst-dsp.o sst-firmware.o |
3 | snd-soc-sst-acpi-objs := sst-acpi.o | 3 | snd-soc-sst-acpi-objs := sst-acpi.o |
4 | 4 | ||
5 | snd-soc-sst-mfld-platform-objs := sst-mfld-platform.o | 5 | snd-soc-sst-mfld-platform-objs := sst-mfld-platform-pcm.o sst-mfld-platform-compress.o |
6 | snd-soc-mfld-machine-objs := mfld_machine.o | 6 | snd-soc-mfld-machine-objs := mfld_machine.o |
7 | 7 | ||
8 | obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o | 8 | obj-$(CONFIG_SND_SST_MFLD_PLATFORM) += snd-soc-sst-mfld-platform.o |
diff --git a/sound/soc/intel/byt-rt5640.c b/sound/soc/intel/byt-rt5640.c index eff97c8e5218..5535c3fb7922 100644 --- a/sound/soc/intel/byt-rt5640.c +++ b/sound/soc/intel/byt-rt5640.c | |||
@@ -100,12 +100,6 @@ static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime) | |||
100 | snd_soc_dapm_ignore_suspend(dapm, "SPORP"); | 100 | snd_soc_dapm_ignore_suspend(dapm, "SPORP"); |
101 | snd_soc_dapm_ignore_suspend(dapm, "SPORN"); | 101 | snd_soc_dapm_ignore_suspend(dapm, "SPORN"); |
102 | 102 | ||
103 | snd_soc_dapm_enable_pin(dapm, "Headset Mic"); | ||
104 | snd_soc_dapm_enable_pin(dapm, "Headphone"); | ||
105 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | ||
106 | snd_soc_dapm_enable_pin(dapm, "Internal Mic"); | ||
107 | |||
108 | snd_soc_dapm_sync(dapm); | ||
109 | return ret; | 103 | return ret; |
110 | } | 104 | } |
111 | 105 | ||
@@ -117,27 +111,13 @@ static struct snd_soc_dai_link byt_rt5640_dais[] = { | |||
117 | { | 111 | { |
118 | .name = "Baytrail Audio", | 112 | .name = "Baytrail Audio", |
119 | .stream_name = "Audio", | 113 | .stream_name = "Audio", |
120 | .cpu_dai_name = "Front-cpu-dai", | 114 | .cpu_dai_name = "baytrail-pcm-audio", |
121 | .codec_dai_name = "rt5640-aif1", | 115 | .codec_dai_name = "rt5640-aif1", |
122 | .codec_name = "i2c-10EC5640:00", | 116 | .codec_name = "i2c-10EC5640:00", |
123 | .platform_name = "baytrail-pcm-audio", | 117 | .platform_name = "baytrail-pcm-audio", |
124 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 118 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
125 | SND_SOC_DAIFMT_CBS_CFS, | 119 | SND_SOC_DAIFMT_CBS_CFS, |
126 | .init = byt_rt5640_init, | 120 | .init = byt_rt5640_init, |
127 | .ignore_suspend = 1, | ||
128 | .ops = &byt_rt5640_ops, | ||
129 | }, | ||
130 | { | ||
131 | .name = "Baytrail Voice", | ||
132 | .stream_name = "Voice", | ||
133 | .cpu_dai_name = "Mic1-cpu-dai", | ||
134 | .codec_dai_name = "rt5640-aif1", | ||
135 | .codec_name = "i2c-10EC5640:00", | ||
136 | .platform_name = "baytrail-pcm-audio", | ||
137 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
138 | SND_SOC_DAIFMT_CBS_CFS, | ||
139 | .init = NULL, | ||
140 | .ignore_suspend = 1, | ||
141 | .ops = &byt_rt5640_ops, | 121 | .ops = &byt_rt5640_ops, |
142 | }, | 122 | }, |
143 | }; | 123 | }; |
@@ -152,6 +132,17 @@ static struct snd_soc_card byt_rt5640_card = { | |||
152 | .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map), | 132 | .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map), |
153 | }; | 133 | }; |
154 | 134 | ||
135 | #ifdef CONFIG_PM_SLEEP | ||
136 | static const struct dev_pm_ops byt_rt5640_pm_ops = { | ||
137 | .suspend = snd_soc_suspend, | ||
138 | .resume = snd_soc_resume, | ||
139 | }; | ||
140 | |||
141 | #define BYT_RT5640_PM_OPS (&byt_rt5640_pm_ops) | ||
142 | #else | ||
143 | #define BYT_RT5640_PM_OPS NULL | ||
144 | #endif | ||
145 | |||
155 | static int byt_rt5640_probe(struct platform_device *pdev) | 146 | static int byt_rt5640_probe(struct platform_device *pdev) |
156 | { | 147 | { |
157 | struct snd_soc_card *card = &byt_rt5640_card; | 148 | struct snd_soc_card *card = &byt_rt5640_card; |
@@ -177,6 +168,7 @@ static struct platform_driver byt_rt5640_audio = { | |||
177 | .driver = { | 168 | .driver = { |
178 | .name = "byt-rt5640", | 169 | .name = "byt-rt5640", |
179 | .owner = THIS_MODULE, | 170 | .owner = THIS_MODULE, |
171 | .pm = BYT_RT5640_PM_OPS, | ||
180 | }, | 172 | }, |
181 | }; | 173 | }; |
182 | module_platform_driver(byt_rt5640_audio) | 174 | module_platform_driver(byt_rt5640_audio) |
diff --git a/sound/soc/intel/haswell.c b/sound/soc/intel/haswell.c index 54345a2a7386..94c2c33ffe49 100644 --- a/sound/soc/intel/haswell.c +++ b/sound/soc/intel/haswell.c | |||
@@ -89,8 +89,6 @@ static struct snd_soc_ops haswell_rt5640_ops = { | |||
89 | 89 | ||
90 | static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd) | 90 | static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd) |
91 | { | 91 | { |
92 | struct snd_soc_codec *codec = rtd->codec; | ||
93 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
94 | struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); | 92 | struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev); |
95 | struct sst_hsw *haswell = pdata->dsp; | 93 | struct sst_hsw *haswell = pdata->dsp; |
96 | int ret; | 94 | int ret; |
@@ -104,10 +102,6 @@ static int haswell_rtd_init(struct snd_soc_pcm_runtime *rtd) | |||
104 | return ret; | 102 | return ret; |
105 | } | 103 | } |
106 | 104 | ||
107 | /* always connected */ | ||
108 | snd_soc_dapm_enable_pin(dapm, "Headphones"); | ||
109 | snd_soc_dapm_enable_pin(dapm, "Mic"); | ||
110 | |||
111 | return 0; | 105 | return 0; |
112 | } | 106 | } |
113 | 107 | ||
diff --git a/sound/soc/intel/sst-baytrail-dsp.c b/sound/soc/intel/sst-baytrail-dsp.c index adf0aca5aca6..fc588764ffa3 100644 --- a/sound/soc/intel/sst-baytrail-dsp.c +++ b/sound/soc/intel/sst-baytrail-dsp.c | |||
@@ -214,6 +214,13 @@ static void sst_byt_boot(struct sst_dsp *sst) | |||
214 | { | 214 | { |
215 | int tries = 10; | 215 | int tries = 10; |
216 | 216 | ||
217 | /* | ||
218 | * save the physical address of extended firmware block in the first | ||
219 | * 4 bytes of the mailbox | ||
220 | */ | ||
221 | memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET, | ||
222 | &sst->pdata->fw_base, sizeof(u32)); | ||
223 | |||
217 | /* release stall and wait to unstall */ | 224 | /* release stall and wait to unstall */ |
218 | sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_STALL, 0x0); | 225 | sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_STALL, 0x0); |
219 | while (tries--) { | 226 | while (tries--) { |
@@ -317,13 +324,6 @@ static int sst_byt_init(struct sst_dsp *sst, struct sst_pdata *pdata) | |||
317 | return ret; | 324 | return ret; |
318 | } | 325 | } |
319 | 326 | ||
320 | /* | ||
321 | * save the physical address of extended firmware block in the first | ||
322 | * 4 bytes of the mailbox | ||
323 | */ | ||
324 | memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET, | ||
325 | &pdata->fw_base, sizeof(u32)); | ||
326 | |||
327 | ret = dma_coerce_mask_and_coherent(sst->dma_dev, DMA_BIT_MASK(32)); | 327 | ret = dma_coerce_mask_and_coherent(sst->dma_dev, DMA_BIT_MASK(32)); |
328 | if (ret) | 328 | if (ret) |
329 | return ret; | 329 | return ret; |
diff --git a/sound/soc/intel/sst-baytrail-ipc.c b/sound/soc/intel/sst-baytrail-ipc.c index 0d31dbbf4806..7c1ec003d55d 100644 --- a/sound/soc/intel/sst-baytrail-ipc.c +++ b/sound/soc/intel/sst-baytrail-ipc.c | |||
@@ -173,6 +173,7 @@ struct sst_byt { | |||
173 | /* boot */ | 173 | /* boot */ |
174 | wait_queue_head_t boot_wait; | 174 | wait_queue_head_t boot_wait; |
175 | bool boot_complete; | 175 | bool boot_complete; |
176 | struct sst_fw *fw; | ||
176 | 177 | ||
177 | /* IPC messaging */ | 178 | /* IPC messaging */ |
178 | struct list_head tx_list; | 179 | struct list_head tx_list; |
@@ -299,6 +300,24 @@ static inline void sst_byt_tx_msg_reply_complete(struct sst_byt *byt, | |||
299 | wake_up(&msg->waitq); | 300 | wake_up(&msg->waitq); |
300 | } | 301 | } |
301 | 302 | ||
303 | static void sst_byt_drop_all(struct sst_byt *byt) | ||
304 | { | ||
305 | struct ipc_message *msg, *tmp; | ||
306 | unsigned long flags; | ||
307 | |||
308 | /* drop all TX and Rx messages before we stall + reset DSP */ | ||
309 | spin_lock_irqsave(&byt->dsp->spinlock, flags); | ||
310 | list_for_each_entry_safe(msg, tmp, &byt->tx_list, list) { | ||
311 | list_move(&msg->list, &byt->empty_list); | ||
312 | } | ||
313 | |||
314 | list_for_each_entry_safe(msg, tmp, &byt->rx_list, list) { | ||
315 | list_move(&msg->list, &byt->empty_list); | ||
316 | } | ||
317 | |||
318 | spin_unlock_irqrestore(&byt->dsp->spinlock, flags); | ||
319 | } | ||
320 | |||
302 | static int sst_byt_tx_wait_done(struct sst_byt *byt, struct ipc_message *msg, | 321 | static int sst_byt_tx_wait_done(struct sst_byt *byt, struct ipc_message *msg, |
303 | void *rx_data) | 322 | void *rx_data) |
304 | { | 323 | { |
@@ -661,36 +680,33 @@ out: | |||
661 | static int sst_byt_stream_operations(struct sst_byt *byt, int type, | 680 | static int sst_byt_stream_operations(struct sst_byt *byt, int type, |
662 | int stream_id, int wait) | 681 | int stream_id, int wait) |
663 | { | 682 | { |
664 | struct sst_byt_start_stream_params start_stream; | ||
665 | u64 header; | 683 | u64 header; |
666 | void *tx_msg = NULL; | ||
667 | size_t size = 0; | ||
668 | |||
669 | if (type != IPC_IA_START_STREAM) { | ||
670 | header = sst_byt_header(type, 0, false, stream_id); | ||
671 | } else { | ||
672 | start_stream.byte_offset = 0; | ||
673 | header = sst_byt_header(IPC_IA_START_STREAM, | ||
674 | sizeof(start_stream) + sizeof(u32), | ||
675 | true, stream_id); | ||
676 | tx_msg = &start_stream; | ||
677 | size = sizeof(start_stream); | ||
678 | } | ||
679 | 684 | ||
685 | header = sst_byt_header(type, 0, false, stream_id); | ||
680 | if (wait) | 686 | if (wait) |
681 | return sst_byt_ipc_tx_msg_wait(byt, header, | 687 | return sst_byt_ipc_tx_msg_wait(byt, header, NULL, 0, NULL, 0); |
682 | tx_msg, size, NULL, 0); | ||
683 | else | 688 | else |
684 | return sst_byt_ipc_tx_msg_nowait(byt, header, tx_msg, size); | 689 | return sst_byt_ipc_tx_msg_nowait(byt, header, NULL, 0); |
685 | } | 690 | } |
686 | 691 | ||
687 | /* stream ALSA trigger operations */ | 692 | /* stream ALSA trigger operations */ |
688 | int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream) | 693 | int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream, |
694 | u32 start_offset) | ||
689 | { | 695 | { |
696 | struct sst_byt_start_stream_params start_stream; | ||
697 | void *tx_msg; | ||
698 | size_t size; | ||
699 | u64 header; | ||
690 | int ret; | 700 | int ret; |
691 | 701 | ||
692 | ret = sst_byt_stream_operations(byt, IPC_IA_START_STREAM, | 702 | start_stream.byte_offset = start_offset; |
693 | stream->str_id, 0); | 703 | header = sst_byt_header(IPC_IA_START_STREAM, |
704 | sizeof(start_stream) + sizeof(u32), | ||
705 | true, stream->str_id); | ||
706 | tx_msg = &start_stream; | ||
707 | size = sizeof(start_stream); | ||
708 | |||
709 | ret = sst_byt_ipc_tx_msg_nowait(byt, header, tx_msg, size); | ||
694 | if (ret < 0) | 710 | if (ret < 0) |
695 | dev_err(byt->dev, "ipc: error failed to start stream %d\n", | 711 | dev_err(byt->dev, "ipc: error failed to start stream %d\n", |
696 | stream->str_id); | 712 | stream->str_id); |
@@ -782,6 +798,73 @@ static struct sst_dsp_device byt_dev = { | |||
782 | .ops = &sst_byt_ops, | 798 | .ops = &sst_byt_ops, |
783 | }; | 799 | }; |
784 | 800 | ||
801 | int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata) | ||
802 | { | ||
803 | struct sst_byt *byt = pdata->dsp; | ||
804 | |||
805 | dev_dbg(byt->dev, "dsp reset\n"); | ||
806 | sst_dsp_reset(byt->dsp); | ||
807 | sst_byt_drop_all(byt); | ||
808 | dev_dbg(byt->dev, "dsp in reset\n"); | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_noirq); | ||
813 | |||
814 | int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata) | ||
815 | { | ||
816 | struct sst_byt *byt = pdata->dsp; | ||
817 | |||
818 | dev_dbg(byt->dev, "free all blocks and unload fw\n"); | ||
819 | sst_fw_unload(byt->fw); | ||
820 | |||
821 | return 0; | ||
822 | } | ||
823 | EXPORT_SYMBOL_GPL(sst_byt_dsp_suspend_late); | ||
824 | |||
825 | int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata) | ||
826 | { | ||
827 | struct sst_byt *byt = pdata->dsp; | ||
828 | int ret; | ||
829 | |||
830 | dev_dbg(byt->dev, "reload dsp fw\n"); | ||
831 | |||
832 | sst_dsp_reset(byt->dsp); | ||
833 | |||
834 | ret = sst_fw_reload(byt->fw); | ||
835 | if (ret < 0) { | ||
836 | dev_err(dev, "error: failed to reload firmware\n"); | ||
837 | return ret; | ||
838 | } | ||
839 | |||
840 | /* wait for DSP boot completion */ | ||
841 | byt->boot_complete = false; | ||
842 | sst_dsp_boot(byt->dsp); | ||
843 | dev_dbg(byt->dev, "dsp booting...\n"); | ||
844 | |||
845 | return 0; | ||
846 | } | ||
847 | EXPORT_SYMBOL_GPL(sst_byt_dsp_boot); | ||
848 | |||
849 | int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata) | ||
850 | { | ||
851 | struct sst_byt *byt = pdata->dsp; | ||
852 | int err; | ||
853 | |||
854 | dev_dbg(byt->dev, "wait for dsp reboot\n"); | ||
855 | |||
856 | err = wait_event_timeout(byt->boot_wait, byt->boot_complete, | ||
857 | msecs_to_jiffies(IPC_BOOT_MSECS)); | ||
858 | if (err == 0) { | ||
859 | dev_err(byt->dev, "ipc: error DSP boot timeout\n"); | ||
860 | return -EIO; | ||
861 | } | ||
862 | |||
863 | dev_dbg(byt->dev, "dsp rebooted\n"); | ||
864 | return 0; | ||
865 | } | ||
866 | EXPORT_SYMBOL_GPL(sst_byt_dsp_wait_for_ready); | ||
867 | |||
785 | int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) | 868 | int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) |
786 | { | 869 | { |
787 | struct sst_byt *byt; | 870 | struct sst_byt *byt; |
@@ -848,6 +931,7 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata) | |||
848 | } | 931 | } |
849 | 932 | ||
850 | pdata->dsp = byt; | 933 | pdata->dsp = byt; |
934 | byt->fw = byt_sst_fw; | ||
851 | 935 | ||
852 | return 0; | 936 | return 0; |
853 | 937 | ||
diff --git a/sound/soc/intel/sst-baytrail-ipc.h b/sound/soc/intel/sst-baytrail-ipc.h index f172b6440fa9..06a4d202689b 100644 --- a/sound/soc/intel/sst-baytrail-ipc.h +++ b/sound/soc/intel/sst-baytrail-ipc.h | |||
@@ -53,7 +53,8 @@ int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream); | |||
53 | int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream); | 53 | int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream); |
54 | 54 | ||
55 | /* stream ALSA trigger operations */ | 55 | /* stream ALSA trigger operations */ |
56 | int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream); | 56 | int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream, |
57 | u32 start_offset); | ||
57 | int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream); | 58 | int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream); |
58 | int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream); | 59 | int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream); |
59 | int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream); | 60 | int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream); |
@@ -65,5 +66,9 @@ int sst_byt_get_dsp_position(struct sst_byt *byt, | |||
65 | int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata); | 66 | int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata); |
66 | void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata); | 67 | void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata); |
67 | struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt); | 68 | struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt); |
69 | int sst_byt_dsp_suspend_noirq(struct device *dev, struct sst_pdata *pdata); | ||
70 | int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata); | ||
71 | int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata); | ||
72 | int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata); | ||
68 | 73 | ||
69 | #endif | 74 | #endif |
diff --git a/sound/soc/intel/sst-baytrail-pcm.c b/sound/soc/intel/sst-baytrail-pcm.c index 6d101f3813b4..3af38576e91e 100644 --- a/sound/soc/intel/sst-baytrail-pcm.c +++ b/sound/soc/intel/sst-baytrail-pcm.c | |||
@@ -45,6 +45,11 @@ struct sst_byt_pcm_data { | |||
45 | struct sst_byt_stream *stream; | 45 | struct sst_byt_stream *stream; |
46 | struct snd_pcm_substream *substream; | 46 | struct snd_pcm_substream *substream; |
47 | struct mutex mutex; | 47 | struct mutex mutex; |
48 | |||
49 | /* latest DSP DMA hw pointer */ | ||
50 | u32 hw_ptr; | ||
51 | |||
52 | struct work_struct work; | ||
48 | }; | 53 | }; |
49 | 54 | ||
50 | /* private data for the driver */ | 55 | /* private data for the driver */ |
@@ -63,7 +68,7 @@ static int sst_byt_pcm_hw_params(struct snd_pcm_substream *substream, | |||
63 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 68 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
64 | struct sst_byt_priv_data *pdata = | 69 | struct sst_byt_priv_data *pdata = |
65 | snd_soc_platform_get_drvdata(rtd->platform); | 70 | snd_soc_platform_get_drvdata(rtd->platform); |
66 | struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 71 | struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream]; |
67 | struct sst_byt *byt = pdata->byt; | 72 | struct sst_byt *byt = pdata->byt; |
68 | u32 rate, bits; | 73 | u32 rate, bits; |
69 | u8 channels; | 74 | u8 channels; |
@@ -130,21 +135,56 @@ static int sst_byt_pcm_hw_free(struct snd_pcm_substream *substream) | |||
130 | return 0; | 135 | return 0; |
131 | } | 136 | } |
132 | 137 | ||
138 | static int sst_byt_pcm_restore_stream_context(struct snd_pcm_substream *substream) | ||
139 | { | ||
140 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
141 | struct sst_byt_priv_data *pdata = | ||
142 | snd_soc_platform_get_drvdata(rtd->platform); | ||
143 | struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream]; | ||
144 | struct sst_byt *byt = pdata->byt; | ||
145 | int ret; | ||
146 | |||
147 | /* commit stream using existing stream params */ | ||
148 | ret = sst_byt_stream_commit(byt, pcm_data->stream); | ||
149 | if (ret < 0) { | ||
150 | dev_err(rtd->dev, "PCM: failed stream commit %d\n", ret); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
154 | sst_byt_stream_start(byt, pcm_data->stream, pcm_data->hw_ptr); | ||
155 | |||
156 | dev_dbg(rtd->dev, "stream context restored at offset %d\n", | ||
157 | pcm_data->hw_ptr); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | |||
162 | static void sst_byt_pcm_work(struct work_struct *work) | ||
163 | { | ||
164 | struct sst_byt_pcm_data *pcm_data = | ||
165 | container_of(work, struct sst_byt_pcm_data, work); | ||
166 | |||
167 | if (snd_pcm_running(pcm_data->substream)) | ||
168 | sst_byt_pcm_restore_stream_context(pcm_data->substream); | ||
169 | } | ||
170 | |||
133 | static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 171 | static int sst_byt_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
134 | { | 172 | { |
135 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 173 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
136 | struct sst_byt_priv_data *pdata = | 174 | struct sst_byt_priv_data *pdata = |
137 | snd_soc_platform_get_drvdata(rtd->platform); | 175 | snd_soc_platform_get_drvdata(rtd->platform); |
138 | struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 176 | struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream]; |
139 | struct sst_byt *byt = pdata->byt; | 177 | struct sst_byt *byt = pdata->byt; |
140 | 178 | ||
141 | dev_dbg(rtd->dev, "PCM: trigger %d\n", cmd); | 179 | dev_dbg(rtd->dev, "PCM: trigger %d\n", cmd); |
142 | 180 | ||
143 | switch (cmd) { | 181 | switch (cmd) { |
144 | case SNDRV_PCM_TRIGGER_START: | 182 | case SNDRV_PCM_TRIGGER_START: |
145 | sst_byt_stream_start(byt, pcm_data->stream); | 183 | sst_byt_stream_start(byt, pcm_data->stream, 0); |
146 | break; | 184 | break; |
147 | case SNDRV_PCM_TRIGGER_RESUME: | 185 | case SNDRV_PCM_TRIGGER_RESUME: |
186 | schedule_work(&pcm_data->work); | ||
187 | break; | ||
148 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 188 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
149 | sst_byt_stream_resume(byt, pcm_data->stream); | 189 | sst_byt_stream_resume(byt, pcm_data->stream); |
150 | break; | 190 | break; |
@@ -168,13 +208,19 @@ static u32 byt_notify_pointer(struct sst_byt_stream *stream, void *data) | |||
168 | struct snd_pcm_substream *substream = pcm_data->substream; | 208 | struct snd_pcm_substream *substream = pcm_data->substream; |
169 | struct snd_pcm_runtime *runtime = substream->runtime; | 209 | struct snd_pcm_runtime *runtime = substream->runtime; |
170 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 210 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
171 | u32 pos; | 211 | struct sst_byt_priv_data *pdata = |
212 | snd_soc_platform_get_drvdata(rtd->platform); | ||
213 | struct sst_byt *byt = pdata->byt; | ||
214 | u32 pos, hw_pos; | ||
172 | 215 | ||
216 | hw_pos = sst_byt_get_dsp_position(byt, pcm_data->stream, | ||
217 | snd_pcm_lib_buffer_bytes(substream)); | ||
218 | pcm_data->hw_ptr = hw_pos; | ||
173 | pos = frames_to_bytes(runtime, | 219 | pos = frames_to_bytes(runtime, |
174 | (runtime->control->appl_ptr % | 220 | (runtime->control->appl_ptr % |
175 | runtime->buffer_size)); | 221 | runtime->buffer_size)); |
176 | 222 | ||
177 | dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos); | 223 | dev_dbg(rtd->dev, "PCM: App/DMA pointer %u/%u bytes\n", pos, hw_pos); |
178 | 224 | ||
179 | snd_pcm_period_elapsed(substream); | 225 | snd_pcm_period_elapsed(substream); |
180 | return pos; | 226 | return pos; |
@@ -186,18 +232,11 @@ static snd_pcm_uframes_t sst_byt_pcm_pointer(struct snd_pcm_substream *substream | |||
186 | struct snd_pcm_runtime *runtime = substream->runtime; | 232 | struct snd_pcm_runtime *runtime = substream->runtime; |
187 | struct sst_byt_priv_data *pdata = | 233 | struct sst_byt_priv_data *pdata = |
188 | snd_soc_platform_get_drvdata(rtd->platform); | 234 | snd_soc_platform_get_drvdata(rtd->platform); |
189 | struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 235 | struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream]; |
190 | struct sst_byt *byt = pdata->byt; | ||
191 | snd_pcm_uframes_t offset; | ||
192 | int pos; | ||
193 | 236 | ||
194 | pos = sst_byt_get_dsp_position(byt, pcm_data->stream, | 237 | dev_dbg(rtd->dev, "PCM: DMA pointer %u bytes\n", pcm_data->hw_ptr); |
195 | snd_pcm_lib_buffer_bytes(substream)); | ||
196 | offset = bytes_to_frames(runtime, pos); | ||
197 | 238 | ||
198 | dev_dbg(rtd->dev, "PCM: DMA pointer %zu bytes\n", | 239 | return bytes_to_frames(runtime, pcm_data->hw_ptr); |
199 | frames_to_bytes(runtime, (u32)offset)); | ||
200 | return offset; | ||
201 | } | 240 | } |
202 | 241 | ||
203 | static int sst_byt_pcm_open(struct snd_pcm_substream *substream) | 242 | static int sst_byt_pcm_open(struct snd_pcm_substream *substream) |
@@ -205,20 +244,18 @@ static int sst_byt_pcm_open(struct snd_pcm_substream *substream) | |||
205 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 244 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
206 | struct sst_byt_priv_data *pdata = | 245 | struct sst_byt_priv_data *pdata = |
207 | snd_soc_platform_get_drvdata(rtd->platform); | 246 | snd_soc_platform_get_drvdata(rtd->platform); |
208 | struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 247 | struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream]; |
209 | struct sst_byt *byt = pdata->byt; | 248 | struct sst_byt *byt = pdata->byt; |
210 | 249 | ||
211 | dev_dbg(rtd->dev, "PCM: open\n"); | 250 | dev_dbg(rtd->dev, "PCM: open\n"); |
212 | 251 | ||
213 | pcm_data = &pdata->pcm[rtd->cpu_dai->id]; | ||
214 | mutex_lock(&pcm_data->mutex); | 252 | mutex_lock(&pcm_data->mutex); |
215 | 253 | ||
216 | snd_soc_pcm_set_drvdata(rtd, pcm_data); | ||
217 | pcm_data->substream = substream; | 254 | pcm_data->substream = substream; |
218 | 255 | ||
219 | snd_soc_set_runtime_hwparams(substream, &sst_byt_pcm_hardware); | 256 | snd_soc_set_runtime_hwparams(substream, &sst_byt_pcm_hardware); |
220 | 257 | ||
221 | pcm_data->stream = sst_byt_stream_new(byt, rtd->cpu_dai->id + 1, | 258 | pcm_data->stream = sst_byt_stream_new(byt, substream->stream + 1, |
222 | byt_notify_pointer, pcm_data); | 259 | byt_notify_pointer, pcm_data); |
223 | if (pcm_data->stream == NULL) { | 260 | if (pcm_data->stream == NULL) { |
224 | dev_err(rtd->dev, "failed to create stream\n"); | 261 | dev_err(rtd->dev, "failed to create stream\n"); |
@@ -235,12 +272,13 @@ static int sst_byt_pcm_close(struct snd_pcm_substream *substream) | |||
235 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 272 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
236 | struct sst_byt_priv_data *pdata = | 273 | struct sst_byt_priv_data *pdata = |
237 | snd_soc_platform_get_drvdata(rtd->platform); | 274 | snd_soc_platform_get_drvdata(rtd->platform); |
238 | struct sst_byt_pcm_data *pcm_data = snd_soc_pcm_get_drvdata(rtd); | 275 | struct sst_byt_pcm_data *pcm_data = &pdata->pcm[substream->stream]; |
239 | struct sst_byt *byt = pdata->byt; | 276 | struct sst_byt *byt = pdata->byt; |
240 | int ret; | 277 | int ret; |
241 | 278 | ||
242 | dev_dbg(rtd->dev, "PCM: close\n"); | 279 | dev_dbg(rtd->dev, "PCM: close\n"); |
243 | 280 | ||
281 | cancel_work_sync(&pcm_data->work); | ||
244 | mutex_lock(&pcm_data->mutex); | 282 | mutex_lock(&pcm_data->mutex); |
245 | ret = sst_byt_stream_free(byt, pcm_data->stream); | 283 | ret = sst_byt_stream_free(byt, pcm_data->stream); |
246 | if (ret < 0) { | 284 | if (ret < 0) { |
@@ -283,18 +321,16 @@ static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
283 | { | 321 | { |
284 | struct snd_pcm *pcm = rtd->pcm; | 322 | struct snd_pcm *pcm = rtd->pcm; |
285 | size_t size; | 323 | size_t size; |
324 | struct snd_soc_platform *platform = rtd->platform; | ||
325 | struct sst_pdata *pdata = dev_get_platdata(platform->dev); | ||
286 | int ret = 0; | 326 | int ret = 0; |
287 | 327 | ||
288 | ret = dma_coerce_mask_and_coherent(rtd->card->dev, DMA_BIT_MASK(32)); | ||
289 | if (ret) | ||
290 | return ret; | ||
291 | |||
292 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || | 328 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream || |
293 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | 329 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
294 | size = sst_byt_pcm_hardware.buffer_bytes_max; | 330 | size = sst_byt_pcm_hardware.buffer_bytes_max; |
295 | ret = snd_pcm_lib_preallocate_pages_for_all(pcm, | 331 | ret = snd_pcm_lib_preallocate_pages_for_all(pcm, |
296 | SNDRV_DMA_TYPE_DEV, | 332 | SNDRV_DMA_TYPE_DEV, |
297 | rtd->card->dev, | 333 | pdata->dma_dev, |
298 | size, size); | 334 | size, size); |
299 | if (ret) { | 335 | if (ret) { |
300 | dev_err(rtd->dev, "dma buffer allocation failed %d\n", | 336 | dev_err(rtd->dev, "dma buffer allocation failed %d\n", |
@@ -308,7 +344,7 @@ static int sst_byt_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
308 | 344 | ||
309 | static struct snd_soc_dai_driver byt_dais[] = { | 345 | static struct snd_soc_dai_driver byt_dais[] = { |
310 | { | 346 | { |
311 | .name = "Front-cpu-dai", | 347 | .name = "Baytrail PCM", |
312 | .playback = { | 348 | .playback = { |
313 | .stream_name = "System Playback", | 349 | .stream_name = "System Playback", |
314 | .channels_min = 2, | 350 | .channels_min = 2, |
@@ -317,9 +353,6 @@ static struct snd_soc_dai_driver byt_dais[] = { | |||
317 | .formats = SNDRV_PCM_FMTBIT_S24_3LE | | 353 | .formats = SNDRV_PCM_FMTBIT_S24_3LE | |
318 | SNDRV_PCM_FMTBIT_S16_LE, | 354 | SNDRV_PCM_FMTBIT_S16_LE, |
319 | }, | 355 | }, |
320 | }, | ||
321 | { | ||
322 | .name = "Mic1-cpu-dai", | ||
323 | .capture = { | 356 | .capture = { |
324 | .stream_name = "Analog Capture", | 357 | .stream_name = "Analog Capture", |
325 | .channels_min = 2, | 358 | .channels_min = 2, |
@@ -344,8 +377,10 @@ static int sst_byt_pcm_probe(struct snd_soc_platform *platform) | |||
344 | priv_data->byt = plat_data->dsp; | 377 | priv_data->byt = plat_data->dsp; |
345 | snd_soc_platform_set_drvdata(platform, priv_data); | 378 | snd_soc_platform_set_drvdata(platform, priv_data); |
346 | 379 | ||
347 | for (i = 0; i < ARRAY_SIZE(byt_dais); i++) | 380 | for (i = 0; i < BYT_PCM_COUNT; i++) { |
348 | mutex_init(&priv_data->pcm[i].mutex); | 381 | mutex_init(&priv_data->pcm[i].mutex); |
382 | INIT_WORK(&priv_data->pcm[i].work, sst_byt_pcm_work); | ||
383 | } | ||
349 | 384 | ||
350 | return 0; | 385 | return 0; |
351 | } | 386 | } |
@@ -367,6 +402,72 @@ static const struct snd_soc_component_driver byt_dai_component = { | |||
367 | .name = "byt-dai", | 402 | .name = "byt-dai", |
368 | }; | 403 | }; |
369 | 404 | ||
405 | #ifdef CONFIG_PM | ||
406 | static int sst_byt_pcm_dev_suspend_noirq(struct device *dev) | ||
407 | { | ||
408 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | ||
409 | int ret; | ||
410 | |||
411 | dev_dbg(dev, "suspending noirq\n"); | ||
412 | |||
413 | /* at this point all streams will be stopped and context saved */ | ||
414 | ret = sst_byt_dsp_suspend_noirq(dev, sst_pdata); | ||
415 | if (ret < 0) { | ||
416 | dev_err(dev, "failed to suspend %d\n", ret); | ||
417 | return ret; | ||
418 | } | ||
419 | |||
420 | return ret; | ||
421 | } | ||
422 | |||
423 | static int sst_byt_pcm_dev_suspend_late(struct device *dev) | ||
424 | { | ||
425 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | ||
426 | int ret; | ||
427 | |||
428 | dev_dbg(dev, "suspending late\n"); | ||
429 | |||
430 | ret = sst_byt_dsp_suspend_late(dev, sst_pdata); | ||
431 | if (ret < 0) { | ||
432 | dev_err(dev, "failed to suspend %d\n", ret); | ||
433 | return ret; | ||
434 | } | ||
435 | |||
436 | return ret; | ||
437 | } | ||
438 | |||
439 | static int sst_byt_pcm_dev_resume_early(struct device *dev) | ||
440 | { | ||
441 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | ||
442 | |||
443 | dev_dbg(dev, "resume early\n"); | ||
444 | |||
445 | /* load fw and boot DSP */ | ||
446 | return sst_byt_dsp_boot(dev, sst_pdata); | ||
447 | } | ||
448 | |||
449 | static int sst_byt_pcm_dev_resume(struct device *dev) | ||
450 | { | ||
451 | struct sst_pdata *sst_pdata = dev_get_platdata(dev); | ||
452 | |||
453 | dev_dbg(dev, "resume\n"); | ||
454 | |||
455 | /* wait for FW to finish booting */ | ||
456 | return sst_byt_dsp_wait_for_ready(dev, sst_pdata); | ||
457 | } | ||
458 | |||
459 | static const struct dev_pm_ops sst_byt_pm_ops = { | ||
460 | .suspend_noirq = sst_byt_pcm_dev_suspend_noirq, | ||
461 | .suspend_late = sst_byt_pcm_dev_suspend_late, | ||
462 | .resume_early = sst_byt_pcm_dev_resume_early, | ||
463 | .resume = sst_byt_pcm_dev_resume, | ||
464 | }; | ||
465 | |||
466 | #define SST_BYT_PM_OPS (&sst_byt_pm_ops) | ||
467 | #else | ||
468 | #define SST_BYT_PM_OPS NULL | ||
469 | #endif | ||
470 | |||
370 | static int sst_byt_pcm_dev_probe(struct platform_device *pdev) | 471 | static int sst_byt_pcm_dev_probe(struct platform_device *pdev) |
371 | { | 472 | { |
372 | struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev); | 473 | struct sst_pdata *sst_pdata = dev_get_platdata(&pdev->dev); |
@@ -409,6 +510,7 @@ static struct platform_driver sst_byt_pcm_driver = { | |||
409 | .driver = { | 510 | .driver = { |
410 | .name = "baytrail-pcm-audio", | 511 | .name = "baytrail-pcm-audio", |
411 | .owner = THIS_MODULE, | 512 | .owner = THIS_MODULE, |
513 | .pm = SST_BYT_PM_OPS, | ||
412 | }, | 514 | }, |
413 | 515 | ||
414 | .probe = sst_byt_pcm_dev_probe, | 516 | .probe = sst_byt_pcm_dev_probe, |
diff --git a/sound/soc/intel/sst-dsp-priv.h b/sound/soc/intel/sst-dsp-priv.h index 401213455497..ffb308bd81ce 100644 --- a/sound/soc/intel/sst-dsp-priv.h +++ b/sound/soc/intel/sst-dsp-priv.h | |||
@@ -284,6 +284,8 @@ struct sst_fw *sst_fw_new(struct sst_dsp *dsp, | |||
284 | const struct firmware *fw, void *private); | 284 | const struct firmware *fw, void *private); |
285 | void sst_fw_free(struct sst_fw *sst_fw); | 285 | void sst_fw_free(struct sst_fw *sst_fw); |
286 | void sst_fw_free_all(struct sst_dsp *dsp); | 286 | void sst_fw_free_all(struct sst_dsp *dsp); |
287 | int sst_fw_reload(struct sst_fw *sst_fw); | ||
288 | void sst_fw_unload(struct sst_fw *sst_fw); | ||
287 | 289 | ||
288 | /* Create/Free firmware modules */ | 290 | /* Create/Free firmware modules */ |
289 | struct sst_module *sst_module_new(struct sst_fw *sst_fw, | 291 | struct sst_module *sst_module_new(struct sst_fw *sst_fw, |
diff --git a/sound/soc/intel/sst-firmware.c b/sound/soc/intel/sst-firmware.c index 928f228c38e7..3bb43dac892d 100644 --- a/sound/soc/intel/sst-firmware.c +++ b/sound/soc/intel/sst-firmware.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "sst-dsp.h" | 30 | #include "sst-dsp.h" |
31 | #include "sst-dsp-priv.h" | 31 | #include "sst-dsp-priv.h" |
32 | 32 | ||
33 | static void block_module_remove(struct sst_module *module); | ||
34 | |||
33 | static void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) | 35 | static void sst_memcpy32(volatile void __iomem *dest, void *src, u32 bytes) |
34 | { | 36 | { |
35 | u32 i; | 37 | u32 i; |
@@ -91,6 +93,42 @@ parse_err: | |||
91 | } | 93 | } |
92 | EXPORT_SYMBOL_GPL(sst_fw_new); | 94 | EXPORT_SYMBOL_GPL(sst_fw_new); |
93 | 95 | ||
96 | int sst_fw_reload(struct sst_fw *sst_fw) | ||
97 | { | ||
98 | struct sst_dsp *dsp = sst_fw->dsp; | ||
99 | int ret; | ||
100 | |||
101 | dev_dbg(dsp->dev, "reloading firmware\n"); | ||
102 | |||
103 | /* call core specific FW paser to load FW data into DSP */ | ||
104 | ret = dsp->ops->parse_fw(sst_fw); | ||
105 | if (ret < 0) | ||
106 | dev_err(dsp->dev, "error: parse fw failed %d\n", ret); | ||
107 | |||
108 | return ret; | ||
109 | } | ||
110 | EXPORT_SYMBOL_GPL(sst_fw_reload); | ||
111 | |||
112 | void sst_fw_unload(struct sst_fw *sst_fw) | ||
113 | { | ||
114 | struct sst_dsp *dsp = sst_fw->dsp; | ||
115 | struct sst_module *module, *tmp; | ||
116 | |||
117 | dev_dbg(dsp->dev, "unloading firmware\n"); | ||
118 | |||
119 | mutex_lock(&dsp->mutex); | ||
120 | list_for_each_entry_safe(module, tmp, &dsp->module_list, list) { | ||
121 | if (module->sst_fw == sst_fw) { | ||
122 | block_module_remove(module); | ||
123 | list_del(&module->list); | ||
124 | kfree(module); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | mutex_unlock(&dsp->mutex); | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(sst_fw_unload); | ||
131 | |||
94 | /* free single firmware object */ | 132 | /* free single firmware object */ |
95 | void sst_fw_free(struct sst_fw *sst_fw) | 133 | void sst_fw_free(struct sst_fw *sst_fw) |
96 | { | 134 | { |
@@ -496,9 +534,7 @@ struct sst_module *sst_mem_block_alloc_scratch(struct sst_dsp *dsp) | |||
496 | 534 | ||
497 | /* calculate required scratch size */ | 535 | /* calculate required scratch size */ |
498 | list_for_each_entry(sst_module, &dsp->module_list, list) { | 536 | list_for_each_entry(sst_module, &dsp->module_list, list) { |
499 | if (scratch->s.size > sst_module->s.size) | 537 | if (scratch->s.size < sst_module->s.size) |
500 | scratch->s.size = scratch->s.size; | ||
501 | else | ||
502 | scratch->s.size = sst_module->s.size; | 538 | scratch->s.size = sst_module->s.size; |
503 | } | 539 | } |
504 | 540 | ||
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index 9d5f64a583a3..ce27b507d5ef 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c | |||
@@ -139,7 +139,7 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value) | |||
139 | static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, | 139 | static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, |
140 | struct snd_ctl_elem_value *ucontrol) | 140 | struct snd_ctl_elem_value *ucontrol) |
141 | { | 141 | { |
142 | struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); | 142 | struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); |
143 | struct soc_mixer_control *mc = | 143 | struct soc_mixer_control *mc = |
144 | (struct soc_mixer_control *)kcontrol->private_value; | 144 | (struct soc_mixer_control *)kcontrol->private_value; |
145 | struct hsw_priv_data *pdata = | 145 | struct hsw_priv_data *pdata = |
@@ -177,7 +177,7 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, | |||
177 | static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, | 177 | static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, |
178 | struct snd_ctl_elem_value *ucontrol) | 178 | struct snd_ctl_elem_value *ucontrol) |
179 | { | 179 | { |
180 | struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); | 180 | struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); |
181 | struct soc_mixer_control *mc = | 181 | struct soc_mixer_control *mc = |
182 | (struct soc_mixer_control *)kcontrol->private_value; | 182 | (struct soc_mixer_control *)kcontrol->private_value; |
183 | struct hsw_priv_data *pdata = | 183 | struct hsw_priv_data *pdata = |
@@ -209,7 +209,7 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, | |||
209 | static int hsw_volume_put(struct snd_kcontrol *kcontrol, | 209 | static int hsw_volume_put(struct snd_kcontrol *kcontrol, |
210 | struct snd_ctl_elem_value *ucontrol) | 210 | struct snd_ctl_elem_value *ucontrol) |
211 | { | 211 | { |
212 | struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); | 212 | struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); |
213 | struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); | 213 | struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); |
214 | struct sst_hsw *hsw = pdata->hsw; | 214 | struct sst_hsw *hsw = pdata->hsw; |
215 | u32 volume; | 215 | u32 volume; |
@@ -234,7 +234,7 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol, | |||
234 | static int hsw_volume_get(struct snd_kcontrol *kcontrol, | 234 | static int hsw_volume_get(struct snd_kcontrol *kcontrol, |
235 | struct snd_ctl_elem_value *ucontrol) | 235 | struct snd_ctl_elem_value *ucontrol) |
236 | { | 236 | { |
237 | struct snd_soc_platform *platform = snd_kcontrol_chip(kcontrol); | 237 | struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol); |
238 | struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); | 238 | struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform); |
239 | struct sst_hsw *hsw = pdata->hsw; | 239 | struct sst_hsw *hsw = pdata->hsw; |
240 | unsigned int volume = 0; | 240 | unsigned int volume = 0; |
diff --git a/sound/soc/intel/sst-mfld-dsp.h b/sound/soc/intel/sst-mfld-dsp.h index 3b63edc04b7f..8d482d76475a 100644 --- a/sound/soc/intel/sst-mfld-dsp.h +++ b/sound/soc/intel/sst-mfld-dsp.h | |||
@@ -16,10 +16,6 @@ | |||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * General Public License for more details. | 17 | * General Public License for more details. |
18 | * | 18 | * |
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
21 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | ||
22 | * | ||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
24 | */ | 20 | */ |
25 | 21 | ||
@@ -40,7 +36,6 @@ enum stream_type { | |||
40 | }; | 36 | }; |
41 | 37 | ||
42 | struct snd_pcm_params { | 38 | struct snd_pcm_params { |
43 | u16 codec; /* codec type */ | ||
44 | u8 num_chan; /* 1=Mono, 2=Stereo */ | 39 | u8 num_chan; /* 1=Mono, 2=Stereo */ |
45 | u8 pcm_wd_sz; /* 16/24 - bit*/ | 40 | u8 pcm_wd_sz; /* 16/24 - bit*/ |
46 | u32 reserved; /* Bitrate in bits per second */ | 41 | u32 reserved; /* Bitrate in bits per second */ |
@@ -53,7 +48,6 @@ struct snd_pcm_params { | |||
53 | 48 | ||
54 | /* MP3 Music Parameters Message */ | 49 | /* MP3 Music Parameters Message */ |
55 | struct snd_mp3_params { | 50 | struct snd_mp3_params { |
56 | u16 codec; | ||
57 | u8 num_chan; /* 1=Mono, 2=Stereo */ | 51 | u8 num_chan; /* 1=Mono, 2=Stereo */ |
58 | u8 pcm_wd_sz; /* 16/24 - bit*/ | 52 | u8 pcm_wd_sz; /* 16/24 - bit*/ |
59 | u8 crc_check; /* crc_check - disable (0) or enable (1) */ | 53 | u8 crc_check; /* crc_check - disable (0) or enable (1) */ |
@@ -67,7 +61,6 @@ struct snd_mp3_params { | |||
67 | 61 | ||
68 | /* AAC Music Parameters Message */ | 62 | /* AAC Music Parameters Message */ |
69 | struct snd_aac_params { | 63 | struct snd_aac_params { |
70 | u16 codec; | ||
71 | u8 num_chan; /* 1=Mono, 2=Stereo*/ | 64 | u8 num_chan; /* 1=Mono, 2=Stereo*/ |
72 | u8 pcm_wd_sz; /* 16/24 - bit*/ | 65 | u8 pcm_wd_sz; /* 16/24 - bit*/ |
73 | u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */ | 66 | u8 bdownsample; /*SBR downsampling 0 - disable 1 -enabled AAC+ only */ |
@@ -81,7 +74,6 @@ struct snd_aac_params { | |||
81 | 74 | ||
82 | /* WMA Music Parameters Message */ | 75 | /* WMA Music Parameters Message */ |
83 | struct snd_wma_params { | 76 | struct snd_wma_params { |
84 | u16 codec; | ||
85 | u8 num_chan; /* 1=Mono, 2=Stereo */ | 77 | u8 num_chan; /* 1=Mono, 2=Stereo */ |
86 | u8 pcm_wd_sz; /* 16/24 - bit*/ | 78 | u8 pcm_wd_sz; /* 16/24 - bit*/ |
87 | u32 brate; /* Use the hard coded value. */ | 79 | u32 brate; /* Use the hard coded value. */ |
diff --git a/sound/soc/intel/sst-mfld-platform-compress.c b/sound/soc/intel/sst-mfld-platform-compress.c new file mode 100644 index 000000000000..02abd19fce1d --- /dev/null +++ b/sound/soc/intel/sst-mfld-platform-compress.c | |||
@@ -0,0 +1,237 @@ | |||
1 | /* | ||
2 | * sst_mfld_platform.c - Intel MID Platform driver | ||
3 | * | ||
4 | * Copyright (C) 2010-2014 Intel Corp | ||
5 | * Author: Vinod Koul <vinod.koul@intel.com> | ||
6 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; version 2 of the License. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
18 | */ | ||
19 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
20 | |||
21 | #include <linux/slab.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include <sound/pcm_params.h> | ||
27 | #include <sound/soc.h> | ||
28 | #include <sound/compress_driver.h> | ||
29 | #include "sst-mfld-platform.h" | ||
30 | |||
31 | /* compress stream operations */ | ||
32 | static void sst_compr_fragment_elapsed(void *arg) | ||
33 | { | ||
34 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
35 | |||
36 | pr_debug("fragment elapsed by driver\n"); | ||
37 | if (cstream) | ||
38 | snd_compr_fragment_elapsed(cstream); | ||
39 | } | ||
40 | |||
41 | static void sst_drain_notify(void *arg) | ||
42 | { | ||
43 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
44 | |||
45 | pr_debug("drain notify by driver\n"); | ||
46 | if (cstream) | ||
47 | snd_compr_drain_notify(cstream); | ||
48 | } | ||
49 | |||
50 | static int sst_platform_compr_open(struct snd_compr_stream *cstream) | ||
51 | { | ||
52 | |||
53 | int ret_val = 0; | ||
54 | struct snd_compr_runtime *runtime = cstream->runtime; | ||
55 | struct sst_runtime_stream *stream; | ||
56 | |||
57 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
58 | if (!stream) | ||
59 | return -ENOMEM; | ||
60 | |||
61 | spin_lock_init(&stream->status_lock); | ||
62 | |||
63 | /* get the sst ops */ | ||
64 | if (!sst || !try_module_get(sst->dev->driver->owner)) { | ||
65 | pr_err("no device available to run\n"); | ||
66 | ret_val = -ENODEV; | ||
67 | goto out_ops; | ||
68 | } | ||
69 | stream->compr_ops = sst->compr_ops; | ||
70 | |||
71 | stream->id = 0; | ||
72 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
73 | runtime->private_data = stream; | ||
74 | return 0; | ||
75 | out_ops: | ||
76 | kfree(stream); | ||
77 | return ret_val; | ||
78 | } | ||
79 | |||
80 | static int sst_platform_compr_free(struct snd_compr_stream *cstream) | ||
81 | { | ||
82 | struct sst_runtime_stream *stream; | ||
83 | int ret_val = 0, str_id; | ||
84 | |||
85 | stream = cstream->runtime->private_data; | ||
86 | /*need to check*/ | ||
87 | str_id = stream->id; | ||
88 | if (str_id) | ||
89 | ret_val = stream->compr_ops->close(str_id); | ||
90 | module_put(sst->dev->driver->owner); | ||
91 | kfree(stream); | ||
92 | pr_debug("%s: %d\n", __func__, ret_val); | ||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static int sst_platform_compr_set_params(struct snd_compr_stream *cstream, | ||
97 | struct snd_compr_params *params) | ||
98 | { | ||
99 | struct sst_runtime_stream *stream; | ||
100 | int retval; | ||
101 | struct snd_sst_params str_params; | ||
102 | struct sst_compress_cb cb; | ||
103 | |||
104 | stream = cstream->runtime->private_data; | ||
105 | /* construct fw structure for this*/ | ||
106 | memset(&str_params, 0, sizeof(str_params)); | ||
107 | |||
108 | str_params.ops = STREAM_OPS_PLAYBACK; | ||
109 | str_params.stream_type = SST_STREAM_TYPE_MUSIC; | ||
110 | str_params.device_type = SND_SST_DEVICE_COMPRESS; | ||
111 | |||
112 | switch (params->codec.id) { | ||
113 | case SND_AUDIOCODEC_MP3: { | ||
114 | str_params.codec = SST_CODEC_TYPE_MP3; | ||
115 | str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in; | ||
116 | str_params.sparams.uc.mp3_params.pcm_wd_sz = 16; | ||
117 | break; | ||
118 | } | ||
119 | |||
120 | case SND_AUDIOCODEC_AAC: { | ||
121 | str_params.codec = SST_CODEC_TYPE_AAC; | ||
122 | str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in; | ||
123 | str_params.sparams.uc.aac_params.pcm_wd_sz = 16; | ||
124 | if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS) | ||
125 | str_params.sparams.uc.aac_params.bs_format = | ||
126 | AAC_BIT_STREAM_ADTS; | ||
127 | else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW) | ||
128 | str_params.sparams.uc.aac_params.bs_format = | ||
129 | AAC_BIT_STREAM_RAW; | ||
130 | else { | ||
131 | pr_err("Undefined format%d\n", params->codec.format); | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | str_params.sparams.uc.aac_params.externalsr = | ||
135 | params->codec.sample_rate; | ||
136 | break; | ||
137 | } | ||
138 | |||
139 | default: | ||
140 | pr_err("codec not supported, id =%d\n", params->codec.id); | ||
141 | return -EINVAL; | ||
142 | } | ||
143 | |||
144 | str_params.aparams.ring_buf_info[0].addr = | ||
145 | virt_to_phys(cstream->runtime->buffer); | ||
146 | str_params.aparams.ring_buf_info[0].size = | ||
147 | cstream->runtime->buffer_size; | ||
148 | str_params.aparams.sg_count = 1; | ||
149 | str_params.aparams.frag_size = cstream->runtime->fragment_size; | ||
150 | |||
151 | cb.param = cstream; | ||
152 | cb.compr_cb = sst_compr_fragment_elapsed; | ||
153 | cb.drain_cb_param = cstream; | ||
154 | cb.drain_notify = sst_drain_notify; | ||
155 | |||
156 | retval = stream->compr_ops->open(&str_params, &cb); | ||
157 | if (retval < 0) { | ||
158 | pr_err("stream allocation failed %d\n", retval); | ||
159 | return retval; | ||
160 | } | ||
161 | |||
162 | stream->id = retval; | ||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
167 | { | ||
168 | struct sst_runtime_stream *stream = | ||
169 | cstream->runtime->private_data; | ||
170 | |||
171 | return stream->compr_ops->control(cmd, stream->id); | ||
172 | } | ||
173 | |||
174 | static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, | ||
175 | struct snd_compr_tstamp *tstamp) | ||
176 | { | ||
177 | struct sst_runtime_stream *stream; | ||
178 | |||
179 | stream = cstream->runtime->private_data; | ||
180 | stream->compr_ops->tstamp(stream->id, tstamp); | ||
181 | tstamp->byte_offset = tstamp->copied_total % | ||
182 | (u32)cstream->runtime->buffer_size; | ||
183 | pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static int sst_platform_compr_ack(struct snd_compr_stream *cstream, | ||
188 | size_t bytes) | ||
189 | { | ||
190 | struct sst_runtime_stream *stream; | ||
191 | |||
192 | stream = cstream->runtime->private_data; | ||
193 | stream->compr_ops->ack(stream->id, (unsigned long)bytes); | ||
194 | stream->bytes_written += bytes; | ||
195 | |||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream, | ||
200 | struct snd_compr_caps *caps) | ||
201 | { | ||
202 | struct sst_runtime_stream *stream = | ||
203 | cstream->runtime->private_data; | ||
204 | |||
205 | return stream->compr_ops->get_caps(caps); | ||
206 | } | ||
207 | |||
208 | static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
209 | struct snd_compr_codec_caps *codec) | ||
210 | { | ||
211 | struct sst_runtime_stream *stream = | ||
212 | cstream->runtime->private_data; | ||
213 | |||
214 | return stream->compr_ops->get_codec_caps(codec); | ||
215 | } | ||
216 | |||
217 | static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, | ||
218 | struct snd_compr_metadata *metadata) | ||
219 | { | ||
220 | struct sst_runtime_stream *stream = | ||
221 | cstream->runtime->private_data; | ||
222 | |||
223 | return stream->compr_ops->set_metadata(stream->id, metadata); | ||
224 | } | ||
225 | |||
226 | struct snd_compr_ops sst_platform_compr_ops = { | ||
227 | |||
228 | .open = sst_platform_compr_open, | ||
229 | .free = sst_platform_compr_free, | ||
230 | .set_params = sst_platform_compr_set_params, | ||
231 | .set_metadata = sst_platform_compr_set_metadata, | ||
232 | .trigger = sst_platform_compr_trigger, | ||
233 | .pointer = sst_platform_compr_pointer, | ||
234 | .ack = sst_platform_compr_ack, | ||
235 | .get_caps = sst_platform_compr_get_caps, | ||
236 | .get_codec_caps = sst_platform_compr_get_codec_caps, | ||
237 | }; | ||
diff --git a/sound/soc/intel/sst-mfld-platform.c b/sound/soc/intel/sst-mfld-platform-pcm.c index 840306c2ef14..7c790f51d259 100644 --- a/sound/soc/intel/sst-mfld-platform.c +++ b/sound/soc/intel/sst-mfld-platform-pcm.c | |||
@@ -15,13 +15,7 @@ | |||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | * General Public License for more details. | 16 | * General Public License for more details. |
17 | * | 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 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
23 | * | ||
24 | * | ||
25 | */ | 19 | */ |
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 20 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
27 | 21 | ||
@@ -35,8 +29,9 @@ | |||
35 | #include <sound/compress_driver.h> | 29 | #include <sound/compress_driver.h> |
36 | #include "sst-mfld-platform.h" | 30 | #include "sst-mfld-platform.h" |
37 | 31 | ||
38 | static struct sst_device *sst; | 32 | struct sst_device *sst; |
39 | static DEFINE_MUTEX(sst_lock); | 33 | static DEFINE_MUTEX(sst_lock); |
34 | extern struct snd_compr_ops sst_platform_compr_ops; | ||
40 | 35 | ||
41 | int sst_register_dsp(struct sst_device *dev) | 36 | int sst_register_dsp(struct sst_device *dev) |
42 | { | 37 | { |
@@ -116,36 +111,6 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { | |||
116 | }, | 111 | }, |
117 | }, | 112 | }, |
118 | { | 113 | { |
119 | .name = "Speaker-cpu-dai", | ||
120 | .id = 1, | ||
121 | .playback = { | ||
122 | .channels_min = SST_MONO, | ||
123 | .channels_max = SST_STEREO, | ||
124 | .rates = SNDRV_PCM_RATE_48000, | ||
125 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | ||
126 | }, | ||
127 | }, | ||
128 | { | ||
129 | .name = "Vibra1-cpu-dai", | ||
130 | .id = 2, | ||
131 | .playback = { | ||
132 | .channels_min = SST_MONO, | ||
133 | .channels_max = SST_MONO, | ||
134 | .rates = SNDRV_PCM_RATE_48000, | ||
135 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | ||
136 | }, | ||
137 | }, | ||
138 | { | ||
139 | .name = "Vibra2-cpu-dai", | ||
140 | .id = 3, | ||
141 | .playback = { | ||
142 | .channels_min = SST_MONO, | ||
143 | .channels_max = SST_STEREO, | ||
144 | .rates = SNDRV_PCM_RATE_48000, | ||
145 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | ||
146 | }, | ||
147 | }, | ||
148 | { | ||
149 | .name = "Compress-cpu-dai", | 114 | .name = "Compress-cpu-dai", |
150 | .compress_dai = 1, | 115 | .compress_dai = 1, |
151 | .playback = { | 116 | .playback = { |
@@ -157,12 +122,8 @@ static struct snd_soc_dai_driver sst_platform_dai[] = { | |||
157 | }, | 122 | }, |
158 | }; | 123 | }; |
159 | 124 | ||
160 | static const struct snd_soc_component_driver sst_component = { | ||
161 | .name = "sst", | ||
162 | }; | ||
163 | |||
164 | /* helper functions */ | 125 | /* helper functions */ |
165 | static inline void sst_set_stream_status(struct sst_runtime_stream *stream, | 126 | void sst_set_stream_status(struct sst_runtime_stream *stream, |
166 | int state) | 127 | int state) |
167 | { | 128 | { |
168 | unsigned long flags; | 129 | unsigned long flags; |
@@ -186,7 +147,6 @@ static void sst_fill_pcm_params(struct snd_pcm_substream *substream, | |||
186 | struct sst_pcm_params *param) | 147 | struct sst_pcm_params *param) |
187 | { | 148 | { |
188 | 149 | ||
189 | param->codec = SST_CODEC_TYPE_PCM; | ||
190 | param->num_chan = (u8) substream->runtime->channels; | 150 | param->num_chan = (u8) substream->runtime->channels; |
191 | param->pcm_wd_sz = substream->runtime->sample_bits; | 151 | param->pcm_wd_sz = substream->runtime->sample_bits; |
192 | param->reserved = 0; | 152 | param->reserved = 0; |
@@ -471,205 +431,6 @@ static int sst_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
471 | return retval; | 431 | return retval; |
472 | } | 432 | } |
473 | 433 | ||
474 | /* compress stream operations */ | ||
475 | static void sst_compr_fragment_elapsed(void *arg) | ||
476 | { | ||
477 | struct snd_compr_stream *cstream = (struct snd_compr_stream *)arg; | ||
478 | |||
479 | pr_debug("fragment elapsed by driver\n"); | ||
480 | if (cstream) | ||
481 | snd_compr_fragment_elapsed(cstream); | ||
482 | } | ||
483 | |||
484 | static int sst_platform_compr_open(struct snd_compr_stream *cstream) | ||
485 | { | ||
486 | |||
487 | int ret_val = 0; | ||
488 | struct snd_compr_runtime *runtime = cstream->runtime; | ||
489 | struct sst_runtime_stream *stream; | ||
490 | |||
491 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | ||
492 | if (!stream) | ||
493 | return -ENOMEM; | ||
494 | |||
495 | spin_lock_init(&stream->status_lock); | ||
496 | |||
497 | /* get the sst ops */ | ||
498 | if (!sst || !try_module_get(sst->dev->driver->owner)) { | ||
499 | pr_err("no device available to run\n"); | ||
500 | ret_val = -ENODEV; | ||
501 | goto out_ops; | ||
502 | } | ||
503 | stream->compr_ops = sst->compr_ops; | ||
504 | |||
505 | stream->id = 0; | ||
506 | sst_set_stream_status(stream, SST_PLATFORM_INIT); | ||
507 | runtime->private_data = stream; | ||
508 | return 0; | ||
509 | out_ops: | ||
510 | kfree(stream); | ||
511 | return ret_val; | ||
512 | } | ||
513 | |||
514 | static int sst_platform_compr_free(struct snd_compr_stream *cstream) | ||
515 | { | ||
516 | struct sst_runtime_stream *stream; | ||
517 | int ret_val = 0, str_id; | ||
518 | |||
519 | stream = cstream->runtime->private_data; | ||
520 | /*need to check*/ | ||
521 | str_id = stream->id; | ||
522 | if (str_id) | ||
523 | ret_val = stream->compr_ops->close(str_id); | ||
524 | module_put(sst->dev->driver->owner); | ||
525 | kfree(stream); | ||
526 | pr_debug("%s: %d\n", __func__, ret_val); | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static int sst_platform_compr_set_params(struct snd_compr_stream *cstream, | ||
531 | struct snd_compr_params *params) | ||
532 | { | ||
533 | struct sst_runtime_stream *stream; | ||
534 | int retval; | ||
535 | struct snd_sst_params str_params; | ||
536 | struct sst_compress_cb cb; | ||
537 | |||
538 | stream = cstream->runtime->private_data; | ||
539 | /* construct fw structure for this*/ | ||
540 | memset(&str_params, 0, sizeof(str_params)); | ||
541 | |||
542 | str_params.ops = STREAM_OPS_PLAYBACK; | ||
543 | str_params.stream_type = SST_STREAM_TYPE_MUSIC; | ||
544 | str_params.device_type = SND_SST_DEVICE_COMPRESS; | ||
545 | |||
546 | switch (params->codec.id) { | ||
547 | case SND_AUDIOCODEC_MP3: { | ||
548 | str_params.codec = SST_CODEC_TYPE_MP3; | ||
549 | str_params.sparams.uc.mp3_params.codec = SST_CODEC_TYPE_MP3; | ||
550 | str_params.sparams.uc.mp3_params.num_chan = params->codec.ch_in; | ||
551 | str_params.sparams.uc.mp3_params.pcm_wd_sz = 16; | ||
552 | break; | ||
553 | } | ||
554 | |||
555 | case SND_AUDIOCODEC_AAC: { | ||
556 | str_params.codec = SST_CODEC_TYPE_AAC; | ||
557 | str_params.sparams.uc.aac_params.codec = SST_CODEC_TYPE_AAC; | ||
558 | str_params.sparams.uc.aac_params.num_chan = params->codec.ch_in; | ||
559 | str_params.sparams.uc.aac_params.pcm_wd_sz = 16; | ||
560 | if (params->codec.format == SND_AUDIOSTREAMFORMAT_MP4ADTS) | ||
561 | str_params.sparams.uc.aac_params.bs_format = | ||
562 | AAC_BIT_STREAM_ADTS; | ||
563 | else if (params->codec.format == SND_AUDIOSTREAMFORMAT_RAW) | ||
564 | str_params.sparams.uc.aac_params.bs_format = | ||
565 | AAC_BIT_STREAM_RAW; | ||
566 | else { | ||
567 | pr_err("Undefined format%d\n", params->codec.format); | ||
568 | return -EINVAL; | ||
569 | } | ||
570 | str_params.sparams.uc.aac_params.externalsr = | ||
571 | params->codec.sample_rate; | ||
572 | break; | ||
573 | } | ||
574 | |||
575 | default: | ||
576 | pr_err("codec not supported, id =%d\n", params->codec.id); | ||
577 | return -EINVAL; | ||
578 | } | ||
579 | |||
580 | str_params.aparams.ring_buf_info[0].addr = | ||
581 | virt_to_phys(cstream->runtime->buffer); | ||
582 | str_params.aparams.ring_buf_info[0].size = | ||
583 | cstream->runtime->buffer_size; | ||
584 | str_params.aparams.sg_count = 1; | ||
585 | str_params.aparams.frag_size = cstream->runtime->fragment_size; | ||
586 | |||
587 | cb.param = cstream; | ||
588 | cb.compr_cb = sst_compr_fragment_elapsed; | ||
589 | |||
590 | retval = stream->compr_ops->open(&str_params, &cb); | ||
591 | if (retval < 0) { | ||
592 | pr_err("stream allocation failed %d\n", retval); | ||
593 | return retval; | ||
594 | } | ||
595 | |||
596 | stream->id = retval; | ||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static int sst_platform_compr_trigger(struct snd_compr_stream *cstream, int cmd) | ||
601 | { | ||
602 | struct sst_runtime_stream *stream = | ||
603 | cstream->runtime->private_data; | ||
604 | |||
605 | return stream->compr_ops->control(cmd, stream->id); | ||
606 | } | ||
607 | |||
608 | static int sst_platform_compr_pointer(struct snd_compr_stream *cstream, | ||
609 | struct snd_compr_tstamp *tstamp) | ||
610 | { | ||
611 | struct sst_runtime_stream *stream; | ||
612 | |||
613 | stream = cstream->runtime->private_data; | ||
614 | stream->compr_ops->tstamp(stream->id, tstamp); | ||
615 | tstamp->byte_offset = tstamp->copied_total % | ||
616 | (u32)cstream->runtime->buffer_size; | ||
617 | pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); | ||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | static int sst_platform_compr_ack(struct snd_compr_stream *cstream, | ||
622 | size_t bytes) | ||
623 | { | ||
624 | struct sst_runtime_stream *stream; | ||
625 | |||
626 | stream = cstream->runtime->private_data; | ||
627 | stream->compr_ops->ack(stream->id, (unsigned long)bytes); | ||
628 | stream->bytes_written += bytes; | ||
629 | |||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | static int sst_platform_compr_get_caps(struct snd_compr_stream *cstream, | ||
634 | struct snd_compr_caps *caps) | ||
635 | { | ||
636 | struct sst_runtime_stream *stream = | ||
637 | cstream->runtime->private_data; | ||
638 | |||
639 | return stream->compr_ops->get_caps(caps); | ||
640 | } | ||
641 | |||
642 | static int sst_platform_compr_get_codec_caps(struct snd_compr_stream *cstream, | ||
643 | struct snd_compr_codec_caps *codec) | ||
644 | { | ||
645 | struct sst_runtime_stream *stream = | ||
646 | cstream->runtime->private_data; | ||
647 | |||
648 | return stream->compr_ops->get_codec_caps(codec); | ||
649 | } | ||
650 | |||
651 | static int sst_platform_compr_set_metadata(struct snd_compr_stream *cstream, | ||
652 | struct snd_compr_metadata *metadata) | ||
653 | { | ||
654 | struct sst_runtime_stream *stream = | ||
655 | cstream->runtime->private_data; | ||
656 | |||
657 | return stream->compr_ops->set_metadata(stream->id, metadata); | ||
658 | } | ||
659 | |||
660 | static struct snd_compr_ops sst_platform_compr_ops = { | ||
661 | |||
662 | .open = sst_platform_compr_open, | ||
663 | .free = sst_platform_compr_free, | ||
664 | .set_params = sst_platform_compr_set_params, | ||
665 | .set_metadata = sst_platform_compr_set_metadata, | ||
666 | .trigger = sst_platform_compr_trigger, | ||
667 | .pointer = sst_platform_compr_pointer, | ||
668 | .ack = sst_platform_compr_ack, | ||
669 | .get_caps = sst_platform_compr_get_caps, | ||
670 | .get_codec_caps = sst_platform_compr_get_codec_caps, | ||
671 | }; | ||
672 | |||
673 | static struct snd_soc_platform_driver sst_soc_platform_drv = { | 434 | static struct snd_soc_platform_driver sst_soc_platform_drv = { |
674 | .ops = &sst_platform_ops, | 435 | .ops = &sst_platform_ops, |
675 | .compr_ops = &sst_platform_compr_ops, | 436 | .compr_ops = &sst_platform_compr_ops, |
@@ -677,6 +438,11 @@ static struct snd_soc_platform_driver sst_soc_platform_drv = { | |||
677 | .pcm_free = sst_pcm_free, | 438 | .pcm_free = sst_pcm_free, |
678 | }; | 439 | }; |
679 | 440 | ||
441 | static const struct snd_soc_component_driver sst_component = { | ||
442 | .name = "sst", | ||
443 | }; | ||
444 | |||
445 | |||
680 | static int sst_platform_probe(struct platform_device *pdev) | 446 | static int sst_platform_probe(struct platform_device *pdev) |
681 | { | 447 | { |
682 | int ret; | 448 | int ret; |
diff --git a/sound/soc/intel/sst-mfld-platform.h b/sound/soc/intel/sst-mfld-platform.h index 0c4e2ddcecb1..6c5e7dc49e3c 100644 --- a/sound/soc/intel/sst-mfld-platform.h +++ b/sound/soc/intel/sst-mfld-platform.h | |||
@@ -15,13 +15,7 @@ | |||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | * General Public License for more details. | 16 | * General Public License for more details. |
17 | * | 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 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 18 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
23 | * | ||
24 | * | ||
25 | */ | 19 | */ |
26 | 20 | ||
27 | #ifndef __SST_PLATFORMDRV_H__ | 21 | #ifndef __SST_PLATFORMDRV_H__ |
@@ -29,6 +23,8 @@ | |||
29 | 23 | ||
30 | #include "sst-mfld-dsp.h" | 24 | #include "sst-mfld-dsp.h" |
31 | 25 | ||
26 | extern struct sst_device *sst; | ||
27 | |||
32 | #define SST_MONO 1 | 28 | #define SST_MONO 1 |
33 | #define SST_STEREO 2 | 29 | #define SST_STEREO 2 |
34 | #define SST_MAX_CAP 5 | 30 | #define SST_MAX_CAP 5 |
@@ -108,6 +104,8 @@ struct sst_stream_params { | |||
108 | struct sst_compress_cb { | 104 | struct sst_compress_cb { |
109 | void *param; | 105 | void *param; |
110 | void (*compr_cb)(void *param); | 106 | void (*compr_cb)(void *param); |
107 | void *drain_cb_param; | ||
108 | void (*drain_notify)(void *param); | ||
111 | }; | 109 | }; |
112 | 110 | ||
113 | struct compress_sst_ops { | 111 | struct compress_sst_ops { |
@@ -148,6 +146,7 @@ struct sst_device { | |||
148 | struct compress_sst_ops *compr_ops; | 146 | struct compress_sst_ops *compr_ops; |
149 | }; | 147 | }; |
150 | 148 | ||
149 | void sst_set_stream_status(struct sst_runtime_stream *stream, int state); | ||
151 | int sst_register_dsp(struct sst_device *sst); | 150 | int sst_register_dsp(struct sst_device *sst); |
152 | int sst_unregister_dsp(struct sst_device *sst); | 151 | int sst_unregister_dsp(struct sst_device *sst); |
153 | #endif | 152 | #endif |
diff --git a/sound/soc/jz4740/Kconfig b/sound/soc/jz4740/Kconfig index 29f76af5d963..1a354a6b6e87 100644 --- a/sound/soc/jz4740/Kconfig +++ b/sound/soc/jz4740/Kconfig | |||
@@ -1,24 +1,29 @@ | |||
1 | config SND_JZ4740_SOC | 1 | config SND_JZ4740_SOC |
2 | tristate "SoC Audio for Ingenic JZ4740 SoC" | 2 | tristate "SoC Audio for Ingenic JZ4740 SoC" |
3 | depends on MACH_JZ4740 && SND_SOC | 3 | depends on MACH_JZ4740 || COMPILE_TEST |
4 | select SND_SOC_GENERIC_DMAENGINE_PCM | 4 | select SND_SOC_GENERIC_DMAENGINE_PCM |
5 | help | 5 | help |
6 | Say Y or M if you want to add support for codecs attached to | 6 | Say Y or M if you want to add support for codecs attached to |
7 | the JZ4740 I2S interface. You will also need to select the audio | 7 | the JZ4740 I2S interface. You will also need to select the audio |
8 | interfaces to support below. | 8 | interfaces to support below. |
9 | 9 | ||
10 | if SND_JZ4740_SOC | ||
11 | |||
10 | config SND_JZ4740_SOC_I2S | 12 | config SND_JZ4740_SOC_I2S |
11 | depends on SND_JZ4740_SOC | ||
12 | tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC" | 13 | tristate "SoC Audio (I2S protocol) for Ingenic JZ4740 SoC" |
14 | depends on HAS_IOMEM | ||
13 | help | 15 | help |
14 | Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740 | 16 | Say Y if you want to use I2S protocol and I2S codec on Ingenic JZ4740 |
15 | based boards. | 17 | based boards. |
16 | 18 | ||
17 | config SND_JZ4740_SOC_QI_LB60 | 19 | config SND_JZ4740_SOC_QI_LB60 |
18 | tristate "SoC Audio support for Qi LB60" | 20 | tristate "SoC Audio support for Qi LB60" |
19 | depends on SND_JZ4740_SOC && JZ4740_QI_LB60 | 21 | depends on HAS_IOMEM |
22 | depends on JZ4740_QI_LB60 || COMPILE_TEST | ||
20 | select SND_JZ4740_SOC_I2S | 23 | select SND_JZ4740_SOC_I2S |
21 | select SND_SOC_JZ4740_CODEC | 24 | select SND_SOC_JZ4740_CODEC |
22 | help | 25 | help |
23 | Say Y if you want to add support for ASoC audio on the Qi LB60 board | 26 | Say Y if you want to add support for ASoC audio on the Qi LB60 board |
24 | a.k.a Qi Ben NanoNote. | 27 | a.k.a Qi Ben NanoNote. |
28 | |||
29 | endif | ||
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index 8f220009e0f6..3f9c3a9ae36f 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c | |||
@@ -31,10 +31,11 @@ | |||
31 | #include <sound/initval.h> | 31 | #include <sound/initval.h> |
32 | #include <sound/dmaengine_pcm.h> | 32 | #include <sound/dmaengine_pcm.h> |
33 | 33 | ||
34 | #include <asm/mach-jz4740/dma.h> | ||
35 | |||
36 | #include "jz4740-i2s.h" | 34 | #include "jz4740-i2s.h" |
37 | 35 | ||
36 | #define JZ4740_DMA_TYPE_AIC_TRANSMIT 24 | ||
37 | #define JZ4740_DMA_TYPE_AIC_RECEIVE 25 | ||
38 | |||
38 | #define JZ_REG_AIC_CONF 0x00 | 39 | #define JZ_REG_AIC_CONF 0x00 |
39 | #define JZ_REG_AIC_CTRL 0x04 | 40 | #define JZ_REG_AIC_CTRL 0x04 |
40 | #define JZ_REG_AIC_I2S_FMT 0x10 | 41 | #define JZ_REG_AIC_I2S_FMT 0x10 |
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 82b5f37cd2c7..5cb91f9e8626 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c | |||
@@ -19,18 +19,21 @@ | |||
19 | #include <sound/core.h> | 19 | #include <sound/core.h> |
20 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
21 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio/consumer.h> |
23 | 23 | ||
24 | #define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29) | 24 | struct qi_lb60 { |
25 | #define QI_LB60_AMP_GPIO JZ_GPIO_PORTD(4) | 25 | struct gpio_desc *snd_gpio; |
26 | struct gpio_desc *amp_gpio; | ||
27 | }; | ||
26 | 28 | ||
27 | static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, | 29 | static int qi_lb60_spk_event(struct snd_soc_dapm_widget *widget, |
28 | struct snd_kcontrol *ctrl, int event) | 30 | struct snd_kcontrol *ctrl, int event) |
29 | { | 31 | { |
32 | struct qi_lb60 *qi_lb60 = snd_soc_card_get_drvdata(widget->dapm->card); | ||
30 | int on = !SND_SOC_DAPM_EVENT_OFF(event); | 33 | int on = !SND_SOC_DAPM_EVENT_OFF(event); |
31 | 34 | ||
32 | gpio_set_value(QI_LB60_SND_GPIO, on); | 35 | gpiod_set_value_cansleep(qi_lb60->snd_gpio, on); |
33 | gpio_set_value(QI_LB60_AMP_GPIO, on); | 36 | gpiod_set_value_cansleep(qi_lb60->amp_gpio, on); |
34 | 37 | ||
35 | return 0; | 38 | return 0; |
36 | } | 39 | } |
@@ -46,29 +49,6 @@ static const struct snd_soc_dapm_route qi_lb60_routes[] = { | |||
46 | {"Speaker", NULL, "ROUT"}, | 49 | {"Speaker", NULL, "ROUT"}, |
47 | }; | 50 | }; |
48 | 51 | ||
49 | #define QI_LB60_DAIFMT (SND_SOC_DAIFMT_I2S | \ | ||
50 | SND_SOC_DAIFMT_NB_NF | \ | ||
51 | SND_SOC_DAIFMT_CBM_CFM) | ||
52 | |||
53 | static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd) | ||
54 | { | ||
55 | struct snd_soc_codec *codec = rtd->codec; | ||
56 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
57 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
58 | int ret; | ||
59 | |||
60 | snd_soc_dapm_nc_pin(dapm, "LIN"); | ||
61 | snd_soc_dapm_nc_pin(dapm, "RIN"); | ||
62 | |||
63 | ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT); | ||
64 | if (ret < 0) { | ||
65 | dev_err(codec->dev, "Failed to set cpu dai format: %d\n", ret); | ||
66 | return ret; | ||
67 | } | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static struct snd_soc_dai_link qi_lb60_dai = { | 52 | static struct snd_soc_dai_link qi_lb60_dai = { |
73 | .name = "jz4740", | 53 | .name = "jz4740", |
74 | .stream_name = "jz4740", | 54 | .stream_name = "jz4740", |
@@ -76,10 +56,11 @@ static struct snd_soc_dai_link qi_lb60_dai = { | |||
76 | .platform_name = "jz4740-i2s", | 56 | .platform_name = "jz4740-i2s", |
77 | .codec_dai_name = "jz4740-hifi", | 57 | .codec_dai_name = "jz4740-hifi", |
78 | .codec_name = "jz4740-codec", | 58 | .codec_name = "jz4740-codec", |
79 | .init = qi_lb60_codec_init, | 59 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
60 | SND_SOC_DAIFMT_CBM_CFM, | ||
80 | }; | 61 | }; |
81 | 62 | ||
82 | static struct snd_soc_card qi_lb60 = { | 63 | static struct snd_soc_card qi_lb60_card = { |
83 | .name = "QI LB60", | 64 | .name = "QI LB60", |
84 | .owner = THIS_MODULE, | 65 | .owner = THIS_MODULE, |
85 | .dai_link = &qi_lb60_dai, | 66 | .dai_link = &qi_lb60_dai, |
@@ -89,40 +70,38 @@ static struct snd_soc_card qi_lb60 = { | |||
89 | .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets), | 70 | .num_dapm_widgets = ARRAY_SIZE(qi_lb60_widgets), |
90 | .dapm_routes = qi_lb60_routes, | 71 | .dapm_routes = qi_lb60_routes, |
91 | .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), | 72 | .num_dapm_routes = ARRAY_SIZE(qi_lb60_routes), |
92 | }; | 73 | .fully_routed = true, |
93 | |||
94 | static const struct gpio qi_lb60_gpios[] = { | ||
95 | { QI_LB60_SND_GPIO, GPIOF_OUT_INIT_LOW, "SND" }, | ||
96 | { QI_LB60_AMP_GPIO, GPIOF_OUT_INIT_LOW, "AMP" }, | ||
97 | }; | 74 | }; |
98 | 75 | ||
99 | static int qi_lb60_probe(struct platform_device *pdev) | 76 | static int qi_lb60_probe(struct platform_device *pdev) |
100 | { | 77 | { |
101 | struct snd_soc_card *card = &qi_lb60; | 78 | struct qi_lb60 *qi_lb60; |
79 | struct snd_soc_card *card = &qi_lb60_card; | ||
102 | int ret; | 80 | int ret; |
103 | 81 | ||
104 | ret = gpio_request_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | 82 | qi_lb60 = devm_kzalloc(&pdev->dev, sizeof(*qi_lb60), GFP_KERNEL); |
83 | if (!qi_lb60) | ||
84 | return -ENOMEM; | ||
85 | |||
86 | qi_lb60->snd_gpio = devm_gpiod_get(&pdev->dev, "snd"); | ||
87 | if (IS_ERR(qi_lb60->snd_gpio)) | ||
88 | return PTR_ERR(qi_lb60->snd_gpio); | ||
89 | ret = gpiod_direction_output(qi_lb60->snd_gpio, 0); | ||
105 | if (ret) | 90 | if (ret) |
106 | return ret; | 91 | return ret; |
107 | 92 | ||
108 | card->dev = &pdev->dev; | 93 | qi_lb60->amp_gpio = devm_gpiod_get(&pdev->dev, "amp"); |
94 | if (IS_ERR(qi_lb60->amp_gpio)) | ||
95 | return PTR_ERR(qi_lb60->amp_gpio); | ||
96 | ret = gpiod_direction_output(qi_lb60->amp_gpio, 0); | ||
97 | if (ret) | ||
98 | return ret; | ||
109 | 99 | ||
110 | ret = snd_soc_register_card(card); | 100 | card->dev = &pdev->dev; |
111 | if (ret) { | ||
112 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | ||
113 | ret); | ||
114 | gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | ||
115 | } | ||
116 | return ret; | ||
117 | } | ||
118 | 101 | ||
119 | static int qi_lb60_remove(struct platform_device *pdev) | 102 | snd_soc_card_set_drvdata(card, qi_lb60); |
120 | { | ||
121 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
122 | 103 | ||
123 | snd_soc_unregister_card(card); | 104 | return devm_snd_soc_register_card(&pdev->dev, card); |
124 | gpio_free_array(qi_lb60_gpios, ARRAY_SIZE(qi_lb60_gpios)); | ||
125 | return 0; | ||
126 | } | 105 | } |
127 | 106 | ||
128 | static struct platform_driver qi_lb60_driver = { | 107 | static struct platform_driver qi_lb60_driver = { |
@@ -131,7 +110,6 @@ static struct platform_driver qi_lb60_driver = { | |||
131 | .owner = THIS_MODULE, | 110 | .owner = THIS_MODULE, |
132 | }, | 111 | }, |
133 | .probe = qi_lb60_probe, | 112 | .probe = qi_lb60_probe, |
134 | .remove = qi_lb60_remove, | ||
135 | }; | 113 | }; |
136 | 114 | ||
137 | module_platform_driver(qi_lb60_driver); | 115 | module_platform_driver(qi_lb60_driver); |
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index d213832b0c72..844b8415a011 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c | |||
@@ -52,18 +52,6 @@ static const struct snd_soc_dapm_route t5325_route[] = { | |||
52 | { "MIC2", NULL, "Mic Jack" }, | 52 | { "MIC2", NULL, "Mic Jack" }, |
53 | }; | 53 | }; |
54 | 54 | ||
55 | static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd) | ||
56 | { | ||
57 | struct snd_soc_codec *codec = rtd->codec; | ||
58 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
59 | |||
60 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
61 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
62 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | ||
63 | |||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | static struct snd_soc_dai_link t5325_dai[] = { | 55 | static struct snd_soc_dai_link t5325_dai[] = { |
68 | { | 56 | { |
69 | .name = "ALC5621", | 57 | .name = "ALC5621", |
@@ -74,7 +62,6 @@ static struct snd_soc_dai_link t5325_dai[] = { | |||
74 | .codec_name = "alc562x-codec.0-001a", | 62 | .codec_name = "alc562x-codec.0-001a", |
75 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, | 63 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS, |
76 | .ops = &t5325_ops, | 64 | .ops = &t5325_ops, |
77 | .init = t5325_dai_init, | ||
78 | }, | 65 | }, |
79 | }; | 66 | }; |
80 | 67 | ||
diff --git a/sound/soc/nuc900/Kconfig b/sound/soc/nuc900/Kconfig index a0ed1c618f60..7f0c954dff6f 100644 --- a/sound/soc/nuc900/Kconfig +++ b/sound/soc/nuc900/Kconfig | |||
@@ -4,6 +4,7 @@ | |||
4 | config SND_SOC_NUC900 | 4 | config SND_SOC_NUC900 |
5 | tristate "SoC Audio for NUC900 series" | 5 | tristate "SoC Audio for NUC900 series" |
6 | depends on ARCH_W90X900 | 6 | depends on ARCH_W90X900 |
7 | select SND_SOC_NUC900_AC97 | ||
7 | help | 8 | help |
8 | This option enables support for AC97 mode on the NUC900 SoC. | 9 | This option enables support for AC97 mode on the NUC900 SoC. |
9 | 10 | ||
diff --git a/sound/soc/nuc900/nuc900-ac97.c b/sound/soc/nuc900/nuc900-ac97.c index 8987bf987e58..f2f67942b229 100644 --- a/sound/soc/nuc900/nuc900-ac97.c +++ b/sound/soc/nuc900/nuc900-ac97.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | static DEFINE_MUTEX(ac97_mutex); | 29 | static DEFINE_MUTEX(ac97_mutex); |
30 | struct nuc900_audio *nuc900_ac97_data; | 30 | struct nuc900_audio *nuc900_ac97_data; |
31 | EXPORT_SYMBOL_GPL(nuc900_ac97_data); | ||
31 | 32 | ||
32 | static int nuc900_checkready(void) | 33 | static int nuc900_checkready(void) |
33 | { | 34 | { |
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index e00659351a4e..d44463a7b0fa 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig | |||
@@ -26,7 +26,7 @@ config SND_OMAP_SOC_N810 | |||
26 | 26 | ||
27 | config SND_OMAP_SOC_RX51 | 27 | config SND_OMAP_SOC_RX51 |
28 | tristate "SoC Audio support for Nokia RX-51" | 28 | tristate "SoC Audio support for Nokia RX-51" |
29 | depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) | 29 | depends on SND_OMAP_SOC && ARM && (MACH_NOKIA_RX51 || COMPILE_TEST) && I2C |
30 | select SND_OMAP_SOC_MCBSP | 30 | select SND_OMAP_SOC_MCBSP |
31 | select SND_SOC_TLV320AIC3X | 31 | select SND_SOC_TLV320AIC3X |
32 | select SND_SOC_TPA6130A2 | 32 | select SND_SOC_TPA6130A2 |
@@ -37,7 +37,7 @@ config SND_OMAP_SOC_RX51 | |||
37 | 37 | ||
38 | config SND_OMAP_SOC_AMS_DELTA | 38 | config SND_OMAP_SOC_AMS_DELTA |
39 | tristate "SoC Audio support for Amstrad E3 (Delta) videophone" | 39 | tristate "SoC Audio support for Amstrad E3 (Delta) videophone" |
40 | depends on SND_OMAP_SOC && MACH_AMS_DELTA | 40 | depends on SND_OMAP_SOC && MACH_AMS_DELTA && TTY |
41 | select SND_OMAP_SOC_MCBSP | 41 | select SND_OMAP_SOC_MCBSP |
42 | select SND_SOC_CX20442 | 42 | select SND_SOC_CX20442 |
43 | help | 43 | help |
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 994dcf345975..25a33e9d417a 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c | |||
@@ -77,7 +77,7 @@ static struct snd_soc_dai_link am3517evm_dai = { | |||
77 | .stream_name = "AIC23", | 77 | .stream_name = "AIC23", |
78 | .cpu_dai_name = "omap-mcbsp.1", | 78 | .cpu_dai_name = "omap-mcbsp.1", |
79 | .codec_dai_name = "tlv320aic23-hifi", | 79 | .codec_dai_name = "tlv320aic23-hifi", |
80 | .platform_name = "omap-pcm-audio", | 80 | .platform_name = "omap-mcbsp.1", |
81 | .codec_name = "tlv320aic23-codec.2-001a", | 81 | .codec_name = "tlv320aic23-codec.2-001a", |
82 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | | 82 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | |
83 | SND_SOC_DAIFMT_CBM_CFM, | 83 | SND_SOC_DAIFMT_CBM_CFM, |
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 56a5219c0a00..bb243c663e6b 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
@@ -38,7 +38,6 @@ | |||
38 | #include "omap-mcbsp.h" | 38 | #include "omap-mcbsp.h" |
39 | #include "../codecs/cx20442.h" | 39 | #include "../codecs/cx20442.h" |
40 | 40 | ||
41 | |||
42 | /* Board specific DAPM widgets */ | 41 | /* Board specific DAPM widgets */ |
43 | static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { | 42 | static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { |
44 | /* Handset */ | 43 | /* Handset */ |
@@ -90,17 +89,23 @@ static const unsigned short ams_delta_audio_mode_pins[] = { | |||
90 | 89 | ||
91 | static unsigned short ams_delta_audio_agc; | 90 | static unsigned short ams_delta_audio_agc; |
92 | 91 | ||
92 | /* | ||
93 | * Used for passing a codec structure pointer | ||
94 | * from the board initialization code to the tty line discipline. | ||
95 | */ | ||
96 | static struct snd_soc_codec *cx20442_codec; | ||
97 | |||
93 | static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, | 98 | static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, |
94 | struct snd_ctl_elem_value *ucontrol) | 99 | struct snd_ctl_elem_value *ucontrol) |
95 | { | 100 | { |
96 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 101 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
97 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 102 | struct snd_soc_dapm_context *dapm = &card->dapm; |
98 | struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; | 103 | struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; |
99 | unsigned short pins; | 104 | unsigned short pins; |
100 | int pin, changed = 0; | 105 | int pin, changed = 0; |
101 | 106 | ||
102 | /* 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. */ |
103 | if (!codec->hw_write) | 108 | if (!cx20442_codec->hw_write) |
104 | return -EUNATCH; | 109 | return -EUNATCH; |
105 | 110 | ||
106 | if (ucontrol->value.enumerated.item[0] >= control->items) | 111 | if (ucontrol->value.enumerated.item[0] >= control->items) |
@@ -166,8 +171,8 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, | |||
166 | static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, | 171 | static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol, |
167 | struct snd_ctl_elem_value *ucontrol) | 172 | struct snd_ctl_elem_value *ucontrol) |
168 | { | 173 | { |
169 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 174 | struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); |
170 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 175 | struct snd_soc_dapm_context *dapm = &card->dapm; |
171 | unsigned short pins, mode; | 176 | unsigned short pins, mode; |
172 | 177 | ||
173 | pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << | 178 | pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << |
@@ -270,12 +275,6 @@ static void cx81801_timeout(unsigned long data) | |||
270 | ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); | 275 | ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_CODEC, 0); |
271 | } | 276 | } |
272 | 277 | ||
273 | /* | ||
274 | * Used for passing a codec structure pointer | ||
275 | * from the board initialization code to the tty line discipline. | ||
276 | */ | ||
277 | static struct snd_soc_codec *cx20442_codec; | ||
278 | |||
279 | /* Line discipline .open() */ | 278 | /* Line discipline .open() */ |
280 | static int cx81801_open(struct tty_struct *tty) | 279 | static int cx81801_open(struct tty_struct *tty) |
281 | { | 280 | { |
@@ -302,7 +301,7 @@ static int cx81801_open(struct tty_struct *tty) | |||
302 | static void cx81801_close(struct tty_struct *tty) | 301 | static void cx81801_close(struct tty_struct *tty) |
303 | { | 302 | { |
304 | struct snd_soc_codec *codec = tty->disc_data; | 303 | struct snd_soc_codec *codec = tty->disc_data; |
305 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 304 | struct snd_soc_dapm_context *dapm = &codec->card->dapm; |
306 | 305 | ||
307 | del_timer_sync(&cx81801_timer); | 306 | del_timer_sync(&cx81801_timer); |
308 | 307 | ||
@@ -475,15 +474,14 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream) | |||
475 | 474 | ||
476 | static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | 475 | static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) |
477 | { | 476 | { |
478 | struct snd_soc_codec *codec = rtd->codec; | ||
479 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
480 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 477 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
481 | struct snd_soc_card *card = rtd->card; | 478 | struct snd_soc_card *card = rtd->card; |
479 | struct snd_soc_dapm_context *dapm = &card->dapm; | ||
482 | int ret; | 480 | int ret; |
483 | /* Codec is ready, now add/activate board specific controls */ | 481 | /* Codec is ready, now add/activate board specific controls */ |
484 | 482 | ||
485 | /* Store a pointer to the codec structure for tty ldisc use */ | 483 | /* Store a pointer to the codec structure for tty ldisc use */ |
486 | cx20442_codec = codec; | 484 | cx20442_codec = rtd->codec; |
487 | 485 | ||
488 | /* Set up digital mute if not provided by the codec */ | 486 | /* Set up digital mute if not provided by the codec */ |
489 | if (!codec_dai->driver->ops) { | 487 | if (!codec_dai->driver->ops) { |
@@ -520,41 +518,12 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | |||
520 | return 0; | 518 | return 0; |
521 | } | 519 | } |
522 | 520 | ||
523 | /* Add board specific DAPM widgets and routes */ | ||
524 | ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, | ||
525 | ARRAY_SIZE(ams_delta_dapm_widgets)); | ||
526 | if (ret) { | ||
527 | dev_warn(card->dev, | ||
528 | "Failed to register DAPM controls, " | ||
529 | "will continue without any.\n"); | ||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, | ||
534 | ARRAY_SIZE(ams_delta_audio_map)); | ||
535 | if (ret) { | ||
536 | dev_warn(card->dev, | ||
537 | "Failed to set up DAPM routes, " | ||
538 | "will continue with codec default map.\n"); | ||
539 | return 0; | ||
540 | } | ||
541 | |||
542 | /* Set up initial pin constellation */ | 521 | /* Set up initial pin constellation */ |
543 | snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); | 522 | snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); |
544 | snd_soc_dapm_enable_pin(dapm, "Earpiece"); | ||
545 | snd_soc_dapm_enable_pin(dapm, "Microphone"); | ||
546 | snd_soc_dapm_disable_pin(dapm, "Speaker"); | 523 | snd_soc_dapm_disable_pin(dapm, "Speaker"); |
547 | snd_soc_dapm_disable_pin(dapm, "AGCIN"); | 524 | snd_soc_dapm_disable_pin(dapm, "AGCIN"); |
548 | snd_soc_dapm_disable_pin(dapm, "AGCOUT"); | 525 | snd_soc_dapm_disable_pin(dapm, "AGCOUT"); |
549 | 526 | ||
550 | /* Add virtual switch */ | ||
551 | ret = snd_soc_add_codec_controls(codec, ams_delta_audio_controls, | ||
552 | ARRAY_SIZE(ams_delta_audio_controls)); | ||
553 | if (ret) | ||
554 | dev_warn(card->dev, | ||
555 | "Failed to register audio mode control, " | ||
556 | "will continue without it.\n"); | ||
557 | |||
558 | return 0; | 527 | return 0; |
559 | } | 528 | } |
560 | 529 | ||
@@ -565,7 +534,7 @@ static struct snd_soc_dai_link ams_delta_dai_link = { | |||
565 | .cpu_dai_name = "omap-mcbsp.1", | 534 | .cpu_dai_name = "omap-mcbsp.1", |
566 | .codec_dai_name = "cx20442-voice", | 535 | .codec_dai_name = "cx20442-voice", |
567 | .init = ams_delta_cx20442_init, | 536 | .init = ams_delta_cx20442_init, |
568 | .platform_name = "omap-pcm-audio", | 537 | .platform_name = "omap-mcbsp.1", |
569 | .codec_name = "cx20442-codec", | 538 | .codec_name = "cx20442-codec", |
570 | .ops = &ams_delta_ops, | 539 | .ops = &ams_delta_ops, |
571 | }; | 540 | }; |
@@ -576,6 +545,13 @@ static struct snd_soc_card ams_delta_audio_card = { | |||
576 | .owner = THIS_MODULE, | 545 | .owner = THIS_MODULE, |
577 | .dai_link = &ams_delta_dai_link, | 546 | .dai_link = &ams_delta_dai_link, |
578 | .num_links = 1, | 547 | .num_links = 1, |
548 | |||
549 | .controls = ams_delta_audio_controls, | ||
550 | .num_controls = ARRAY_SIZE(ams_delta_audio_controls), | ||
551 | .dapm_widgets = ams_delta_dapm_widgets, | ||
552 | .num_dapm_widgets = ARRAY_SIZE(ams_delta_dapm_widgets), | ||
553 | .dapm_routes = ams_delta_audio_map, | ||
554 | .num_dapm_routes = ARRAY_SIZE(ams_delta_audio_map), | ||
579 | }; | 555 | }; |
580 | 556 | ||
581 | /* Module init/exit */ | 557 | /* Module init/exit */ |
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index fd4d9c809e50..5d7f9cebe041 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
@@ -278,7 +278,7 @@ static struct snd_soc_dai_link n810_dai = { | |||
278 | .name = "TLV320AIC33", | 278 | .name = "TLV320AIC33", |
279 | .stream_name = "AIC33", | 279 | .stream_name = "AIC33", |
280 | .cpu_dai_name = "omap-mcbsp.2", | 280 | .cpu_dai_name = "omap-mcbsp.2", |
281 | .platform_name = "omap-pcm-audio", | 281 | .platform_name = "omap-mcbsp.2", |
282 | .codec_name = "tlv320aic3x-codec.2-0018", | 282 | .codec_name = "tlv320aic3x-codec.2-0018", |
283 | .codec_dai_name = "tlv320aic3x-hifi", | 283 | .codec_dai_name = "tlv320aic3x-hifi", |
284 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 284 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
diff --git a/sound/soc/omap/omap-abe-twl6040.c b/sound/soc/omap/omap-abe-twl6040.c index 024dafc3e298..cec836ed0c01 100644 --- a/sound/soc/omap/omap-abe-twl6040.c +++ b/sound/soc/omap/omap-abe-twl6040.c | |||
@@ -47,8 +47,7 @@ static int omap_abe_hw_params(struct snd_pcm_substream *substream, | |||
47 | { | 47 | { |
48 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 48 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
49 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 49 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
50 | struct snd_soc_codec *codec = rtd->codec; | 50 | struct snd_soc_card *card = rtd->card; |
51 | struct snd_soc_card *card = codec->card; | ||
52 | struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); | 51 | struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); |
53 | int clk_id, freq; | 52 | int clk_id, freq; |
54 | int ret; | 53 | int ret; |
@@ -168,7 +167,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
168 | static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) | 167 | static int omap_abe_twl6040_init(struct snd_soc_pcm_runtime *rtd) |
169 | { | 168 | { |
170 | struct snd_soc_codec *codec = rtd->codec; | 169 | struct snd_soc_codec *codec = rtd->codec; |
171 | struct snd_soc_card *card = codec->card; | 170 | struct snd_soc_card *card = rtd->card; |
172 | struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); | 171 | struct abe_twl6040 *priv = snd_soc_card_get_drvdata(card); |
173 | int hs_trim; | 172 | int hs_trim; |
174 | int ret = 0; | 173 | int ret = 0; |
@@ -214,9 +213,7 @@ static struct snd_soc_dai_link abe_twl6040_dai_links[] = { | |||
214 | { | 213 | { |
215 | .name = "TWL6040", | 214 | .name = "TWL6040", |
216 | .stream_name = "TWL6040", | 215 | .stream_name = "TWL6040", |
217 | .cpu_dai_name = "omap-mcpdm", | ||
218 | .codec_dai_name = "twl6040-legacy", | 216 | .codec_dai_name = "twl6040-legacy", |
219 | .platform_name = "omap-pcm-audio", | ||
220 | .codec_name = "twl6040-codec", | 217 | .codec_name = "twl6040-codec", |
221 | .init = omap_abe_twl6040_init, | 218 | .init = omap_abe_twl6040_init, |
222 | .ops = &omap_abe_ops, | 219 | .ops = &omap_abe_ops, |
@@ -224,9 +221,7 @@ static struct snd_soc_dai_link abe_twl6040_dai_links[] = { | |||
224 | { | 221 | { |
225 | .name = "DMIC", | 222 | .name = "DMIC", |
226 | .stream_name = "DMIC Capture", | 223 | .stream_name = "DMIC Capture", |
227 | .cpu_dai_name = "omap-dmic", | ||
228 | .codec_dai_name = "dmic-hifi", | 224 | .codec_dai_name = "dmic-hifi", |
229 | .platform_name = "omap-pcm-audio", | ||
230 | .codec_name = "dmic-codec", | 225 | .codec_name = "dmic-codec", |
231 | .init = omap_abe_dmic_init, | 226 | .init = omap_abe_dmic_init, |
232 | .ops = &omap_abe_dmic_ops, | 227 | .ops = &omap_abe_dmic_ops, |
@@ -281,14 +276,14 @@ static int omap_abe_probe(struct platform_device *pdev) | |||
281 | dev_err(&pdev->dev, "McPDM node is not provided\n"); | 276 | dev_err(&pdev->dev, "McPDM node is not provided\n"); |
282 | return -EINVAL; | 277 | return -EINVAL; |
283 | } | 278 | } |
284 | abe_twl6040_dai_links[0].cpu_dai_name = NULL; | ||
285 | abe_twl6040_dai_links[0].cpu_of_node = dai_node; | 279 | abe_twl6040_dai_links[0].cpu_of_node = dai_node; |
280 | abe_twl6040_dai_links[0].platform_of_node = dai_node; | ||
286 | 281 | ||
287 | dai_node = of_parse_phandle(node, "ti,dmic", 0); | 282 | dai_node = of_parse_phandle(node, "ti,dmic", 0); |
288 | if (dai_node) { | 283 | if (dai_node) { |
289 | num_links = 2; | 284 | num_links = 2; |
290 | abe_twl6040_dai_links[1].cpu_dai_name = NULL; | ||
291 | abe_twl6040_dai_links[1].cpu_of_node = dai_node; | 285 | abe_twl6040_dai_links[1].cpu_of_node = dai_node; |
286 | abe_twl6040_dai_links[1].platform_of_node = dai_node; | ||
292 | 287 | ||
293 | priv->dmic_codec_dev = platform_device_register_simple( | 288 | priv->dmic_codec_dev = platform_device_register_simple( |
294 | "dmic-codec", -1, NULL, 0); | 289 | "dmic-codec", -1, NULL, 0); |
diff --git a/sound/soc/omap/omap-dmic.c b/sound/soc/omap/omap-dmic.c index 1bd531d718f9..53da041896c4 100644 --- a/sound/soc/omap/omap-dmic.c +++ b/sound/soc/omap/omap-dmic.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <sound/dmaengine_pcm.h> | 42 | #include <sound/dmaengine_pcm.h> |
43 | 43 | ||
44 | #include "omap-dmic.h" | 44 | #include "omap-dmic.h" |
45 | #include "omap-pcm.h" | ||
45 | 46 | ||
46 | struct omap_dmic { | 47 | struct omap_dmic { |
47 | struct device *dev; | 48 | struct device *dev; |
@@ -113,7 +114,6 @@ static int omap_dmic_dai_startup(struct snd_pcm_substream *substream, | |||
113 | 114 | ||
114 | mutex_unlock(&dmic->mutex); | 115 | mutex_unlock(&dmic->mutex); |
115 | 116 | ||
116 | snd_soc_dai_set_dma_data(dai, substream, &dmic->dma_data); | ||
117 | return ret; | 117 | return ret; |
118 | } | 118 | } |
119 | 119 | ||
@@ -417,6 +417,9 @@ static int omap_dmic_probe(struct snd_soc_dai *dai) | |||
417 | 417 | ||
418 | /* Configure DMIC threshold value */ | 418 | /* Configure DMIC threshold value */ |
419 | dmic->threshold = OMAP_DMIC_THRES_MAX - 3; | 419 | dmic->threshold = OMAP_DMIC_THRES_MAX - 3; |
420 | |||
421 | snd_soc_dai_init_dma_data(dai, NULL, &dmic->dma_data); | ||
422 | |||
420 | return 0; | 423 | return 0; |
421 | } | 424 | } |
422 | 425 | ||
@@ -492,6 +495,10 @@ static int asoc_dmic_probe(struct platform_device *pdev) | |||
492 | if (ret) | 495 | if (ret) |
493 | goto err_put_clk; | 496 | goto err_put_clk; |
494 | 497 | ||
498 | ret = omap_pcm_platform_register(&pdev->dev); | ||
499 | if (ret) | ||
500 | goto err_put_clk; | ||
501 | |||
495 | return 0; | 502 | return 0; |
496 | 503 | ||
497 | err_put_clk: | 504 | err_put_clk: |
diff --git a/sound/soc/omap/omap-hdmi-card.c b/sound/soc/omap/omap-hdmi-card.c index 7e66e9cba5a8..f649fe84b629 100644 --- a/sound/soc/omap/omap-hdmi-card.c +++ b/sound/soc/omap/omap-hdmi-card.c | |||
@@ -33,7 +33,7 @@ static struct snd_soc_dai_link omap_hdmi_dai = { | |||
33 | .name = "HDMI", | 33 | .name = "HDMI", |
34 | .stream_name = "HDMI", | 34 | .stream_name = "HDMI", |
35 | .cpu_dai_name = "omap-hdmi-audio-dai", | 35 | .cpu_dai_name = "omap-hdmi-audio-dai", |
36 | .platform_name = "omap-pcm-audio", | 36 | .platform_name = "omap-hdmi-audio-dai", |
37 | .codec_name = "hdmi-audio-codec", | 37 | .codec_name = "hdmi-audio-codec", |
38 | .codec_dai_name = "hdmi-hifi", | 38 | .codec_dai_name = "hdmi-hifi", |
39 | }; | 39 | }; |
diff --git a/sound/soc/omap/omap-hdmi.c b/sound/soc/omap/omap-hdmi.c index ced3b88b44d4..537a1ec8ad61 100644 --- a/sound/soc/omap/omap-hdmi.c +++ b/sound/soc/omap/omap-hdmi.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <video/omapdss.h> | 36 | #include <video/omapdss.h> |
37 | 37 | ||
38 | #include "omap-hdmi.h" | 38 | #include "omap-hdmi.h" |
39 | #include "omap-pcm.h" | ||
39 | 40 | ||
40 | #define DRV_NAME "omap-hdmi-audio-dai" | 41 | #define DRV_NAME "omap-hdmi-audio-dai" |
41 | 42 | ||
@@ -324,7 +325,10 @@ static int omap_hdmi_probe(struct platform_device *pdev) | |||
324 | ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component, | 325 | ret = snd_soc_register_component(&pdev->dev, &omap_hdmi_component, |
325 | &omap_hdmi_dai, 1); | 326 | &omap_hdmi_dai, 1); |
326 | 327 | ||
327 | return ret; | 328 | if (ret) |
329 | return ret; | ||
330 | |||
331 | return omap_pcm_platform_register(&pdev->dev); | ||
328 | } | 332 | } |
329 | 333 | ||
330 | static int omap_hdmi_remove(struct platform_device *pdev) | 334 | static int omap_hdmi_remove(struct platform_device *pdev) |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 6c19bba23570..71d226626f7c 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/platform_data/asoc-ti-mcbsp.h> | 38 | #include <linux/platform_data/asoc-ti-mcbsp.h> |
39 | #include "mcbsp.h" | 39 | #include "mcbsp.h" |
40 | #include "omap-mcbsp.h" | 40 | #include "omap-mcbsp.h" |
41 | #include "omap-pcm.h" | ||
41 | 42 | ||
42 | #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) | 43 | #define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000) |
43 | 44 | ||
@@ -149,9 +150,6 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, | |||
149 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); | 150 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 2); |
150 | } | 151 | } |
151 | 152 | ||
152 | snd_soc_dai_set_dma_data(cpu_dai, substream, | ||
153 | &mcbsp->dma_data[substream->stream]); | ||
154 | |||
155 | return err; | 153 | return err; |
156 | } | 154 | } |
157 | 155 | ||
@@ -559,6 +557,10 @@ static int omap_mcbsp_probe(struct snd_soc_dai *dai) | |||
559 | 557 | ||
560 | pm_runtime_enable(mcbsp->dev); | 558 | pm_runtime_enable(mcbsp->dev); |
561 | 559 | ||
560 | snd_soc_dai_init_dma_data(dai, | ||
561 | &mcbsp->dma_data[SNDRV_PCM_STREAM_PLAYBACK], | ||
562 | &mcbsp->dma_data[SNDRV_PCM_STREAM_CAPTURE]); | ||
563 | |||
562 | return 0; | 564 | return 0; |
563 | } | 565 | } |
564 | 566 | ||
@@ -691,7 +693,7 @@ OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \ | |||
691 | OMAP_MCBSP_ST_CONTROLS(2); | 693 | OMAP_MCBSP_ST_CONTROLS(2); |
692 | OMAP_MCBSP_ST_CONTROLS(3); | 694 | OMAP_MCBSP_ST_CONTROLS(3); |
693 | 695 | ||
694 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) | 696 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id) |
695 | { | 697 | { |
696 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 698 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
697 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); | 699 | struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai); |
@@ -701,7 +703,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) | |||
701 | return 0; | 703 | return 0; |
702 | } | 704 | } |
703 | 705 | ||
704 | switch (mcbsp->id) { | 706 | switch (port_id) { |
705 | case 2: /* McBSP 2 */ | 707 | case 2: /* McBSP 2 */ |
706 | return snd_soc_add_dai_controls(cpu_dai, | 708 | return snd_soc_add_dai_controls(cpu_dai, |
707 | omap_mcbsp2_st_controls, | 709 | omap_mcbsp2_st_controls, |
@@ -711,6 +713,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd) | |||
711 | omap_mcbsp3_st_controls, | 713 | omap_mcbsp3_st_controls, |
712 | ARRAY_SIZE(omap_mcbsp3_st_controls)); | 714 | ARRAY_SIZE(omap_mcbsp3_st_controls)); |
713 | default: | 715 | default: |
716 | dev_err(mcbsp->dev, "Port %d not supported\n", port_id); | ||
714 | break; | 717 | break; |
715 | } | 718 | } |
716 | 719 | ||
@@ -799,11 +802,15 @@ static int asoc_mcbsp_probe(struct platform_device *pdev) | |||
799 | platform_set_drvdata(pdev, mcbsp); | 802 | platform_set_drvdata(pdev, mcbsp); |
800 | 803 | ||
801 | ret = omap_mcbsp_init(pdev); | 804 | ret = omap_mcbsp_init(pdev); |
802 | if (!ret) | 805 | if (ret) |
803 | return snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, | 806 | return ret; |
804 | &omap_mcbsp_dai, 1); | 807 | |
808 | ret = snd_soc_register_component(&pdev->dev, &omap_mcbsp_component, | ||
809 | &omap_mcbsp_dai, 1); | ||
810 | if (ret) | ||
811 | return ret; | ||
805 | 812 | ||
806 | return ret; | 813 | return omap_pcm_platform_register(&pdev->dev); |
807 | } | 814 | } |
808 | 815 | ||
809 | static int asoc_mcbsp_remove(struct platform_device *pdev) | 816 | static int asoc_mcbsp_remove(struct platform_device *pdev) |
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index ba8386a0d8dc..2e3369c27be3 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h | |||
@@ -39,6 +39,6 @@ enum omap_mcbsp_div { | |||
39 | OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ | 39 | OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */ |
40 | }; | 40 | }; |
41 | 41 | ||
42 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd); | 42 | int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id); |
43 | 43 | ||
44 | #endif | 44 | #endif |
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 2f5b1536477e..d8ebb52645a9 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <sound/dmaengine_pcm.h> | 42 | #include <sound/dmaengine_pcm.h> |
43 | 43 | ||
44 | #include "omap-mcpdm.h" | 44 | #include "omap-mcpdm.h" |
45 | #include "omap-pcm.h" | ||
45 | 46 | ||
46 | struct mcpdm_link_config { | 47 | struct mcpdm_link_config { |
47 | u32 link_mask; /* channel mask for the direction */ | 48 | u32 link_mask; /* channel mask for the direction */ |
@@ -265,9 +266,6 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, | |||
265 | } | 266 | } |
266 | mutex_unlock(&mcpdm->mutex); | 267 | mutex_unlock(&mcpdm->mutex); |
267 | 268 | ||
268 | snd_soc_dai_set_dma_data(dai, substream, | ||
269 | &mcpdm->dma_data[substream->stream]); | ||
270 | |||
271 | return 0; | 269 | return 0; |
272 | } | 270 | } |
273 | 271 | ||
@@ -406,6 +404,11 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) | |||
406 | mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; | 404 | mcpdm->config[SNDRV_PCM_STREAM_PLAYBACK].threshold = 2; |
407 | mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = | 405 | mcpdm->config[SNDRV_PCM_STREAM_CAPTURE].threshold = |
408 | MCPDM_UP_THRES_MAX - 3; | 406 | MCPDM_UP_THRES_MAX - 3; |
407 | |||
408 | snd_soc_dai_init_dma_data(dai, | ||
409 | &mcpdm->dma_data[SNDRV_PCM_STREAM_PLAYBACK], | ||
410 | &mcpdm->dma_data[SNDRV_PCM_STREAM_CAPTURE]); | ||
411 | |||
409 | return ret; | 412 | return ret; |
410 | } | 413 | } |
411 | 414 | ||
@@ -460,6 +463,7 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) | |||
460 | { | 463 | { |
461 | struct omap_mcpdm *mcpdm; | 464 | struct omap_mcpdm *mcpdm; |
462 | struct resource *res; | 465 | struct resource *res; |
466 | int ret; | ||
463 | 467 | ||
464 | mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); | 468 | mcpdm = devm_kzalloc(&pdev->dev, sizeof(struct omap_mcpdm), GFP_KERNEL); |
465 | if (!mcpdm) | 469 | if (!mcpdm) |
@@ -490,9 +494,13 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) | |||
490 | 494 | ||
491 | mcpdm->dev = &pdev->dev; | 495 | mcpdm->dev = &pdev->dev; |
492 | 496 | ||
493 | return devm_snd_soc_register_component(&pdev->dev, | 497 | ret = devm_snd_soc_register_component(&pdev->dev, |
494 | &omap_mcpdm_component, | 498 | &omap_mcpdm_component, |
495 | &omap_mcpdm_dai, 1); | 499 | &omap_mcpdm_dai, 1); |
500 | if (ret) | ||
501 | return ret; | ||
502 | |||
503 | return omap_pcm_platform_register(&pdev->dev); | ||
496 | } | 504 | } |
497 | 505 | ||
498 | static const struct of_device_id omap_mcpdm_of_match[] = { | 506 | static const struct of_device_id omap_mcpdm_of_match[] = { |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 07b8b7bc9d20..8d809f8509c8 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -232,31 +232,12 @@ static struct snd_soc_platform_driver omap_soc_platform = { | |||
232 | .pcm_free = omap_pcm_free_dma_buffers, | 232 | .pcm_free = omap_pcm_free_dma_buffers, |
233 | }; | 233 | }; |
234 | 234 | ||
235 | static int omap_pcm_probe(struct platform_device *pdev) | 235 | int omap_pcm_platform_register(struct device *dev) |
236 | { | 236 | { |
237 | return snd_soc_register_platform(&pdev->dev, | 237 | return devm_snd_soc_register_platform(dev, &omap_soc_platform); |
238 | &omap_soc_platform); | ||
239 | } | 238 | } |
240 | 239 | EXPORT_SYMBOL_GPL(omap_pcm_platform_register); | |
241 | static int omap_pcm_remove(struct platform_device *pdev) | ||
242 | { | ||
243 | snd_soc_unregister_platform(&pdev->dev); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static struct platform_driver omap_pcm_driver = { | ||
248 | .driver = { | ||
249 | .name = "omap-pcm-audio", | ||
250 | .owner = THIS_MODULE, | ||
251 | }, | ||
252 | |||
253 | .probe = omap_pcm_probe, | ||
254 | .remove = omap_pcm_remove, | ||
255 | }; | ||
256 | |||
257 | module_platform_driver(omap_pcm_driver); | ||
258 | 240 | ||
259 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); | 241 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); |
260 | MODULE_DESCRIPTION("OMAP PCM DMA module"); | 242 | MODULE_DESCRIPTION("OMAP PCM DMA module"); |
261 | MODULE_LICENSE("GPL"); | 243 | MODULE_LICENSE("GPL"); |
262 | MODULE_ALIAS("platform:omap-pcm-audio"); | ||
diff --git a/sound/soc/omap/omap-pcm.h b/sound/soc/omap/omap-pcm.h new file mode 100644 index 000000000000..c1d2f31d71e9 --- /dev/null +++ b/sound/soc/omap/omap-pcm.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * omap-pcm.h - OMAP PCM driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Texas Instruments, Inc. | ||
5 | * | ||
6 | * Author: Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #ifndef __OMAP_PCM_H__ | ||
19 | #define __OMAP_PCM_H__ | ||
20 | |||
21 | #if IS_ENABLED(CONFIG_SND_OMAP_SOC) | ||
22 | int omap_pcm_platform_register(struct device *dev); | ||
23 | #else | ||
24 | static inline int omap_pcm_platform_register(struct device *dev) | ||
25 | { | ||
26 | return 0; | ||
27 | } | ||
28 | #endif /* CONFIG_SND_OMAP_SOC */ | ||
29 | |||
30 | #endif /* __OMAP_PCM_H__ */ | ||
diff --git a/sound/soc/omap/omap-twl4030.c b/sound/soc/omap/omap-twl4030.c index 6a8d6b5f160d..64141db311b2 100644 --- a/sound/soc/omap/omap-twl4030.c +++ b/sound/soc/omap/omap-twl4030.c | |||
@@ -55,8 +55,7 @@ static int omap_twl4030_hw_params(struct snd_pcm_substream *substream, | |||
55 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 55 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
56 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 56 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
57 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 57 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
58 | struct snd_soc_codec *codec = rtd->codec; | 58 | struct snd_soc_card *card = rtd->card; |
59 | struct snd_soc_card *card = codec->card; | ||
60 | unsigned int fmt; | 59 | unsigned int fmt; |
61 | int ret; | 60 | int ret; |
62 | 61 | ||
@@ -179,7 +178,7 @@ static inline void twl4030_disconnect_pin(struct snd_soc_dapm_context *dapm, | |||
179 | static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) | 178 | static int omap_twl4030_init(struct snd_soc_pcm_runtime *rtd) |
180 | { | 179 | { |
181 | struct snd_soc_codec *codec = rtd->codec; | 180 | struct snd_soc_codec *codec = rtd->codec; |
182 | struct snd_soc_card *card = codec->card; | 181 | struct snd_soc_card *card = rtd->card; |
183 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 182 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
184 | struct omap_tw4030_pdata *pdata = dev_get_platdata(card->dev); | 183 | struct omap_tw4030_pdata *pdata = dev_get_platdata(card->dev); |
185 | struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); | 184 | struct omap_twl4030 *priv = snd_soc_card_get_drvdata(card); |
@@ -239,7 +238,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { | |||
239 | .stream_name = "TWL4030 HiFi", | 238 | .stream_name = "TWL4030 HiFi", |
240 | .cpu_dai_name = "omap-mcbsp.2", | 239 | .cpu_dai_name = "omap-mcbsp.2", |
241 | .codec_dai_name = "twl4030-hifi", | 240 | .codec_dai_name = "twl4030-hifi", |
242 | .platform_name = "omap-pcm-audio", | 241 | .platform_name = "omap-mcbsp.2", |
243 | .codec_name = "twl4030-codec", | 242 | .codec_name = "twl4030-codec", |
244 | .init = omap_twl4030_init, | 243 | .init = omap_twl4030_init, |
245 | .ops = &omap_twl4030_ops, | 244 | .ops = &omap_twl4030_ops, |
@@ -249,7 +248,7 @@ static struct snd_soc_dai_link omap_twl4030_dai_links[] = { | |||
249 | .stream_name = "TWL4030 Voice", | 248 | .stream_name = "TWL4030 Voice", |
250 | .cpu_dai_name = "omap-mcbsp.3", | 249 | .cpu_dai_name = "omap-mcbsp.3", |
251 | .codec_dai_name = "twl4030-voice", | 250 | .codec_dai_name = "twl4030-voice", |
252 | .platform_name = "omap-pcm-audio", | 251 | .platform_name = "omap-mcbsp.2", |
253 | .codec_name = "twl4030-codec", | 252 | .codec_name = "twl4030-codec", |
254 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | | 253 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | |
255 | SND_SOC_DAIFMT_CBM_CFM, | 254 | SND_SOC_DAIFMT_CBM_CFM, |
@@ -299,12 +298,18 @@ static int omap_twl4030_probe(struct platform_device *pdev) | |||
299 | omap_twl4030_dai_links[0].cpu_dai_name = NULL; | 298 | omap_twl4030_dai_links[0].cpu_dai_name = NULL; |
300 | omap_twl4030_dai_links[0].cpu_of_node = dai_node; | 299 | omap_twl4030_dai_links[0].cpu_of_node = dai_node; |
301 | 300 | ||
301 | omap_twl4030_dai_links[0].platform_name = NULL; | ||
302 | omap_twl4030_dai_links[0].platform_of_node = dai_node; | ||
303 | |||
302 | dai_node = of_parse_phandle(node, "ti,mcbsp-voice", 0); | 304 | dai_node = of_parse_phandle(node, "ti,mcbsp-voice", 0); |
303 | if (!dai_node) { | 305 | if (!dai_node) { |
304 | card->num_links = 1; | 306 | card->num_links = 1; |
305 | } else { | 307 | } else { |
306 | omap_twl4030_dai_links[1].cpu_dai_name = NULL; | 308 | omap_twl4030_dai_links[1].cpu_dai_name = NULL; |
307 | omap_twl4030_dai_links[1].cpu_of_node = dai_node; | 309 | omap_twl4030_dai_links[1].cpu_of_node = dai_node; |
310 | |||
311 | omap_twl4030_dai_links[1].platform_name = NULL; | ||
312 | omap_twl4030_dai_links[1].platform_of_node = dai_node; | ||
308 | } | 313 | } |
309 | 314 | ||
310 | priv->jack_detect = of_get_named_gpio(node, | 315 | priv->jack_detect = of_get_named_gpio(node, |
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index cf604a2faa18..076bec606d78 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
@@ -121,7 +121,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w, | |||
121 | * |A| <~~clk~~+ | 121 | * |A| <~~clk~~+ |
122 | * |P| <--- TWL4030 <--------- Line In and MICs | 122 | * |P| <--- TWL4030 <--------- Line In and MICs |
123 | */ | 123 | */ |
124 | static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { | 124 | static const struct snd_soc_dapm_widget omap3pandora_dapm_widgets[] = { |
125 | SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM, | 125 | SND_SOC_DAPM_DAC_E("PCM DAC", "HiFi Playback", SND_SOC_NOPM, |
126 | 0, 0, omap3pandora_dac_event, | 126 | 0, 0, omap3pandora_dac_event, |
127 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 127 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
@@ -130,22 +130,18 @@ static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { | |||
130 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 130 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
131 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | 131 | SND_SOC_DAPM_HP("Headphone Jack", NULL), |
132 | SND_SOC_DAPM_LINE("Line Out", NULL), | 132 | SND_SOC_DAPM_LINE("Line Out", NULL), |
133 | }; | ||
134 | 133 | ||
135 | static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = { | ||
136 | SND_SOC_DAPM_MIC("Mic (internal)", NULL), | 134 | SND_SOC_DAPM_MIC("Mic (internal)", NULL), |
137 | SND_SOC_DAPM_MIC("Mic (external)", NULL), | 135 | SND_SOC_DAPM_MIC("Mic (external)", NULL), |
138 | SND_SOC_DAPM_LINE("Line In", NULL), | 136 | SND_SOC_DAPM_LINE("Line In", NULL), |
139 | }; | 137 | }; |
140 | 138 | ||
141 | static const struct snd_soc_dapm_route omap3pandora_out_map[] = { | 139 | static const struct snd_soc_dapm_route omap3pandora_map[] = { |
142 | {"PCM DAC", NULL, "APLL Enable"}, | 140 | {"PCM DAC", NULL, "APLL Enable"}, |
143 | {"Headphone Amplifier", NULL, "PCM DAC"}, | 141 | {"Headphone Amplifier", NULL, "PCM DAC"}, |
144 | {"Line Out", NULL, "PCM DAC"}, | 142 | {"Line Out", NULL, "PCM DAC"}, |
145 | {"Headphone Jack", NULL, "Headphone Amplifier"}, | 143 | {"Headphone Jack", NULL, "Headphone Amplifier"}, |
146 | }; | ||
147 | 144 | ||
148 | static const struct snd_soc_dapm_route omap3pandora_in_map[] = { | ||
149 | {"AUXL", NULL, "Line In"}, | 145 | {"AUXL", NULL, "Line In"}, |
150 | {"AUXR", NULL, "Line In"}, | 146 | {"AUXR", NULL, "Line In"}, |
151 | 147 | ||
@@ -160,7 +156,6 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) | |||
160 | { | 156 | { |
161 | struct snd_soc_codec *codec = rtd->codec; | 157 | struct snd_soc_codec *codec = rtd->codec; |
162 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 158 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
163 | int ret; | ||
164 | 159 | ||
165 | /* All TWL4030 output pins are floating */ | 160 | /* All TWL4030 output pins are floating */ |
166 | snd_soc_dapm_nc_pin(dapm, "EARPIECE"); | 161 | snd_soc_dapm_nc_pin(dapm, "EARPIECE"); |
@@ -174,20 +169,13 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) | |||
174 | snd_soc_dapm_nc_pin(dapm, "HFR"); | 169 | snd_soc_dapm_nc_pin(dapm, "HFR"); |
175 | snd_soc_dapm_nc_pin(dapm, "VIBRA"); | 170 | snd_soc_dapm_nc_pin(dapm, "VIBRA"); |
176 | 171 | ||
177 | ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets, | 172 | return 0; |
178 | ARRAY_SIZE(omap3pandora_out_dapm_widgets)); | ||
179 | if (ret < 0) | ||
180 | return ret; | ||
181 | |||
182 | return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, | ||
183 | ARRAY_SIZE(omap3pandora_out_map)); | ||
184 | } | 173 | } |
185 | 174 | ||
186 | static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) | 175 | static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) |
187 | { | 176 | { |
188 | struct snd_soc_codec *codec = rtd->codec; | 177 | struct snd_soc_codec *codec = rtd->codec; |
189 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 178 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
190 | int ret; | ||
191 | 179 | ||
192 | /* Not comnnected */ | 180 | /* Not comnnected */ |
193 | snd_soc_dapm_nc_pin(dapm, "HSMIC"); | 181 | snd_soc_dapm_nc_pin(dapm, "HSMIC"); |
@@ -195,13 +183,7 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) | |||
195 | snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); | 183 | snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); |
196 | snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); | 184 | snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); |
197 | 185 | ||
198 | ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets, | 186 | return 0; |
199 | ARRAY_SIZE(omap3pandora_in_dapm_widgets)); | ||
200 | if (ret < 0) | ||
201 | return ret; | ||
202 | |||
203 | return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, | ||
204 | ARRAY_SIZE(omap3pandora_in_map)); | ||
205 | } | 187 | } |
206 | 188 | ||
207 | static struct snd_soc_ops omap3pandora_ops = { | 189 | static struct snd_soc_ops omap3pandora_ops = { |
@@ -215,7 +197,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
215 | .stream_name = "HiFi Out", | 197 | .stream_name = "HiFi Out", |
216 | .cpu_dai_name = "omap-mcbsp.2", | 198 | .cpu_dai_name = "omap-mcbsp.2", |
217 | .codec_dai_name = "twl4030-hifi", | 199 | .codec_dai_name = "twl4030-hifi", |
218 | .platform_name = "omap-pcm-audio", | 200 | .platform_name = "omap-mcbsp.2", |
219 | .codec_name = "twl4030-codec", | 201 | .codec_name = "twl4030-codec", |
220 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 202 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
221 | SND_SOC_DAIFMT_CBS_CFS, | 203 | SND_SOC_DAIFMT_CBS_CFS, |
@@ -226,7 +208,7 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
226 | .stream_name = "Line/Mic In", | 208 | .stream_name = "Line/Mic In", |
227 | .cpu_dai_name = "omap-mcbsp.4", | 209 | .cpu_dai_name = "omap-mcbsp.4", |
228 | .codec_dai_name = "twl4030-hifi", | 210 | .codec_dai_name = "twl4030-hifi", |
229 | .platform_name = "omap-pcm-audio", | 211 | .platform_name = "omap-mcbsp.4", |
230 | .codec_name = "twl4030-codec", | 212 | .codec_name = "twl4030-codec", |
231 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | 213 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | |
232 | SND_SOC_DAIFMT_CBS_CFS, | 214 | SND_SOC_DAIFMT_CBS_CFS, |
@@ -241,6 +223,11 @@ static struct snd_soc_card snd_soc_card_omap3pandora = { | |||
241 | .owner = THIS_MODULE, | 223 | .owner = THIS_MODULE, |
242 | .dai_link = omap3pandora_dai, | 224 | .dai_link = omap3pandora_dai, |
243 | .num_links = ARRAY_SIZE(omap3pandora_dai), | 225 | .num_links = ARRAY_SIZE(omap3pandora_dai), |
226 | |||
227 | .dapm_widgets = omap3pandora_dapm_widgets, | ||
228 | .num_dapm_widgets = ARRAY_SIZE(omap3pandora_dapm_widgets), | ||
229 | .dapm_routes = omap3pandora_map, | ||
230 | .num_dapm_routes = ARRAY_SIZE(omap3pandora_map), | ||
244 | }; | 231 | }; |
245 | 232 | ||
246 | static struct platform_device *omap3pandora_snd_device; | 233 | static struct platform_device *omap3pandora_snd_device; |
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index d03e57da7708..aa4053bf6710 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c | |||
@@ -96,7 +96,7 @@ static struct snd_soc_dai_link osk_dai = { | |||
96 | .stream_name = "AIC23", | 96 | .stream_name = "AIC23", |
97 | .cpu_dai_name = "omap-mcbsp.1", | 97 | .cpu_dai_name = "omap-mcbsp.1", |
98 | .codec_dai_name = "tlv320aic23-hifi", | 98 | .codec_dai_name = "tlv320aic23-hifi", |
99 | .platform_name = "omap-pcm-audio", | 99 | .platform_name = "omap-mcbsp.1", |
100 | .codec_name = "tlv320aic23-codec", | 100 | .codec_name = "tlv320aic23-codec", |
101 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | | 101 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | |
102 | SND_SOC_DAIFMT_CBM_CFM, | 102 | SND_SOC_DAIFMT_CBM_CFM, |
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 7fb3d4b10370..6951dc812055 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/delay.h> | 26 | #include <linux/delay.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/gpio/consumer.h> | ||
29 | #include <linux/module.h> | 30 | #include <linux/module.h> |
30 | #include <sound/core.h> | 31 | #include <sound/core.h> |
31 | #include <sound/jack.h> | 32 | #include <sound/jack.h> |
@@ -38,15 +39,6 @@ | |||
38 | 39 | ||
39 | #include "omap-mcbsp.h" | 40 | #include "omap-mcbsp.h" |
40 | 41 | ||
41 | #define RX51_TVOUT_SEL_GPIO 40 | ||
42 | #define RX51_JACK_DETECT_GPIO 177 | ||
43 | #define RX51_ECI_SW_GPIO 182 | ||
44 | /* | ||
45 | * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This | ||
46 | * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c | ||
47 | */ | ||
48 | #define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7) | ||
49 | |||
50 | enum { | 42 | enum { |
51 | RX51_JACK_DISABLED, | 43 | RX51_JACK_DISABLED, |
52 | RX51_JACK_TVOUT, /* tv-out with stereo output */ | 44 | RX51_JACK_TVOUT, /* tv-out with stereo output */ |
@@ -54,12 +46,21 @@ enum { | |||
54 | RX51_JACK_HS, /* headset: stereo output with mic */ | 46 | RX51_JACK_HS, /* headset: stereo output with mic */ |
55 | }; | 47 | }; |
56 | 48 | ||
49 | struct rx51_audio_pdata { | ||
50 | struct gpio_desc *tvout_selection_gpio; | ||
51 | struct gpio_desc *jack_detection_gpio; | ||
52 | struct gpio_desc *eci_sw_gpio; | ||
53 | struct gpio_desc *speaker_amp_gpio; | ||
54 | }; | ||
55 | |||
57 | static int rx51_spk_func; | 56 | static int rx51_spk_func; |
58 | static int rx51_dmic_func; | 57 | static int rx51_dmic_func; |
59 | static int rx51_jack_func; | 58 | static int rx51_jack_func; |
60 | 59 | ||
61 | static void rx51_ext_control(struct snd_soc_dapm_context *dapm) | 60 | static void rx51_ext_control(struct snd_soc_dapm_context *dapm) |
62 | { | 61 | { |
62 | struct snd_soc_card *card = dapm->card; | ||
63 | struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); | ||
63 | int hp = 0, hs = 0, tvout = 0; | 64 | int hp = 0, hs = 0, tvout = 0; |
64 | 65 | ||
65 | switch (rx51_jack_func) { | 66 | switch (rx51_jack_func) { |
@@ -93,7 +94,7 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm) | |||
93 | else | 94 | else |
94 | snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic"); | 95 | snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic"); |
95 | 96 | ||
96 | gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout); | 97 | gpiod_set_value(pdata->tvout_selection_gpio, tvout); |
97 | 98 | ||
98 | snd_soc_dapm_sync_unlocked(dapm); | 99 | snd_soc_dapm_sync_unlocked(dapm); |
99 | 100 | ||
@@ -154,10 +155,12 @@ static int rx51_set_spk(struct snd_kcontrol *kcontrol, | |||
154 | static int rx51_spk_event(struct snd_soc_dapm_widget *w, | 155 | static int rx51_spk_event(struct snd_soc_dapm_widget *w, |
155 | struct snd_kcontrol *k, int event) | 156 | struct snd_kcontrol *k, int event) |
156 | { | 157 | { |
157 | if (SND_SOC_DAPM_EVENT_ON(event)) | 158 | struct snd_soc_dapm_context *dapm = w->dapm; |
158 | gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 1); | 159 | struct snd_soc_card *card = dapm->card; |
159 | else | 160 | struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); |
160 | gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 0); | 161 | |
162 | gpiod_set_raw_value_cansleep(pdata->speaker_amp_gpio, | ||
163 | !!SND_SOC_DAPM_EVENT_ON(event)); | ||
161 | 164 | ||
162 | return 0; | 165 | return 0; |
163 | } | 166 | } |
@@ -223,7 +226,6 @@ static struct snd_soc_jack rx51_av_jack; | |||
223 | 226 | ||
224 | static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = { | 227 | static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = { |
225 | { | 228 | { |
226 | .gpio = RX51_JACK_DETECT_GPIO, | ||
227 | .name = "avdet-gpio", | 229 | .name = "avdet-gpio", |
228 | .report = SND_JACK_HEADSET, | 230 | .report = SND_JACK_HEADSET, |
229 | .invert = 1, | 231 | .invert = 1, |
@@ -237,9 +239,6 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = { | |||
237 | SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), | 239 | SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event), |
238 | SND_SOC_DAPM_MIC("HS Mic", NULL), | 240 | SND_SOC_DAPM_MIC("HS Mic", NULL), |
239 | SND_SOC_DAPM_LINE("FM Transmitter", NULL), | 241 | SND_SOC_DAPM_LINE("FM Transmitter", NULL), |
240 | }; | ||
241 | |||
242 | static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = { | ||
243 | SND_SOC_DAPM_SPK("Earphone", NULL), | 242 | SND_SOC_DAPM_SPK("Earphone", NULL), |
244 | }; | 243 | }; |
245 | 244 | ||
@@ -253,9 +252,7 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
253 | 252 | ||
254 | {"DMic Rate 64", NULL, "Mic Bias"}, | 253 | {"DMic Rate 64", NULL, "Mic Bias"}, |
255 | {"Mic Bias", NULL, "DMic"}, | 254 | {"Mic Bias", NULL, "DMic"}, |
256 | }; | ||
257 | 255 | ||
258 | static const struct snd_soc_dapm_route audio_mapb[] = { | ||
259 | {"b LINE2R", NULL, "MONO_LOUT"}, | 256 | {"b LINE2R", NULL, "MONO_LOUT"}, |
260 | {"Earphone", NULL, "b HPLOUT"}, | 257 | {"Earphone", NULL, "b HPLOUT"}, |
261 | 258 | ||
@@ -263,9 +260,11 @@ static const struct snd_soc_dapm_route audio_mapb[] = { | |||
263 | {"b Mic Bias", NULL, "HS Mic"} | 260 | {"b Mic Bias", NULL, "HS Mic"} |
264 | }; | 261 | }; |
265 | 262 | ||
266 | static const char *spk_function[] = {"Off", "On"}; | 263 | static const char * const spk_function[] = {"Off", "On"}; |
267 | static const char *input_function[] = {"ADC", "Digital Mic"}; | 264 | static const char * const input_function[] = {"ADC", "Digital Mic"}; |
268 | static const char *jack_function[] = {"Off", "TV-OUT", "Headphone", "Headset"}; | 265 | static const char * const jack_function[] = { |
266 | "Off", "TV-OUT", "Headphone", "Headset" | ||
267 | }; | ||
269 | 268 | ||
270 | static const struct soc_enum rx51_enum[] = { | 269 | static const struct soc_enum rx51_enum[] = { |
271 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), | 270 | SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spk_function), spk_function), |
@@ -281,15 +280,15 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { | |||
281 | SOC_ENUM_EXT("Jack Function", rx51_enum[2], | 280 | SOC_ENUM_EXT("Jack Function", rx51_enum[2], |
282 | rx51_get_jack, rx51_set_jack), | 281 | rx51_get_jack, rx51_set_jack), |
283 | SOC_DAPM_PIN_SWITCH("FM Transmitter"), | 282 | SOC_DAPM_PIN_SWITCH("FM Transmitter"), |
284 | }; | ||
285 | |||
286 | static const struct snd_kcontrol_new aic34_rx51_controlsb[] = { | ||
287 | SOC_DAPM_PIN_SWITCH("Earphone"), | 283 | SOC_DAPM_PIN_SWITCH("Earphone"), |
288 | }; | 284 | }; |
289 | 285 | ||
290 | static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) | 286 | static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) |
291 | { | 287 | { |
292 | struct snd_soc_codec *codec = rtd->codec; | 288 | struct snd_soc_codec *codec = rtd->codec; |
289 | struct snd_soc_card *card = rtd->card; | ||
290 | struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card); | ||
291 | |||
293 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 292 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
294 | int err; | 293 | int err; |
295 | 294 | ||
@@ -298,57 +297,41 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) | |||
298 | snd_soc_dapm_nc_pin(dapm, "MIC3R"); | 297 | snd_soc_dapm_nc_pin(dapm, "MIC3R"); |
299 | snd_soc_dapm_nc_pin(dapm, "LINE1R"); | 298 | snd_soc_dapm_nc_pin(dapm, "LINE1R"); |
300 | 299 | ||
301 | /* Add RX-51 specific controls */ | ||
302 | err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls, | ||
303 | ARRAY_SIZE(aic34_rx51_controls)); | ||
304 | if (err < 0) | ||
305 | return err; | ||
306 | |||
307 | /* Add RX-51 specific widgets */ | ||
308 | snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets, | ||
309 | ARRAY_SIZE(aic34_dapm_widgets)); | ||
310 | |||
311 | /* Set up RX-51 specific audio path audio_map */ | ||
312 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
313 | |||
314 | err = tpa6130a2_add_controls(codec); | 300 | err = tpa6130a2_add_controls(codec); |
315 | if (err < 0) | 301 | if (err < 0) { |
302 | dev_err(card->dev, "Failed to add TPA6130A2 controls\n"); | ||
316 | return err; | 303 | return err; |
304 | } | ||
317 | snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); | 305 | snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42); |
318 | 306 | ||
319 | err = omap_mcbsp_st_add_controls(rtd); | 307 | err = omap_mcbsp_st_add_controls(rtd, 2); |
320 | if (err < 0) | 308 | if (err < 0) { |
309 | dev_err(card->dev, "Failed to add MCBSP controls\n"); | ||
321 | return err; | 310 | return err; |
311 | } | ||
322 | 312 | ||
323 | /* AV jack detection */ | 313 | /* AV jack detection */ |
324 | err = snd_soc_jack_new(codec, "AV Jack", | 314 | err = snd_soc_jack_new(codec, "AV Jack", |
325 | SND_JACK_HEADSET | SND_JACK_VIDEOOUT, | 315 | SND_JACK_HEADSET | SND_JACK_VIDEOOUT, |
326 | &rx51_av_jack); | 316 | &rx51_av_jack); |
327 | if (err) | 317 | if (err) { |
318 | dev_err(card->dev, "Failed to add AV Jack\n"); | ||
328 | return err; | 319 | return err; |
320 | } | ||
321 | |||
322 | /* prepare gpio for snd_soc_jack_add_gpios */ | ||
323 | rx51_av_jack_gpios[0].gpio = desc_to_gpio(pdata->jack_detection_gpio); | ||
324 | devm_gpiod_put(card->dev, pdata->jack_detection_gpio); | ||
325 | |||
329 | err = snd_soc_jack_add_gpios(&rx51_av_jack, | 326 | err = snd_soc_jack_add_gpios(&rx51_av_jack, |
330 | ARRAY_SIZE(rx51_av_jack_gpios), | 327 | ARRAY_SIZE(rx51_av_jack_gpios), |
331 | rx51_av_jack_gpios); | 328 | rx51_av_jack_gpios); |
332 | 329 | if (err) { | |
333 | return err; | 330 | dev_err(card->dev, "Failed to add GPIOs\n"); |
334 | } | ||
335 | |||
336 | static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm) | ||
337 | { | ||
338 | int err; | ||
339 | |||
340 | err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb, | ||
341 | ARRAY_SIZE(aic34_rx51_controlsb)); | ||
342 | if (err < 0) | ||
343 | return err; | 331 | return err; |
332 | } | ||
344 | 333 | ||
345 | err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb, | 334 | return err; |
346 | ARRAY_SIZE(aic34_dapm_widgetsb)); | ||
347 | if (err < 0) | ||
348 | return 0; | ||
349 | |||
350 | return snd_soc_dapm_add_routes(dapm, audio_mapb, | ||
351 | ARRAY_SIZE(audio_mapb)); | ||
352 | } | 335 | } |
353 | 336 | ||
354 | /* Digital audio interface glue - connects codec <--> CPU */ | 337 | /* Digital audio interface glue - connects codec <--> CPU */ |
@@ -358,7 +341,7 @@ static struct snd_soc_dai_link rx51_dai[] = { | |||
358 | .stream_name = "AIC34", | 341 | .stream_name = "AIC34", |
359 | .cpu_dai_name = "omap-mcbsp.2", | 342 | .cpu_dai_name = "omap-mcbsp.2", |
360 | .codec_dai_name = "tlv320aic3x-hifi", | 343 | .codec_dai_name = "tlv320aic3x-hifi", |
361 | .platform_name = "omap-pcm-audio", | 344 | .platform_name = "omap-mcbsp.2", |
362 | .codec_name = "tlv320aic3x-codec.2-0018", | 345 | .codec_name = "tlv320aic3x-codec.2-0018", |
363 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | | 346 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | |
364 | SND_SOC_DAIFMT_CBM_CFM, | 347 | SND_SOC_DAIFMT_CBM_CFM, |
@@ -371,7 +354,6 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = { | |||
371 | { | 354 | { |
372 | .name = "TLV320AIC34b", | 355 | .name = "TLV320AIC34b", |
373 | .codec_name = "tlv320aic3x-codec.2-0019", | 356 | .codec_name = "tlv320aic3x-codec.2-0019", |
374 | .init = rx51_aic34b_init, | ||
375 | }, | 357 | }, |
376 | }; | 358 | }; |
377 | 359 | ||
@@ -392,63 +374,160 @@ static struct snd_soc_card rx51_sound_card = { | |||
392 | .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), | 374 | .num_aux_devs = ARRAY_SIZE(rx51_aux_dev), |
393 | .codec_conf = rx51_codec_conf, | 375 | .codec_conf = rx51_codec_conf, |
394 | .num_configs = ARRAY_SIZE(rx51_codec_conf), | 376 | .num_configs = ARRAY_SIZE(rx51_codec_conf), |
395 | }; | ||
396 | 377 | ||
397 | static struct platform_device *rx51_snd_device; | 378 | .controls = aic34_rx51_controls, |
379 | .num_controls = ARRAY_SIZE(aic34_rx51_controls), | ||
380 | .dapm_widgets = aic34_dapm_widgets, | ||
381 | .num_dapm_widgets = ARRAY_SIZE(aic34_dapm_widgets), | ||
382 | .dapm_routes = audio_map, | ||
383 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
384 | }; | ||
398 | 385 | ||
399 | static int __init rx51_soc_init(void) | 386 | static int rx51_soc_probe(struct platform_device *pdev) |
400 | { | 387 | { |
388 | struct rx51_audio_pdata *pdata; | ||
389 | struct device_node *np = pdev->dev.of_node; | ||
390 | struct snd_soc_card *card = &rx51_sound_card; | ||
401 | int err; | 391 | int err; |
402 | 392 | ||
403 | if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900")) | 393 | if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900")) |
404 | return -ENODEV; | 394 | return -ENODEV; |
405 | 395 | ||
406 | err = gpio_request_one(RX51_TVOUT_SEL_GPIO, | 396 | card->dev = &pdev->dev; |
407 | GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel"); | 397 | |
408 | if (err) | 398 | if (np) { |
409 | goto err_gpio_tvout_sel; | 399 | struct device_node *dai_node; |
410 | err = gpio_request_one(RX51_ECI_SW_GPIO, | 400 | |
411 | GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw"); | 401 | dai_node = of_parse_phandle(np, "nokia,cpu-dai", 0); |
412 | if (err) | 402 | if (!dai_node) { |
413 | goto err_gpio_eci_sw; | 403 | dev_err(&pdev->dev, "McBSP node is not provided\n"); |
414 | 404 | return -EINVAL; | |
415 | rx51_snd_device = platform_device_alloc("soc-audio", -1); | 405 | } |
416 | if (!rx51_snd_device) { | 406 | rx51_dai[0].cpu_dai_name = NULL; |
417 | err = -ENOMEM; | 407 | rx51_dai[0].platform_name = NULL; |
418 | goto err1; | 408 | rx51_dai[0].cpu_of_node = dai_node; |
409 | rx51_dai[0].platform_of_node = dai_node; | ||
410 | |||
411 | dai_node = of_parse_phandle(np, "nokia,audio-codec", 0); | ||
412 | if (!dai_node) { | ||
413 | dev_err(&pdev->dev, "Codec node is not provided\n"); | ||
414 | return -EINVAL; | ||
415 | } | ||
416 | rx51_dai[0].codec_name = NULL; | ||
417 | rx51_dai[0].codec_of_node = dai_node; | ||
418 | |||
419 | dai_node = of_parse_phandle(np, "nokia,audio-codec", 1); | ||
420 | if (!dai_node) { | ||
421 | dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n"); | ||
422 | return -EINVAL; | ||
423 | } | ||
424 | rx51_aux_dev[0].codec_name = NULL; | ||
425 | rx51_aux_dev[0].codec_of_node = dai_node; | ||
426 | rx51_codec_conf[0].dev_name = NULL; | ||
427 | rx51_codec_conf[0].of_node = dai_node; | ||
428 | |||
429 | dai_node = of_parse_phandle(np, "nokia,headphone-amplifier", 0); | ||
430 | if (!dai_node) { | ||
431 | dev_err(&pdev->dev, "Headphone amplifier node is not provided\n"); | ||
432 | return -EINVAL; | ||
433 | } | ||
434 | |||
435 | /* TODO: tpa6130a2a driver supports only a single instance, so | ||
436 | * this driver ignores the headphone-amplifier node for now. | ||
437 | * It's already mandatory in the DT binding to be future proof. | ||
438 | */ | ||
419 | } | 439 | } |
420 | 440 | ||
421 | platform_set_drvdata(rx51_snd_device, &rx51_sound_card); | 441 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); |
442 | if (pdata == NULL) { | ||
443 | dev_err(card->dev, "failed to create private data\n"); | ||
444 | return -ENOMEM; | ||
445 | } | ||
446 | snd_soc_card_set_drvdata(card, pdata); | ||
422 | 447 | ||
423 | err = platform_device_add(rx51_snd_device); | 448 | pdata->tvout_selection_gpio = devm_gpiod_get(card->dev, |
424 | if (err) | 449 | "tvout-selection"); |
425 | goto err2; | 450 | if (IS_ERR(pdata->tvout_selection_gpio)) { |
451 | dev_err(card->dev, "could not get tvout selection gpio\n"); | ||
452 | return PTR_ERR(pdata->tvout_selection_gpio); | ||
453 | } | ||
426 | 454 | ||
427 | return 0; | 455 | err = gpiod_direction_output(pdata->tvout_selection_gpio, 0); |
428 | err2: | 456 | if (err) { |
429 | platform_device_put(rx51_snd_device); | 457 | dev_err(card->dev, "could not setup tvout selection gpio\n"); |
430 | err1: | 458 | return err; |
431 | gpio_free(RX51_ECI_SW_GPIO); | 459 | } |
432 | err_gpio_eci_sw: | ||
433 | gpio_free(RX51_TVOUT_SEL_GPIO); | ||
434 | err_gpio_tvout_sel: | ||
435 | 460 | ||
436 | return err; | 461 | pdata->jack_detection_gpio = devm_gpiod_get(card->dev, |
462 | "jack-detection"); | ||
463 | if (IS_ERR(pdata->jack_detection_gpio)) { | ||
464 | dev_err(card->dev, "could not get jack detection gpio\n"); | ||
465 | return PTR_ERR(pdata->jack_detection_gpio); | ||
466 | } | ||
467 | |||
468 | pdata->eci_sw_gpio = devm_gpiod_get(card->dev, "eci-switch"); | ||
469 | if (IS_ERR(pdata->eci_sw_gpio)) { | ||
470 | dev_err(card->dev, "could not get eci switch gpio\n"); | ||
471 | return PTR_ERR(pdata->eci_sw_gpio); | ||
472 | } | ||
473 | |||
474 | err = gpiod_direction_output(pdata->eci_sw_gpio, 1); | ||
475 | if (err) { | ||
476 | dev_err(card->dev, "could not setup eci switch gpio\n"); | ||
477 | return err; | ||
478 | } | ||
479 | |||
480 | pdata->speaker_amp_gpio = devm_gpiod_get(card->dev, | ||
481 | "speaker-amplifier"); | ||
482 | if (IS_ERR(pdata->speaker_amp_gpio)) { | ||
483 | dev_err(card->dev, "could not get speaker enable gpio\n"); | ||
484 | return PTR_ERR(pdata->speaker_amp_gpio); | ||
485 | } | ||
486 | |||
487 | err = gpiod_direction_output(pdata->speaker_amp_gpio, 0); | ||
488 | if (err) { | ||
489 | dev_err(card->dev, "could not setup speaker enable gpio\n"); | ||
490 | return err; | ||
491 | } | ||
492 | |||
493 | err = devm_snd_soc_register_card(card->dev, card); | ||
494 | if (err) { | ||
495 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", err); | ||
496 | return err; | ||
497 | } | ||
498 | |||
499 | return 0; | ||
437 | } | 500 | } |
438 | 501 | ||
439 | static void __exit rx51_soc_exit(void) | 502 | static int rx51_soc_remove(struct platform_device *pdev) |
440 | { | 503 | { |
441 | snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), | 504 | snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios), |
442 | rx51_av_jack_gpios); | 505 | rx51_av_jack_gpios); |
443 | 506 | ||
444 | platform_device_unregister(rx51_snd_device); | 507 | return 0; |
445 | gpio_free(RX51_ECI_SW_GPIO); | ||
446 | gpio_free(RX51_TVOUT_SEL_GPIO); | ||
447 | } | 508 | } |
448 | 509 | ||
449 | module_init(rx51_soc_init); | 510 | #if defined(CONFIG_OF) |
450 | module_exit(rx51_soc_exit); | 511 | static const struct of_device_id rx51_audio_of_match[] = { |
512 | { .compatible = "nokia,n900-audio", }, | ||
513 | {}, | ||
514 | }; | ||
515 | MODULE_DEVICE_TABLE(of, rx51_audio_of_match); | ||
516 | #endif | ||
517 | |||
518 | static struct platform_driver rx51_soc_driver = { | ||
519 | .driver = { | ||
520 | .name = "rx51-audio", | ||
521 | .owner = THIS_MODULE, | ||
522 | .of_match_table = of_match_ptr(rx51_audio_of_match), | ||
523 | }, | ||
524 | .probe = rx51_soc_probe, | ||
525 | .remove = rx51_soc_remove, | ||
526 | }; | ||
527 | |||
528 | module_platform_driver(rx51_soc_driver); | ||
451 | 529 | ||
452 | MODULE_AUTHOR("Nokia Corporation"); | 530 | MODULE_AUTHOR("Nokia Corporation"); |
453 | MODULE_DESCRIPTION("ALSA SoC Nokia RX-51"); | 531 | MODULE_DESCRIPTION("ALSA SoC Nokia RX-51"); |
454 | MODULE_LICENSE("GPL"); | 532 | MODULE_LICENSE("GPL"); |
533 | MODULE_ALIAS("platform:rx51-audio"); | ||
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 6473052b6899..6acb225ec6fd 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -140,7 +140,7 @@ config SND_PXA910_SOC | |||
140 | 140 | ||
141 | config SND_SOC_TTC_DKB | 141 | config SND_SOC_TTC_DKB |
142 | bool "SoC Audio support for TTC DKB" | 142 | bool "SoC Audio support for TTC DKB" |
143 | depends on SND_PXA910_SOC && MACH_TTC_DKB | 143 | depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y |
144 | select PXA_SSP | 144 | select PXA_SSP |
145 | select SND_PXA_SOC_SSP | 145 | select SND_PXA_SOC_SSP |
146 | select SND_MMP_SOC | 146 | select SND_MMP_SOC |
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c index 08acdc236bf8..c8dd53f9c35d 100644 --- a/sound/soc/pxa/brownstone.c +++ b/sound/soc/pxa/brownstone.c | |||
@@ -50,11 +50,6 @@ static int brownstone_wm8994_init(struct snd_soc_pcm_runtime *rtd) | |||
50 | struct snd_soc_codec *codec = rtd->codec; | 50 | struct snd_soc_codec *codec = rtd->codec; |
51 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 51 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
52 | 52 | ||
53 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | ||
54 | snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); | ||
55 | snd_soc_dapm_enable_pin(dapm, "Headset Mic"); | ||
56 | snd_soc_dapm_enable_pin(dapm, "Main Mic"); | ||
57 | |||
58 | /* set endpoints to not connected */ | 53 | /* set endpoints to not connected */ |
59 | snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); | 54 | snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); |
60 | snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); | 55 | snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); |
@@ -70,8 +65,6 @@ static int brownstone_wm8994_init(struct snd_soc_pcm_runtime *rtd) | |||
70 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); | 65 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); |
71 | snd_soc_dapm_nc_pin(dapm, "IN2LN"); | 66 | snd_soc_dapm_nc_pin(dapm, "IN2LN"); |
72 | 67 | ||
73 | snd_soc_dapm_sync(dapm); | ||
74 | |||
75 | return 0; | 68 | return 0; |
76 | } | 69 | } |
77 | 70 | ||
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 3284c4b901cb..17f9521ff6ea 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c | |||
@@ -79,14 +79,6 @@ static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
79 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 79 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
80 | int err; | 80 | int err; |
81 | 81 | ||
82 | /* connected pins */ | ||
83 | if (machine_is_palmld()) | ||
84 | snd_soc_dapm_enable_pin(dapm, "MIC1"); | ||
85 | snd_soc_dapm_enable_pin(dapm, "HPOUTL"); | ||
86 | snd_soc_dapm_enable_pin(dapm, "HPOUTR"); | ||
87 | snd_soc_dapm_enable_pin(dapm, "LOUT2"); | ||
88 | snd_soc_dapm_enable_pin(dapm, "ROUT2"); | ||
89 | |||
90 | /* not connected pins */ | 82 | /* not connected pins */ |
91 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | 83 | snd_soc_dapm_nc_pin(dapm, "OUT3"); |
92 | snd_soc_dapm_nc_pin(dapm, "MONOOUT"); | 84 | snd_soc_dapm_nc_pin(dapm, "MONOOUT"); |
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index c6bdc6c0eff6..21f340065318 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
@@ -230,7 +230,6 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
230 | 230 | ||
231 | snd_soc_dapm_nc_pin(dapm, "LLINEIN"); | 231 | snd_soc_dapm_nc_pin(dapm, "LLINEIN"); |
232 | snd_soc_dapm_nc_pin(dapm, "RLINEIN"); | 232 | snd_soc_dapm_nc_pin(dapm, "RLINEIN"); |
233 | snd_soc_dapm_enable_pin(dapm, "MICIN"); | ||
234 | 233 | ||
235 | return 0; | 234 | return 0; |
236 | } | 235 | } |
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index a3119a00d8fa..9b19ee70291f 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include <sound/pxa2xx-lib.h> | 34 | #include <sound/pxa2xx-lib.h> |
35 | #include <sound/dmaengine_pcm.h> | 35 | #include <sound/dmaengine_pcm.h> |
36 | 36 | ||
37 | #include <mach/hardware.h> | ||
38 | |||
39 | #include "../../arm/pxa2xx-pcm.h" | 37 | #include "../../arm/pxa2xx-pcm.h" |
40 | #include "pxa-ssp.h" | 38 | #include "pxa-ssp.h" |
41 | 39 | ||
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index d58b09f4f7a4..42f2f0175981 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <linux/dmaengine.h> | 15 | #include <linux/dmaengine.h> |
16 | #include <linux/of.h> | 16 | #include <linux/of.h> |
17 | 17 | ||
18 | #include <mach/dma.h> | ||
19 | |||
18 | #include <sound/core.h> | 20 | #include <sound/core.h> |
19 | #include <sound/soc.h> | 21 | #include <sound/soc.h> |
20 | #include <sound/pxa2xx-lib.h> | 22 | #include <sound/pxa2xx-lib.h> |
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c index 0b535b570622..9d7c5b7e9539 100644 --- a/sound/soc/pxa/ttc-dkb.c +++ b/sound/soc/pxa/ttc-dkb.c | |||
@@ -78,10 +78,6 @@ static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) | |||
78 | struct snd_soc_codec *codec = rtd->codec; | 78 | struct snd_soc_codec *codec = rtd->codec; |
79 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 79 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
80 | 80 | ||
81 | /* connected pins */ | ||
82 | snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); | ||
83 | snd_soc_dapm_enable_pin(dapm, "Ext Mic 1"); | ||
84 | snd_soc_dapm_enable_pin(dapm, "Ext Mic 3"); | ||
85 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); | 81 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); |
86 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); | 82 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); |
87 | 83 | ||
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index f2e289180e46..753b8c93ab51 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -64,6 +64,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
64 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 64 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
65 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 65 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
66 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) | 66 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) |
67 | depends on REGMAP_I2C | ||
67 | select SND_SOC_WM8580 | 68 | select SND_SOC_WM8580 |
68 | select SND_SAMSUNG_I2S | 69 | select SND_SAMSUNG_I2S |
69 | help | 70 | help |
@@ -115,21 +116,21 @@ config SND_SOC_SAMSUNG_SIMTEC | |||
115 | 116 | ||
116 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 | 117 | config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 |
117 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" | 118 | tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" |
118 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX | 119 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C |
119 | select SND_S3C24XX_I2S | 120 | select SND_S3C24XX_I2S |
120 | select SND_SOC_TLV320AIC23_I2C | 121 | select SND_SOC_TLV320AIC23_I2C |
121 | select SND_SOC_SAMSUNG_SIMTEC | 122 | select SND_SOC_SAMSUNG_SIMTEC |
122 | 123 | ||
123 | config SND_SOC_SAMSUNG_SIMTEC_HERMES | 124 | config SND_SOC_SAMSUNG_SIMTEC_HERMES |
124 | tristate "SoC I2S Audio support for Simtec Hermes board" | 125 | tristate "SoC I2S Audio support for Simtec Hermes board" |
125 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX | 126 | depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C |
126 | select SND_S3C24XX_I2S | 127 | select SND_S3C24XX_I2S |
127 | select SND_SOC_TLV320AIC3X | 128 | select SND_SOC_TLV320AIC3X |
128 | select SND_SOC_SAMSUNG_SIMTEC | 129 | select SND_SOC_SAMSUNG_SIMTEC |
129 | 130 | ||
130 | config SND_SOC_SAMSUNG_H1940_UDA1380 | 131 | config SND_SOC_SAMSUNG_H1940_UDA1380 |
131 | tristate "Audio support for the HP iPAQ H1940" | 132 | tristate "Audio support for the HP iPAQ H1940" |
132 | depends on SND_SOC_SAMSUNG && ARCH_H1940 | 133 | depends on SND_SOC_SAMSUNG && ARCH_H1940 && I2C |
133 | select SND_S3C24XX_I2S | 134 | select SND_S3C24XX_I2S |
134 | select SND_SOC_UDA1380 | 135 | select SND_SOC_UDA1380 |
135 | help | 136 | help |
@@ -137,7 +138,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380 | |||
137 | 138 | ||
138 | config SND_SOC_SAMSUNG_RX1950_UDA1380 | 139 | config SND_SOC_SAMSUNG_RX1950_UDA1380 |
139 | tristate "Audio support for the HP iPAQ RX1950" | 140 | tristate "Audio support for the HP iPAQ RX1950" |
140 | depends on SND_SOC_SAMSUNG && MACH_RX1950 | 141 | depends on SND_SOC_SAMSUNG && MACH_RX1950 && I2C |
141 | select SND_S3C24XX_I2S | 142 | select SND_S3C24XX_I2S |
142 | select SND_SOC_UDA1380 | 143 | select SND_SOC_UDA1380 |
143 | help | 144 | help |
@@ -178,6 +179,7 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF | |||
178 | config SND_SOC_SMDK_WM8580_PCM | 179 | config SND_SOC_SMDK_WM8580_PCM |
179 | tristate "SoC PCM Audio support for WM8580 on SMDK" | 180 | tristate "SoC PCM Audio support for WM8580 on SMDK" |
180 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) | 181 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) |
182 | depends on REGMAP_I2C | ||
181 | select SND_SOC_WM8580 | 183 | select SND_SOC_WM8580 |
182 | select SND_SAMSUNG_PCM | 184 | select SND_SAMSUNG_PCM |
183 | help | 185 | help |
@@ -204,7 +206,7 @@ config SND_SOC_SPEYSIDE | |||
204 | 206 | ||
205 | config SND_SOC_TOBERMORY | 207 | config SND_SOC_TOBERMORY |
206 | tristate "Audio support for Wolfson Tobermory" | 208 | tristate "Audio support for Wolfson Tobermory" |
207 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 | 209 | depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && INPUT |
208 | select SND_SAMSUNG_I2S | 210 | select SND_SAMSUNG_I2S |
209 | select SND_SOC_WM8962 | 211 | select SND_SOC_WM8962 |
210 | 212 | ||
@@ -231,3 +233,13 @@ config SND_SOC_LITTLEMILL | |||
231 | select SND_SAMSUNG_I2S | 233 | select SND_SAMSUNG_I2S |
232 | select MFD_WM8994 | 234 | select MFD_WM8994 |
233 | select SND_SOC_WM8994 | 235 | select SND_SOC_WM8994 |
236 | |||
237 | config SND_SOC_SNOW | ||
238 | tristate "Audio support for Google Snow boards" | ||
239 | depends on SND_SOC_SAMSUNG | ||
240 | select SND_SOC_MAX98090 | ||
241 | select SND_SOC_MAX98095 | ||
242 | select SND_SAMSUNG_I2S | ||
243 | help | ||
244 | Say Y if you want to add audio support for various Snow | ||
245 | boards based on Exynos5 series of SoCs. | ||
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 86715d8efee6..6d0212ba571c 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile | |||
@@ -34,6 +34,7 @@ snd-soc-h1940-uda1380-objs := h1940_uda1380.o | |||
34 | snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o | 34 | snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o |
35 | snd-soc-smdk-wm8580-objs := smdk_wm8580.o | 35 | snd-soc-smdk-wm8580-objs := smdk_wm8580.o |
36 | snd-soc-smdk-wm8994-objs := smdk_wm8994.o | 36 | snd-soc-smdk-wm8994-objs := smdk_wm8994.o |
37 | snd-soc-snow-objs := snow.o | ||
37 | snd-soc-smdk-wm9713-objs := smdk_wm9713.o | 38 | snd-soc-smdk-wm9713-objs := smdk_wm9713.o |
38 | snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o | 39 | snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o |
39 | snd-soc-goni-wm8994-objs := goni_wm8994.o | 40 | snd-soc-goni-wm8994-objs := goni_wm8994.o |
@@ -58,6 +59,7 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o | |||
58 | obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o | 59 | obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o |
59 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o | 60 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o |
60 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o | 61 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o |
62 | obj-$(CONFIG_SND_SOC_SNOW) += snd-soc-snow.o | ||
61 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o | 63 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o |
62 | obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o | 64 | obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o |
63 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o | 65 | obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index 76b072bd4ba2..68d9303047e8 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
@@ -433,7 +433,7 @@ static int s3c_ac97_probe(struct platform_device *pdev) | |||
433 | goto err4; | 433 | goto err4; |
434 | } | 434 | } |
435 | 435 | ||
436 | ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, | 436 | ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component, |
437 | s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); | 437 | s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); |
438 | if (ret) | 438 | if (ret) |
439 | goto err5; | 439 | goto err5; |
@@ -441,12 +441,10 @@ static int s3c_ac97_probe(struct platform_device *pdev) | |||
441 | ret = samsung_asoc_dma_platform_register(&pdev->dev); | 441 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
442 | if (ret) { | 442 | if (ret) { |
443 | dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); | 443 | dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); |
444 | goto err6; | 444 | goto err5; |
445 | } | 445 | } |
446 | 446 | ||
447 | return 0; | 447 | return 0; |
448 | err6: | ||
449 | snd_soc_unregister_component(&pdev->dev); | ||
450 | err5: | 448 | err5: |
451 | free_irq(irq_res->start, NULL); | 449 | free_irq(irq_res->start, NULL); |
452 | err4: | 450 | err4: |
@@ -461,9 +459,6 @@ static int s3c_ac97_remove(struct platform_device *pdev) | |||
461 | { | 459 | { |
462 | struct resource *irq_res; | 460 | struct resource *irq_res; |
463 | 461 | ||
464 | samsung_asoc_dma_platform_unregister(&pdev->dev); | ||
465 | snd_soc_unregister_component(&pdev->dev); | ||
466 | |||
467 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 462 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); |
468 | if (irq_res) | 463 | if (irq_res) |
469 | free_irq(irq_res->start, NULL); | 464 | free_irq(irq_res->start, NULL); |
diff --git a/sound/soc/samsung/bells.c b/sound/soc/samsung/bells.c index 84f5d8b76679..5b21207cf551 100644 --- a/sound/soc/samsung/bells.c +++ b/sound/soc/samsung/bells.c | |||
@@ -433,22 +433,13 @@ static int bells_probe(struct platform_device *pdev) | |||
433 | 433 | ||
434 | bells_cards[pdev->id].dev = &pdev->dev; | 434 | bells_cards[pdev->id].dev = &pdev->dev; |
435 | 435 | ||
436 | ret = snd_soc_register_card(&bells_cards[pdev->id]); | 436 | ret = devm_snd_soc_register_card(&pdev->dev, &bells_cards[pdev->id]); |
437 | if (ret) { | 437 | if (ret) |
438 | dev_err(&pdev->dev, | 438 | dev_err(&pdev->dev, |
439 | "snd_soc_register_card(%s) failed: %d\n", | 439 | "snd_soc_register_card(%s) failed: %d\n", |
440 | bells_cards[pdev->id].name, ret); | 440 | bells_cards[pdev->id].name, ret); |
441 | return ret; | ||
442 | } | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static int bells_remove(struct platform_device *pdev) | ||
448 | { | ||
449 | snd_soc_unregister_card(&bells_cards[pdev->id]); | ||
450 | 441 | ||
451 | return 0; | 442 | return ret; |
452 | } | 443 | } |
453 | 444 | ||
454 | static struct platform_driver bells_driver = { | 445 | static struct platform_driver bells_driver = { |
@@ -458,7 +449,6 @@ static struct platform_driver bells_driver = { | |||
458 | .pm = &snd_soc_pm_ops, | 449 | .pm = &snd_soc_pm_ops, |
459 | }, | 450 | }, |
460 | .probe = bells_probe, | 451 | .probe = bells_probe, |
461 | .remove = bells_remove, | ||
462 | }; | 452 | }; |
463 | 453 | ||
464 | module_platform_driver(bells_driver); | 454 | module_platform_driver(bells_driver); |
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c index dc09b71b7d9f..d9dc7bcc0336 100644 --- a/sound/soc/samsung/dma.c +++ b/sound/soc/samsung/dma.c | |||
@@ -445,16 +445,10 @@ EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); | |||
445 | 445 | ||
446 | int samsung_asoc_dma_platform_register(struct device *dev) | 446 | int samsung_asoc_dma_platform_register(struct device *dev) |
447 | { | 447 | { |
448 | return snd_soc_register_platform(dev, &samsung_asoc_platform); | 448 | return devm_snd_soc_register_platform(dev, &samsung_asoc_platform); |
449 | } | 449 | } |
450 | EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); | 450 | EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); |
451 | 451 | ||
452 | void samsung_asoc_dma_platform_unregister(struct device *dev) | ||
453 | { | ||
454 | snd_soc_unregister_platform(dev); | ||
455 | } | ||
456 | EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister); | ||
457 | |||
458 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); | 452 | MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); |
459 | MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); | 453 | MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); |
460 | MODULE_LICENSE("GPL"); | 454 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h index ad7c0f04f00d..070ab0f09609 100644 --- a/sound/soc/samsung/dma.h +++ b/sound/soc/samsung/dma.h | |||
@@ -33,6 +33,5 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, | |||
33 | struct s3c_dma_params *playback, | 33 | struct s3c_dma_params *playback, |
34 | struct s3c_dma_params *capture); | 34 | struct s3c_dma_params *capture); |
35 | int samsung_asoc_dma_platform_register(struct device *dev); | 35 | int samsung_asoc_dma_platform_register(struct device *dev); |
36 | void samsung_asoc_dma_platform_unregister(struct device *dev); | ||
37 | 36 | ||
38 | #endif | 37 | #endif |
diff --git a/sound/soc/samsung/dmaengine.c b/sound/soc/samsung/dmaengine.c index 750ce5808d9f..a0e4e7948909 100644 --- a/sound/soc/samsung/dmaengine.c +++ b/sound/soc/samsung/dmaengine.c | |||
@@ -66,18 +66,13 @@ EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); | |||
66 | 66 | ||
67 | int samsung_asoc_dma_platform_register(struct device *dev) | 67 | int samsung_asoc_dma_platform_register(struct device *dev) |
68 | { | 68 | { |
69 | return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config, | 69 | return devm_snd_dmaengine_pcm_register(dev, |
70 | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | | 70 | &samsung_dmaengine_pcm_config, |
71 | SND_DMAENGINE_PCM_FLAG_COMPAT); | 71 | SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | |
72 | SND_DMAENGINE_PCM_FLAG_COMPAT); | ||
72 | } | 73 | } |
73 | EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); | 74 | EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); |
74 | 75 | ||
75 | void samsung_asoc_dma_platform_unregister(struct device *dev) | ||
76 | { | ||
77 | return snd_dmaengine_pcm_unregister(dev); | ||
78 | } | ||
79 | EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister); | ||
80 | |||
81 | MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); | 76 | MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); |
82 | MODULE_DESCRIPTION("Samsung dmaengine ASoC driver"); | 77 | MODULE_DESCRIPTION("Samsung dmaengine ASoC driver"); |
83 | MODULE_LICENSE("GPL"); | 78 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index 415ad81999c4..9506d7617223 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c | |||
@@ -274,8 +274,8 @@ static int __init goni_init(void) | |||
274 | return -ENOMEM; | 274 | return -ENOMEM; |
275 | 275 | ||
276 | /* register voice DAI here */ | 276 | /* register voice DAI here */ |
277 | ret = snd_soc_register_component(&goni_snd_device->dev, &voice_component, | 277 | ret = devm_snd_soc_register_component(&goni_snd_device->dev, |
278 | &voice_dai, 1); | 278 | &voice_component, &voice_dai, 1); |
279 | if (ret) { | 279 | if (ret) { |
280 | platform_device_put(goni_snd_device); | 280 | platform_device_put(goni_snd_device); |
281 | return ret; | 281 | return ret; |
@@ -284,17 +284,14 @@ static int __init goni_init(void) | |||
284 | platform_set_drvdata(goni_snd_device, &goni); | 284 | platform_set_drvdata(goni_snd_device, &goni); |
285 | ret = platform_device_add(goni_snd_device); | 285 | ret = platform_device_add(goni_snd_device); |
286 | 286 | ||
287 | if (ret) { | 287 | if (ret) |
288 | snd_soc_unregister_component(&goni_snd_device->dev); | ||
289 | platform_device_put(goni_snd_device); | 288 | platform_device_put(goni_snd_device); |
290 | } | ||
291 | 289 | ||
292 | return ret; | 290 | return ret; |
293 | } | 291 | } |
294 | 292 | ||
295 | static void __exit goni_exit(void) | 293 | static void __exit goni_exit(void) |
296 | { | 294 | { |
297 | snd_soc_unregister_component(&goni_snd_device->dev); | ||
298 | platform_device_unregister(goni_snd_device); | 295 | platform_device_unregister(goni_snd_device); |
299 | } | 296 | } |
300 | 297 | ||
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index 88b09e022503..9f2fb69dbaae 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c | |||
@@ -176,11 +176,6 @@ static struct platform_device *s3c24xx_snd_device; | |||
176 | static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) | 176 | static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) |
177 | { | 177 | { |
178 | struct snd_soc_codec *codec = rtd->codec; | 178 | struct snd_soc_codec *codec = rtd->codec; |
179 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
180 | |||
181 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
182 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | ||
183 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
184 | 179 | ||
185 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | 180 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, |
186 | &hp_jack); | 181 | &hp_jack); |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 048ead967199..07ff3e7cb890 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
@@ -451,6 +451,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, | |||
451 | u32 mod = readl(i2s->addr + I2SMOD); | 451 | u32 mod = readl(i2s->addr + I2SMOD); |
452 | 452 | ||
453 | switch (clk_id) { | 453 | switch (clk_id) { |
454 | case SAMSUNG_I2S_OPCLK: | ||
455 | mod &= ~MOD_OPCLK_MASK; | ||
456 | mod |= dir; | ||
457 | break; | ||
454 | case SAMSUNG_I2S_CDCLK: | 458 | case SAMSUNG_I2S_CDCLK: |
455 | /* Shouldn't matter in GATING(CLOCK_IN) mode */ | 459 | /* Shouldn't matter in GATING(CLOCK_IN) mode */ |
456 | if (dir == SND_SOC_CLOCK_IN) | 460 | if (dir == SND_SOC_CLOCK_IN) |
@@ -724,9 +728,6 @@ static int i2s_startup(struct snd_pcm_substream *substream, | |||
724 | else | 728 | else |
725 | i2s->mode |= DAI_MANAGER; | 729 | i2s->mode |= DAI_MANAGER; |
726 | 730 | ||
727 | /* Enforce set_sysclk in Master mode */ | ||
728 | i2s->rclk_srcrate = 0; | ||
729 | |||
730 | if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR)) | 731 | if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR)) |
731 | writel(CON_RSTCLR, i2s->addr + I2SCON); | 732 | writel(CON_RSTCLR, i2s->addr + I2SCON); |
732 | 733 | ||
@@ -984,6 +985,7 @@ probe_exit: | |||
984 | /* Reset any constraint on RFS and BFS */ | 985 | /* Reset any constraint on RFS and BFS */ |
985 | i2s->rfs = 0; | 986 | i2s->rfs = 0; |
986 | i2s->bfs = 0; | 987 | i2s->bfs = 0; |
988 | i2s->rclk_srcrate = 0; | ||
987 | i2s_txctrl(i2s, 0); | 989 | i2s_txctrl(i2s, 0); |
988 | i2s_rxctrl(i2s, 0); | 990 | i2s_rxctrl(i2s, 0); |
989 | i2s_fifo(i2s, FIC_TXFLUSH); | 991 | i2s_fifo(i2s, FIC_TXFLUSH); |
@@ -1293,8 +1295,6 @@ static int samsung_i2s_remove(struct platform_device *pdev) | |||
1293 | i2s->pri_dai = NULL; | 1295 | i2s->pri_dai = NULL; |
1294 | i2s->sec_dai = NULL; | 1296 | i2s->sec_dai = NULL; |
1295 | 1297 | ||
1296 | samsung_asoc_dma_platform_unregister(&pdev->dev); | ||
1297 | |||
1298 | return 0; | 1298 | return 0; |
1299 | } | 1299 | } |
1300 | 1300 | ||
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h index 7966afc934db..21ff24e930db 100644 --- a/sound/soc/samsung/i2s.h +++ b/sound/soc/samsung/i2s.h | |||
@@ -18,5 +18,6 @@ | |||
18 | #define SAMSUNG_I2S_RCLKSRC_0 0 | 18 | #define SAMSUNG_I2S_RCLKSRC_0 0 |
19 | #define SAMSUNG_I2S_RCLKSRC_1 1 | 19 | #define SAMSUNG_I2S_RCLKSRC_1 1 |
20 | #define SAMSUNG_I2S_CDCLK 2 | 20 | #define SAMSUNG_I2S_CDCLK 2 |
21 | #define SAMSUNG_I2S_OPCLK 3 | ||
21 | 22 | ||
22 | #endif /* __SND_SOC_SAMSUNG_I2S_H */ | 23 | #endif /* __SND_SOC_SAMSUNG_I2S_H */ |
diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c index 3d5cf1530b6f..8cc5770abb39 100644 --- a/sound/soc/samsung/idma.c +++ b/sound/soc/samsung/idma.c | |||
@@ -274,7 +274,7 @@ static irqreturn_t iis_irq(int irqno, void *dev_id) | |||
274 | 274 | ||
275 | addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr; | 275 | addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr; |
276 | addr += prtd->periodsz; | 276 | addr += prtd->periodsz; |
277 | addr %= (prtd->end - prtd->start); | 277 | addr %= (u32)(prtd->end - prtd->start); |
278 | addr += idma.lp_tx_addr; | 278 | addr += idma.lp_tx_addr; |
279 | 279 | ||
280 | writel(addr, idma.regs + I2SLVL0ADDR); | 280 | writel(addr, idma.regs + I2SLVL0ADDR); |
@@ -413,13 +413,7 @@ static int asoc_idma_platform_probe(struct platform_device *pdev) | |||
413 | if (idma_irq < 0) | 413 | if (idma_irq < 0) |
414 | return idma_irq; | 414 | return idma_irq; |
415 | 415 | ||
416 | return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); | 416 | return devm_snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); |
417 | } | ||
418 | |||
419 | static int asoc_idma_platform_remove(struct platform_device *pdev) | ||
420 | { | ||
421 | snd_soc_unregister_platform(&pdev->dev); | ||
422 | return 0; | ||
423 | } | 417 | } |
424 | 418 | ||
425 | static struct platform_driver asoc_idma_driver = { | 419 | static struct platform_driver asoc_idma_driver = { |
@@ -429,7 +423,6 @@ static struct platform_driver asoc_idma_driver = { | |||
429 | }, | 423 | }, |
430 | 424 | ||
431 | .probe = asoc_idma_platform_probe, | 425 | .probe = asoc_idma_platform_probe, |
432 | .remove = asoc_idma_platform_remove, | ||
433 | }; | 426 | }; |
434 | 427 | ||
435 | module_platform_driver(asoc_idma_driver); | 428 | module_platform_driver(asoc_idma_driver); |
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c index bfb91f34a22a..840787e63cb1 100644 --- a/sound/soc/samsung/littlemill.c +++ b/sound/soc/samsung/littlemill.c | |||
@@ -304,23 +304,12 @@ static int littlemill_probe(struct platform_device *pdev) | |||
304 | 304 | ||
305 | card->dev = &pdev->dev; | 305 | card->dev = &pdev->dev; |
306 | 306 | ||
307 | ret = snd_soc_register_card(card); | 307 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
308 | if (ret) { | 308 | if (ret) |
309 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 309 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
310 | ret); | 310 | ret); |
311 | return ret; | ||
312 | } | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | static int littlemill_remove(struct platform_device *pdev) | ||
318 | { | ||
319 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
320 | 311 | ||
321 | snd_soc_unregister_card(card); | 312 | return ret; |
322 | |||
323 | return 0; | ||
324 | } | 313 | } |
325 | 314 | ||
326 | static struct platform_driver littlemill_driver = { | 315 | static struct platform_driver littlemill_driver = { |
@@ -330,7 +319,6 @@ static struct platform_driver littlemill_driver = { | |||
330 | .pm = &snd_soc_pm_ops, | 319 | .pm = &snd_soc_pm_ops, |
331 | }, | 320 | }, |
332 | .probe = littlemill_probe, | 321 | .probe = littlemill_probe, |
333 | .remove = littlemill_remove, | ||
334 | }; | 322 | }; |
335 | 323 | ||
336 | module_platform_driver(littlemill_driver); | 324 | module_platform_driver(littlemill_driver); |
diff --git a/sound/soc/samsung/lowland.c b/sound/soc/samsung/lowland.c index 570cf5229508..bd5f0d643a86 100644 --- a/sound/soc/samsung/lowland.c +++ b/sound/soc/samsung/lowland.c | |||
@@ -187,23 +187,12 @@ static int lowland_probe(struct platform_device *pdev) | |||
187 | 187 | ||
188 | card->dev = &pdev->dev; | 188 | card->dev = &pdev->dev; |
189 | 189 | ||
190 | ret = snd_soc_register_card(card); | 190 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
191 | if (ret) { | 191 | if (ret) |
192 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 192 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
193 | ret); | 193 | ret); |
194 | return ret; | ||
195 | } | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int lowland_remove(struct platform_device *pdev) | ||
201 | { | ||
202 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
203 | 194 | ||
204 | snd_soc_unregister_card(card); | 195 | return ret; |
205 | |||
206 | return 0; | ||
207 | } | 196 | } |
208 | 197 | ||
209 | static struct platform_driver lowland_driver = { | 198 | static struct platform_driver lowland_driver = { |
@@ -213,7 +202,6 @@ static struct platform_driver lowland_driver = { | |||
213 | .pm = &snd_soc_pm_ops, | 202 | .pm = &snd_soc_pm_ops, |
214 | }, | 203 | }, |
215 | .probe = lowland_probe, | 204 | .probe = lowland_probe, |
216 | .remove = lowland_remove, | ||
217 | }; | 205 | }; |
218 | 206 | ||
219 | module_platform_driver(lowland_driver); | 207 | module_platform_driver(lowland_driver); |
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index b0800337b79e..9b4a09f14b6c 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
@@ -271,15 +271,8 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { | |||
271 | 271 | ||
272 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | 272 | static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) |
273 | { | 273 | { |
274 | struct snd_soc_codec *codec = rtd->codec; | ||
275 | struct snd_soc_card *card = rtd->card; | 274 | struct snd_soc_card *card = rtd->card; |
276 | 275 | ||
277 | /* set up NC codec pins */ | ||
278 | snd_soc_dapm_nc_pin(&codec->dapm, "OUT3"); | ||
279 | snd_soc_dapm_nc_pin(&codec->dapm, "OUT4"); | ||
280 | snd_soc_dapm_nc_pin(&codec->dapm, "LINE1"); | ||
281 | snd_soc_dapm_nc_pin(&codec->dapm, "LINE2"); | ||
282 | |||
283 | /* set endpoints to default off mode */ | 276 | /* set endpoints to default off mode */ |
284 | snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out"); | 277 | snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out"); |
285 | snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In"); | 278 | snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In"); |
@@ -355,6 +348,7 @@ static struct snd_soc_card neo1973 = { | |||
355 | .num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets), | 348 | .num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets), |
356 | .dapm_routes = neo1973_wm8753_routes, | 349 | .dapm_routes = neo1973_wm8753_routes, |
357 | .num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes), | 350 | .num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes), |
351 | .fully_routed = true, | ||
358 | }; | 352 | }; |
359 | 353 | ||
360 | static struct platform_device *neo1973_snd_device; | 354 | static struct platform_device *neo1973_snd_device; |
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index ab54e297957c..a3c9c9cba3b0 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -542,7 +542,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
542 | /* Default is 128fs */ | 542 | /* Default is 128fs */ |
543 | pcm->sclk_per_fs = 128; | 543 | pcm->sclk_per_fs = 128; |
544 | 544 | ||
545 | pcm->cclk = clk_get(&pdev->dev, "audio-bus"); | 545 | pcm->cclk = devm_clk_get(&pdev->dev, "audio-bus"); |
546 | if (IS_ERR(pcm->cclk)) { | 546 | if (IS_ERR(pcm->cclk)) { |
547 | dev_err(&pdev->dev, "failed to get audio-bus\n"); | 547 | dev_err(&pdev->dev, "failed to get audio-bus\n"); |
548 | ret = PTR_ERR(pcm->cclk); | 548 | ret = PTR_ERR(pcm->cclk); |
@@ -567,7 +567,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
567 | goto err3; | 567 | goto err3; |
568 | } | 568 | } |
569 | 569 | ||
570 | pcm->pclk = clk_get(&pdev->dev, "pcm"); | 570 | pcm->pclk = devm_clk_get(&pdev->dev, "pcm"); |
571 | if (IS_ERR(pcm->pclk)) { | 571 | if (IS_ERR(pcm->pclk)) { |
572 | dev_err(&pdev->dev, "failed to get pcm_clock\n"); | 572 | dev_err(&pdev->dev, "failed to get pcm_clock\n"); |
573 | ret = -ENOENT; | 573 | ret = -ENOENT; |
@@ -588,7 +588,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
588 | 588 | ||
589 | pm_runtime_enable(&pdev->dev); | 589 | pm_runtime_enable(&pdev->dev); |
590 | 590 | ||
591 | ret = snd_soc_register_component(&pdev->dev, &s3c_pcm_component, | 591 | ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component, |
592 | &s3c_pcm_dai[pdev->id], 1); | 592 | &s3c_pcm_dai[pdev->id], 1); |
593 | if (ret != 0) { | 593 | if (ret != 0) { |
594 | dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); | 594 | dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); |
@@ -598,23 +598,19 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) | |||
598 | ret = samsung_asoc_dma_platform_register(&pdev->dev); | 598 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
599 | if (ret) { | 599 | if (ret) { |
600 | dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); | 600 | dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); |
601 | goto err6; | 601 | goto err5; |
602 | } | 602 | } |
603 | 603 | ||
604 | return 0; | 604 | return 0; |
605 | 605 | ||
606 | err6: | ||
607 | snd_soc_unregister_component(&pdev->dev); | ||
608 | err5: | 606 | err5: |
609 | clk_disable_unprepare(pcm->pclk); | 607 | clk_disable_unprepare(pcm->pclk); |
610 | clk_put(pcm->pclk); | ||
611 | err4: | 608 | err4: |
612 | iounmap(pcm->regs); | 609 | iounmap(pcm->regs); |
613 | err3: | 610 | err3: |
614 | release_mem_region(mem_res->start, resource_size(mem_res)); | 611 | release_mem_region(mem_res->start, resource_size(mem_res)); |
615 | err2: | 612 | err2: |
616 | clk_disable_unprepare(pcm->cclk); | 613 | clk_disable_unprepare(pcm->cclk); |
617 | clk_put(pcm->cclk); | ||
618 | err1: | 614 | err1: |
619 | return ret; | 615 | return ret; |
620 | } | 616 | } |
@@ -624,9 +620,6 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
624 | struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; | 620 | struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; |
625 | struct resource *mem_res; | 621 | struct resource *mem_res; |
626 | 622 | ||
627 | samsung_asoc_dma_platform_unregister(&pdev->dev); | ||
628 | snd_soc_unregister_component(&pdev->dev); | ||
629 | |||
630 | pm_runtime_disable(&pdev->dev); | 623 | pm_runtime_disable(&pdev->dev); |
631 | 624 | ||
632 | iounmap(pcm->regs); | 625 | iounmap(pcm->regs); |
@@ -636,8 +629,6 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
636 | 629 | ||
637 | clk_disable_unprepare(pcm->cclk); | 630 | clk_disable_unprepare(pcm->cclk); |
638 | clk_disable_unprepare(pcm->pclk); | 631 | clk_disable_unprepare(pcm->pclk); |
639 | clk_put(pcm->pclk); | ||
640 | clk_put(pcm->cclk); | ||
641 | 632 | ||
642 | return 0; | 633 | return 0; |
643 | } | 634 | } |
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index 2982d9e7f268..5b3e504d3a32 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c | |||
@@ -221,11 +221,6 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, | |||
221 | static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) | 221 | static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) |
222 | { | 222 | { |
223 | struct snd_soc_codec *codec = rtd->codec; | 223 | struct snd_soc_codec *codec = rtd->codec; |
224 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
225 | |||
226 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
227 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | ||
228 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
229 | 224 | ||
230 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | 225 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, |
231 | &hp_jack); | 226 | &hp_jack); |
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 79e7efb9283c..77a2ae50dc94 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c | |||
@@ -745,7 +745,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id, | |||
745 | dai_drv->suspend = s3c2412_i2s_suspend; | 745 | dai_drv->suspend = s3c2412_i2s_suspend; |
746 | dai_drv->resume = s3c2412_i2s_resume; | 746 | dai_drv->resume = s3c2412_i2s_resume; |
747 | 747 | ||
748 | return snd_soc_register_component(dev, cmp_drv, dai_drv, 1); | 748 | return devm_snd_soc_register_component(dev, cmp_drv, dai_drv, 1); |
749 | } | 749 | } |
750 | EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component); | 750 | EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component); |
751 | 751 | ||
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index e9bb5d7a71ee..843f315dcb3a 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
@@ -179,27 +179,14 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) | |||
179 | } | 179 | } |
180 | 180 | ||
181 | ret = samsung_asoc_dma_platform_register(&pdev->dev); | 181 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
182 | if (ret) { | 182 | if (ret) |
183 | pr_err("failed to register the DMA: %d\n", ret); | 183 | pr_err("failed to register the DMA: %d\n", ret); |
184 | goto err; | ||
185 | } | ||
186 | 184 | ||
187 | return 0; | ||
188 | err: | ||
189 | snd_soc_unregister_component(&pdev->dev); | ||
190 | return ret; | 185 | return ret; |
191 | } | 186 | } |
192 | 187 | ||
193 | static int s3c2412_iis_dev_remove(struct platform_device *pdev) | ||
194 | { | ||
195 | samsung_asoc_dma_platform_unregister(&pdev->dev); | ||
196 | snd_soc_unregister_component(&pdev->dev); | ||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static struct platform_driver s3c2412_iis_driver = { | 188 | static struct platform_driver s3c2412_iis_driver = { |
201 | .probe = s3c2412_iis_dev_probe, | 189 | .probe = s3c2412_iis_dev_probe, |
202 | .remove = s3c2412_iis_dev_remove, | ||
203 | .driver = { | 190 | .driver = { |
204 | .name = "s3c2412-iis", | 191 | .name = "s3c2412-iis", |
205 | .owner = THIS_MODULE, | 192 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index d7b8457b5650..4a6d206db222 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
@@ -475,35 +475,22 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) | |||
475 | { | 475 | { |
476 | int ret = 0; | 476 | int ret = 0; |
477 | 477 | ||
478 | ret = snd_soc_register_component(&pdev->dev, &s3c24xx_i2s_component, | 478 | ret = devm_snd_soc_register_component(&pdev->dev, |
479 | &s3c24xx_i2s_dai, 1); | 479 | &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); |
480 | if (ret) { | 480 | if (ret) { |
481 | pr_err("failed to register the dai\n"); | 481 | pr_err("failed to register the dai\n"); |
482 | return ret; | 482 | return ret; |
483 | } | 483 | } |
484 | 484 | ||
485 | ret = samsung_asoc_dma_platform_register(&pdev->dev); | 485 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
486 | if (ret) { | 486 | if (ret) |
487 | pr_err("failed to register the dma: %d\n", ret); | 487 | pr_err("failed to register the dma: %d\n", ret); |
488 | goto err; | ||
489 | } | ||
490 | 488 | ||
491 | return 0; | ||
492 | err: | ||
493 | snd_soc_unregister_component(&pdev->dev); | ||
494 | return ret; | 489 | return ret; |
495 | } | 490 | } |
496 | 491 | ||
497 | static int s3c24xx_iis_dev_remove(struct platform_device *pdev) | ||
498 | { | ||
499 | samsung_asoc_dma_platform_unregister(&pdev->dev); | ||
500 | snd_soc_unregister_component(&pdev->dev); | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | static struct platform_driver s3c24xx_iis_driver = { | 492 | static struct platform_driver s3c24xx_iis_driver = { |
505 | .probe = s3c24xx_iis_dev_probe, | 493 | .probe = s3c24xx_iis_dev_probe, |
506 | .remove = s3c24xx_iis_dev_remove, | ||
507 | .driver = { | 494 | .driver = { |
508 | .name = "s3c24xx-iis", | 495 | .name = "s3c24xx-iis", |
509 | .owner = THIS_MODULE, | 496 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index d8a0543cae5e..2d30b7b6818a 100644 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c | |||
@@ -63,14 +63,6 @@ static const struct snd_soc_dapm_route base_map[] = { | |||
63 | */ | 63 | */ |
64 | static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) | 64 | static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) |
65 | { | 65 | { |
66 | struct snd_soc_codec *codec = rtd->codec; | ||
67 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
68 | |||
69 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
70 | snd_soc_dapm_enable_pin(dapm, "Line In"); | ||
71 | snd_soc_dapm_enable_pin(dapm, "Line Out"); | ||
72 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
73 | |||
74 | simtec_audio_init(rtd); | 66 | simtec_audio_init(rtd); |
75 | 67 | ||
76 | return 0; | 68 | return 0; |
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index 1ac0d7a63a3a..83f6c7d49cd6 100644 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c | |||
@@ -52,14 +52,6 @@ static const struct snd_soc_dapm_route base_map[] = { | |||
52 | */ | 52 | */ |
53 | static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | 53 | static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) |
54 | { | 54 | { |
55 | struct snd_soc_codec *codec = rtd->codec; | ||
56 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
57 | |||
58 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
59 | snd_soc_dapm_enable_pin(dapm, "Line In"); | ||
60 | snd_soc_dapm_enable_pin(dapm, "Line Out"); | ||
61 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
62 | |||
63 | simtec_audio_init(rtd); | 55 | simtec_audio_init(rtd); |
64 | 56 | ||
65 | return 0; | 57 | return 0; |
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index c3b2adafb7b5..df55db5d3554 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c | |||
@@ -162,8 +162,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) | |||
162 | snd_soc_dapm_nc_pin(dapm, "ROUT1"); | 162 | snd_soc_dapm_nc_pin(dapm, "ROUT1"); |
163 | 163 | ||
164 | /* set endpoints to default off mode */ | 164 | /* set endpoints to default off mode */ |
165 | snd_soc_dapm_enable_pin(dapm, "Internal Speaker"); | ||
166 | snd_soc_dapm_enable_pin(dapm, "Internal Mic"); | ||
167 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 165 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
168 | 166 | ||
169 | /* Headphone jack detection */ | 167 | /* Headphone jack detection */ |
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 23a9204b106d..e119aaa91c28 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c | |||
@@ -164,19 +164,11 @@ static int snd_smdk_probe(struct platform_device *pdev) | |||
164 | xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE; | 164 | xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE; |
165 | 165 | ||
166 | smdk_pcm.dev = &pdev->dev; | 166 | smdk_pcm.dev = &pdev->dev; |
167 | ret = snd_soc_register_card(&smdk_pcm); | 167 | ret = devm_snd_soc_register_card(&pdev->dev, &smdk_pcm); |
168 | if (ret) { | 168 | if (ret) |
169 | dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); | 169 | dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); |
170 | return ret; | ||
171 | } | ||
172 | 170 | ||
173 | return 0; | 171 | return ret; |
174 | } | ||
175 | |||
176 | static int snd_smdk_remove(struct platform_device *pdev) | ||
177 | { | ||
178 | snd_soc_unregister_card(&smdk_pcm); | ||
179 | return 0; | ||
180 | } | 172 | } |
181 | 173 | ||
182 | static struct platform_driver snd_smdk_driver = { | 174 | static struct platform_driver snd_smdk_driver = { |
@@ -185,7 +177,6 @@ static struct platform_driver snd_smdk_driver = { | |||
185 | .name = "samsung-smdk-pcm", | 177 | .name = "samsung-smdk-pcm", |
186 | }, | 178 | }, |
187 | .probe = snd_smdk_probe, | 179 | .probe = snd_smdk_probe, |
188 | .remove = snd_smdk_remove, | ||
189 | }; | 180 | }; |
190 | 181 | ||
191 | module_platform_driver(snd_smdk_driver); | 182 | module_platform_driver(snd_smdk_driver); |
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index 682eb4f7ba0c..fc25cc00f0f2 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c | |||
@@ -89,18 +89,6 @@ static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd) | |||
89 | struct snd_soc_codec *codec = rtd->codec; | 89 | struct snd_soc_codec *codec = rtd->codec; |
90 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 90 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
91 | 91 | ||
92 | /* HeadPhone */ | ||
93 | snd_soc_dapm_enable_pin(dapm, "HPOUT1R"); | ||
94 | snd_soc_dapm_enable_pin(dapm, "HPOUT1L"); | ||
95 | |||
96 | /* MicIn */ | ||
97 | snd_soc_dapm_enable_pin(dapm, "IN1LN"); | ||
98 | snd_soc_dapm_enable_pin(dapm, "IN1RN"); | ||
99 | |||
100 | /* LineIn */ | ||
101 | snd_soc_dapm_enable_pin(dapm, "IN2LN"); | ||
102 | snd_soc_dapm_enable_pin(dapm, "IN2RN"); | ||
103 | |||
104 | /* Other pins NC */ | 92 | /* Other pins NC */ |
105 | snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); | 93 | snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); |
106 | snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); | 94 | snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); |
diff --git a/sound/soc/samsung/smdk_wm8994pcm.c b/sound/soc/samsung/smdk_wm8994pcm.c index 0c84ca099612..b6c09979be1f 100644 --- a/sound/soc/samsung/smdk_wm8994pcm.c +++ b/sound/soc/samsung/smdk_wm8994pcm.c | |||
@@ -134,19 +134,11 @@ static int snd_smdk_probe(struct platform_device *pdev) | |||
134 | int ret = 0; | 134 | int ret = 0; |
135 | 135 | ||
136 | smdk_pcm.dev = &pdev->dev; | 136 | smdk_pcm.dev = &pdev->dev; |
137 | ret = snd_soc_register_card(&smdk_pcm); | 137 | ret = devm_snd_soc_register_card(&pdev->dev, &smdk_pcm); |
138 | if (ret) { | 138 | if (ret) |
139 | dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); | 139 | dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret); |
140 | return ret; | ||
141 | } | ||
142 | 140 | ||
143 | return 0; | 141 | return ret; |
144 | } | ||
145 | |||
146 | static int snd_smdk_remove(struct platform_device *pdev) | ||
147 | { | ||
148 | snd_soc_unregister_card(&smdk_pcm); | ||
149 | return 0; | ||
150 | } | 142 | } |
151 | 143 | ||
152 | static struct platform_driver snd_smdk_driver = { | 144 | static struct platform_driver snd_smdk_driver = { |
@@ -155,7 +147,6 @@ static struct platform_driver snd_smdk_driver = { | |||
155 | .name = "samsung-smdk-pcm", | 147 | .name = "samsung-smdk-pcm", |
156 | }, | 148 | }, |
157 | .probe = snd_smdk_probe, | 149 | .probe = snd_smdk_probe, |
158 | .remove = snd_smdk_remove, | ||
159 | }; | 150 | }; |
160 | 151 | ||
161 | module_platform_driver(snd_smdk_driver); | 152 | module_platform_driver(snd_smdk_driver); |
diff --git a/sound/soc/samsung/snow.c b/sound/soc/samsung/snow.c new file mode 100644 index 000000000000..014c177840ba --- /dev/null +++ b/sound/soc/samsung/snow.c | |||
@@ -0,0 +1,123 @@ | |||
1 | /* | ||
2 | * ASoC machine driver for Snow boards | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * version 2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, but | ||
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | |||
19 | #include <sound/soc.h> | ||
20 | |||
21 | #include "i2s.h" | ||
22 | |||
23 | #define FIN_PLL_RATE 24000000 | ||
24 | |||
25 | static struct snd_soc_dai_link snow_dai[] = { | ||
26 | { | ||
27 | .name = "Primary", | ||
28 | .stream_name = "Primary", | ||
29 | .codec_dai_name = "HiFi", | ||
30 | .dai_fmt = SND_SOC_DAIFMT_I2S | | ||
31 | SND_SOC_DAIFMT_NB_NF | | ||
32 | SND_SOC_DAIFMT_CBS_CFS, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static int snow_late_probe(struct snd_soc_card *card) | ||
37 | { | ||
38 | struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai; | ||
39 | struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai; | ||
40 | int ret; | ||
41 | |||
42 | /* Set the MCLK rate for the codec */ | ||
43 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | ||
44 | FIN_PLL_RATE, SND_SOC_CLOCK_IN); | ||
45 | if (ret < 0) | ||
46 | return ret; | ||
47 | |||
48 | /* Select I2S Bus clock to set RCLK and BCLK */ | ||
49 | ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, | ||
50 | 0, SND_SOC_CLOCK_IN); | ||
51 | if (ret < 0) | ||
52 | return ret; | ||
53 | |||
54 | return 0; | ||
55 | } | ||
56 | |||
57 | static struct snd_soc_card snow_snd = { | ||
58 | .name = "Snow-I2S", | ||
59 | .dai_link = snow_dai, | ||
60 | .num_links = ARRAY_SIZE(snow_dai), | ||
61 | |||
62 | .late_probe = snow_late_probe, | ||
63 | }; | ||
64 | |||
65 | static int snow_probe(struct platform_device *pdev) | ||
66 | { | ||
67 | struct snd_soc_card *card = &snow_snd; | ||
68 | struct device_node *i2s_node, *codec_node; | ||
69 | int i, ret; | ||
70 | |||
71 | i2s_node = of_parse_phandle(pdev->dev.of_node, | ||
72 | "samsung,i2s-controller", 0); | ||
73 | if (!i2s_node) { | ||
74 | dev_err(&pdev->dev, | ||
75 | "Property 'i2s-controller' missing or invalid\n"); | ||
76 | return -EINVAL; | ||
77 | } | ||
78 | |||
79 | codec_node = of_parse_phandle(pdev->dev.of_node, | ||
80 | "samsung,audio-codec", 0); | ||
81 | if (!codec_node) { | ||
82 | dev_err(&pdev->dev, | ||
83 | "Property 'audio-codec' missing or invalid\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | |||
87 | for (i = 0; i < ARRAY_SIZE(snow_dai); i++) { | ||
88 | snow_dai[i].codec_of_node = codec_node; | ||
89 | snow_dai[i].cpu_of_node = i2s_node; | ||
90 | snow_dai[i].platform_of_node = i2s_node; | ||
91 | } | ||
92 | |||
93 | card->dev = &pdev->dev; | ||
94 | |||
95 | ret = devm_snd_soc_register_card(&pdev->dev, card); | ||
96 | if (ret) { | ||
97 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | return ret; | ||
102 | } | ||
103 | |||
104 | static const struct of_device_id snow_of_match[] = { | ||
105 | { .compatible = "google,snow-audio-max98090", }, | ||
106 | { .compatible = "google,snow-audio-max98095", }, | ||
107 | {}, | ||
108 | }; | ||
109 | |||
110 | static struct platform_driver snow_driver = { | ||
111 | .driver = { | ||
112 | .name = "snow-audio", | ||
113 | .owner = THIS_MODULE, | ||
114 | .pm = &snd_soc_pm_ops, | ||
115 | .of_match_table = snow_of_match, | ||
116 | }, | ||
117 | .probe = snow_probe, | ||
118 | }; | ||
119 | |||
120 | module_platform_driver(snow_driver); | ||
121 | |||
122 | MODULE_DESCRIPTION("ALSA SoC Audio machine driver for Snow"); | ||
123 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index cfe63b7bcc9f..e93a93e296f4 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
@@ -427,8 +427,8 @@ static int spdif_probe(struct platform_device *pdev) | |||
427 | 427 | ||
428 | dev_set_drvdata(&pdev->dev, spdif); | 428 | dev_set_drvdata(&pdev->dev, spdif); |
429 | 429 | ||
430 | ret = snd_soc_register_component(&pdev->dev, &samsung_spdif_component, | 430 | ret = devm_snd_soc_register_component(&pdev->dev, |
431 | &samsung_spdif_dai, 1); | 431 | &samsung_spdif_component, &samsung_spdif_dai, 1); |
432 | if (ret != 0) { | 432 | if (ret != 0) { |
433 | dev_err(&pdev->dev, "fail to register dai\n"); | 433 | dev_err(&pdev->dev, "fail to register dai\n"); |
434 | goto err4; | 434 | goto err4; |
@@ -444,12 +444,10 @@ static int spdif_probe(struct platform_device *pdev) | |||
444 | ret = samsung_asoc_dma_platform_register(&pdev->dev); | 444 | ret = samsung_asoc_dma_platform_register(&pdev->dev); |
445 | if (ret) { | 445 | if (ret) { |
446 | dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); | 446 | dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); |
447 | goto err5; | 447 | goto err4; |
448 | } | 448 | } |
449 | 449 | ||
450 | return 0; | 450 | return 0; |
451 | err5: | ||
452 | snd_soc_unregister_component(&pdev->dev); | ||
453 | err4: | 451 | err4: |
454 | iounmap(spdif->regs); | 452 | iounmap(spdif->regs); |
455 | err3: | 453 | err3: |
@@ -467,9 +465,6 @@ static int spdif_remove(struct platform_device *pdev) | |||
467 | struct samsung_spdif_info *spdif = &spdif_info; | 465 | struct samsung_spdif_info *spdif = &spdif_info; |
468 | struct resource *mem_res; | 466 | struct resource *mem_res; |
469 | 467 | ||
470 | samsung_asoc_dma_platform_unregister(&pdev->dev); | ||
471 | snd_soc_unregister_component(&pdev->dev); | ||
472 | |||
473 | iounmap(spdif->regs); | 468 | iounmap(spdif->regs); |
474 | 469 | ||
475 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 470 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 57df90d6b7c1..9902efcb8ea1 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c | |||
@@ -327,23 +327,12 @@ static int speyside_probe(struct platform_device *pdev) | |||
327 | 327 | ||
328 | card->dev = &pdev->dev; | 328 | card->dev = &pdev->dev; |
329 | 329 | ||
330 | ret = snd_soc_register_card(card); | 330 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
331 | if (ret) { | 331 | if (ret) |
332 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 332 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
333 | ret); | 333 | ret); |
334 | return ret; | ||
335 | } | ||
336 | |||
337 | return 0; | ||
338 | } | ||
339 | |||
340 | static int speyside_remove(struct platform_device *pdev) | ||
341 | { | ||
342 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
343 | 334 | ||
344 | snd_soc_unregister_card(card); | 335 | return ret; |
345 | |||
346 | return 0; | ||
347 | } | 336 | } |
348 | 337 | ||
349 | static struct platform_driver speyside_driver = { | 338 | static struct platform_driver speyside_driver = { |
@@ -353,7 +342,6 @@ static struct platform_driver speyside_driver = { | |||
353 | .pm = &snd_soc_pm_ops, | 342 | .pm = &snd_soc_pm_ops, |
354 | }, | 343 | }, |
355 | .probe = speyside_probe, | 344 | .probe = speyside_probe, |
356 | .remove = speyside_remove, | ||
357 | }; | 345 | }; |
358 | 346 | ||
359 | module_platform_driver(speyside_driver); | 347 | module_platform_driver(speyside_driver); |
diff --git a/sound/soc/samsung/tobermory.c b/sound/soc/samsung/tobermory.c index 1807b75ccc12..6a2b9f14d624 100644 --- a/sound/soc/samsung/tobermory.c +++ b/sound/soc/samsung/tobermory.c | |||
@@ -223,23 +223,12 @@ static int tobermory_probe(struct platform_device *pdev) | |||
223 | 223 | ||
224 | card->dev = &pdev->dev; | 224 | card->dev = &pdev->dev; |
225 | 225 | ||
226 | ret = snd_soc_register_card(card); | 226 | ret = devm_snd_soc_register_card(&pdev->dev, card); |
227 | if (ret) { | 227 | if (ret) |
228 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | 228 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
229 | ret); | 229 | ret); |
230 | return ret; | ||
231 | } | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int tobermory_remove(struct platform_device *pdev) | ||
237 | { | ||
238 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
239 | 230 | ||
240 | snd_soc_unregister_card(card); | 231 | return ret; |
241 | |||
242 | return 0; | ||
243 | } | 232 | } |
244 | 233 | ||
245 | static struct platform_driver tobermory_driver = { | 234 | static struct platform_driver tobermory_driver = { |
@@ -249,7 +238,6 @@ static struct platform_driver tobermory_driver = { | |||
249 | .pm = &snd_soc_pm_ops, | 238 | .pm = &snd_soc_pm_ops, |
250 | }, | 239 | }, |
251 | .probe = tobermory_probe, | 240 | .probe = tobermory_probe, |
252 | .remove = tobermory_remove, | ||
253 | }; | 241 | }; |
254 | 242 | ||
255 | module_platform_driver(tobermory_driver); | 243 | module_platform_driver(tobermory_driver); |
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index ff60e11ecb56..b43fdf0d08af 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig | |||
@@ -56,7 +56,7 @@ config SND_SH7760_AC97 | |||
56 | 56 | ||
57 | config SND_SIU_MIGOR | 57 | config SND_SIU_MIGOR |
58 | tristate "SIU sound support on Migo-R" | 58 | tristate "SIU sound support on Migo-R" |
59 | depends on SH_MIGOR | 59 | depends on SH_MIGOR && I2C |
60 | select SND_SOC_SH4_SIU | 60 | select SND_SOC_SH4_SIU |
61 | select SND_SOC_WM8978 | 61 | select SND_SOC_WM8978 |
62 | help | 62 | help |
diff --git a/sound/soc/sh/rcar/Makefile b/sound/soc/sh/rcar/Makefile index 7d0051ced838..9ac536429800 100644 --- a/sound/soc/sh/rcar/Makefile +++ b/sound/soc/sh/rcar/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o | 1 | snd-soc-rcar-objs := core.o gen.o src.o adg.o ssi.o dvc.o |
2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file | 2 | obj-$(CONFIG_SND_SOC_RCAR) += snd-soc-rcar.o \ No newline at end of file |
diff --git a/sound/soc/sh/rcar/adg.c b/sound/soc/sh/rcar/adg.c index 69c44269ebdb..fc41a0e8b09f 100644 --- a/sound/soc/sh/rcar/adg.c +++ b/sound/soc/sh/rcar/adg.c | |||
@@ -57,6 +57,24 @@ static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io) | |||
57 | return (0x6 + ws) << 8; | 57 | return (0x6 + ws) << 8; |
58 | } | 58 | } |
59 | 59 | ||
60 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | ||
61 | struct rsnd_mod *mod, | ||
62 | struct rsnd_dai_stream *io) | ||
63 | { | ||
64 | int id = rsnd_mod_id(mod); | ||
65 | int shift = (id % 2) ? 16 : 0; | ||
66 | u32 mask, val; | ||
67 | |||
68 | val = rsnd_adg_ssi_ws_timing_gen2(io); | ||
69 | |||
70 | val = val << shift; | ||
71 | mask = 0xffff << shift; | ||
72 | |||
73 | rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val); | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
60 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, | 78 | static int rsnd_adg_set_src_timsel_gen2(struct rsnd_dai *rdai, |
61 | struct rsnd_mod *mod, | 79 | struct rsnd_mod *mod, |
62 | struct rsnd_dai_stream *io, | 80 | struct rsnd_dai_stream *io, |
@@ -397,9 +415,8 @@ int rsnd_adg_probe(struct platform_device *pdev, | |||
397 | { | 415 | { |
398 | struct rsnd_adg *adg; | 416 | struct rsnd_adg *adg; |
399 | struct device *dev = rsnd_priv_to_dev(priv); | 417 | struct device *dev = rsnd_priv_to_dev(priv); |
400 | struct clk *clk, *clk_orig; | 418 | struct clk *clk; |
401 | int i; | 419 | int i; |
402 | bool use_old_style = false; | ||
403 | 420 | ||
404 | adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); | 421 | adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); |
405 | if (!adg) { | 422 | if (!adg) { |
@@ -407,45 +424,13 @@ int rsnd_adg_probe(struct platform_device *pdev, | |||
407 | return -ENOMEM; | 424 | return -ENOMEM; |
408 | } | 425 | } |
409 | 426 | ||
410 | clk_orig = devm_clk_get(dev, NULL); | ||
411 | adg->clk[CLKA] = devm_clk_get(dev, "clk_a"); | 427 | adg->clk[CLKA] = devm_clk_get(dev, "clk_a"); |
412 | adg->clk[CLKB] = devm_clk_get(dev, "clk_b"); | 428 | adg->clk[CLKB] = devm_clk_get(dev, "clk_b"); |
413 | adg->clk[CLKC] = devm_clk_get(dev, "clk_c"); | 429 | adg->clk[CLKC] = devm_clk_get(dev, "clk_c"); |
414 | adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); | 430 | adg->clk[CLKI] = devm_clk_get(dev, "clk_i"); |
415 | 431 | ||
416 | /* | 432 | for_each_rsnd_clk(clk, adg, i) |
417 | * It request device dependent audio clock. | 433 | dev_dbg(dev, "clk %d : %p\n", i, clk); |
418 | * But above all clks will indicate rsnd module clock | ||
419 | * if platform doesn't it | ||
420 | */ | ||
421 | for_each_rsnd_clk(clk, adg, i) { | ||
422 | if (clk_orig == clk) { | ||
423 | dev_warn(dev, | ||
424 | "doesn't have device dependent clock, use independent clock\n"); | ||
425 | use_old_style = true; | ||
426 | break; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | /* | ||
431 | * note: | ||
432 | * these exist in order to keep compatible with | ||
433 | * platform which has device independent audio clock, | ||
434 | * but will be removed soon | ||
435 | */ | ||
436 | if (use_old_style) { | ||
437 | adg->clk[CLKA] = devm_clk_get(NULL, "audio_clk_a"); | ||
438 | adg->clk[CLKB] = devm_clk_get(NULL, "audio_clk_b"); | ||
439 | adg->clk[CLKC] = devm_clk_get(NULL, "audio_clk_c"); | ||
440 | adg->clk[CLKI] = devm_clk_get(NULL, "audio_clk_internal"); | ||
441 | } | ||
442 | |||
443 | for_each_rsnd_clk(clk, adg, i) { | ||
444 | if (IS_ERR(clk)) { | ||
445 | dev_err(dev, "Audio clock failed\n"); | ||
446 | return -EIO; | ||
447 | } | ||
448 | } | ||
449 | 434 | ||
450 | rsnd_adg_ssi_clk_init(priv, adg); | 435 | rsnd_adg_ssi_clk_init(priv, adg); |
451 | 436 | ||
diff --git a/sound/soc/sh/rcar/core.c b/sound/soc/sh/rcar/core.c index 89424470a1f3..964463dada87 100644 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c | |||
@@ -309,23 +309,49 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
309 | } | 309 | } |
310 | 310 | ||
311 | /* | 311 | /* |
312 | * settting function | ||
313 | */ | ||
314 | u32 rsnd_get_adinr(struct rsnd_mod *mod) | ||
315 | { | ||
316 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
317 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
318 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | ||
319 | struct device *dev = rsnd_priv_to_dev(priv); | ||
320 | u32 adinr = runtime->channels; | ||
321 | |||
322 | switch (runtime->sample_bits) { | ||
323 | case 16: | ||
324 | adinr |= (8 << 16); | ||
325 | break; | ||
326 | case 32: | ||
327 | adinr |= (0 << 16); | ||
328 | break; | ||
329 | default: | ||
330 | dev_warn(dev, "not supported sample bits\n"); | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | return adinr; | ||
335 | } | ||
336 | |||
337 | /* | ||
312 | * rsnd_dai functions | 338 | * rsnd_dai functions |
313 | */ | 339 | */ |
314 | #define __rsnd_mod_call(mod, func, rdai, io) \ | 340 | #define __rsnd_mod_call(mod, func, rdai...) \ |
315 | ({ \ | 341 | ({ \ |
316 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ | 342 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ |
317 | struct device *dev = rsnd_priv_to_dev(priv); \ | 343 | struct device *dev = rsnd_priv_to_dev(priv); \ |
318 | dev_dbg(dev, "%s [%d] %s\n", \ | 344 | dev_dbg(dev, "%s [%d] %s\n", \ |
319 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ | 345 | rsnd_mod_name(mod), rsnd_mod_id(mod), #func); \ |
320 | (mod)->ops->func(mod, rdai, io); \ | 346 | (mod)->ops->func(mod, rdai); \ |
321 | }) | 347 | }) |
322 | 348 | ||
323 | #define rsnd_mod_call(mod, func, rdai, io) \ | 349 | #define rsnd_mod_call(mod, func, rdai...) \ |
324 | (!(mod) ? -ENODEV : \ | 350 | (!(mod) ? -ENODEV : \ |
325 | !((mod)->ops->func) ? 0 : \ | 351 | !((mod)->ops->func) ? 0 : \ |
326 | __rsnd_mod_call(mod, func, (rdai), (io))) | 352 | __rsnd_mod_call(mod, func, rdai)) |
327 | 353 | ||
328 | #define rsnd_dai_call(rdai, io, fn) \ | 354 | #define rsnd_dai_call(fn, io, rdai...) \ |
329 | ({ \ | 355 | ({ \ |
330 | struct rsnd_mod *mod; \ | 356 | struct rsnd_mod *mod; \ |
331 | int ret = 0, i; \ | 357 | int ret = 0, i; \ |
@@ -333,7 +359,7 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
333 | mod = (io)->mod[i]; \ | 359 | mod = (io)->mod[i]; \ |
334 | if (!mod) \ | 360 | if (!mod) \ |
335 | continue; \ | 361 | continue; \ |
336 | ret = rsnd_mod_call(mod, fn, (rdai), (io)); \ | 362 | ret = rsnd_mod_call(mod, fn, rdai); \ |
337 | if (ret < 0) \ | 363 | if (ret < 0) \ |
338 | break; \ | 364 | break; \ |
339 | } \ | 365 | } \ |
@@ -467,10 +493,7 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
467 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); | 493 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(dai); |
468 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); | 494 | struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); |
469 | struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); | 495 | struct rsnd_dai_stream *io = rsnd_rdai_to_io(rdai, substream); |
470 | struct rsnd_mod *mod = rsnd_ssi_mod_get_frm_dai(priv, | 496 | int ssi_id = rsnd_mod_id(rsnd_io_to_mod_ssi(io)); |
471 | rsnd_dai_id(priv, rdai), | ||
472 | rsnd_dai_is_play(rdai, io)); | ||
473 | int ssi_id = rsnd_mod_id(mod); | ||
474 | int ret; | 497 | int ret; |
475 | unsigned long flags; | 498 | unsigned long flags; |
476 | 499 | ||
@@ -486,20 +509,20 @@ static int rsnd_soc_dai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
486 | if (ret < 0) | 509 | if (ret < 0) |
487 | goto dai_trigger_end; | 510 | goto dai_trigger_end; |
488 | 511 | ||
489 | ret = rsnd_dai_call(rdai, io, init); | 512 | ret = rsnd_dai_call(init, io, rdai); |
490 | if (ret < 0) | 513 | if (ret < 0) |
491 | goto dai_trigger_end; | 514 | goto dai_trigger_end; |
492 | 515 | ||
493 | ret = rsnd_dai_call(rdai, io, start); | 516 | ret = rsnd_dai_call(start, io, rdai); |
494 | if (ret < 0) | 517 | if (ret < 0) |
495 | goto dai_trigger_end; | 518 | goto dai_trigger_end; |
496 | break; | 519 | break; |
497 | case SNDRV_PCM_TRIGGER_STOP: | 520 | case SNDRV_PCM_TRIGGER_STOP: |
498 | ret = rsnd_dai_call(rdai, io, stop); | 521 | ret = rsnd_dai_call(stop, io, rdai); |
499 | if (ret < 0) | 522 | if (ret < 0) |
500 | goto dai_trigger_end; | 523 | goto dai_trigger_end; |
501 | 524 | ||
502 | ret = rsnd_dai_call(rdai, io, quit); | 525 | ret = rsnd_dai_call(quit, io, rdai); |
503 | if (ret < 0) | 526 | if (ret < 0) |
504 | goto dai_trigger_end; | 527 | goto dai_trigger_end; |
505 | 528 | ||
@@ -578,15 +601,27 @@ static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { | |||
578 | .set_fmt = rsnd_soc_dai_set_fmt, | 601 | .set_fmt = rsnd_soc_dai_set_fmt, |
579 | }; | 602 | }; |
580 | 603 | ||
604 | #define rsnd_path_parse(priv, io, type) \ | ||
605 | ({ \ | ||
606 | struct rsnd_mod *mod; \ | ||
607 | int ret = 0; \ | ||
608 | int id = -1; \ | ||
609 | \ | ||
610 | if (rsnd_is_enable_path(io, type)) { \ | ||
611 | id = rsnd_info_id(priv, io, type); \ | ||
612 | if (id >= 0) { \ | ||
613 | mod = rsnd_##type##_mod_get(priv, id); \ | ||
614 | ret = rsnd_dai_connect(mod, io); \ | ||
615 | } \ | ||
616 | } \ | ||
617 | ret; \ | ||
618 | }) | ||
619 | |||
581 | static int rsnd_path_init(struct rsnd_priv *priv, | 620 | static int rsnd_path_init(struct rsnd_priv *priv, |
582 | struct rsnd_dai *rdai, | 621 | struct rsnd_dai *rdai, |
583 | struct rsnd_dai_stream *io) | 622 | struct rsnd_dai_stream *io) |
584 | { | 623 | { |
585 | struct rsnd_mod *mod; | ||
586 | struct rsnd_dai_platform_info *dai_info = rdai->info; | ||
587 | int ret; | 624 | int ret; |
588 | int ssi_id = -1; | ||
589 | int src_id = -1; | ||
590 | 625 | ||
591 | /* | 626 | /* |
592 | * Gen1 is created by SRU/SSI, and this SRU is base module of | 627 | * Gen1 is created by SRU/SSI, and this SRU is base module of |
@@ -598,38 +633,21 @@ static int rsnd_path_init(struct rsnd_priv *priv, | |||
598 | * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is | 633 | * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is |
599 | * using fixed path. | 634 | * using fixed path. |
600 | */ | 635 | */ |
601 | if (dai_info) { | ||
602 | if (rsnd_is_enable_path(io, ssi)) | ||
603 | ssi_id = rsnd_info_id(priv, io, ssi); | ||
604 | if (rsnd_is_enable_path(io, src)) | ||
605 | src_id = rsnd_info_id(priv, io, src); | ||
606 | } else { | ||
607 | /* get SSI's ID */ | ||
608 | mod = rsnd_ssi_mod_get_frm_dai(priv, | ||
609 | rsnd_dai_id(priv, rdai), | ||
610 | rsnd_dai_is_play(rdai, io)); | ||
611 | if (!mod) | ||
612 | return 0; | ||
613 | ssi_id = src_id = rsnd_mod_id(mod); | ||
614 | } | ||
615 | |||
616 | ret = 0; | ||
617 | 636 | ||
618 | /* SRC */ | 637 | /* SRC */ |
619 | if (src_id >= 0) { | 638 | ret = rsnd_path_parse(priv, io, src); |
620 | mod = rsnd_src_mod_get(priv, src_id); | 639 | if (ret < 0) |
621 | ret = rsnd_dai_connect(mod, io); | 640 | return ret; |
622 | if (ret < 0) | ||
623 | return ret; | ||
624 | } | ||
625 | 641 | ||
626 | /* SSI */ | 642 | /* SSI */ |
627 | if (ssi_id >= 0) { | 643 | ret = rsnd_path_parse(priv, io, ssi); |
628 | mod = rsnd_ssi_mod_get(priv, ssi_id); | 644 | if (ret < 0) |
629 | ret = rsnd_dai_connect(mod, io); | 645 | return ret; |
630 | if (ret < 0) | 646 | |
631 | return ret; | 647 | /* DVC */ |
632 | } | 648 | ret = rsnd_path_parse(priv, io, dvc); |
649 | if (ret < 0) | ||
650 | return ret; | ||
633 | 651 | ||
634 | return ret; | 652 | return ret; |
635 | } | 653 | } |
@@ -725,30 +743,15 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
725 | struct snd_soc_dai_driver *drv; | 743 | struct snd_soc_dai_driver *drv; |
726 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | 744 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); |
727 | struct rsnd_dai *rdai; | 745 | struct rsnd_dai *rdai; |
728 | struct rsnd_mod *pmod, *cmod; | 746 | struct rsnd_ssi_platform_info *pmod, *cmod; |
729 | struct device *dev = rsnd_priv_to_dev(priv); | 747 | struct device *dev = rsnd_priv_to_dev(priv); |
730 | int dai_nr; | 748 | int dai_nr; |
731 | int i; | 749 | int i; |
732 | 750 | ||
733 | rsnd_of_parse_dai(pdev, of_data, priv); | 751 | rsnd_of_parse_dai(pdev, of_data, priv); |
734 | 752 | ||
735 | /* | ||
736 | * dai_nr should be set via dai_info_nr, | ||
737 | * but allow it to keeping compatible | ||
738 | */ | ||
739 | dai_nr = info->dai_info_nr; | 753 | dai_nr = info->dai_info_nr; |
740 | if (!dai_nr) { | 754 | if (!dai_nr) { |
741 | /* get max dai nr */ | ||
742 | for (dai_nr = 0; dai_nr < 32; dai_nr++) { | ||
743 | pmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 1); | ||
744 | cmod = rsnd_ssi_mod_get_frm_dai(priv, dai_nr, 0); | ||
745 | |||
746 | if (!pmod && !cmod) | ||
747 | break; | ||
748 | } | ||
749 | } | ||
750 | |||
751 | if (!dai_nr) { | ||
752 | dev_err(dev, "no dai\n"); | 755 | dev_err(dev, "no dai\n"); |
753 | return -EIO; | 756 | return -EIO; |
754 | } | 757 | } |
@@ -765,11 +768,10 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
765 | priv->rdai = rdai; | 768 | priv->rdai = rdai; |
766 | 769 | ||
767 | for (i = 0; i < dai_nr; i++) { | 770 | for (i = 0; i < dai_nr; i++) { |
768 | if (info->dai_info) | 771 | rdai[i].info = &info->dai_info[i]; |
769 | rdai[i].info = &info->dai_info[i]; | ||
770 | 772 | ||
771 | pmod = rsnd_ssi_mod_get_frm_dai(priv, i, 1); | 773 | pmod = rdai[i].info->playback.ssi; |
772 | cmod = rsnd_ssi_mod_get_frm_dai(priv, i, 0); | 774 | cmod = rdai[i].info->capture.ssi; |
773 | 775 | ||
774 | /* | 776 | /* |
775 | * init rsnd_dai | 777 | * init rsnd_dai |
@@ -787,8 +789,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
787 | drv[i].playback.channels_min = 2; | 789 | drv[i].playback.channels_min = 2; |
788 | drv[i].playback.channels_max = 2; | 790 | drv[i].playback.channels_max = 2; |
789 | 791 | ||
790 | if (info->dai_info) | 792 | rdai[i].playback.info = &info->dai_info[i].playback; |
791 | rdai[i].playback.info = &info->dai_info[i].playback; | ||
792 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); | 793 | rsnd_path_init(priv, &rdai[i], &rdai[i].playback); |
793 | } | 794 | } |
794 | if (cmod) { | 795 | if (cmod) { |
@@ -797,8 +798,7 @@ static int rsnd_dai_probe(struct platform_device *pdev, | |||
797 | drv[i].capture.channels_min = 2; | 798 | drv[i].capture.channels_min = 2; |
798 | drv[i].capture.channels_max = 2; | 799 | drv[i].capture.channels_max = 2; |
799 | 800 | ||
800 | if (info->dai_info) | 801 | rdai[i].capture.info = &info->dai_info[i].capture; |
801 | rdai[i].capture.info = &info->dai_info[i].capture; | ||
802 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); | 802 | rsnd_path_init(priv, &rdai[i], &rdai[i].capture); |
803 | } | 803 | } |
804 | 804 | ||
@@ -873,6 +873,20 @@ static struct snd_pcm_ops rsnd_pcm_ops = { | |||
873 | 873 | ||
874 | static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) | 874 | static int rsnd_pcm_new(struct snd_soc_pcm_runtime *rtd) |
875 | { | 875 | { |
876 | struct rsnd_priv *priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
877 | struct rsnd_dai *rdai; | ||
878 | int i, ret; | ||
879 | |||
880 | for_each_rsnd_dai(rdai, priv, i) { | ||
881 | ret = rsnd_dai_call(pcm_new, &rdai->playback, rdai, rtd); | ||
882 | if (ret) | ||
883 | return ret; | ||
884 | |||
885 | ret = rsnd_dai_call(pcm_new, &rdai->capture, rdai, rtd); | ||
886 | if (ret) | ||
887 | return ret; | ||
888 | } | ||
889 | |||
876 | return snd_pcm_lib_preallocate_pages_for_all( | 890 | return snd_pcm_lib_preallocate_pages_for_all( |
877 | rtd->pcm, | 891 | rtd->pcm, |
878 | SNDRV_DMA_TYPE_DEV, | 892 | SNDRV_DMA_TYPE_DEV, |
@@ -912,6 +926,7 @@ static int rsnd_probe(struct platform_device *pdev) | |||
912 | rsnd_gen_probe, | 926 | rsnd_gen_probe, |
913 | rsnd_ssi_probe, | 927 | rsnd_ssi_probe, |
914 | rsnd_src_probe, | 928 | rsnd_src_probe, |
929 | rsnd_dvc_probe, | ||
915 | rsnd_adg_probe, | 930 | rsnd_adg_probe, |
916 | rsnd_dai_probe, | 931 | rsnd_dai_probe, |
917 | }; | 932 | }; |
@@ -955,11 +970,11 @@ static int rsnd_probe(struct platform_device *pdev) | |||
955 | } | 970 | } |
956 | 971 | ||
957 | for_each_rsnd_dai(rdai, priv, i) { | 972 | for_each_rsnd_dai(rdai, priv, i) { |
958 | ret = rsnd_dai_call(rdai, &rdai->playback, probe); | 973 | ret = rsnd_dai_call(probe, &rdai->playback, rdai); |
959 | if (ret) | 974 | if (ret) |
960 | return ret; | 975 | return ret; |
961 | 976 | ||
962 | ret = rsnd_dai_call(rdai, &rdai->capture, probe); | 977 | ret = rsnd_dai_call(probe, &rdai->capture, rdai); |
963 | if (ret) | 978 | if (ret) |
964 | return ret; | 979 | return ret; |
965 | } | 980 | } |
@@ -1002,11 +1017,11 @@ static int rsnd_remove(struct platform_device *pdev) | |||
1002 | pm_runtime_disable(&pdev->dev); | 1017 | pm_runtime_disable(&pdev->dev); |
1003 | 1018 | ||
1004 | for_each_rsnd_dai(rdai, priv, i) { | 1019 | for_each_rsnd_dai(rdai, priv, i) { |
1005 | ret = rsnd_dai_call(rdai, &rdai->playback, remove); | 1020 | ret = rsnd_dai_call(remove, &rdai->playback, rdai); |
1006 | if (ret) | 1021 | if (ret) |
1007 | return ret; | 1022 | return ret; |
1008 | 1023 | ||
1009 | ret = rsnd_dai_call(rdai, &rdai->capture, remove); | 1024 | ret = rsnd_dai_call(remove, &rdai->capture, rdai); |
1010 | if (ret) | 1025 | if (ret) |
1011 | return ret; | 1026 | return ret; |
1012 | } | 1027 | } |
diff --git a/sound/soc/sh/rcar/dvc.c b/sound/soc/sh/rcar/dvc.c new file mode 100644 index 000000000000..74769b1be005 --- /dev/null +++ b/sound/soc/sh/rcar/dvc.c | |||
@@ -0,0 +1,273 @@ | |||
1 | /* | ||
2 | * Renesas R-Car DVC support | ||
3 | * | ||
4 | * Copyright (C) 2014 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include "rsnd.h" | ||
12 | |||
13 | #define RSND_DVC_NAME_SIZE 16 | ||
14 | #define RSND_DVC_VOLUME_MAX 100 | ||
15 | #define RSND_DVC_VOLUME_NUM 2 | ||
16 | struct rsnd_dvc { | ||
17 | struct rsnd_dvc_platform_info *info; /* rcar_snd.h */ | ||
18 | struct rsnd_mod mod; | ||
19 | struct clk *clk; | ||
20 | long volume[RSND_DVC_VOLUME_NUM]; | ||
21 | }; | ||
22 | |||
23 | #define rsnd_mod_to_dvc(_mod) \ | ||
24 | container_of((_mod), struct rsnd_dvc, mod) | ||
25 | |||
26 | #define for_each_rsnd_dvc(pos, priv, i) \ | ||
27 | for ((i) = 0; \ | ||
28 | ((i) < rsnd_dvc_nr(priv)) && \ | ||
29 | ((pos) = (struct rsnd_dvc *)(priv)->dvc + i); \ | ||
30 | i++) | ||
31 | |||
32 | static void rsnd_dvc_volume_update(struct rsnd_mod *mod) | ||
33 | { | ||
34 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
35 | u32 max = (0x00800000 - 1); | ||
36 | u32 vol[RSND_DVC_VOLUME_NUM]; | ||
37 | int i; | ||
38 | |||
39 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) | ||
40 | vol[i] = max / RSND_DVC_VOLUME_MAX * dvc->volume[i]; | ||
41 | |||
42 | rsnd_mod_write(mod, DVC_VOL0R, vol[0]); | ||
43 | rsnd_mod_write(mod, DVC_VOL1R, vol[1]); | ||
44 | } | ||
45 | |||
46 | static int rsnd_dvc_init(struct rsnd_mod *dvc_mod, | ||
47 | struct rsnd_dai *rdai) | ||
48 | { | ||
49 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(dvc_mod); | ||
50 | struct rsnd_dai_stream *io = rsnd_mod_to_io(dvc_mod); | ||
51 | struct rsnd_priv *priv = rsnd_mod_to_priv(dvc_mod); | ||
52 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | ||
53 | struct device *dev = rsnd_priv_to_dev(priv); | ||
54 | int dvc_id = rsnd_mod_id(dvc_mod); | ||
55 | int src_id = rsnd_mod_id(src_mod); | ||
56 | u32 route[] = { | ||
57 | [0] = 0x30000, | ||
58 | [1] = 0x30001, | ||
59 | [2] = 0x40000, | ||
60 | [3] = 0x10000, | ||
61 | [4] = 0x20000, | ||
62 | [5] = 0x40100 | ||
63 | }; | ||
64 | |||
65 | if (src_id >= ARRAY_SIZE(route)) { | ||
66 | dev_err(dev, "DVC%d isn't connected to SRC%d\n", dvc_id, src_id); | ||
67 | return -EINVAL; | ||
68 | } | ||
69 | |||
70 | clk_prepare_enable(dvc->clk); | ||
71 | |||
72 | /* | ||
73 | * fixme | ||
74 | * it doesn't support CTU/MIX | ||
75 | */ | ||
76 | rsnd_mod_write(dvc_mod, CMD_ROUTE_SLCT, route[src_id]); | ||
77 | |||
78 | rsnd_mod_write(dvc_mod, DVC_SWRSR, 0); | ||
79 | rsnd_mod_write(dvc_mod, DVC_SWRSR, 1); | ||
80 | |||
81 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 1); | ||
82 | |||
83 | rsnd_mod_write(dvc_mod, DVC_ADINR, rsnd_get_adinr(dvc_mod)); | ||
84 | |||
85 | /* enable Volume */ | ||
86 | rsnd_mod_write(dvc_mod, DVC_DVUCR, 0x100); | ||
87 | |||
88 | /* ch0/ch1 Volume */ | ||
89 | rsnd_dvc_volume_update(dvc_mod); | ||
90 | |||
91 | rsnd_mod_write(dvc_mod, DVC_DVUIR, 0); | ||
92 | |||
93 | rsnd_mod_write(dvc_mod, DVC_DVUER, 1); | ||
94 | |||
95 | rsnd_adg_set_cmd_timsel_gen2(rdai, dvc_mod, io); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | static int rsnd_dvc_quit(struct rsnd_mod *mod, | ||
101 | struct rsnd_dai *rdai) | ||
102 | { | ||
103 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
104 | |||
105 | clk_disable_unprepare(dvc->clk); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int rsnd_dvc_start(struct rsnd_mod *mod, | ||
111 | struct rsnd_dai *rdai) | ||
112 | { | ||
113 | rsnd_mod_write(mod, CMD_CTRL, 0x10); | ||
114 | |||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | static int rsnd_dvc_stop(struct rsnd_mod *mod, | ||
119 | struct rsnd_dai *rdai) | ||
120 | { | ||
121 | rsnd_mod_write(mod, CMD_CTRL, 0); | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int rsnd_dvc_volume_info(struct snd_kcontrol *kctrl, | ||
127 | struct snd_ctl_elem_info *uinfo) | ||
128 | { | ||
129 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
130 | uinfo->count = RSND_DVC_VOLUME_NUM; | ||
131 | uinfo->value.integer.min = 0; | ||
132 | uinfo->value.integer.max = RSND_DVC_VOLUME_MAX; | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int rsnd_dvc_volume_get(struct snd_kcontrol *kctrl, | ||
138 | struct snd_ctl_elem_value *ucontrol) | ||
139 | { | ||
140 | struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); | ||
141 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
142 | int i; | ||
143 | |||
144 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) | ||
145 | ucontrol->value.integer.value[i] = dvc->volume[i]; | ||
146 | |||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int rsnd_dvc_volume_put(struct snd_kcontrol *kctrl, | ||
151 | struct snd_ctl_elem_value *ucontrol) | ||
152 | { | ||
153 | struct rsnd_mod *mod = snd_kcontrol_chip(kctrl); | ||
154 | struct rsnd_dvc *dvc = rsnd_mod_to_dvc(mod); | ||
155 | int i, change = 0; | ||
156 | |||
157 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) { | ||
158 | if (ucontrol->value.integer.value[i] < 0 || | ||
159 | ucontrol->value.integer.value[i] > RSND_DVC_VOLUME_MAX) | ||
160 | return -EINVAL; | ||
161 | |||
162 | change |= (ucontrol->value.integer.value[i] != dvc->volume[i]); | ||
163 | } | ||
164 | |||
165 | if (change) { | ||
166 | for (i = 0; i < RSND_DVC_VOLUME_NUM; i++) | ||
167 | dvc->volume[i] = ucontrol->value.integer.value[i]; | ||
168 | |||
169 | rsnd_dvc_volume_update(mod); | ||
170 | } | ||
171 | |||
172 | return change; | ||
173 | } | ||
174 | |||
175 | static int rsnd_dvc_pcm_new(struct rsnd_mod *mod, | ||
176 | struct rsnd_dai *rdai, | ||
177 | struct snd_soc_pcm_runtime *rtd) | ||
178 | { | ||
179 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
180 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | ||
181 | struct device *dev = rsnd_priv_to_dev(priv); | ||
182 | struct snd_card *card = rtd->card->snd_card; | ||
183 | struct snd_kcontrol *kctrl; | ||
184 | static struct snd_kcontrol_new knew = { | ||
185 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
186 | .name = "Playback Volume", | ||
187 | .info = rsnd_dvc_volume_info, | ||
188 | .get = rsnd_dvc_volume_get, | ||
189 | .put = rsnd_dvc_volume_put, | ||
190 | }; | ||
191 | int ret; | ||
192 | |||
193 | if (!rsnd_dai_is_play(rdai, io)) { | ||
194 | dev_err(dev, "DVC%d is connected to Capture DAI\n", | ||
195 | rsnd_mod_id(mod)); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
199 | kctrl = snd_ctl_new1(&knew, mod); | ||
200 | if (!kctrl) | ||
201 | return -ENOMEM; | ||
202 | |||
203 | ret = snd_ctl_add(card, kctrl); | ||
204 | if (ret < 0) | ||
205 | return ret; | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static struct rsnd_mod_ops rsnd_dvc_ops = { | ||
211 | .name = "dvc (gen2)", | ||
212 | .init = rsnd_dvc_init, | ||
213 | .quit = rsnd_dvc_quit, | ||
214 | .start = rsnd_dvc_start, | ||
215 | .stop = rsnd_dvc_stop, | ||
216 | .pcm_new = rsnd_dvc_pcm_new, | ||
217 | }; | ||
218 | |||
219 | struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id) | ||
220 | { | ||
221 | if (WARN_ON(id < 0 || id >= rsnd_dvc_nr(priv))) | ||
222 | id = 0; | ||
223 | |||
224 | return &((struct rsnd_dvc *)(priv->dvc) + id)->mod; | ||
225 | } | ||
226 | |||
227 | int rsnd_dvc_probe(struct platform_device *pdev, | ||
228 | const struct rsnd_of_data *of_data, | ||
229 | struct rsnd_priv *priv) | ||
230 | { | ||
231 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
232 | struct device *dev = rsnd_priv_to_dev(priv); | ||
233 | struct rsnd_dvc *dvc; | ||
234 | struct clk *clk; | ||
235 | char name[RSND_DVC_NAME_SIZE]; | ||
236 | int i, nr; | ||
237 | |||
238 | nr = info->dvc_info_nr; | ||
239 | if (!nr) | ||
240 | return 0; | ||
241 | |||
242 | /* This driver doesn't support Gen1 at this point */ | ||
243 | if (rsnd_is_gen1(priv)) { | ||
244 | dev_warn(dev, "CMD is not supported on Gen1\n"); | ||
245 | return -EINVAL; | ||
246 | } | ||
247 | |||
248 | dvc = devm_kzalloc(dev, sizeof(*dvc) * nr, GFP_KERNEL); | ||
249 | if (!dvc) { | ||
250 | dev_err(dev, "CMD allocate failed\n"); | ||
251 | return -ENOMEM; | ||
252 | } | ||
253 | |||
254 | priv->dvc_nr = nr; | ||
255 | priv->dvc = dvc; | ||
256 | |||
257 | for_each_rsnd_dvc(dvc, priv, i) { | ||
258 | snprintf(name, RSND_DVC_NAME_SIZE, "dvc.%d", i); | ||
259 | |||
260 | clk = devm_clk_get(dev, name); | ||
261 | if (IS_ERR(clk)) | ||
262 | return PTR_ERR(clk); | ||
263 | |||
264 | dvc->info = &info->dvc_info[i]; | ||
265 | dvc->clk = clk; | ||
266 | |||
267 | rsnd_mod_init(priv, &dvc->mod, &rsnd_dvc_ops, RSND_MOD_DVC, i); | ||
268 | |||
269 | dev_dbg(dev, "CMD%d probed\n", i); | ||
270 | } | ||
271 | |||
272 | return 0; | ||
273 | } | ||
diff --git a/sound/soc/sh/rcar/gen.c b/sound/soc/sh/rcar/gen.c index 50a1ef3eb1c6..a1583b57bf8d 100644 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c | |||
@@ -181,6 +181,8 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) | |||
181 | RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20), | 181 | RSND_GEN2_M_REG(gen, SCU, SRC_BUSIF_MODE, 0x0, 0x20), |
182 | RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20), | 182 | RSND_GEN2_M_REG(gen, SCU, SRC_ROUTE_MODE0,0xc, 0x20), |
183 | RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20), | 183 | RSND_GEN2_M_REG(gen, SCU, SRC_CTRL, 0x10, 0x20), |
184 | RSND_GEN2_M_REG(gen, SCU, CMD_ROUTE_SLCT, 0x18c, 0x20), | ||
185 | RSND_GEN2_M_REG(gen, SCU, CMD_CTRL, 0x190, 0x20), | ||
184 | RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40), | 186 | RSND_GEN2_M_REG(gen, SCU, SRC_SWRSR, 0x200, 0x40), |
185 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40), | 187 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCIR, 0x204, 0x40), |
186 | RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40), | 188 | RSND_GEN2_M_REG(gen, SCU, SRC_ADINR, 0x214, 0x40), |
@@ -189,6 +191,14 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) | |||
189 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40), | 191 | RSND_GEN2_M_REG(gen, SCU, SRC_SRCCR, 0x224, 0x40), |
190 | RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40), | 192 | RSND_GEN2_M_REG(gen, SCU, SRC_BSDSR, 0x22c, 0x40), |
191 | RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40), | 193 | RSND_GEN2_M_REG(gen, SCU, SRC_BSISR, 0x238, 0x40), |
194 | RSND_GEN2_M_REG(gen, SCU, DVC_SWRSR, 0xe00, 0x100), | ||
195 | RSND_GEN2_M_REG(gen, SCU, DVC_DVUIR, 0xe04, 0x100), | ||
196 | RSND_GEN2_M_REG(gen, SCU, DVC_ADINR, 0xe08, 0x100), | ||
197 | RSND_GEN2_M_REG(gen, SCU, DVC_DVUCR, 0xe10, 0x100), | ||
198 | RSND_GEN2_M_REG(gen, SCU, DVC_ZCMCR, 0xe14, 0x100), | ||
199 | RSND_GEN2_M_REG(gen, SCU, DVC_VOL0R, 0xe28, 0x100), | ||
200 | RSND_GEN2_M_REG(gen, SCU, DVC_VOL1R, 0xe2c, 0x100), | ||
201 | RSND_GEN2_M_REG(gen, SCU, DVC_DVUER, 0xe48, 0x100), | ||
192 | 202 | ||
193 | RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), | 203 | RSND_GEN2_S_REG(gen, ADG, BRRA, 0x00), |
194 | RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), | 204 | RSND_GEN2_S_REG(gen, ADG, BRRB, 0x04), |
@@ -207,6 +217,7 @@ static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) | |||
207 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50), | 217 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL2, 0x50), |
208 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54), | 218 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL3, 0x54), |
209 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58), | 219 | RSND_GEN2_S_REG(gen, ADG, SRCOUT_TIMSEL4, 0x58), |
220 | RSND_GEN2_S_REG(gen, ADG, CMDOUT_TIMSEL, 0x5c), | ||
210 | 221 | ||
211 | RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), | 222 | RSND_GEN2_M_REG(gen, SSI, SSICR, 0x00, 0x40), |
212 | RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), | 223 | RSND_GEN2_M_REG(gen, SSI, SSISR, 0x04, 0x40), |
@@ -252,13 +263,13 @@ static int rsnd_gen2_probe(struct platform_device *pdev, | |||
252 | return ret; | 263 | return ret; |
253 | 264 | ||
254 | dev_dbg(dev, "Gen2 device probed\n"); | 265 | dev_dbg(dev, "Gen2 device probed\n"); |
255 | dev_dbg(dev, "SCU : %08x => %p\n", scu_res->start, | 266 | dev_dbg(dev, "SCU : %pap => %p\n", &scu_res->start, |
256 | gen->base[RSND_GEN2_SCU]); | 267 | gen->base[RSND_GEN2_SCU]); |
257 | dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, | 268 | dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start, |
258 | gen->base[RSND_GEN2_ADG]); | 269 | gen->base[RSND_GEN2_ADG]); |
259 | dev_dbg(dev, "SSIU : %08x => %p\n", ssiu_res->start, | 270 | dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start, |
260 | gen->base[RSND_GEN2_SSIU]); | 271 | gen->base[RSND_GEN2_SSIU]); |
261 | dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, | 272 | dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start, |
262 | gen->base[RSND_GEN2_SSI]); | 273 | gen->base[RSND_GEN2_SSI]); |
263 | 274 | ||
264 | return 0; | 275 | return 0; |
@@ -345,11 +356,11 @@ static int rsnd_gen1_probe(struct platform_device *pdev, | |||
345 | return ret; | 356 | return ret; |
346 | 357 | ||
347 | dev_dbg(dev, "Gen1 device probed\n"); | 358 | dev_dbg(dev, "Gen1 device probed\n"); |
348 | dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, | 359 | dev_dbg(dev, "SRU : %pap => %p\n", &sru_res->start, |
349 | gen->base[RSND_GEN1_SRU]); | 360 | gen->base[RSND_GEN1_SRU]); |
350 | dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, | 361 | dev_dbg(dev, "ADG : %pap => %p\n", &adg_res->start, |
351 | gen->base[RSND_GEN1_ADG]); | 362 | gen->base[RSND_GEN1_ADG]); |
352 | dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, | 363 | dev_dbg(dev, "SSI : %pap => %p\n", &ssi_res->start, |
353 | gen->base[RSND_GEN1_SSI]); | 364 | gen->base[RSND_GEN1_SSI]); |
354 | 365 | ||
355 | return 0; | 366 | return 0; |
diff --git a/sound/soc/sh/rcar/rsnd.h b/sound/soc/sh/rcar/rsnd.h index 619d198c7d2e..5aa790170b01 100644 --- a/sound/soc/sh/rcar/rsnd.h +++ b/sound/soc/sh/rcar/rsnd.h | |||
@@ -44,6 +44,15 @@ enum rsnd_reg { | |||
44 | RSND_REG_SRC_IFSCR, | 44 | RSND_REG_SRC_IFSCR, |
45 | RSND_REG_SRC_IFSVR, | 45 | RSND_REG_SRC_IFSVR, |
46 | RSND_REG_SRC_SRCCR, | 46 | RSND_REG_SRC_SRCCR, |
47 | RSND_REG_CMD_ROUTE_SLCT, | ||
48 | RSND_REG_DVC_SWRSR, | ||
49 | RSND_REG_DVC_DVUIR, | ||
50 | RSND_REG_DVC_ADINR, | ||
51 | RSND_REG_DVC_DVUCR, | ||
52 | RSND_REG_DVC_ZCMCR, | ||
53 | RSND_REG_DVC_VOL0R, | ||
54 | RSND_REG_DVC_VOL1R, | ||
55 | RSND_REG_DVC_DVUER, | ||
47 | 56 | ||
48 | /* ADG */ | 57 | /* ADG */ |
49 | RSND_REG_BRRA, | 58 | RSND_REG_BRRA, |
@@ -79,6 +88,8 @@ enum rsnd_reg { | |||
79 | RSND_REG_SHARE17, | 88 | RSND_REG_SHARE17, |
80 | RSND_REG_SHARE18, | 89 | RSND_REG_SHARE18, |
81 | RSND_REG_SHARE19, | 90 | RSND_REG_SHARE19, |
91 | RSND_REG_SHARE20, | ||
92 | RSND_REG_SHARE21, | ||
82 | 93 | ||
83 | RSND_REG_MAX, | 94 | RSND_REG_MAX, |
84 | }; | 95 | }; |
@@ -114,6 +125,8 @@ enum rsnd_reg { | |||
114 | #define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17 | 125 | #define RSND_REG_SRCOUT_TIMSEL3 RSND_REG_SHARE17 |
115 | #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 | 126 | #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 |
116 | #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 | 127 | #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 |
128 | #define RSND_REG_CMD_CTRL RSND_REG_SHARE20 | ||
129 | #define RSND_REG_CMDOUT_TIMSEL RSND_REG_SHARE21 | ||
117 | 130 | ||
118 | struct rsnd_of_data; | 131 | struct rsnd_of_data; |
119 | struct rsnd_priv; | 132 | struct rsnd_priv; |
@@ -136,6 +149,7 @@ void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, | |||
136 | enum rsnd_reg reg, u32 data); | 149 | enum rsnd_reg reg, u32 data); |
137 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | 150 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, |
138 | u32 mask, u32 data); | 151 | u32 mask, u32 data); |
152 | u32 rsnd_get_adinr(struct rsnd_mod *mod); | ||
139 | 153 | ||
140 | /* | 154 | /* |
141 | * R-Car DMA | 155 | * R-Car DMA |
@@ -165,29 +179,27 @@ void rsnd_dma_quit(struct rsnd_priv *priv, | |||
165 | enum rsnd_mod_type { | 179 | enum rsnd_mod_type { |
166 | RSND_MOD_SRC = 0, | 180 | RSND_MOD_SRC = 0, |
167 | RSND_MOD_SSI, | 181 | RSND_MOD_SSI, |
182 | RSND_MOD_DVC, | ||
168 | RSND_MOD_MAX, | 183 | RSND_MOD_MAX, |
169 | }; | 184 | }; |
170 | 185 | ||
171 | struct rsnd_mod_ops { | 186 | struct rsnd_mod_ops { |
172 | char *name; | 187 | char *name; |
173 | int (*probe)(struct rsnd_mod *mod, | 188 | int (*probe)(struct rsnd_mod *mod, |
174 | struct rsnd_dai *rdai, | 189 | struct rsnd_dai *rdai); |
175 | struct rsnd_dai_stream *io); | ||
176 | int (*remove)(struct rsnd_mod *mod, | 190 | int (*remove)(struct rsnd_mod *mod, |
177 | struct rsnd_dai *rdai, | 191 | struct rsnd_dai *rdai); |
178 | struct rsnd_dai_stream *io); | ||
179 | int (*init)(struct rsnd_mod *mod, | 192 | int (*init)(struct rsnd_mod *mod, |
180 | struct rsnd_dai *rdai, | 193 | struct rsnd_dai *rdai); |
181 | struct rsnd_dai_stream *io); | ||
182 | int (*quit)(struct rsnd_mod *mod, | 194 | int (*quit)(struct rsnd_mod *mod, |
183 | struct rsnd_dai *rdai, | 195 | struct rsnd_dai *rdai); |
184 | struct rsnd_dai_stream *io); | ||
185 | int (*start)(struct rsnd_mod *mod, | 196 | int (*start)(struct rsnd_mod *mod, |
186 | struct rsnd_dai *rdai, | 197 | struct rsnd_dai *rdai); |
187 | struct rsnd_dai_stream *io); | ||
188 | int (*stop)(struct rsnd_mod *mod, | 198 | int (*stop)(struct rsnd_mod *mod, |
189 | struct rsnd_dai *rdai, | 199 | struct rsnd_dai *rdai); |
190 | struct rsnd_dai_stream *io); | 200 | int (*pcm_new)(struct rsnd_mod *mod, |
201 | struct rsnd_dai *rdai, | ||
202 | struct snd_soc_pcm_runtime *rtd); | ||
191 | }; | 203 | }; |
192 | 204 | ||
193 | struct rsnd_dai_stream; | 205 | struct rsnd_dai_stream; |
@@ -228,6 +240,7 @@ struct rsnd_dai_stream { | |||
228 | }; | 240 | }; |
229 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) | 241 | #define rsnd_io_to_mod_ssi(io) ((io)->mod[RSND_MOD_SSI]) |
230 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) | 242 | #define rsnd_io_to_mod_src(io) ((io)->mod[RSND_MOD_SRC]) |
243 | #define rsnd_io_to_mod_dvc(io) ((io)->mod[RSND_MOD_DVC]) | ||
231 | 244 | ||
232 | struct rsnd_dai { | 245 | struct rsnd_dai { |
233 | char name[RSND_DAI_NAME_SIZE]; | 246 | char name[RSND_DAI_NAME_SIZE]; |
@@ -291,6 +304,9 @@ int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod, | |||
291 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, | 304 | int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, |
292 | struct rsnd_dai *rdai, | 305 | struct rsnd_dai *rdai, |
293 | struct rsnd_dai_stream *io); | 306 | struct rsnd_dai_stream *io); |
307 | int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_dai *rdai, | ||
308 | struct rsnd_mod *mod, | ||
309 | struct rsnd_dai_stream *io); | ||
294 | 310 | ||
295 | /* | 311 | /* |
296 | * R-Car sound priv | 312 | * R-Car sound priv |
@@ -328,6 +344,12 @@ struct rsnd_priv { | |||
328 | int ssi_nr; | 344 | int ssi_nr; |
329 | 345 | ||
330 | /* | 346 | /* |
347 | * below value will be filled on rsnd_dvc_probe() | ||
348 | */ | ||
349 | void *dvc; | ||
350 | int dvc_nr; | ||
351 | |||
352 | /* | ||
331 | * below value will be filled on rsnd_dai_probe() | 353 | * below value will be filled on rsnd_dai_probe() |
332 | */ | 354 | */ |
333 | struct snd_soc_dai_driver *daidrv; | 355 | struct snd_soc_dai_driver *daidrv; |
@@ -364,11 +386,9 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
364 | struct rsnd_dai_stream *io, | 386 | struct rsnd_dai_stream *io, |
365 | struct snd_pcm_runtime *runtime); | 387 | struct snd_pcm_runtime *runtime); |
366 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | 388 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, |
367 | struct rsnd_dai *rdai, | 389 | struct rsnd_dai *rdai); |
368 | struct rsnd_dai_stream *io); | ||
369 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, | 390 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, |
370 | struct rsnd_dai *rdai, | 391 | struct rsnd_dai *rdai); |
371 | struct rsnd_dai_stream *io); | ||
372 | 392 | ||
373 | #define rsnd_src_nr(priv) ((priv)->src_nr) | 393 | #define rsnd_src_nr(priv) ((priv)->src_nr) |
374 | 394 | ||
@@ -379,9 +399,19 @@ int rsnd_ssi_probe(struct platform_device *pdev, | |||
379 | const struct rsnd_of_data *of_data, | 399 | const struct rsnd_of_data *of_data, |
380 | struct rsnd_priv *priv); | 400 | struct rsnd_priv *priv); |
381 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); | 401 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); |
382 | struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, | ||
383 | int dai_id, int is_play); | ||
384 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); | 402 | int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod); |
385 | int rsnd_ssi_is_play(struct rsnd_mod *mod); | 403 | |
404 | /* | ||
405 | * R-Car DVC | ||
406 | */ | ||
407 | int rsnd_dvc_probe(struct platform_device *pdev, | ||
408 | const struct rsnd_of_data *of_data, | ||
409 | struct rsnd_priv *priv); | ||
410 | void rsnd_dvc_remove(struct platform_device *pdev, | ||
411 | struct rsnd_priv *priv); | ||
412 | struct rsnd_mod *rsnd_dvc_mod_get(struct rsnd_priv *priv, int id); | ||
413 | |||
414 | #define rsnd_dvc_nr(priv) ((priv)->dvc_nr) | ||
415 | |||
386 | 416 | ||
387 | #endif | 417 | #endif |
diff --git a/sound/soc/sh/rcar/src.c b/sound/soc/sh/rcar/src.c index 4d0720ed5a90..e3b078e7c3aa 100644 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c | |||
@@ -18,21 +18,9 @@ struct rsnd_src { | |||
18 | 18 | ||
19 | #define RSND_SRC_NAME_SIZE 16 | 19 | #define RSND_SRC_NAME_SIZE 16 |
20 | 20 | ||
21 | /* | ||
22 | * ADINR | ||
23 | */ | ||
24 | #define OTBL_24 (0 << 16) | ||
25 | #define OTBL_22 (2 << 16) | ||
26 | #define OTBL_20 (4 << 16) | ||
27 | #define OTBL_18 (6 << 16) | ||
28 | #define OTBL_16 (8 << 16) | ||
29 | |||
30 | #define rsnd_src_mode_flags(p) ((p)->info->flags) | ||
31 | #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) | 21 | #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) |
32 | #define rsnd_mod_to_src(_mod) \ | 22 | #define rsnd_mod_to_src(_mod) \ |
33 | container_of((_mod), struct rsnd_src, mod) | 23 | container_of((_mod), struct rsnd_src, mod) |
34 | #define rsnd_src_hpbif_is_enable(src) \ | ||
35 | (rsnd_src_mode_flags(src) & RSND_SCU_USE_HPBIF) | ||
36 | #define rsnd_src_dma_available(src) \ | 24 | #define rsnd_src_dma_available(src) \ |
37 | rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) | 25 | rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) |
38 | 26 | ||
@@ -80,34 +68,35 @@ struct rsnd_src { | |||
80 | * | 68 | * |
81 | * This driver request | 69 | * This driver request |
82 | * struct rsnd_src_platform_info { | 70 | * struct rsnd_src_platform_info { |
83 | * u32 flags; | ||
84 | * u32 convert_rate; | 71 | * u32 convert_rate; |
72 | * int dma_id; | ||
85 | * } | 73 | * } |
86 | * | 74 | * |
87 | * rsnd_src_hpbif_is_enable() will be true | ||
88 | * if flags had RSND_SRC_USE_HPBIF, | ||
89 | * and it controls whether SSIU is used or not. | ||
90 | * | ||
91 | * rsnd_src_convert_rate() indicates | 75 | * rsnd_src_convert_rate() indicates |
92 | * above convert_rate, and it controls | 76 | * above convert_rate, and it controls |
93 | * whether SRC is used or not. | 77 | * whether SRC is used or not. |
94 | * | 78 | * |
95 | * ex) doesn't use SRC | 79 | * ex) doesn't use SRC |
96 | * struct rsnd_src_platform_info info = { | 80 | * static struct rsnd_dai_platform_info rsnd_dai = { |
97 | * .flags = 0, | 81 | * .playback = { .ssi = &rsnd_ssi[0], }, |
98 | * .convert_rate = 0, | ||
99 | * }; | 82 | * }; |
100 | * | 83 | * |
101 | * ex) uses SRC | 84 | * ex) uses SRC |
102 | * struct rsnd_src_platform_info info = { | 85 | * static struct rsnd_src_platform_info rsnd_src[] = { |
103 | * .flags = RSND_SRC_USE_HPBIF, | 86 | * RSND_SCU(48000, 0), |
104 | * .convert_rate = 48000, | 87 | * ... |
88 | * }; | ||
89 | * static struct rsnd_dai_platform_info rsnd_dai = { | ||
90 | * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, | ||
105 | * }; | 91 | * }; |
106 | * | 92 | * |
107 | * ex) uses SRC bypass mode | 93 | * ex) uses SRC bypass mode |
108 | * struct rsnd_src_platform_info info = { | 94 | * static struct rsnd_src_platform_info rsnd_src[] = { |
109 | * .flags = RSND_SRC_USE_HPBIF, | 95 | * RSND_SCU(0, 0), |
110 | * .convert_rate = 0, | 96 | * ... |
97 | * }; | ||
98 | * static struct rsnd_dai_platform_info rsnd_dai = { | ||
99 | * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, | ||
111 | * }; | 100 | * }; |
112 | * | 101 | * |
113 | */ | 102 | */ |
@@ -116,27 +105,17 @@ struct rsnd_src { | |||
116 | * Gen1/Gen2 common functions | 105 | * Gen1/Gen2 common functions |
117 | */ | 106 | */ |
118 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | 107 | int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, |
119 | struct rsnd_dai *rdai, | 108 | struct rsnd_dai *rdai) |
120 | struct rsnd_dai_stream *io) | ||
121 | { | 109 | { |
122 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 110 | struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); |
123 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); | 111 | struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); |
124 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
125 | int ssi_id = rsnd_mod_id(ssi_mod); | 112 | int ssi_id = rsnd_mod_id(ssi_mod); |
126 | int has_src = 0; | ||
127 | 113 | ||
128 | /* | 114 | /* |
129 | * SSI_MODE0 | 115 | * SSI_MODE0 |
130 | */ | 116 | */ |
131 | if (info->dai_info) { | ||
132 | has_src = !!src_mod; | ||
133 | } else { | ||
134 | struct rsnd_src *src = rsnd_mod_to_src(src_mod); | ||
135 | has_src = rsnd_src_hpbif_is_enable(src); | ||
136 | } | ||
137 | |||
138 | rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), | 117 | rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), |
139 | has_src ? 0 : (1 << ssi_id)); | 118 | src_mod ? 0 : (1 << ssi_id)); |
140 | 119 | ||
141 | /* | 120 | /* |
142 | * SSI_MODE1 | 121 | * SSI_MODE1 |
@@ -166,8 +145,7 @@ int rsnd_src_ssi_mode_init(struct rsnd_mod *ssi_mod, | |||
166 | } | 145 | } |
167 | 146 | ||
168 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, | 147 | int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, |
169 | struct rsnd_dai *rdai, | 148 | struct rsnd_dai *rdai) |
170 | struct rsnd_dai_stream *io) | ||
171 | { | 149 | { |
172 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); | 150 | struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); |
173 | 151 | ||
@@ -203,13 +181,12 @@ unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, | |||
203 | } | 181 | } |
204 | 182 | ||
205 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | 183 | static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, |
206 | struct rsnd_dai *rdai, | 184 | struct rsnd_dai *rdai) |
207 | struct rsnd_dai_stream *io) | ||
208 | { | 185 | { |
186 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
209 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 187 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
210 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 188 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
211 | u32 convert_rate = rsnd_src_convert_rate(src); | 189 | u32 convert_rate = rsnd_src_convert_rate(src); |
212 | u32 adinr = runtime->channels; | ||
213 | u32 fsrate = 0; | 190 | u32 fsrate = 0; |
214 | 191 | ||
215 | if (convert_rate) | 192 | if (convert_rate) |
@@ -226,17 +203,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
226 | rsnd_mod_write(mod, SRC_SRCIR, 1); | 203 | rsnd_mod_write(mod, SRC_SRCIR, 1); |
227 | 204 | ||
228 | /* Set channel number and output bit length */ | 205 | /* Set channel number and output bit length */ |
229 | switch (runtime->sample_bits) { | 206 | rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); |
230 | case 16: | ||
231 | adinr |= OTBL_16; | ||
232 | break; | ||
233 | case 32: | ||
234 | adinr |= OTBL_24; | ||
235 | break; | ||
236 | default: | ||
237 | return -EIO; | ||
238 | } | ||
239 | rsnd_mod_write(mod, SRC_ADINR, adinr); | ||
240 | 207 | ||
241 | /* Enable the initial value of IFS */ | 208 | /* Enable the initial value of IFS */ |
242 | if (fsrate) { | 209 | if (fsrate) { |
@@ -253,8 +220,7 @@ static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, | |||
253 | } | 220 | } |
254 | 221 | ||
255 | static int rsnd_src_init(struct rsnd_mod *mod, | 222 | static int rsnd_src_init(struct rsnd_mod *mod, |
256 | struct rsnd_dai *rdai, | 223 | struct rsnd_dai *rdai) |
257 | struct rsnd_dai_stream *io) | ||
258 | { | 224 | { |
259 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 225 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
260 | 226 | ||
@@ -264,8 +230,7 @@ static int rsnd_src_init(struct rsnd_mod *mod, | |||
264 | } | 230 | } |
265 | 231 | ||
266 | static int rsnd_src_quit(struct rsnd_mod *mod, | 232 | static int rsnd_src_quit(struct rsnd_mod *mod, |
267 | struct rsnd_dai *rdai, | 233 | struct rsnd_dai *rdai) |
268 | struct rsnd_dai_stream *io) | ||
269 | { | 234 | { |
270 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 235 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
271 | 236 | ||
@@ -275,8 +240,7 @@ static int rsnd_src_quit(struct rsnd_mod *mod, | |||
275 | } | 240 | } |
276 | 241 | ||
277 | static int rsnd_src_start(struct rsnd_mod *mod, | 242 | static int rsnd_src_start(struct rsnd_mod *mod, |
278 | struct rsnd_dai *rdai, | 243 | struct rsnd_dai *rdai) |
279 | struct rsnd_dai_stream *io) | ||
280 | { | 244 | { |
281 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 245 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
282 | 246 | ||
@@ -294,8 +258,7 @@ static int rsnd_src_start(struct rsnd_mod *mod, | |||
294 | 258 | ||
295 | 259 | ||
296 | static int rsnd_src_stop(struct rsnd_mod *mod, | 260 | static int rsnd_src_stop(struct rsnd_mod *mod, |
297 | struct rsnd_dai *rdai, | 261 | struct rsnd_dai *rdai) |
298 | struct rsnd_dai_stream *io) | ||
299 | { | 262 | { |
300 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 263 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
301 | 264 | ||
@@ -313,9 +276,9 @@ static struct rsnd_mod_ops rsnd_src_non_ops = { | |||
313 | * Gen1 functions | 276 | * Gen1 functions |
314 | */ | 277 | */ |
315 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | 278 | static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, |
316 | struct rsnd_dai *rdai, | 279 | struct rsnd_dai *rdai) |
317 | struct rsnd_dai_stream *io) | ||
318 | { | 280 | { |
281 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
319 | struct src_route_config { | 282 | struct src_route_config { |
320 | u32 mask; | 283 | u32 mask; |
321 | int shift; | 284 | int shift; |
@@ -351,9 +314,9 @@ static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, | |||
351 | } | 314 | } |
352 | 315 | ||
353 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | 316 | static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, |
354 | struct rsnd_dai *rdai, | 317 | struct rsnd_dai *rdai) |
355 | struct rsnd_dai_stream *io) | ||
356 | { | 318 | { |
319 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
357 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 320 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
358 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 321 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
359 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 322 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
@@ -410,12 +373,11 @@ static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, | |||
410 | } | 373 | } |
411 | 374 | ||
412 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | 375 | static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, |
413 | struct rsnd_dai *rdai, | 376 | struct rsnd_dai *rdai) |
414 | struct rsnd_dai_stream *io) | ||
415 | { | 377 | { |
416 | int ret; | 378 | int ret; |
417 | 379 | ||
418 | ret = rsnd_src_set_convert_rate(mod, rdai, io); | 380 | ret = rsnd_src_set_convert_rate(mod, rdai); |
419 | if (ret < 0) | 381 | if (ret < 0) |
420 | return ret; | 382 | return ret; |
421 | 383 | ||
@@ -432,24 +394,23 @@ static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, | |||
432 | } | 394 | } |
433 | 395 | ||
434 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, | 396 | static int rsnd_src_init_gen1(struct rsnd_mod *mod, |
435 | struct rsnd_dai *rdai, | 397 | struct rsnd_dai *rdai) |
436 | struct rsnd_dai_stream *io) | ||
437 | { | 398 | { |
438 | int ret; | 399 | int ret; |
439 | 400 | ||
440 | ret = rsnd_src_init(mod, rdai, io); | 401 | ret = rsnd_src_init(mod, rdai); |
441 | if (ret < 0) | 402 | if (ret < 0) |
442 | return ret; | 403 | return ret; |
443 | 404 | ||
444 | ret = rsnd_src_set_route_gen1(mod, rdai, io); | 405 | ret = rsnd_src_set_route_gen1(mod, rdai); |
445 | if (ret < 0) | 406 | if (ret < 0) |
446 | return ret; | 407 | return ret; |
447 | 408 | ||
448 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai, io); | 409 | ret = rsnd_src_set_convert_rate_gen1(mod, rdai); |
449 | if (ret < 0) | 410 | if (ret < 0) |
450 | return ret; | 411 | return ret; |
451 | 412 | ||
452 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai, io); | 413 | ret = rsnd_src_set_convert_timing_gen1(mod, rdai); |
453 | if (ret < 0) | 414 | if (ret < 0) |
454 | return ret; | 415 | return ret; |
455 | 416 | ||
@@ -457,25 +418,23 @@ static int rsnd_src_init_gen1(struct rsnd_mod *mod, | |||
457 | } | 418 | } |
458 | 419 | ||
459 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, | 420 | static int rsnd_src_start_gen1(struct rsnd_mod *mod, |
460 | struct rsnd_dai *rdai, | 421 | struct rsnd_dai *rdai) |
461 | struct rsnd_dai_stream *io) | ||
462 | { | 422 | { |
463 | int id = rsnd_mod_id(mod); | 423 | int id = rsnd_mod_id(mod); |
464 | 424 | ||
465 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); | 425 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); |
466 | 426 | ||
467 | return rsnd_src_start(mod, rdai, io); | 427 | return rsnd_src_start(mod, rdai); |
468 | } | 428 | } |
469 | 429 | ||
470 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, | 430 | static int rsnd_src_stop_gen1(struct rsnd_mod *mod, |
471 | struct rsnd_dai *rdai, | 431 | struct rsnd_dai *rdai) |
472 | struct rsnd_dai_stream *io) | ||
473 | { | 432 | { |
474 | int id = rsnd_mod_id(mod); | 433 | int id = rsnd_mod_id(mod); |
475 | 434 | ||
476 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); | 435 | rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); |
477 | 436 | ||
478 | return rsnd_src_stop(mod, rdai, io); | 437 | return rsnd_src_stop(mod, rdai); |
479 | } | 438 | } |
480 | 439 | ||
481 | static struct rsnd_mod_ops rsnd_src_gen1_ops = { | 440 | static struct rsnd_mod_ops rsnd_src_gen1_ops = { |
@@ -490,17 +449,16 @@ static struct rsnd_mod_ops rsnd_src_gen1_ops = { | |||
490 | * Gen2 functions | 449 | * Gen2 functions |
491 | */ | 450 | */ |
492 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | 451 | static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, |
493 | struct rsnd_dai *rdai, | 452 | struct rsnd_dai *rdai) |
494 | struct rsnd_dai_stream *io) | ||
495 | { | 453 | { |
496 | int ret; | 454 | int ret; |
497 | 455 | ||
498 | ret = rsnd_src_set_convert_rate(mod, rdai, io); | 456 | ret = rsnd_src_set_convert_rate(mod, rdai); |
499 | if (ret < 0) | 457 | if (ret < 0) |
500 | return ret; | 458 | return ret; |
501 | 459 | ||
502 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_mod_read(mod, SRC_ADINR)); | 460 | rsnd_mod_write(mod, SSI_BUSIF_ADINR, rsnd_get_adinr(mod)); |
503 | rsnd_mod_write(mod, SSI_BUSIF_MODE, rsnd_mod_read(mod, SRC_BUSIF_MODE)); | 461 | rsnd_mod_write(mod, SSI_BUSIF_MODE, 1); |
504 | 462 | ||
505 | rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); | 463 | rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); |
506 | 464 | ||
@@ -511,9 +469,9 @@ static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, | |||
511 | } | 469 | } |
512 | 470 | ||
513 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | 471 | static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, |
514 | struct rsnd_dai *rdai, | 472 | struct rsnd_dai *rdai) |
515 | struct rsnd_dai_stream *io) | ||
516 | { | 473 | { |
474 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
517 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 475 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
518 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 476 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
519 | u32 convert_rate = rsnd_src_convert_rate(src); | 477 | u32 convert_rate = rsnd_src_convert_rate(src); |
@@ -530,25 +488,16 @@ static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, | |||
530 | } | 488 | } |
531 | 489 | ||
532 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | 490 | static int rsnd_src_probe_gen2(struct rsnd_mod *mod, |
533 | struct rsnd_dai *rdai, | 491 | struct rsnd_dai *rdai) |
534 | struct rsnd_dai_stream *io) | ||
535 | { | 492 | { |
536 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 493 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
537 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
538 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 494 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
539 | struct rsnd_mod *ssi = rsnd_ssi_mod_get(priv, rsnd_mod_id(mod)); | ||
540 | struct device *dev = rsnd_priv_to_dev(priv); | 495 | struct device *dev = rsnd_priv_to_dev(priv); |
541 | int ret; | 496 | int ret; |
542 | int is_play; | ||
543 | |||
544 | if (info->dai_info) | ||
545 | is_play = rsnd_info_is_playback(priv, src); | ||
546 | else | ||
547 | is_play = rsnd_ssi_is_play(ssi); | ||
548 | 497 | ||
549 | ret = rsnd_dma_init(priv, | 498 | ret = rsnd_dma_init(priv, |
550 | rsnd_mod_to_dma(mod), | 499 | rsnd_mod_to_dma(mod), |
551 | is_play, | 500 | rsnd_info_is_playback(priv, src), |
552 | src->info->dma_id); | 501 | src->info->dma_id); |
553 | if (ret < 0) | 502 | if (ret < 0) |
554 | dev_err(dev, "SRC DMA failed\n"); | 503 | dev_err(dev, "SRC DMA failed\n"); |
@@ -557,8 +506,7 @@ static int rsnd_src_probe_gen2(struct rsnd_mod *mod, | |||
557 | } | 506 | } |
558 | 507 | ||
559 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | 508 | static int rsnd_src_remove_gen2(struct rsnd_mod *mod, |
560 | struct rsnd_dai *rdai, | 509 | struct rsnd_dai *rdai) |
561 | struct rsnd_dai_stream *io) | ||
562 | { | 510 | { |
563 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 511 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); |
564 | 512 | ||
@@ -566,20 +514,19 @@ static int rsnd_src_remove_gen2(struct rsnd_mod *mod, | |||
566 | } | 514 | } |
567 | 515 | ||
568 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, | 516 | static int rsnd_src_init_gen2(struct rsnd_mod *mod, |
569 | struct rsnd_dai *rdai, | 517 | struct rsnd_dai *rdai) |
570 | struct rsnd_dai_stream *io) | ||
571 | { | 518 | { |
572 | int ret; | 519 | int ret; |
573 | 520 | ||
574 | ret = rsnd_src_init(mod, rdai, io); | 521 | ret = rsnd_src_init(mod, rdai); |
575 | if (ret < 0) | 522 | if (ret < 0) |
576 | return ret; | 523 | return ret; |
577 | 524 | ||
578 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai, io); | 525 | ret = rsnd_src_set_convert_rate_gen2(mod, rdai); |
579 | if (ret < 0) | 526 | if (ret < 0) |
580 | return ret; | 527 | return ret; |
581 | 528 | ||
582 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai, io); | 529 | ret = rsnd_src_set_convert_timing_gen2(mod, rdai); |
583 | if (ret < 0) | 530 | if (ret < 0) |
584 | return ret; | 531 | return ret; |
585 | 532 | ||
@@ -587,22 +534,22 @@ static int rsnd_src_init_gen2(struct rsnd_mod *mod, | |||
587 | } | 534 | } |
588 | 535 | ||
589 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, | 536 | static int rsnd_src_start_gen2(struct rsnd_mod *mod, |
590 | struct rsnd_dai *rdai, | 537 | struct rsnd_dai *rdai) |
591 | struct rsnd_dai_stream *io) | ||
592 | { | 538 | { |
539 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
593 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 540 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
541 | u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; | ||
594 | 542 | ||
595 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); | 543 | rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); |
596 | 544 | ||
597 | rsnd_mod_write(mod, SSI_CTRL, 0x1); | 545 | rsnd_mod_write(mod, SSI_CTRL, 0x1); |
598 | rsnd_mod_write(mod, SRC_CTRL, 0x11); | 546 | rsnd_mod_write(mod, SRC_CTRL, val); |
599 | 547 | ||
600 | return rsnd_src_start(mod, rdai, io); | 548 | return rsnd_src_start(mod, rdai); |
601 | } | 549 | } |
602 | 550 | ||
603 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | 551 | static int rsnd_src_stop_gen2(struct rsnd_mod *mod, |
604 | struct rsnd_dai *rdai, | 552 | struct rsnd_dai *rdai) |
605 | struct rsnd_dai_stream *io) | ||
606 | { | 553 | { |
607 | struct rsnd_src *src = rsnd_mod_to_src(mod); | 554 | struct rsnd_src *src = rsnd_mod_to_src(mod); |
608 | 555 | ||
@@ -611,7 +558,7 @@ static int rsnd_src_stop_gen2(struct rsnd_mod *mod, | |||
611 | 558 | ||
612 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); | 559 | rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); |
613 | 560 | ||
614 | return rsnd_src_stop(mod, rdai, io); | 561 | return rsnd_src_stop(mod, rdai); |
615 | } | 562 | } |
616 | 563 | ||
617 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { | 564 | static struct rsnd_mod_ops rsnd_src_gen2_ops = { |
@@ -699,11 +646,6 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
699 | snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i); | 646 | snprintf(name, RSND_SRC_NAME_SIZE, "src.%d", i); |
700 | 647 | ||
701 | clk = devm_clk_get(dev, name); | 648 | clk = devm_clk_get(dev, name); |
702 | if (IS_ERR(clk)) { | ||
703 | snprintf(name, RSND_SRC_NAME_SIZE, "scu.%d", i); | ||
704 | clk = devm_clk_get(dev, name); | ||
705 | } | ||
706 | |||
707 | if (IS_ERR(clk)) | 649 | if (IS_ERR(clk)) |
708 | return PTR_ERR(clk); | 650 | return PTR_ERR(clk); |
709 | 651 | ||
@@ -711,12 +653,10 @@ int rsnd_src_probe(struct platform_device *pdev, | |||
711 | src->clk = clk; | 653 | src->clk = clk; |
712 | 654 | ||
713 | ops = &rsnd_src_non_ops; | 655 | ops = &rsnd_src_non_ops; |
714 | if (rsnd_src_hpbif_is_enable(src)) { | 656 | if (rsnd_is_gen1(priv)) |
715 | if (rsnd_is_gen1(priv)) | 657 | ops = &rsnd_src_gen1_ops; |
716 | ops = &rsnd_src_gen1_ops; | 658 | if (rsnd_is_gen2(priv)) |
717 | if (rsnd_is_gen2(priv)) | 659 | ops = &rsnd_src_gen2_ops; |
718 | ops = &rsnd_src_gen2_ops; | ||
719 | } | ||
720 | 660 | ||
721 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); | 661 | rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); |
722 | 662 | ||
diff --git a/sound/soc/sh/rcar/ssi.c b/sound/soc/sh/rcar/ssi.c index 1d8387c25bd8..36654bd4e428 100644 --- a/sound/soc/sh/rcar/ssi.c +++ b/sound/soc/sh/rcar/ssi.c | |||
@@ -240,10 +240,10 @@ static void rsnd_ssi_hw_stop(struct rsnd_ssi *ssi, | |||
240 | * SSI mod common functions | 240 | * SSI mod common functions |
241 | */ | 241 | */ |
242 | static int rsnd_ssi_init(struct rsnd_mod *mod, | 242 | static int rsnd_ssi_init(struct rsnd_mod *mod, |
243 | struct rsnd_dai *rdai, | 243 | struct rsnd_dai *rdai) |
244 | struct rsnd_dai_stream *io) | ||
245 | { | 244 | { |
246 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 245 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
246 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
247 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); | 247 | struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); |
248 | u32 cr; | 248 | u32 cr; |
249 | 249 | ||
@@ -287,14 +287,13 @@ static int rsnd_ssi_init(struct rsnd_mod *mod, | |||
287 | ssi->cr_own = cr; | 287 | ssi->cr_own = cr; |
288 | ssi->err = -1; /* ignore 1st error */ | 288 | ssi->err = -1; /* ignore 1st error */ |
289 | 289 | ||
290 | rsnd_src_ssi_mode_init(mod, rdai, io); | 290 | rsnd_src_ssi_mode_init(mod, rdai); |
291 | 291 | ||
292 | return 0; | 292 | return 0; |
293 | } | 293 | } |
294 | 294 | ||
295 | static int rsnd_ssi_quit(struct rsnd_mod *mod, | 295 | static int rsnd_ssi_quit(struct rsnd_mod *mod, |
296 | struct rsnd_dai *rdai, | 296 | struct rsnd_dai *rdai) |
297 | struct rsnd_dai_stream *io) | ||
298 | { | 297 | { |
299 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 298 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
300 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 299 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
@@ -359,8 +358,7 @@ static irqreturn_t rsnd_ssi_pio_interrupt(int irq, void *data) | |||
359 | } | 358 | } |
360 | 359 | ||
361 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | 360 | static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, |
362 | struct rsnd_dai *rdai, | 361 | struct rsnd_dai *rdai) |
363 | struct rsnd_dai_stream *io) | ||
364 | { | 362 | { |
365 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 363 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
366 | struct device *dev = rsnd_priv_to_dev(priv); | 364 | struct device *dev = rsnd_priv_to_dev(priv); |
@@ -379,15 +377,15 @@ static int rsnd_ssi_pio_probe(struct rsnd_mod *mod, | |||
379 | } | 377 | } |
380 | 378 | ||
381 | static int rsnd_ssi_pio_start(struct rsnd_mod *mod, | 379 | static int rsnd_ssi_pio_start(struct rsnd_mod *mod, |
382 | struct rsnd_dai *rdai, | 380 | struct rsnd_dai *rdai) |
383 | struct rsnd_dai_stream *io) | ||
384 | { | 381 | { |
385 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 382 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
383 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
386 | 384 | ||
387 | /* enable PIO IRQ */ | 385 | /* enable PIO IRQ */ |
388 | ssi->cr_etc = UIEN | OIEN | DIEN; | 386 | ssi->cr_etc = UIEN | OIEN | DIEN; |
389 | 387 | ||
390 | rsnd_src_enable_ssi_irq(mod, rdai, io); | 388 | rsnd_src_enable_ssi_irq(mod, rdai); |
391 | 389 | ||
392 | rsnd_ssi_hw_start(ssi, rdai, io); | 390 | rsnd_ssi_hw_start(ssi, rdai, io); |
393 | 391 | ||
@@ -395,8 +393,7 @@ static int rsnd_ssi_pio_start(struct rsnd_mod *mod, | |||
395 | } | 393 | } |
396 | 394 | ||
397 | static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, | 395 | static int rsnd_ssi_pio_stop(struct rsnd_mod *mod, |
398 | struct rsnd_dai *rdai, | 396 | struct rsnd_dai *rdai) |
399 | struct rsnd_dai_stream *io) | ||
400 | { | 397 | { |
401 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 398 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
402 | 399 | ||
@@ -417,25 +414,17 @@ static struct rsnd_mod_ops rsnd_ssi_pio_ops = { | |||
417 | }; | 414 | }; |
418 | 415 | ||
419 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | 416 | static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, |
420 | struct rsnd_dai *rdai, | 417 | struct rsnd_dai *rdai) |
421 | struct rsnd_dai_stream *io) | ||
422 | { | 418 | { |
423 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); | 419 | struct rsnd_priv *priv = rsnd_mod_to_priv(mod); |
424 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 420 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
425 | struct rcar_snd_info *info = rsnd_priv_to_info(priv); | ||
426 | struct device *dev = rsnd_priv_to_dev(priv); | 421 | struct device *dev = rsnd_priv_to_dev(priv); |
427 | int dma_id = ssi->info->dma_id; | 422 | int dma_id = ssi->info->dma_id; |
428 | int is_play; | ||
429 | int ret; | 423 | int ret; |
430 | 424 | ||
431 | if (info->dai_info) | ||
432 | is_play = rsnd_info_is_playback(priv, ssi); | ||
433 | else | ||
434 | is_play = rsnd_ssi_is_play(&ssi->mod); | ||
435 | |||
436 | ret = rsnd_dma_init( | 425 | ret = rsnd_dma_init( |
437 | priv, rsnd_mod_to_dma(mod), | 426 | priv, rsnd_mod_to_dma(mod), |
438 | is_play, | 427 | rsnd_info_is_playback(priv, ssi), |
439 | dma_id); | 428 | dma_id); |
440 | 429 | ||
441 | if (ret < 0) | 430 | if (ret < 0) |
@@ -445,8 +434,7 @@ static int rsnd_ssi_dma_probe(struct rsnd_mod *mod, | |||
445 | } | 434 | } |
446 | 435 | ||
447 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | 436 | static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, |
448 | struct rsnd_dai *rdai, | 437 | struct rsnd_dai *rdai) |
449 | struct rsnd_dai_stream *io) | ||
450 | { | 438 | { |
451 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); | 439 | rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); |
452 | 440 | ||
@@ -454,11 +442,11 @@ static int rsnd_ssi_dma_remove(struct rsnd_mod *mod, | |||
454 | } | 442 | } |
455 | 443 | ||
456 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | 444 | static int rsnd_ssi_dma_start(struct rsnd_mod *mod, |
457 | struct rsnd_dai *rdai, | 445 | struct rsnd_dai *rdai) |
458 | struct rsnd_dai_stream *io) | ||
459 | { | 446 | { |
460 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 447 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
461 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); | 448 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); |
449 | struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); | ||
462 | 450 | ||
463 | /* enable DMA transfer */ | 451 | /* enable DMA transfer */ |
464 | ssi->cr_etc = DMEN; | 452 | ssi->cr_etc = DMEN; |
@@ -475,8 +463,7 @@ static int rsnd_ssi_dma_start(struct rsnd_mod *mod, | |||
475 | } | 463 | } |
476 | 464 | ||
477 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, | 465 | static int rsnd_ssi_dma_stop(struct rsnd_mod *mod, |
478 | struct rsnd_dai *rdai, | 466 | struct rsnd_dai *rdai) |
479 | struct rsnd_dai_stream *io) | ||
480 | { | 467 | { |
481 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | 468 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); |
482 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); | 469 | struct rsnd_dma *dma = rsnd_mod_to_dma(&ssi->mod); |
@@ -512,41 +499,6 @@ static struct rsnd_mod_ops rsnd_ssi_non_ops = { | |||
512 | /* | 499 | /* |
513 | * ssi mod function | 500 | * ssi mod function |
514 | */ | 501 | */ |
515 | struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, | ||
516 | int dai_id, int is_play) | ||
517 | { | ||
518 | struct rsnd_dai_platform_info *dai_info = NULL; | ||
519 | struct rsnd_dai_path_info *path_info = NULL; | ||
520 | struct rsnd_ssi_platform_info *target_info = NULL; | ||
521 | struct rsnd_ssi *ssi; | ||
522 | int i, has_play; | ||
523 | |||
524 | if (priv->rdai) | ||
525 | dai_info = priv->rdai[dai_id].info; | ||
526 | if (dai_info) | ||
527 | path_info = (is_play) ? &dai_info->playback : &dai_info->capture; | ||
528 | if (path_info) | ||
529 | target_info = path_info->ssi; | ||
530 | |||
531 | is_play = !!is_play; | ||
532 | |||
533 | for_each_rsnd_ssi(ssi, priv, i) { | ||
534 | if (target_info == ssi->info) | ||
535 | return &ssi->mod; | ||
536 | |||
537 | /* for compatible */ | ||
538 | if (rsnd_ssi_dai_id(ssi) != dai_id) | ||
539 | continue; | ||
540 | |||
541 | has_play = rsnd_ssi_is_play(&ssi->mod); | ||
542 | |||
543 | if (is_play == has_play) | ||
544 | return &ssi->mod; | ||
545 | } | ||
546 | |||
547 | return NULL; | ||
548 | } | ||
549 | |||
550 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) | 502 | struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id) |
551 | { | 503 | { |
552 | if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) | 504 | if (WARN_ON(id < 0 || id >= rsnd_ssi_nr(priv))) |
@@ -562,13 +514,6 @@ int rsnd_ssi_is_pin_sharing(struct rsnd_mod *mod) | |||
562 | return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); | 514 | return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_CLK_PIN_SHARE); |
563 | } | 515 | } |
564 | 516 | ||
565 | int rsnd_ssi_is_play(struct rsnd_mod *mod) | ||
566 | { | ||
567 | struct rsnd_ssi *ssi = rsnd_mod_to_ssi(mod); | ||
568 | |||
569 | return !!(rsnd_ssi_mode_flags(ssi) & RSND_SSI_PLAY); | ||
570 | } | ||
571 | |||
572 | static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) | 517 | static void rsnd_ssi_parent_clk_setup(struct rsnd_priv *priv, struct rsnd_ssi *ssi) |
573 | { | 518 | { |
574 | if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) | 519 | if (!rsnd_ssi_is_pin_sharing(&ssi->mod)) |
diff --git a/sound/soc/sirf/sirf-audio-port.c b/sound/soc/sirf/sirf-audio-port.c index b04a53f2b4f6..b4afa31b2bc1 100644 --- a/sound/soc/sirf/sirf-audio-port.c +++ b/sound/soc/sirf/sirf-audio-port.c | |||
@@ -6,60 +6,15 @@ | |||
6 | * Licensed under GPLv2 or later. | 6 | * Licensed under GPLv2 or later. |
7 | */ | 7 | */ |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/io.h> | ||
10 | #include <linux/regmap.h> | ||
11 | #include <sound/soc.h> | 9 | #include <sound/soc.h> |
12 | #include <sound/dmaengine_pcm.h> | 10 | #include <sound/dmaengine_pcm.h> |
13 | 11 | ||
14 | #include "sirf-audio-port.h" | ||
15 | |||
16 | struct sirf_audio_port { | 12 | struct sirf_audio_port { |
17 | struct regmap *regmap; | 13 | struct regmap *regmap; |
18 | struct snd_dmaengine_dai_dma_data playback_dma_data; | 14 | struct snd_dmaengine_dai_dma_data playback_dma_data; |
19 | struct snd_dmaengine_dai_dma_data capture_dma_data; | 15 | struct snd_dmaengine_dai_dma_data capture_dma_data; |
20 | }; | 16 | }; |
21 | 17 | ||
22 | static void sirf_audio_port_tx_enable(struct sirf_audio_port *port) | ||
23 | { | ||
24 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
25 | AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); | ||
26 | regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0); | ||
27 | regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); | ||
28 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, | ||
29 | AUDIO_FIFO_START, AUDIO_FIFO_START); | ||
30 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, | ||
31 | IC_TX_ENABLE, IC_TX_ENABLE); | ||
32 | } | ||
33 | |||
34 | static void sirf_audio_port_tx_disable(struct sirf_audio_port *port) | ||
35 | { | ||
36 | regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0); | ||
37 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL, | ||
38 | IC_TX_ENABLE, ~IC_TX_ENABLE); | ||
39 | } | ||
40 | |||
41 | static void sirf_audio_port_rx_enable(struct sirf_audio_port *port, | ||
42 | int channels) | ||
43 | { | ||
44 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
45 | AUDIO_FIFO_RESET, AUDIO_FIFO_RESET); | ||
46 | regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_INT_MSK, 0); | ||
47 | regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0); | ||
48 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, | ||
49 | AUDIO_FIFO_START, AUDIO_FIFO_START); | ||
50 | if (channels == 1) | ||
51 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
52 | IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO); | ||
53 | else | ||
54 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
55 | IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO); | ||
56 | } | ||
57 | |||
58 | static void sirf_audio_port_rx_disable(struct sirf_audio_port *port) | ||
59 | { | ||
60 | regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL, | ||
61 | IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO); | ||
62 | } | ||
63 | 18 | ||
64 | static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) | 19 | static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) |
65 | { | 20 | { |
@@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) | |||
69 | return 0; | 24 | return 0; |
70 | } | 25 | } |
71 | 26 | ||
72 | static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd, | ||
73 | struct snd_soc_dai *dai) | ||
74 | { | ||
75 | struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai); | ||
76 | int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
77 | |||
78 | switch (cmd) { | ||
79 | case SNDRV_PCM_TRIGGER_STOP: | ||
80 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
81 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
82 | if (playback) | ||
83 | sirf_audio_port_tx_disable(port); | ||
84 | else | ||
85 | sirf_audio_port_rx_disable(port); | ||
86 | break; | ||
87 | case SNDRV_PCM_TRIGGER_START: | ||
88 | case SNDRV_PCM_TRIGGER_RESUME: | ||
89 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
90 | if (playback) | ||
91 | sirf_audio_port_tx_enable(port); | ||
92 | else | ||
93 | sirf_audio_port_rx_enable(port, | ||
94 | substream->runtime->channels); | ||
95 | break; | ||
96 | default: | ||
97 | return -EINVAL; | ||
98 | } | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = { | ||
104 | .trigger = sirf_audio_port_trigger, | ||
105 | }; | ||
106 | |||
107 | static struct snd_soc_dai_driver sirf_audio_port_dai = { | 27 | static struct snd_soc_dai_driver sirf_audio_port_dai = { |
108 | .probe = sirf_audio_port_dai_probe, | 28 | .probe = sirf_audio_port_dai_probe, |
109 | .name = "sirf-audio-port", | 29 | .name = "sirf-audio-port", |
@@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = { | |||
120 | .rates = SNDRV_PCM_RATE_48000, | 40 | .rates = SNDRV_PCM_RATE_48000, |
121 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 41 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
122 | }, | 42 | }, |
123 | .ops = &sirf_audio_port_dai_ops, | ||
124 | }; | 43 | }; |
125 | 44 | ||
126 | static const struct snd_soc_component_driver sirf_audio_port_component = { | 45 | static const struct snd_soc_component_driver sirf_audio_port_component = { |
127 | .name = "sirf-audio-port", | 46 | .name = "sirf-audio-port", |
128 | }; | 47 | }; |
129 | 48 | ||
130 | static const struct regmap_config sirf_audio_port_regmap_config = { | ||
131 | .reg_bits = 32, | ||
132 | .reg_stride = 4, | ||
133 | .val_bits = 32, | ||
134 | .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK, | ||
135 | .cache_type = REGCACHE_NONE, | ||
136 | }; | ||
137 | |||
138 | static int sirf_audio_port_probe(struct platform_device *pdev) | 49 | static int sirf_audio_port_probe(struct platform_device *pdev) |
139 | { | 50 | { |
140 | int ret; | 51 | int ret; |
141 | struct sirf_audio_port *port; | 52 | struct sirf_audio_port *port; |
142 | void __iomem *base; | ||
143 | struct resource *mem_res; | ||
144 | 53 | ||
145 | port = devm_kzalloc(&pdev->dev, | 54 | port = devm_kzalloc(&pdev->dev, |
146 | sizeof(struct sirf_audio_port), GFP_KERNEL); | 55 | sizeof(struct sirf_audio_port), GFP_KERNEL); |
147 | if (!port) | 56 | if (!port) |
148 | return -ENOMEM; | 57 | return -ENOMEM; |
149 | 58 | ||
150 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
151 | if (!mem_res) { | ||
152 | dev_err(&pdev->dev, "no mem resource?\n"); | ||
153 | return -ENODEV; | ||
154 | } | ||
155 | |||
156 | base = devm_ioremap(&pdev->dev, mem_res->start, | ||
157 | resource_size(mem_res)); | ||
158 | if (base == NULL) | ||
159 | return -ENOMEM; | ||
160 | |||
161 | port->regmap = devm_regmap_init_mmio(&pdev->dev, base, | ||
162 | &sirf_audio_port_regmap_config); | ||
163 | if (IS_ERR(port->regmap)) | ||
164 | return PTR_ERR(port->regmap); | ||
165 | |||
166 | ret = devm_snd_soc_register_component(&pdev->dev, | 59 | ret = devm_snd_soc_register_component(&pdev->dev, |
167 | &sirf_audio_port_component, &sirf_audio_port_dai, 1); | 60 | &sirf_audio_port_component, &sirf_audio_port_dai, 1); |
168 | if (ret) | 61 | if (ret) |
diff --git a/sound/soc/sirf/sirf-audio-port.h b/sound/soc/sirf/sirf-audio-port.h deleted file mode 100644 index f32dc54f4499..000000000000 --- a/sound/soc/sirf/sirf-audio-port.h +++ /dev/null | |||
@@ -1,62 +0,0 @@ | |||
1 | /* | ||
2 | * SiRF Audio port controllers define | ||
3 | * | ||
4 | * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. | ||
5 | * | ||
6 | * Licensed under GPLv2 or later. | ||
7 | */ | ||
8 | |||
9 | #ifndef _SIRF_AUDIO_PORT_H | ||
10 | #define _SIRF_AUDIO_PORT_H | ||
11 | |||
12 | #define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F | ||
13 | #define AUDIO_PORT_TX_FIFO_SC_OFFSET 0 | ||
14 | #define AUDIO_PORT_TX_FIFO_LC_OFFSET 10 | ||
15 | #define AUDIO_PORT_TX_FIFO_HC_OFFSET 20 | ||
16 | |||
17 | #define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
18 | << AUDIO_PORT_TX_FIFO_SC_OFFSET) | ||
19 | #define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
20 | << AUDIO_PORT_TX_FIFO_LC_OFFSET) | ||
21 | #define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \ | ||
22 | << AUDIO_PORT_TX_FIFO_HC_OFFSET) | ||
23 | |||
24 | #define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F | ||
25 | #define AUDIO_PORT_RX_FIFO_SC_OFFSET 0 | ||
26 | #define AUDIO_PORT_RX_FIFO_LC_OFFSET 10 | ||
27 | #define AUDIO_PORT_RX_FIFO_HC_OFFSET 20 | ||
28 | |||
29 | #define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
30 | << AUDIO_PORT_RX_FIFO_SC_OFFSET) | ||
31 | #define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
32 | << AUDIO_PORT_RX_FIFO_LC_OFFSET) | ||
33 | #define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \ | ||
34 | << AUDIO_PORT_RX_FIFO_HC_OFFSET) | ||
35 | #define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4) | ||
36 | #define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8) | ||
37 | |||
38 | #define AUDIO_PORT_IC_TXFIFO_OP (0x00FC) | ||
39 | #define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100) | ||
40 | #define AUDIO_PORT_IC_TXFIFO_STS (0x0104) | ||
41 | #define AUDIO_PORT_IC_TXFIFO_INT (0x0108) | ||
42 | #define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C) | ||
43 | |||
44 | #define AUDIO_PORT_IC_RXFIFO_OP (0x0110) | ||
45 | #define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114) | ||
46 | #define AUDIO_PORT_IC_RXFIFO_STS (0x0118) | ||
47 | #define AUDIO_PORT_IC_RXFIFO_INT (0x011C) | ||
48 | #define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120) | ||
49 | |||
50 | #define AUDIO_FIFO_START (1 << 0) | ||
51 | #define AUDIO_FIFO_RESET (1 << 1) | ||
52 | |||
53 | #define AUDIO_FIFO_FULL (1 << 0) | ||
54 | #define AUDIO_FIFO_EMPTY (1 << 1) | ||
55 | #define AUDIO_FIFO_OFLOW (1 << 2) | ||
56 | #define AUDIO_FIFO_UFLOW (1 << 3) | ||
57 | |||
58 | #define IC_TX_ENABLE (0x03) | ||
59 | #define IC_RX_ENABLE_MONO (0x01) | ||
60 | #define IC_RX_ENABLE_STEREO (0x03) | ||
61 | |||
62 | #endif /*__SIRF_AUDIO_PORT_H*/ | ||
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index bfed3e4c45ff..3fa77d5f9b75 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
@@ -162,8 +162,6 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) | |||
162 | i, codec_drv->reg_word_size) == val) | 162 | i, codec_drv->reg_word_size) == val) |
163 | continue; | 163 | continue; |
164 | 164 | ||
165 | WARN_ON(!snd_soc_codec_writable_register(codec, i)); | ||
166 | |||
167 | ret = snd_soc_write(codec, i, val); | 165 | ret = snd_soc_write(codec, i, val); |
168 | if (ret) | 166 | if (ret) |
169 | return ret; | 167 | return ret; |
diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 91083e6a6b38..10f7f1da2aca 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c | |||
@@ -203,7 +203,6 @@ static int soc_compr_free(struct snd_compr_stream *cstream) | |||
203 | 203 | ||
204 | if (platform->driver->compr_ops && platform->driver->compr_ops->free) | 204 | if (platform->driver->compr_ops && platform->driver->compr_ops->free) |
205 | platform->driver->compr_ops->free(cstream); | 205 | platform->driver->compr_ops->free(cstream); |
206 | cpu_dai->runtime = NULL; | ||
207 | 206 | ||
208 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { | 207 | if (cstream->direction == SND_COMPRESS_PLAYBACK) { |
209 | if (snd_soc_runtime_ignore_pmdown_time(rtd)) { | 208 | if (snd_soc_runtime_ignore_pmdown_time(rtd)) { |
@@ -317,8 +316,9 @@ static int soc_compr_trigger_fe(struct snd_compr_stream *cstream, int cmd) | |||
317 | cmd == SND_COMPR_TRIGGER_DRAIN) { | 316 | cmd == SND_COMPR_TRIGGER_DRAIN) { |
318 | 317 | ||
319 | if (platform->driver->compr_ops && | 318 | if (platform->driver->compr_ops && |
320 | platform->driver->compr_ops->trigger) | 319 | platform->driver->compr_ops->trigger) |
321 | return platform->driver->compr_ops->trigger(cstream, cmd); | 320 | return platform->driver->compr_ops->trigger(cstream, |
321 | cmd); | ||
322 | } | 322 | } |
323 | 323 | ||
324 | if (cstream->direction == SND_COMPRESS_PLAYBACK) | 324 | if (cstream->direction == SND_COMPRESS_PLAYBACK) |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 051c006281f5..b87d7d882e6d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -154,22 +154,15 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf, | |||
154 | step = codec->driver->reg_cache_step; | 154 | step = codec->driver->reg_cache_step; |
155 | 155 | ||
156 | for (i = 0; i < codec->driver->reg_cache_size; i += step) { | 156 | for (i = 0; i < codec->driver->reg_cache_size; i += step) { |
157 | if (!snd_soc_codec_readable_register(codec, i)) | 157 | /* only support larger than PAGE_SIZE bytes debugfs |
158 | continue; | 158 | * entries for the default case */ |
159 | if (codec->driver->display_register) { | 159 | if (p >= pos) { |
160 | count += codec->driver->display_register(codec, buf + count, | 160 | if (total + len >= count - 1) |
161 | PAGE_SIZE - count, i); | 161 | break; |
162 | } else { | 162 | format_register_str(codec, i, buf + total, len); |
163 | /* only support larger than PAGE_SIZE bytes debugfs | 163 | total += len; |
164 | * entries for the default case */ | ||
165 | if (p >= pos) { | ||
166 | if (total + len >= count - 1) | ||
167 | break; | ||
168 | format_register_str(codec, i, buf + total, len); | ||
169 | total += len; | ||
170 | } | ||
171 | p += len; | ||
172 | } | 164 | } |
165 | p += len; | ||
173 | } | 166 | } |
174 | 167 | ||
175 | total = min(total, count - 1); | 168 | total = min(total, count - 1); |
@@ -663,8 +656,8 @@ int snd_soc_suspend(struct device *dev) | |||
663 | codec->driver->suspend(codec); | 656 | codec->driver->suspend(codec); |
664 | codec->suspended = 1; | 657 | codec->suspended = 1; |
665 | codec->cache_sync = 1; | 658 | codec->cache_sync = 1; |
666 | if (codec->using_regmap) | 659 | if (codec->component.regmap) |
667 | regcache_mark_dirty(codec->control_data); | 660 | regcache_mark_dirty(codec->component.regmap); |
668 | /* deactivate pins to sleep state */ | 661 | /* deactivate pins to sleep state */ |
669 | pinctrl_pm_select_sleep_state(codec->dev); | 662 | pinctrl_pm_select_sleep_state(codec->dev); |
670 | break; | 663 | break; |
@@ -854,14 +847,47 @@ EXPORT_SYMBOL_GPL(snd_soc_resume); | |||
854 | static const struct snd_soc_dai_ops null_dai_ops = { | 847 | static const struct snd_soc_dai_ops null_dai_ops = { |
855 | }; | 848 | }; |
856 | 849 | ||
850 | static struct snd_soc_codec *soc_find_codec(const struct device_node *codec_of_node, | ||
851 | const char *codec_name) | ||
852 | { | ||
853 | struct snd_soc_codec *codec; | ||
854 | |||
855 | list_for_each_entry(codec, &codec_list, list) { | ||
856 | if (codec_of_node) { | ||
857 | if (codec->dev->of_node != codec_of_node) | ||
858 | continue; | ||
859 | } else { | ||
860 | if (strcmp(codec->name, codec_name)) | ||
861 | continue; | ||
862 | } | ||
863 | |||
864 | return codec; | ||
865 | } | ||
866 | |||
867 | return NULL; | ||
868 | } | ||
869 | |||
870 | static struct snd_soc_dai *soc_find_codec_dai(struct snd_soc_codec *codec, | ||
871 | const char *codec_dai_name) | ||
872 | { | ||
873 | struct snd_soc_dai *codec_dai; | ||
874 | |||
875 | list_for_each_entry(codec_dai, &codec->component.dai_list, list) { | ||
876 | if (!strcmp(codec_dai->name, codec_dai_name)) { | ||
877 | return codec_dai; | ||
878 | } | ||
879 | } | ||
880 | |||
881 | return NULL; | ||
882 | } | ||
883 | |||
857 | static int soc_bind_dai_link(struct snd_soc_card *card, int num) | 884 | static int soc_bind_dai_link(struct snd_soc_card *card, int num) |
858 | { | 885 | { |
859 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; | 886 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; |
860 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; | 887 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; |
861 | struct snd_soc_component *component; | 888 | struct snd_soc_component *component; |
862 | struct snd_soc_codec *codec; | ||
863 | struct snd_soc_platform *platform; | 889 | struct snd_soc_platform *platform; |
864 | struct snd_soc_dai *codec_dai, *cpu_dai; | 890 | struct snd_soc_dai *cpu_dai; |
865 | const char *platform_name; | 891 | const char *platform_name; |
866 | 892 | ||
867 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); | 893 | dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num); |
@@ -889,42 +915,24 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
889 | return -EPROBE_DEFER; | 915 | return -EPROBE_DEFER; |
890 | } | 916 | } |
891 | 917 | ||
892 | /* Find CODEC from registered CODECs */ | 918 | /* Find CODEC from registered list */ |
893 | list_for_each_entry(codec, &codec_list, list) { | 919 | rtd->codec = soc_find_codec(dai_link->codec_of_node, |
894 | if (dai_link->codec_of_node) { | 920 | dai_link->codec_name); |
895 | if (codec->dev->of_node != dai_link->codec_of_node) | ||
896 | continue; | ||
897 | } else { | ||
898 | if (strcmp(codec->name, dai_link->codec_name)) | ||
899 | continue; | ||
900 | } | ||
901 | |||
902 | rtd->codec = codec; | ||
903 | |||
904 | /* | ||
905 | * CODEC found, so find CODEC DAI from registered DAIs from | ||
906 | * this CODEC | ||
907 | */ | ||
908 | list_for_each_entry(codec_dai, &codec->component.dai_list, list) { | ||
909 | if (!strcmp(codec_dai->name, dai_link->codec_dai_name)) { | ||
910 | rtd->codec_dai = codec_dai; | ||
911 | break; | ||
912 | } | ||
913 | } | ||
914 | |||
915 | if (!rtd->codec_dai) { | ||
916 | dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", | ||
917 | dai_link->codec_dai_name); | ||
918 | return -EPROBE_DEFER; | ||
919 | } | ||
920 | } | ||
921 | |||
922 | if (!rtd->codec) { | 921 | if (!rtd->codec) { |
923 | dev_err(card->dev, "ASoC: CODEC %s not registered\n", | 922 | dev_err(card->dev, "ASoC: CODEC %s not registered\n", |
924 | dai_link->codec_name); | 923 | dai_link->codec_name); |
925 | return -EPROBE_DEFER; | 924 | return -EPROBE_DEFER; |
926 | } | 925 | } |
927 | 926 | ||
927 | /* Find CODEC DAI from registered list */ | ||
928 | rtd->codec_dai = soc_find_codec_dai(rtd->codec, | ||
929 | dai_link->codec_dai_name); | ||
930 | if (!rtd->codec_dai) { | ||
931 | dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n", | ||
932 | dai_link->codec_dai_name); | ||
933 | return -EPROBE_DEFER; | ||
934 | } | ||
935 | |||
928 | /* if there's no platform we match on the empty platform */ | 936 | /* if there's no platform we match on the empty platform */ |
929 | platform_name = dai_link->platform_name; | 937 | platform_name = dai_link->platform_name; |
930 | if (!platform_name && !dai_link->platform_of_node) | 938 | if (!platform_name && !dai_link->platform_of_node) |
@@ -995,6 +1003,23 @@ static void soc_remove_codec(struct snd_soc_codec *codec) | |||
995 | module_put(codec->dev->driver->owner); | 1003 | module_put(codec->dev->driver->owner); |
996 | } | 1004 | } |
997 | 1005 | ||
1006 | static void soc_remove_codec_dai(struct snd_soc_dai *codec_dai, int order) | ||
1007 | { | ||
1008 | int err; | ||
1009 | |||
1010 | if (codec_dai && codec_dai->probed && | ||
1011 | codec_dai->driver->remove_order == order) { | ||
1012 | if (codec_dai->driver->remove) { | ||
1013 | err = codec_dai->driver->remove(codec_dai); | ||
1014 | if (err < 0) | ||
1015 | dev_err(codec_dai->dev, | ||
1016 | "ASoC: failed to remove %s: %d\n", | ||
1017 | codec_dai->name, err); | ||
1018 | } | ||
1019 | codec_dai->probed = 0; | ||
1020 | } | ||
1021 | } | ||
1022 | |||
998 | static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | 1023 | static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) |
999 | { | 1024 | { |
1000 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; | 1025 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; |
@@ -1010,18 +1035,7 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
1010 | } | 1035 | } |
1011 | 1036 | ||
1012 | /* remove the CODEC DAI */ | 1037 | /* remove the CODEC DAI */ |
1013 | if (codec_dai && codec_dai->probed && | 1038 | soc_remove_codec_dai(codec_dai, order); |
1014 | codec_dai->driver->remove_order == order) { | ||
1015 | if (codec_dai->driver->remove) { | ||
1016 | err = codec_dai->driver->remove(codec_dai); | ||
1017 | if (err < 0) | ||
1018 | dev_err(codec_dai->dev, | ||
1019 | "ASoC: failed to remove %s: %d\n", | ||
1020 | codec_dai->name, err); | ||
1021 | } | ||
1022 | codec_dai->probed = 0; | ||
1023 | list_del(&codec_dai->card_list); | ||
1024 | } | ||
1025 | 1039 | ||
1026 | /* remove the cpu_dai */ | 1040 | /* remove the cpu_dai */ |
1027 | if (cpu_dai && cpu_dai->probed && | 1041 | if (cpu_dai && cpu_dai->probed && |
@@ -1034,7 +1048,6 @@ static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order) | |||
1034 | cpu_dai->name, err); | 1048 | cpu_dai->name, err); |
1035 | } | 1049 | } |
1036 | cpu_dai->probed = 0; | 1050 | cpu_dai->probed = 0; |
1037 | list_del(&cpu_dai->card_list); | ||
1038 | 1051 | ||
1039 | if (!cpu_dai->codec) { | 1052 | if (!cpu_dai->codec) { |
1040 | snd_soc_dapm_free(&cpu_dai->dapm); | 1053 | snd_soc_dapm_free(&cpu_dai->dapm); |
@@ -1104,10 +1117,12 @@ static void soc_set_name_prefix(struct snd_soc_card *card, | |||
1104 | 1117 | ||
1105 | for (i = 0; i < card->num_configs; i++) { | 1118 | for (i = 0; i < card->num_configs; i++) { |
1106 | struct snd_soc_codec_conf *map = &card->codec_conf[i]; | 1119 | struct snd_soc_codec_conf *map = &card->codec_conf[i]; |
1107 | if (map->dev_name && !strcmp(codec->name, map->dev_name)) { | 1120 | if (map->of_node && codec->dev->of_node != map->of_node) |
1108 | codec->name_prefix = map->name_prefix; | 1121 | continue; |
1109 | break; | 1122 | if (map->dev_name && strcmp(codec->name, map->dev_name)) |
1110 | } | 1123 | continue; |
1124 | codec->name_prefix = map->name_prefix; | ||
1125 | break; | ||
1111 | } | 1126 | } |
1112 | } | 1127 | } |
1113 | 1128 | ||
@@ -1127,26 +1142,31 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1127 | 1142 | ||
1128 | soc_init_codec_debugfs(codec); | 1143 | soc_init_codec_debugfs(codec); |
1129 | 1144 | ||
1130 | if (driver->dapm_widgets) | 1145 | if (driver->dapm_widgets) { |
1131 | snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, | 1146 | ret = snd_soc_dapm_new_controls(&codec->dapm, |
1132 | driver->num_dapm_widgets); | 1147 | driver->dapm_widgets, |
1148 | driver->num_dapm_widgets); | ||
1133 | 1149 | ||
1134 | /* Create DAPM widgets for each DAI stream */ | 1150 | if (ret != 0) { |
1135 | list_for_each_entry(dai, &codec->component.dai_list, list) | 1151 | dev_err(codec->dev, |
1136 | snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); | 1152 | "Failed to create new controls %d\n", ret); |
1153 | goto err_probe; | ||
1154 | } | ||
1155 | } | ||
1137 | 1156 | ||
1138 | codec->dapm.idle_bias_off = driver->idle_bias_off; | 1157 | /* Create DAPM widgets for each DAI stream */ |
1158 | list_for_each_entry(dai, &codec->component.dai_list, list) { | ||
1159 | ret = snd_soc_dapm_new_dai_widgets(&codec->dapm, dai); | ||
1139 | 1160 | ||
1140 | if (!codec->write && dev_get_regmap(codec->dev, NULL)) { | 1161 | if (ret != 0) { |
1141 | /* Set the default I/O up try regmap */ | ||
1142 | ret = snd_soc_codec_set_cache_io(codec, NULL); | ||
1143 | if (ret < 0) { | ||
1144 | dev_err(codec->dev, | 1162 | dev_err(codec->dev, |
1145 | "Failed to set cache I/O: %d\n", ret); | 1163 | "Failed to create DAI widgets %d\n", ret); |
1146 | goto err_probe; | 1164 | goto err_probe; |
1147 | } | 1165 | } |
1148 | } | 1166 | } |
1149 | 1167 | ||
1168 | codec->dapm.idle_bias_off = driver->idle_bias_off; | ||
1169 | |||
1150 | if (driver->probe) { | 1170 | if (driver->probe) { |
1151 | ret = driver->probe(codec); | 1171 | ret = driver->probe(codec); |
1152 | if (ret < 0) { | 1172 | if (ret < 0) { |
@@ -1246,6 +1266,50 @@ static void rtd_release(struct device *dev) | |||
1246 | kfree(dev); | 1266 | kfree(dev); |
1247 | } | 1267 | } |
1248 | 1268 | ||
1269 | static int soc_aux_dev_init(struct snd_soc_card *card, | ||
1270 | struct snd_soc_codec *codec, | ||
1271 | int num) | ||
1272 | { | ||
1273 | struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; | ||
1274 | struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; | ||
1275 | int ret; | ||
1276 | |||
1277 | rtd->card = card; | ||
1278 | |||
1279 | /* do machine specific initialization */ | ||
1280 | if (aux_dev->init) { | ||
1281 | ret = aux_dev->init(&codec->dapm); | ||
1282 | if (ret < 0) | ||
1283 | return ret; | ||
1284 | } | ||
1285 | |||
1286 | rtd->codec = codec; | ||
1287 | |||
1288 | return 0; | ||
1289 | } | ||
1290 | |||
1291 | static int soc_dai_link_init(struct snd_soc_card *card, | ||
1292 | struct snd_soc_codec *codec, | ||
1293 | int num) | ||
1294 | { | ||
1295 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; | ||
1296 | struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; | ||
1297 | int ret; | ||
1298 | |||
1299 | rtd->card = card; | ||
1300 | |||
1301 | /* do machine specific initialization */ | ||
1302 | if (dai_link->init) { | ||
1303 | ret = dai_link->init(rtd); | ||
1304 | if (ret < 0) | ||
1305 | return ret; | ||
1306 | } | ||
1307 | |||
1308 | rtd->codec = codec; | ||
1309 | |||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1249 | static int soc_post_component_init(struct snd_soc_card *card, | 1313 | static int soc_post_component_init(struct snd_soc_card *card, |
1250 | struct snd_soc_codec *codec, | 1314 | struct snd_soc_codec *codec, |
1251 | int num, int dailess) | 1315 | int num, int dailess) |
@@ -1260,26 +1324,20 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
1260 | dai_link = &card->dai_link[num]; | 1324 | dai_link = &card->dai_link[num]; |
1261 | rtd = &card->rtd[num]; | 1325 | rtd = &card->rtd[num]; |
1262 | name = dai_link->name; | 1326 | name = dai_link->name; |
1327 | ret = soc_dai_link_init(card, codec, num); | ||
1263 | } else { | 1328 | } else { |
1264 | aux_dev = &card->aux_dev[num]; | 1329 | aux_dev = &card->aux_dev[num]; |
1265 | rtd = &card->rtd_aux[num]; | 1330 | rtd = &card->rtd_aux[num]; |
1266 | name = aux_dev->name; | 1331 | name = aux_dev->name; |
1332 | ret = soc_aux_dev_init(card, codec, num); | ||
1267 | } | 1333 | } |
1268 | rtd->card = card; | ||
1269 | 1334 | ||
1270 | /* do machine specific initialization */ | ||
1271 | if (!dailess && dai_link->init) | ||
1272 | ret = dai_link->init(rtd); | ||
1273 | else if (dailess && aux_dev->init) | ||
1274 | ret = aux_dev->init(&codec->dapm); | ||
1275 | if (ret < 0) { | 1335 | if (ret < 0) { |
1276 | dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); | 1336 | dev_err(card->dev, "ASoC: failed to init %s: %d\n", name, ret); |
1277 | return ret; | 1337 | return ret; |
1278 | } | 1338 | } |
1279 | 1339 | ||
1280 | /* register the rtd device */ | 1340 | /* register the rtd device */ |
1281 | rtd->codec = codec; | ||
1282 | |||
1283 | rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); | 1341 | rtd->dev = kzalloc(sizeof(struct device), GFP_KERNEL); |
1284 | if (!rtd->dev) | 1342 | if (!rtd->dev) |
1285 | return -ENOMEM; | 1343 | return -ENOMEM; |
@@ -1366,6 +1424,66 @@ static int soc_probe_link_components(struct snd_soc_card *card, int num, | |||
1366 | return 0; | 1424 | return 0; |
1367 | } | 1425 | } |
1368 | 1426 | ||
1427 | static int soc_probe_codec_dai(struct snd_soc_card *card, | ||
1428 | struct snd_soc_dai *codec_dai, | ||
1429 | int order) | ||
1430 | { | ||
1431 | int ret; | ||
1432 | |||
1433 | if (!codec_dai->probed && codec_dai->driver->probe_order == order) { | ||
1434 | if (codec_dai->driver->probe) { | ||
1435 | ret = codec_dai->driver->probe(codec_dai); | ||
1436 | if (ret < 0) { | ||
1437 | dev_err(codec_dai->dev, | ||
1438 | "ASoC: failed to probe CODEC DAI %s: %d\n", | ||
1439 | codec_dai->name, ret); | ||
1440 | return ret; | ||
1441 | } | ||
1442 | } | ||
1443 | |||
1444 | /* mark codec_dai as probed and add to card dai list */ | ||
1445 | codec_dai->probed = 1; | ||
1446 | } | ||
1447 | |||
1448 | return 0; | ||
1449 | } | ||
1450 | |||
1451 | static int soc_link_dai_widgets(struct snd_soc_card *card, | ||
1452 | struct snd_soc_dai_link *dai_link, | ||
1453 | struct snd_soc_dai *cpu_dai, | ||
1454 | struct snd_soc_dai *codec_dai) | ||
1455 | { | ||
1456 | struct snd_soc_dapm_widget *play_w, *capture_w; | ||
1457 | int ret; | ||
1458 | |||
1459 | /* link the DAI widgets */ | ||
1460 | play_w = codec_dai->playback_widget; | ||
1461 | capture_w = cpu_dai->capture_widget; | ||
1462 | if (play_w && capture_w) { | ||
1463 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | ||
1464 | capture_w, play_w); | ||
1465 | if (ret != 0) { | ||
1466 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", | ||
1467 | play_w->name, capture_w->name, ret); | ||
1468 | return ret; | ||
1469 | } | ||
1470 | } | ||
1471 | |||
1472 | play_w = cpu_dai->playback_widget; | ||
1473 | capture_w = codec_dai->capture_widget; | ||
1474 | if (play_w && capture_w) { | ||
1475 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | ||
1476 | capture_w, play_w); | ||
1477 | if (ret != 0) { | ||
1478 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", | ||
1479 | play_w->name, capture_w->name, ret); | ||
1480 | return ret; | ||
1481 | } | ||
1482 | } | ||
1483 | |||
1484 | return 0; | ||
1485 | } | ||
1486 | |||
1369 | static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | 1487 | static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) |
1370 | { | 1488 | { |
1371 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; | 1489 | struct snd_soc_dai_link *dai_link = &card->dai_link[num]; |
@@ -1374,7 +1492,6 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1374 | struct snd_soc_platform *platform = rtd->platform; | 1492 | struct snd_soc_platform *platform = rtd->platform; |
1375 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 1493 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
1376 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 1494 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
1377 | struct snd_soc_dapm_widget *play_w, *capture_w; | ||
1378 | int ret; | 1495 | int ret; |
1379 | 1496 | ||
1380 | dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", | 1497 | dev_dbg(card->dev, "ASoC: probe %s dai link %d late %d\n", |
@@ -1410,26 +1527,12 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1410 | } | 1527 | } |
1411 | } | 1528 | } |
1412 | cpu_dai->probed = 1; | 1529 | cpu_dai->probed = 1; |
1413 | /* mark cpu_dai as probed and add to card dai list */ | ||
1414 | list_add(&cpu_dai->card_list, &card->dai_dev_list); | ||
1415 | } | 1530 | } |
1416 | 1531 | ||
1417 | /* probe the CODEC DAI */ | 1532 | /* probe the CODEC DAI */ |
1418 | if (!codec_dai->probed && codec_dai->driver->probe_order == order) { | 1533 | ret = soc_probe_codec_dai(card, codec_dai, order); |
1419 | if (codec_dai->driver->probe) { | 1534 | if (ret) |
1420 | ret = codec_dai->driver->probe(codec_dai); | 1535 | return ret; |
1421 | if (ret < 0) { | ||
1422 | dev_err(codec_dai->dev, | ||
1423 | "ASoC: failed to probe CODEC DAI %s: %d\n", | ||
1424 | codec_dai->name, ret); | ||
1425 | return ret; | ||
1426 | } | ||
1427 | } | ||
1428 | |||
1429 | /* mark codec_dai as probed and add to card dai list */ | ||
1430 | codec_dai->probed = 1; | ||
1431 | list_add(&codec_dai->card_list, &card->dai_dev_list); | ||
1432 | } | ||
1433 | 1536 | ||
1434 | /* complete DAI probe during last probe */ | 1537 | /* complete DAI probe during last probe */ |
1435 | if (order != SND_SOC_COMP_ORDER_LAST) | 1538 | if (order != SND_SOC_COMP_ORDER_LAST) |
@@ -1467,29 +1570,10 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1467 | codec2codec_close_delayed_work); | 1570 | codec2codec_close_delayed_work); |
1468 | 1571 | ||
1469 | /* link the DAI widgets */ | 1572 | /* link the DAI widgets */ |
1470 | play_w = codec_dai->playback_widget; | 1573 | ret = soc_link_dai_widgets(card, dai_link, |
1471 | capture_w = cpu_dai->capture_widget; | 1574 | cpu_dai, codec_dai); |
1472 | if (play_w && capture_w) { | 1575 | if (ret) |
1473 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | 1576 | return ret; |
1474 | capture_w, play_w); | ||
1475 | if (ret != 0) { | ||
1476 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", | ||
1477 | play_w->name, capture_w->name, ret); | ||
1478 | return ret; | ||
1479 | } | ||
1480 | } | ||
1481 | |||
1482 | play_w = cpu_dai->playback_widget; | ||
1483 | capture_w = codec_dai->capture_widget; | ||
1484 | if (play_w && capture_w) { | ||
1485 | ret = snd_soc_dapm_new_pcm(card, dai_link->params, | ||
1486 | capture_w, play_w); | ||
1487 | if (ret != 0) { | ||
1488 | dev_err(card->dev, "ASoC: Can't link %s to %s: %d\n", | ||
1489 | play_w->name, capture_w->name, ret); | ||
1490 | return ret; | ||
1491 | } | ||
1492 | } | ||
1493 | } | 1577 | } |
1494 | } | 1578 | } |
1495 | 1579 | ||
@@ -1501,14 +1585,15 @@ static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) | |||
1501 | } | 1585 | } |
1502 | 1586 | ||
1503 | #ifdef CONFIG_SND_SOC_AC97_BUS | 1587 | #ifdef CONFIG_SND_SOC_AC97_BUS |
1504 | static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) | 1588 | static int soc_register_ac97_codec(struct snd_soc_codec *codec, |
1589 | struct snd_soc_dai *codec_dai) | ||
1505 | { | 1590 | { |
1506 | int ret; | 1591 | int ret; |
1507 | 1592 | ||
1508 | /* Only instantiate AC97 if not already done by the adaptor | 1593 | /* Only instantiate AC97 if not already done by the adaptor |
1509 | * for the generic AC97 subsystem. | 1594 | * for the generic AC97 subsystem. |
1510 | */ | 1595 | */ |
1511 | if (rtd->codec_dai->driver->ac97_control && !rtd->codec->ac97_registered) { | 1596 | if (codec_dai->driver->ac97_control && !codec->ac97_registered) { |
1512 | /* | 1597 | /* |
1513 | * It is possible that the AC97 device is already registered to | 1598 | * It is possible that the AC97 device is already registered to |
1514 | * the device subsystem. This happens when the device is created | 1599 | * the device subsystem. This happens when the device is created |
@@ -1517,76 +1602,101 @@ static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) | |||
1517 | * | 1602 | * |
1518 | * In those cases we don't try to register the device again. | 1603 | * In those cases we don't try to register the device again. |
1519 | */ | 1604 | */ |
1520 | if (!rtd->codec->ac97_created) | 1605 | if (!codec->ac97_created) |
1521 | return 0; | 1606 | return 0; |
1522 | 1607 | ||
1523 | ret = soc_ac97_dev_register(rtd->codec); | 1608 | ret = soc_ac97_dev_register(codec); |
1524 | if (ret < 0) { | 1609 | if (ret < 0) { |
1525 | dev_err(rtd->codec->dev, | 1610 | dev_err(codec->dev, |
1526 | "ASoC: AC97 device register failed: %d\n", ret); | 1611 | "ASoC: AC97 device register failed: %d\n", ret); |
1527 | return ret; | 1612 | return ret; |
1528 | } | 1613 | } |
1529 | 1614 | ||
1530 | rtd->codec->ac97_registered = 1; | 1615 | codec->ac97_registered = 1; |
1531 | } | 1616 | } |
1532 | return 0; | 1617 | return 0; |
1533 | } | 1618 | } |
1534 | 1619 | ||
1535 | static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec) | 1620 | static int soc_register_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) |
1621 | { | ||
1622 | return soc_register_ac97_codec(rtd->codec, rtd->codec_dai); | ||
1623 | } | ||
1624 | |||
1625 | static void soc_unregister_ac97_codec(struct snd_soc_codec *codec) | ||
1536 | { | 1626 | { |
1537 | if (codec->ac97_registered) { | 1627 | if (codec->ac97_registered) { |
1538 | soc_ac97_dev_unregister(codec); | 1628 | soc_ac97_dev_unregister(codec); |
1539 | codec->ac97_registered = 0; | 1629 | codec->ac97_registered = 0; |
1540 | } | 1630 | } |
1541 | } | 1631 | } |
1632 | |||
1633 | static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd) | ||
1634 | { | ||
1635 | soc_unregister_ac97_codec(rtd->codec); | ||
1636 | } | ||
1542 | #endif | 1637 | #endif |
1543 | 1638 | ||
1544 | static int soc_check_aux_dev(struct snd_soc_card *card, int num) | 1639 | static struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card, |
1640 | int num) | ||
1545 | { | 1641 | { |
1546 | struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; | 1642 | struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; |
1547 | struct snd_soc_codec *codec; | 1643 | struct snd_soc_codec *codec; |
1548 | 1644 | ||
1549 | /* find CODEC from registered CODECs*/ | 1645 | /* find CODEC from registered CODECs */ |
1550 | list_for_each_entry(codec, &codec_list, list) { | 1646 | list_for_each_entry(codec, &codec_list, list) { |
1551 | if (!strcmp(codec->name, aux_dev->codec_name)) | 1647 | if (aux_dev->codec_of_node && |
1552 | return 0; | 1648 | (codec->dev->of_node != aux_dev->codec_of_node)) |
1649 | continue; | ||
1650 | if (aux_dev->codec_name && strcmp(codec->name, aux_dev->codec_name)) | ||
1651 | continue; | ||
1652 | return codec; | ||
1553 | } | 1653 | } |
1554 | 1654 | ||
1555 | dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name); | 1655 | return NULL; |
1656 | } | ||
1556 | 1657 | ||
1658 | static int soc_check_aux_dev(struct snd_soc_card *card, int num) | ||
1659 | { | ||
1660 | struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; | ||
1661 | const char *codecname = aux_dev->codec_name; | ||
1662 | struct snd_soc_codec *codec = soc_find_matching_codec(card, num); | ||
1663 | |||
1664 | if (codec) | ||
1665 | return 0; | ||
1666 | if (aux_dev->codec_of_node) | ||
1667 | codecname = of_node_full_name(aux_dev->codec_of_node); | ||
1668 | |||
1669 | dev_err(card->dev, "ASoC: %s not registered\n", codecname); | ||
1557 | return -EPROBE_DEFER; | 1670 | return -EPROBE_DEFER; |
1558 | } | 1671 | } |
1559 | 1672 | ||
1560 | static int soc_probe_aux_dev(struct snd_soc_card *card, int num) | 1673 | static int soc_probe_aux_dev(struct snd_soc_card *card, int num) |
1561 | { | 1674 | { |
1562 | struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; | 1675 | struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; |
1563 | struct snd_soc_codec *codec; | 1676 | const char *codecname = aux_dev->codec_name; |
1564 | int ret = -ENODEV; | 1677 | int ret = -ENODEV; |
1678 | struct snd_soc_codec *codec = soc_find_matching_codec(card, num); | ||
1565 | 1679 | ||
1566 | /* find CODEC from registered CODECs*/ | 1680 | if (!codec) { |
1567 | list_for_each_entry(codec, &codec_list, list) { | 1681 | if (aux_dev->codec_of_node) |
1568 | if (!strcmp(codec->name, aux_dev->codec_name)) { | 1682 | codecname = of_node_full_name(aux_dev->codec_of_node); |
1569 | if (codec->probed) { | 1683 | |
1570 | dev_err(codec->dev, | 1684 | /* codec not found */ |
1571 | "ASoC: codec already probed"); | 1685 | dev_err(card->dev, "ASoC: codec %s not found", codecname); |
1572 | ret = -EBUSY; | 1686 | return -EPROBE_DEFER; |
1573 | goto out; | 1687 | } |
1574 | } | 1688 | |
1575 | goto found; | 1689 | if (codec->probed) { |
1576 | } | 1690 | dev_err(codec->dev, "ASoC: codec already probed"); |
1691 | return -EBUSY; | ||
1577 | } | 1692 | } |
1578 | /* codec not found */ | ||
1579 | dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name); | ||
1580 | return -EPROBE_DEFER; | ||
1581 | 1693 | ||
1582 | found: | ||
1583 | ret = soc_probe_codec(card, codec); | 1694 | ret = soc_probe_codec(card, codec); |
1584 | if (ret < 0) | 1695 | if (ret < 0) |
1585 | return ret; | 1696 | return ret; |
1586 | 1697 | ||
1587 | ret = soc_post_component_init(card, codec, num, 1); | 1698 | ret = soc_post_component_init(card, codec, num, 1); |
1588 | 1699 | ||
1589 | out: | ||
1590 | return ret; | 1700 | return ret; |
1591 | } | 1701 | } |
1592 | 1702 | ||
@@ -1837,7 +1947,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1837 | dev_err(card->dev, | 1947 | dev_err(card->dev, |
1838 | "ASoC: failed to register AC97: %d\n", ret); | 1948 | "ASoC: failed to register AC97: %d\n", ret); |
1839 | while (--i >= 0) | 1949 | while (--i >= 0) |
1840 | soc_unregister_ac97_dai_link(card->rtd[i].codec); | 1950 | soc_unregister_ac97_dai_link(&card->rtd[i]); |
1841 | goto probe_aux_dev_err; | 1951 | goto probe_aux_dev_err; |
1842 | } | 1952 | } |
1843 | } | 1953 | } |
@@ -1980,92 +2090,6 @@ static struct platform_driver soc_driver = { | |||
1980 | }; | 2090 | }; |
1981 | 2091 | ||
1982 | /** | 2092 | /** |
1983 | * snd_soc_codec_volatile_register: Report if a register is volatile. | ||
1984 | * | ||
1985 | * @codec: CODEC to query. | ||
1986 | * @reg: Register to query. | ||
1987 | * | ||
1988 | * Boolean function indiciating if a CODEC register is volatile. | ||
1989 | */ | ||
1990 | int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, | ||
1991 | unsigned int reg) | ||
1992 | { | ||
1993 | if (codec->volatile_register) | ||
1994 | return codec->volatile_register(codec, reg); | ||
1995 | else | ||
1996 | return 0; | ||
1997 | } | ||
1998 | EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); | ||
1999 | |||
2000 | /** | ||
2001 | * snd_soc_codec_readable_register: Report if a register is readable. | ||
2002 | * | ||
2003 | * @codec: CODEC to query. | ||
2004 | * @reg: Register to query. | ||
2005 | * | ||
2006 | * Boolean function indicating if a CODEC register is readable. | ||
2007 | */ | ||
2008 | int snd_soc_codec_readable_register(struct snd_soc_codec *codec, | ||
2009 | unsigned int reg) | ||
2010 | { | ||
2011 | if (codec->readable_register) | ||
2012 | return codec->readable_register(codec, reg); | ||
2013 | else | ||
2014 | return 1; | ||
2015 | } | ||
2016 | EXPORT_SYMBOL_GPL(snd_soc_codec_readable_register); | ||
2017 | |||
2018 | /** | ||
2019 | * snd_soc_codec_writable_register: Report if a register is writable. | ||
2020 | * | ||
2021 | * @codec: CODEC to query. | ||
2022 | * @reg: Register to query. | ||
2023 | * | ||
2024 | * Boolean function indicating if a CODEC register is writable. | ||
2025 | */ | ||
2026 | int snd_soc_codec_writable_register(struct snd_soc_codec *codec, | ||
2027 | unsigned int reg) | ||
2028 | { | ||
2029 | if (codec->writable_register) | ||
2030 | return codec->writable_register(codec, reg); | ||
2031 | else | ||
2032 | return 1; | ||
2033 | } | ||
2034 | EXPORT_SYMBOL_GPL(snd_soc_codec_writable_register); | ||
2035 | |||
2036 | int snd_soc_platform_read(struct snd_soc_platform *platform, | ||
2037 | unsigned int reg) | ||
2038 | { | ||
2039 | unsigned int ret; | ||
2040 | |||
2041 | if (!platform->driver->read) { | ||
2042 | dev_err(platform->dev, "ASoC: platform has no read back\n"); | ||
2043 | return -1; | ||
2044 | } | ||
2045 | |||
2046 | ret = platform->driver->read(platform, reg); | ||
2047 | dev_dbg(platform->dev, "read %x => %x\n", reg, ret); | ||
2048 | trace_snd_soc_preg_read(platform, reg, ret); | ||
2049 | |||
2050 | return ret; | ||
2051 | } | ||
2052 | EXPORT_SYMBOL_GPL(snd_soc_platform_read); | ||
2053 | |||
2054 | int snd_soc_platform_write(struct snd_soc_platform *platform, | ||
2055 | unsigned int reg, unsigned int val) | ||
2056 | { | ||
2057 | if (!platform->driver->write) { | ||
2058 | dev_err(platform->dev, "ASoC: platform has no write back\n"); | ||
2059 | return -1; | ||
2060 | } | ||
2061 | |||
2062 | dev_dbg(platform->dev, "write %x = %x\n", reg, val); | ||
2063 | trace_snd_soc_preg_write(platform, reg, val); | ||
2064 | return platform->driver->write(platform, reg, val); | ||
2065 | } | ||
2066 | EXPORT_SYMBOL_GPL(snd_soc_platform_write); | ||
2067 | |||
2068 | /** | ||
2069 | * snd_soc_new_ac97_codec - initailise AC97 device | 2093 | * snd_soc_new_ac97_codec - initailise AC97 device |
2070 | * @codec: audio codec | 2094 | * @codec: audio codec |
2071 | * @ops: AC97 bus operations | 2095 | * @ops: AC97 bus operations |
@@ -2153,28 +2177,28 @@ static int snd_soc_ac97_parse_pinctl(struct device *dev, | |||
2153 | p = devm_pinctrl_get(dev); | 2177 | p = devm_pinctrl_get(dev); |
2154 | if (IS_ERR(p)) { | 2178 | if (IS_ERR(p)) { |
2155 | dev_err(dev, "Failed to get pinctrl\n"); | 2179 | dev_err(dev, "Failed to get pinctrl\n"); |
2156 | return PTR_RET(p); | 2180 | return PTR_ERR(p); |
2157 | } | 2181 | } |
2158 | cfg->pctl = p; | 2182 | cfg->pctl = p; |
2159 | 2183 | ||
2160 | state = pinctrl_lookup_state(p, "ac97-reset"); | 2184 | state = pinctrl_lookup_state(p, "ac97-reset"); |
2161 | if (IS_ERR(state)) { | 2185 | if (IS_ERR(state)) { |
2162 | dev_err(dev, "Can't find pinctrl state ac97-reset\n"); | 2186 | dev_err(dev, "Can't find pinctrl state ac97-reset\n"); |
2163 | return PTR_RET(state); | 2187 | return PTR_ERR(state); |
2164 | } | 2188 | } |
2165 | cfg->pstate_reset = state; | 2189 | cfg->pstate_reset = state; |
2166 | 2190 | ||
2167 | state = pinctrl_lookup_state(p, "ac97-warm-reset"); | 2191 | state = pinctrl_lookup_state(p, "ac97-warm-reset"); |
2168 | if (IS_ERR(state)) { | 2192 | if (IS_ERR(state)) { |
2169 | dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n"); | 2193 | dev_err(dev, "Can't find pinctrl state ac97-warm-reset\n"); |
2170 | return PTR_RET(state); | 2194 | return PTR_ERR(state); |
2171 | } | 2195 | } |
2172 | cfg->pstate_warm_reset = state; | 2196 | cfg->pstate_warm_reset = state; |
2173 | 2197 | ||
2174 | state = pinctrl_lookup_state(p, "ac97-running"); | 2198 | state = pinctrl_lookup_state(p, "ac97-running"); |
2175 | if (IS_ERR(state)) { | 2199 | if (IS_ERR(state)) { |
2176 | dev_err(dev, "Can't find pinctrl state ac97-running\n"); | 2200 | dev_err(dev, "Can't find pinctrl state ac97-running\n"); |
2177 | return PTR_RET(state); | 2201 | return PTR_ERR(state); |
2178 | } | 2202 | } |
2179 | cfg->pstate_run = state; | 2203 | cfg->pstate_run = state; |
2180 | 2204 | ||
@@ -2273,7 +2297,7 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) | |||
2273 | { | 2297 | { |
2274 | mutex_lock(&codec->mutex); | 2298 | mutex_lock(&codec->mutex); |
2275 | #ifdef CONFIG_SND_SOC_AC97_BUS | 2299 | #ifdef CONFIG_SND_SOC_AC97_BUS |
2276 | soc_unregister_ac97_dai_link(codec); | 2300 | soc_unregister_ac97_codec(codec); |
2277 | #endif | 2301 | #endif |
2278 | kfree(codec->ac97->bus); | 2302 | kfree(codec->ac97->bus); |
2279 | kfree(codec->ac97); | 2303 | kfree(codec->ac97); |
@@ -2283,118 +2307,6 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec) | |||
2283 | } | 2307 | } |
2284 | EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); | 2308 | EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); |
2285 | 2309 | ||
2286 | unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) | ||
2287 | { | ||
2288 | unsigned int ret; | ||
2289 | |||
2290 | ret = codec->read(codec, reg); | ||
2291 | dev_dbg(codec->dev, "read %x => %x\n", reg, ret); | ||
2292 | trace_snd_soc_reg_read(codec, reg, ret); | ||
2293 | |||
2294 | return ret; | ||
2295 | } | ||
2296 | EXPORT_SYMBOL_GPL(snd_soc_read); | ||
2297 | |||
2298 | unsigned int snd_soc_write(struct snd_soc_codec *codec, | ||
2299 | unsigned int reg, unsigned int val) | ||
2300 | { | ||
2301 | dev_dbg(codec->dev, "write %x = %x\n", reg, val); | ||
2302 | trace_snd_soc_reg_write(codec, reg, val); | ||
2303 | return codec->write(codec, reg, val); | ||
2304 | } | ||
2305 | EXPORT_SYMBOL_GPL(snd_soc_write); | ||
2306 | |||
2307 | /** | ||
2308 | * snd_soc_update_bits - update codec register bits | ||
2309 | * @codec: audio codec | ||
2310 | * @reg: codec register | ||
2311 | * @mask: register mask | ||
2312 | * @value: new value | ||
2313 | * | ||
2314 | * Writes new register value. | ||
2315 | * | ||
2316 | * Returns 1 for change, 0 for no change, or negative error code. | ||
2317 | */ | ||
2318 | int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg, | ||
2319 | unsigned int mask, unsigned int value) | ||
2320 | { | ||
2321 | bool change; | ||
2322 | unsigned int old, new; | ||
2323 | int ret; | ||
2324 | |||
2325 | if (codec->using_regmap) { | ||
2326 | ret = regmap_update_bits_check(codec->control_data, reg, | ||
2327 | mask, value, &change); | ||
2328 | } else { | ||
2329 | ret = snd_soc_read(codec, reg); | ||
2330 | if (ret < 0) | ||
2331 | return ret; | ||
2332 | |||
2333 | old = ret; | ||
2334 | new = (old & ~mask) | (value & mask); | ||
2335 | change = old != new; | ||
2336 | if (change) | ||
2337 | ret = snd_soc_write(codec, reg, new); | ||
2338 | } | ||
2339 | |||
2340 | if (ret < 0) | ||
2341 | return ret; | ||
2342 | |||
2343 | return change; | ||
2344 | } | ||
2345 | EXPORT_SYMBOL_GPL(snd_soc_update_bits); | ||
2346 | |||
2347 | /** | ||
2348 | * snd_soc_update_bits_locked - update codec register bits | ||
2349 | * @codec: audio codec | ||
2350 | * @reg: codec register | ||
2351 | * @mask: register mask | ||
2352 | * @value: new value | ||
2353 | * | ||
2354 | * Writes new register value, and takes the codec mutex. | ||
2355 | * | ||
2356 | * Returns 1 for change else 0. | ||
2357 | */ | ||
2358 | int snd_soc_update_bits_locked(struct snd_soc_codec *codec, | ||
2359 | unsigned short reg, unsigned int mask, | ||
2360 | unsigned int value) | ||
2361 | { | ||
2362 | int change; | ||
2363 | |||
2364 | mutex_lock(&codec->mutex); | ||
2365 | change = snd_soc_update_bits(codec, reg, mask, value); | ||
2366 | mutex_unlock(&codec->mutex); | ||
2367 | |||
2368 | return change; | ||
2369 | } | ||
2370 | EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked); | ||
2371 | |||
2372 | /** | ||
2373 | * snd_soc_test_bits - test register for change | ||
2374 | * @codec: audio codec | ||
2375 | * @reg: codec register | ||
2376 | * @mask: register mask | ||
2377 | * @value: new value | ||
2378 | * | ||
2379 | * Tests a register with a new value and checks if the new value is | ||
2380 | * different from the old value. | ||
2381 | * | ||
2382 | * Returns 1 for change else 0. | ||
2383 | */ | ||
2384 | int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg, | ||
2385 | unsigned int mask, unsigned int value) | ||
2386 | { | ||
2387 | int change; | ||
2388 | unsigned int old, new; | ||
2389 | |||
2390 | old = snd_soc_read(codec, reg); | ||
2391 | new = (old & ~mask) | value; | ||
2392 | change = old != new; | ||
2393 | |||
2394 | return change; | ||
2395 | } | ||
2396 | EXPORT_SYMBOL_GPL(snd_soc_test_bits); | ||
2397 | |||
2398 | /** | 2310 | /** |
2399 | * snd_soc_cnew - create new control | 2311 | * snd_soc_cnew - create new control |
2400 | * @_template: control template | 2312 | * @_template: control template |
@@ -2491,7 +2403,7 @@ int snd_soc_add_codec_controls(struct snd_soc_codec *codec, | |||
2491 | struct snd_card *card = codec->card->snd_card; | 2403 | struct snd_card *card = codec->card->snd_card; |
2492 | 2404 | ||
2493 | return snd_soc_add_controls(card, codec->dev, controls, num_controls, | 2405 | return snd_soc_add_controls(card, codec->dev, controls, num_controls, |
2494 | codec->name_prefix, codec); | 2406 | codec->name_prefix, &codec->component); |
2495 | } | 2407 | } |
2496 | EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls); | 2408 | EXPORT_SYMBOL_GPL(snd_soc_add_codec_controls); |
2497 | 2409 | ||
@@ -2511,7 +2423,7 @@ int snd_soc_add_platform_controls(struct snd_soc_platform *platform, | |||
2511 | struct snd_card *card = platform->card->snd_card; | 2423 | struct snd_card *card = platform->card->snd_card; |
2512 | 2424 | ||
2513 | return snd_soc_add_controls(card, platform->dev, controls, num_controls, | 2425 | return snd_soc_add_controls(card, platform->dev, controls, num_controls, |
2514 | NULL, platform); | 2426 | NULL, &platform->component); |
2515 | } | 2427 | } |
2516 | EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); | 2428 | EXPORT_SYMBOL_GPL(snd_soc_add_platform_controls); |
2517 | 2429 | ||
@@ -2595,12 +2507,15 @@ EXPORT_SYMBOL_GPL(snd_soc_info_enum_double); | |||
2595 | int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, | 2507 | int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol, |
2596 | struct snd_ctl_elem_value *ucontrol) | 2508 | struct snd_ctl_elem_value *ucontrol) |
2597 | { | 2509 | { |
2598 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2510 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
2599 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2511 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2600 | unsigned int val, item; | 2512 | unsigned int val, item; |
2601 | unsigned int reg_val; | 2513 | unsigned int reg_val; |
2514 | int ret; | ||
2602 | 2515 | ||
2603 | reg_val = snd_soc_read(codec, e->reg); | 2516 | ret = snd_soc_component_read(component, e->reg, ®_val); |
2517 | if (ret) | ||
2518 | return ret; | ||
2604 | val = (reg_val >> e->shift_l) & e->mask; | 2519 | val = (reg_val >> e->shift_l) & e->mask; |
2605 | item = snd_soc_enum_val_to_item(e, val); | 2520 | item = snd_soc_enum_val_to_item(e, val); |
2606 | ucontrol->value.enumerated.item[0] = item; | 2521 | ucontrol->value.enumerated.item[0] = item; |
@@ -2626,7 +2541,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_enum_double); | |||
2626 | int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, | 2541 | int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, |
2627 | struct snd_ctl_elem_value *ucontrol) | 2542 | struct snd_ctl_elem_value *ucontrol) |
2628 | { | 2543 | { |
2629 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2544 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
2630 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; | 2545 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
2631 | unsigned int *item = ucontrol->value.enumerated.item; | 2546 | unsigned int *item = ucontrol->value.enumerated.item; |
2632 | unsigned int val; | 2547 | unsigned int val; |
@@ -2643,38 +2558,48 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol, | |||
2643 | mask |= e->mask << e->shift_r; | 2558 | mask |= e->mask << e->shift_r; |
2644 | } | 2559 | } |
2645 | 2560 | ||
2646 | return snd_soc_update_bits_locked(codec, e->reg, mask, val); | 2561 | return snd_soc_component_update_bits(component, e->reg, mask, val); |
2647 | } | 2562 | } |
2648 | EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); | 2563 | EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); |
2649 | 2564 | ||
2650 | /** | 2565 | /** |
2651 | * snd_soc_read_signed - Read a codec register and interprete as signed value | 2566 | * snd_soc_read_signed - Read a codec register and interprete as signed value |
2652 | * @codec: codec | 2567 | * @component: component |
2653 | * @reg: Register to read | 2568 | * @reg: Register to read |
2654 | * @mask: Mask to use after shifting the register value | 2569 | * @mask: Mask to use after shifting the register value |
2655 | * @shift: Right shift of register value | 2570 | * @shift: Right shift of register value |
2656 | * @sign_bit: Bit that describes if a number is negative or not. | 2571 | * @sign_bit: Bit that describes if a number is negative or not. |
2572 | * @signed_val: Pointer to where the read value should be stored | ||
2657 | * | 2573 | * |
2658 | * This functions reads a codec register. The register value is shifted right | 2574 | * This functions reads a codec register. The register value is shifted right |
2659 | * by 'shift' bits and masked with the given 'mask'. Afterwards it translates | 2575 | * by 'shift' bits and masked with the given 'mask'. Afterwards it translates |
2660 | * the given registervalue into a signed integer if sign_bit is non-zero. | 2576 | * the given registervalue into a signed integer if sign_bit is non-zero. |
2661 | * | 2577 | * |
2662 | * Returns the register value as signed int. | 2578 | * Returns 0 on sucess, otherwise an error value |
2663 | */ | 2579 | */ |
2664 | static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg, | 2580 | static int snd_soc_read_signed(struct snd_soc_component *component, |
2665 | unsigned int mask, unsigned int shift, unsigned int sign_bit) | 2581 | unsigned int reg, unsigned int mask, unsigned int shift, |
2582 | unsigned int sign_bit, int *signed_val) | ||
2666 | { | 2583 | { |
2667 | int ret; | 2584 | int ret; |
2668 | unsigned int val; | 2585 | unsigned int val; |
2669 | 2586 | ||
2670 | val = (snd_soc_read(codec, reg) >> shift) & mask; | 2587 | ret = snd_soc_component_read(component, reg, &val); |
2588 | if (ret < 0) | ||
2589 | return ret; | ||
2671 | 2590 | ||
2672 | if (!sign_bit) | 2591 | val = (val >> shift) & mask; |
2673 | return val; | 2592 | |
2593 | if (!sign_bit) { | ||
2594 | *signed_val = val; | ||
2595 | return 0; | ||
2596 | } | ||
2674 | 2597 | ||
2675 | /* non-negative number */ | 2598 | /* non-negative number */ |
2676 | if (!(val & BIT(sign_bit))) | 2599 | if (!(val & BIT(sign_bit))) { |
2677 | return val; | 2600 | *signed_val = val; |
2601 | return 0; | ||
2602 | } | ||
2678 | 2603 | ||
2679 | ret = val; | 2604 | ret = val; |
2680 | 2605 | ||
@@ -2686,7 +2611,9 @@ static int snd_soc_read_signed(struct snd_soc_codec *codec, unsigned int reg, | |||
2686 | */ | 2611 | */ |
2687 | ret |= ~((int)(BIT(sign_bit) - 1)); | 2612 | ret |= ~((int)(BIT(sign_bit) - 1)); |
2688 | 2613 | ||
2689 | return ret; | 2614 | *signed_val = ret; |
2615 | |||
2616 | return 0; | ||
2690 | } | 2617 | } |
2691 | 2618 | ||
2692 | /** | 2619 | /** |
@@ -2735,9 +2662,9 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | |||
2735 | int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | 2662 | int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, |
2736 | struct snd_ctl_elem_value *ucontrol) | 2663 | struct snd_ctl_elem_value *ucontrol) |
2737 | { | 2664 | { |
2665 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
2738 | struct soc_mixer_control *mc = | 2666 | struct soc_mixer_control *mc = |
2739 | (struct soc_mixer_control *)kcontrol->private_value; | 2667 | (struct soc_mixer_control *)kcontrol->private_value; |
2740 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2741 | unsigned int reg = mc->reg; | 2668 | unsigned int reg = mc->reg; |
2742 | unsigned int reg2 = mc->rreg; | 2669 | unsigned int reg2 = mc->rreg; |
2743 | unsigned int shift = mc->shift; | 2670 | unsigned int shift = mc->shift; |
@@ -2747,25 +2674,32 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
2747 | int sign_bit = mc->sign_bit; | 2674 | int sign_bit = mc->sign_bit; |
2748 | unsigned int mask = (1 << fls(max)) - 1; | 2675 | unsigned int mask = (1 << fls(max)) - 1; |
2749 | unsigned int invert = mc->invert; | 2676 | unsigned int invert = mc->invert; |
2677 | int val; | ||
2678 | int ret; | ||
2750 | 2679 | ||
2751 | if (sign_bit) | 2680 | if (sign_bit) |
2752 | mask = BIT(sign_bit + 1) - 1; | 2681 | mask = BIT(sign_bit + 1) - 1; |
2753 | 2682 | ||
2754 | ucontrol->value.integer.value[0] = snd_soc_read_signed(codec, reg, mask, | 2683 | ret = snd_soc_read_signed(component, reg, mask, shift, sign_bit, &val); |
2755 | shift, sign_bit) - min; | 2684 | if (ret) |
2685 | return ret; | ||
2686 | |||
2687 | ucontrol->value.integer.value[0] = val - min; | ||
2756 | if (invert) | 2688 | if (invert) |
2757 | ucontrol->value.integer.value[0] = | 2689 | ucontrol->value.integer.value[0] = |
2758 | max - ucontrol->value.integer.value[0]; | 2690 | max - ucontrol->value.integer.value[0]; |
2759 | 2691 | ||
2760 | if (snd_soc_volsw_is_stereo(mc)) { | 2692 | if (snd_soc_volsw_is_stereo(mc)) { |
2761 | if (reg == reg2) | 2693 | if (reg == reg2) |
2762 | ucontrol->value.integer.value[1] = | 2694 | ret = snd_soc_read_signed(component, reg, mask, rshift, |
2763 | snd_soc_read_signed(codec, reg, mask, rshift, | 2695 | sign_bit, &val); |
2764 | sign_bit) - min; | ||
2765 | else | 2696 | else |
2766 | ucontrol->value.integer.value[1] = | 2697 | ret = snd_soc_read_signed(component, reg2, mask, shift, |
2767 | snd_soc_read_signed(codec, reg2, mask, shift, | 2698 | sign_bit, &val); |
2768 | sign_bit) - min; | 2699 | if (ret) |
2700 | return ret; | ||
2701 | |||
2702 | ucontrol->value.integer.value[1] = val - min; | ||
2769 | if (invert) | 2703 | if (invert) |
2770 | ucontrol->value.integer.value[1] = | 2704 | ucontrol->value.integer.value[1] = |
2771 | max - ucontrol->value.integer.value[1]; | 2705 | max - ucontrol->value.integer.value[1]; |
@@ -2788,9 +2722,9 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw); | |||
2788 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | 2722 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, |
2789 | struct snd_ctl_elem_value *ucontrol) | 2723 | struct snd_ctl_elem_value *ucontrol) |
2790 | { | 2724 | { |
2725 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
2791 | struct soc_mixer_control *mc = | 2726 | struct soc_mixer_control *mc = |
2792 | (struct soc_mixer_control *)kcontrol->private_value; | 2727 | (struct soc_mixer_control *)kcontrol->private_value; |
2793 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2794 | unsigned int reg = mc->reg; | 2728 | unsigned int reg = mc->reg; |
2795 | unsigned int reg2 = mc->rreg; | 2729 | unsigned int reg2 = mc->rreg; |
2796 | unsigned int shift = mc->shift; | 2730 | unsigned int shift = mc->shift; |
@@ -2825,12 +2759,13 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | |||
2825 | type_2r = true; | 2759 | type_2r = true; |
2826 | } | 2760 | } |
2827 | } | 2761 | } |
2828 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); | 2762 | err = snd_soc_component_update_bits(component, reg, val_mask, val); |
2829 | if (err < 0) | 2763 | if (err < 0) |
2830 | return err; | 2764 | return err; |
2831 | 2765 | ||
2832 | if (type_2r) | 2766 | if (type_2r) |
2833 | err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2); | 2767 | err = snd_soc_component_update_bits(component, reg2, val_mask, |
2768 | val2); | ||
2834 | 2769 | ||
2835 | return err; | 2770 | return err; |
2836 | } | 2771 | } |
@@ -2849,10 +2784,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw); | |||
2849 | int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, | 2784 | int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, |
2850 | struct snd_ctl_elem_value *ucontrol) | 2785 | struct snd_ctl_elem_value *ucontrol) |
2851 | { | 2786 | { |
2852 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2787 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
2853 | struct soc_mixer_control *mc = | 2788 | struct soc_mixer_control *mc = |
2854 | (struct soc_mixer_control *)kcontrol->private_value; | 2789 | (struct soc_mixer_control *)kcontrol->private_value; |
2855 | |||
2856 | unsigned int reg = mc->reg; | 2790 | unsigned int reg = mc->reg; |
2857 | unsigned int reg2 = mc->rreg; | 2791 | unsigned int reg2 = mc->rreg; |
2858 | unsigned int shift = mc->shift; | 2792 | unsigned int shift = mc->shift; |
@@ -2860,13 +2794,23 @@ int snd_soc_get_volsw_sx(struct snd_kcontrol *kcontrol, | |||
2860 | int max = mc->max; | 2794 | int max = mc->max; |
2861 | int min = mc->min; | 2795 | int min = mc->min; |
2862 | int mask = (1 << (fls(min + max) - 1)) - 1; | 2796 | int mask = (1 << (fls(min + max) - 1)) - 1; |
2797 | unsigned int val; | ||
2798 | int ret; | ||
2863 | 2799 | ||
2864 | ucontrol->value.integer.value[0] = | 2800 | ret = snd_soc_component_read(component, reg, &val); |
2865 | ((snd_soc_read(codec, reg) >> shift) - min) & mask; | 2801 | if (ret < 0) |
2802 | return ret; | ||
2866 | 2803 | ||
2867 | if (snd_soc_volsw_is_stereo(mc)) | 2804 | ucontrol->value.integer.value[0] = ((val >> shift) - min) & mask; |
2868 | ucontrol->value.integer.value[1] = | 2805 | |
2869 | ((snd_soc_read(codec, reg2) >> rshift) - min) & mask; | 2806 | if (snd_soc_volsw_is_stereo(mc)) { |
2807 | ret = snd_soc_component_read(component, reg2, &val); | ||
2808 | if (ret < 0) | ||
2809 | return ret; | ||
2810 | |||
2811 | val = ((val >> rshift) - min) & mask; | ||
2812 | ucontrol->value.integer.value[1] = val; | ||
2813 | } | ||
2870 | 2814 | ||
2871 | return 0; | 2815 | return 0; |
2872 | } | 2816 | } |
@@ -2884,7 +2828,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw_sx); | |||
2884 | int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, | 2828 | int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, |
2885 | struct snd_ctl_elem_value *ucontrol) | 2829 | struct snd_ctl_elem_value *ucontrol) |
2886 | { | 2830 | { |
2887 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2831 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
2888 | struct soc_mixer_control *mc = | 2832 | struct soc_mixer_control *mc = |
2889 | (struct soc_mixer_control *)kcontrol->private_value; | 2833 | (struct soc_mixer_control *)kcontrol->private_value; |
2890 | 2834 | ||
@@ -2896,13 +2840,13 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, | |||
2896 | int min = mc->min; | 2840 | int min = mc->min; |
2897 | int mask = (1 << (fls(min + max) - 1)) - 1; | 2841 | int mask = (1 << (fls(min + max) - 1)) - 1; |
2898 | int err = 0; | 2842 | int err = 0; |
2899 | unsigned short val, val_mask, val2 = 0; | 2843 | unsigned int val, val_mask, val2 = 0; |
2900 | 2844 | ||
2901 | val_mask = mask << shift; | 2845 | val_mask = mask << shift; |
2902 | val = (ucontrol->value.integer.value[0] + min) & mask; | 2846 | val = (ucontrol->value.integer.value[0] + min) & mask; |
2903 | val = val << shift; | 2847 | val = val << shift; |
2904 | 2848 | ||
2905 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); | 2849 | err = snd_soc_component_update_bits(component, reg, val_mask, val); |
2906 | if (err < 0) | 2850 | if (err < 0) |
2907 | return err; | 2851 | return err; |
2908 | 2852 | ||
@@ -2911,10 +2855,10 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, | |||
2911 | val2 = (ucontrol->value.integer.value[1] + min) & mask; | 2855 | val2 = (ucontrol->value.integer.value[1] + min) & mask; |
2912 | val2 = val2 << rshift; | 2856 | val2 = val2 << rshift; |
2913 | 2857 | ||
2914 | if (snd_soc_update_bits_locked(codec, reg2, val_mask, val2)) | 2858 | err = snd_soc_component_update_bits(component, reg2, val_mask, |
2915 | return err; | 2859 | val2); |
2916 | } | 2860 | } |
2917 | return 0; | 2861 | return err; |
2918 | } | 2862 | } |
2919 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); | 2863 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); |
2920 | 2864 | ||
@@ -2961,10 +2905,15 @@ int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, | |||
2961 | { | 2905 | { |
2962 | struct soc_mixer_control *mc = | 2906 | struct soc_mixer_control *mc = |
2963 | (struct soc_mixer_control *)kcontrol->private_value; | 2907 | (struct soc_mixer_control *)kcontrol->private_value; |
2964 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2908 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
2965 | unsigned int reg = mc->reg; | 2909 | unsigned int reg = mc->reg; |
2910 | unsigned int val; | ||
2966 | int min = mc->min; | 2911 | int min = mc->min; |
2967 | int val = snd_soc_read(codec, reg); | 2912 | int ret; |
2913 | |||
2914 | ret = snd_soc_component_read(component, reg, &val); | ||
2915 | if (ret) | ||
2916 | return ret; | ||
2968 | 2917 | ||
2969 | ucontrol->value.integer.value[0] = | 2918 | ucontrol->value.integer.value[0] = |
2970 | ((signed char)(val & 0xff))-min; | 2919 | ((signed char)(val & 0xff))-min; |
@@ -2988,7 +2937,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, | |||
2988 | { | 2937 | { |
2989 | struct soc_mixer_control *mc = | 2938 | struct soc_mixer_control *mc = |
2990 | (struct soc_mixer_control *)kcontrol->private_value; | 2939 | (struct soc_mixer_control *)kcontrol->private_value; |
2991 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2940 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
2992 | unsigned int reg = mc->reg; | 2941 | unsigned int reg = mc->reg; |
2993 | int min = mc->min; | 2942 | int min = mc->min; |
2994 | unsigned int val; | 2943 | unsigned int val; |
@@ -2996,7 +2945,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol, | |||
2996 | val = (ucontrol->value.integer.value[0]+min) & 0xff; | 2945 | val = (ucontrol->value.integer.value[0]+min) & 0xff; |
2997 | val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; | 2946 | val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; |
2998 | 2947 | ||
2999 | return snd_soc_update_bits_locked(codec, reg, 0xffff, val); | 2948 | return snd_soc_component_update_bits(component, reg, 0xffff, val); |
3000 | } | 2949 | } |
3001 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); | 2950 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); |
3002 | 2951 | ||
@@ -3045,7 +2994,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | |||
3045 | { | 2994 | { |
3046 | struct soc_mixer_control *mc = | 2995 | struct soc_mixer_control *mc = |
3047 | (struct soc_mixer_control *)kcontrol->private_value; | 2996 | (struct soc_mixer_control *)kcontrol->private_value; |
3048 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2997 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
3049 | unsigned int reg = mc->reg; | 2998 | unsigned int reg = mc->reg; |
3050 | unsigned int rreg = mc->rreg; | 2999 | unsigned int rreg = mc->rreg; |
3051 | unsigned int shift = mc->shift; | 3000 | unsigned int shift = mc->shift; |
@@ -3062,7 +3011,7 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | |||
3062 | val_mask = mask << shift; | 3011 | val_mask = mask << shift; |
3063 | val = val << shift; | 3012 | val = val << shift; |
3064 | 3013 | ||
3065 | ret = snd_soc_update_bits_locked(codec, reg, val_mask, val); | 3014 | ret = snd_soc_component_update_bits(component, reg, val_mask, val); |
3066 | if (ret < 0) | 3015 | if (ret < 0) |
3067 | return ret; | 3016 | return ret; |
3068 | 3017 | ||
@@ -3073,7 +3022,8 @@ int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol, | |||
3073 | val_mask = mask << shift; | 3022 | val_mask = mask << shift; |
3074 | val = val << shift; | 3023 | val = val << shift; |
3075 | 3024 | ||
3076 | ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val); | 3025 | ret = snd_soc_component_update_bits(component, rreg, val_mask, |
3026 | val); | ||
3077 | } | 3027 | } |
3078 | 3028 | ||
3079 | return ret; | 3029 | return ret; |
@@ -3092,9 +3042,9 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range); | |||
3092 | int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | 3042 | int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, |
3093 | struct snd_ctl_elem_value *ucontrol) | 3043 | struct snd_ctl_elem_value *ucontrol) |
3094 | { | 3044 | { |
3045 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3095 | struct soc_mixer_control *mc = | 3046 | struct soc_mixer_control *mc = |
3096 | (struct soc_mixer_control *)kcontrol->private_value; | 3047 | (struct soc_mixer_control *)kcontrol->private_value; |
3097 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3098 | unsigned int reg = mc->reg; | 3048 | unsigned int reg = mc->reg; |
3099 | unsigned int rreg = mc->rreg; | 3049 | unsigned int rreg = mc->rreg; |
3100 | unsigned int shift = mc->shift; | 3050 | unsigned int shift = mc->shift; |
@@ -3102,9 +3052,14 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | |||
3102 | int max = mc->max; | 3052 | int max = mc->max; |
3103 | unsigned int mask = (1 << fls(max)) - 1; | 3053 | unsigned int mask = (1 << fls(max)) - 1; |
3104 | unsigned int invert = mc->invert; | 3054 | unsigned int invert = mc->invert; |
3055 | unsigned int val; | ||
3056 | int ret; | ||
3105 | 3057 | ||
3106 | ucontrol->value.integer.value[0] = | 3058 | ret = snd_soc_component_read(component, reg, &val); |
3107 | (snd_soc_read(codec, reg) >> shift) & mask; | 3059 | if (ret) |
3060 | return ret; | ||
3061 | |||
3062 | ucontrol->value.integer.value[0] = (val >> shift) & mask; | ||
3108 | if (invert) | 3063 | if (invert) |
3109 | ucontrol->value.integer.value[0] = | 3064 | ucontrol->value.integer.value[0] = |
3110 | max - ucontrol->value.integer.value[0]; | 3065 | max - ucontrol->value.integer.value[0]; |
@@ -3112,8 +3067,11 @@ int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol, | |||
3112 | ucontrol->value.integer.value[0] - min; | 3067 | ucontrol->value.integer.value[0] - min; |
3113 | 3068 | ||
3114 | if (snd_soc_volsw_is_stereo(mc)) { | 3069 | if (snd_soc_volsw_is_stereo(mc)) { |
3115 | ucontrol->value.integer.value[1] = | 3070 | ret = snd_soc_component_read(component, rreg, &val); |
3116 | (snd_soc_read(codec, rreg) >> shift) & mask; | 3071 | if (ret) |
3072 | return ret; | ||
3073 | |||
3074 | ucontrol->value.integer.value[1] = (val >> shift) & mask; | ||
3117 | if (invert) | 3075 | if (invert) |
3118 | ucontrol->value.integer.value[1] = | 3076 | ucontrol->value.integer.value[1] = |
3119 | max - ucontrol->value.integer.value[1]; | 3077 | max - ucontrol->value.integer.value[1]; |
@@ -3167,11 +3125,11 @@ EXPORT_SYMBOL_GPL(snd_soc_limit_volume); | |||
3167 | int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, | 3125 | int snd_soc_bytes_info(struct snd_kcontrol *kcontrol, |
3168 | struct snd_ctl_elem_info *uinfo) | 3126 | struct snd_ctl_elem_info *uinfo) |
3169 | { | 3127 | { |
3170 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 3128 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
3171 | struct soc_bytes *params = (void *)kcontrol->private_value; | 3129 | struct soc_bytes *params = (void *)kcontrol->private_value; |
3172 | 3130 | ||
3173 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | 3131 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; |
3174 | uinfo->count = params->num_regs * codec->val_bytes; | 3132 | uinfo->count = params->num_regs * component->val_bytes; |
3175 | 3133 | ||
3176 | return 0; | 3134 | return 0; |
3177 | } | 3135 | } |
@@ -3180,20 +3138,20 @@ EXPORT_SYMBOL_GPL(snd_soc_bytes_info); | |||
3180 | int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, | 3138 | int snd_soc_bytes_get(struct snd_kcontrol *kcontrol, |
3181 | struct snd_ctl_elem_value *ucontrol) | 3139 | struct snd_ctl_elem_value *ucontrol) |
3182 | { | 3140 | { |
3141 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3183 | struct soc_bytes *params = (void *)kcontrol->private_value; | 3142 | struct soc_bytes *params = (void *)kcontrol->private_value; |
3184 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3185 | int ret; | 3143 | int ret; |
3186 | 3144 | ||
3187 | if (codec->using_regmap) | 3145 | if (component->regmap) |
3188 | ret = regmap_raw_read(codec->control_data, params->base, | 3146 | ret = regmap_raw_read(component->regmap, params->base, |
3189 | ucontrol->value.bytes.data, | 3147 | ucontrol->value.bytes.data, |
3190 | params->num_regs * codec->val_bytes); | 3148 | params->num_regs * component->val_bytes); |
3191 | else | 3149 | else |
3192 | ret = -EINVAL; | 3150 | ret = -EINVAL; |
3193 | 3151 | ||
3194 | /* Hide any masked bytes to ensure consistent data reporting */ | 3152 | /* Hide any masked bytes to ensure consistent data reporting */ |
3195 | if (ret == 0 && params->mask) { | 3153 | if (ret == 0 && params->mask) { |
3196 | switch (codec->val_bytes) { | 3154 | switch (component->val_bytes) { |
3197 | case 1: | 3155 | case 1: |
3198 | ucontrol->value.bytes.data[0] &= ~params->mask; | 3156 | ucontrol->value.bytes.data[0] &= ~params->mask; |
3199 | break; | 3157 | break; |
@@ -3217,16 +3175,16 @@ EXPORT_SYMBOL_GPL(snd_soc_bytes_get); | |||
3217 | int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | 3175 | int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, |
3218 | struct snd_ctl_elem_value *ucontrol) | 3176 | struct snd_ctl_elem_value *ucontrol) |
3219 | { | 3177 | { |
3178 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3220 | struct soc_bytes *params = (void *)kcontrol->private_value; | 3179 | struct soc_bytes *params = (void *)kcontrol->private_value; |
3221 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3222 | int ret, len; | 3180 | int ret, len; |
3223 | unsigned int val, mask; | 3181 | unsigned int val, mask; |
3224 | void *data; | 3182 | void *data; |
3225 | 3183 | ||
3226 | if (!codec->using_regmap) | 3184 | if (!component->regmap) |
3227 | return -EINVAL; | 3185 | return -EINVAL; |
3228 | 3186 | ||
3229 | len = params->num_regs * codec->val_bytes; | 3187 | len = params->num_regs * component->val_bytes; |
3230 | 3188 | ||
3231 | data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); | 3189 | data = kmemdup(ucontrol->value.bytes.data, len, GFP_KERNEL | GFP_DMA); |
3232 | if (!data) | 3190 | if (!data) |
@@ -3238,27 +3196,27 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | |||
3238 | * copy. | 3196 | * copy. |
3239 | */ | 3197 | */ |
3240 | if (params->mask) { | 3198 | if (params->mask) { |
3241 | ret = regmap_read(codec->control_data, params->base, &val); | 3199 | ret = regmap_read(component->regmap, params->base, &val); |
3242 | if (ret != 0) | 3200 | if (ret != 0) |
3243 | goto out; | 3201 | goto out; |
3244 | 3202 | ||
3245 | val &= params->mask; | 3203 | val &= params->mask; |
3246 | 3204 | ||
3247 | switch (codec->val_bytes) { | 3205 | switch (component->val_bytes) { |
3248 | case 1: | 3206 | case 1: |
3249 | ((u8 *)data)[0] &= ~params->mask; | 3207 | ((u8 *)data)[0] &= ~params->mask; |
3250 | ((u8 *)data)[0] |= val; | 3208 | ((u8 *)data)[0] |= val; |
3251 | break; | 3209 | break; |
3252 | case 2: | 3210 | case 2: |
3253 | mask = ~params->mask; | 3211 | mask = ~params->mask; |
3254 | ret = regmap_parse_val(codec->control_data, | 3212 | ret = regmap_parse_val(component->regmap, |
3255 | &mask, &mask); | 3213 | &mask, &mask); |
3256 | if (ret != 0) | 3214 | if (ret != 0) |
3257 | goto out; | 3215 | goto out; |
3258 | 3216 | ||
3259 | ((u16 *)data)[0] &= mask; | 3217 | ((u16 *)data)[0] &= mask; |
3260 | 3218 | ||
3261 | ret = regmap_parse_val(codec->control_data, | 3219 | ret = regmap_parse_val(component->regmap, |
3262 | &val, &val); | 3220 | &val, &val); |
3263 | if (ret != 0) | 3221 | if (ret != 0) |
3264 | goto out; | 3222 | goto out; |
@@ -3267,14 +3225,14 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | |||
3267 | break; | 3225 | break; |
3268 | case 4: | 3226 | case 4: |
3269 | mask = ~params->mask; | 3227 | mask = ~params->mask; |
3270 | ret = regmap_parse_val(codec->control_data, | 3228 | ret = regmap_parse_val(component->regmap, |
3271 | &mask, &mask); | 3229 | &mask, &mask); |
3272 | if (ret != 0) | 3230 | if (ret != 0) |
3273 | goto out; | 3231 | goto out; |
3274 | 3232 | ||
3275 | ((u32 *)data)[0] &= mask; | 3233 | ((u32 *)data)[0] &= mask; |
3276 | 3234 | ||
3277 | ret = regmap_parse_val(codec->control_data, | 3235 | ret = regmap_parse_val(component->regmap, |
3278 | &val, &val); | 3236 | &val, &val); |
3279 | if (ret != 0) | 3237 | if (ret != 0) |
3280 | goto out; | 3238 | goto out; |
@@ -3287,7 +3245,7 @@ int snd_soc_bytes_put(struct snd_kcontrol *kcontrol, | |||
3287 | } | 3245 | } |
3288 | } | 3246 | } |
3289 | 3247 | ||
3290 | ret = regmap_raw_write(codec->control_data, params->base, | 3248 | ret = regmap_raw_write(component->regmap, params->base, |
3291 | data, len); | 3249 | data, len); |
3292 | 3250 | ||
3293 | out: | 3251 | out: |
@@ -3297,6 +3255,18 @@ out: | |||
3297 | } | 3255 | } |
3298 | EXPORT_SYMBOL_GPL(snd_soc_bytes_put); | 3256 | EXPORT_SYMBOL_GPL(snd_soc_bytes_put); |
3299 | 3257 | ||
3258 | int snd_soc_bytes_info_ext(struct snd_kcontrol *kcontrol, | ||
3259 | struct snd_ctl_elem_info *ucontrol) | ||
3260 | { | ||
3261 | struct soc_bytes_ext *params = (void *)kcontrol->private_value; | ||
3262 | |||
3263 | ucontrol->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
3264 | ucontrol->count = params->max; | ||
3265 | |||
3266 | return 0; | ||
3267 | } | ||
3268 | EXPORT_SYMBOL_GPL(snd_soc_bytes_info_ext); | ||
3269 | |||
3300 | /** | 3270 | /** |
3301 | * snd_soc_info_xr_sx - signed multi register info callback | 3271 | * snd_soc_info_xr_sx - signed multi register info callback |
3302 | * @kcontrol: mreg control | 3272 | * @kcontrol: mreg control |
@@ -3338,24 +3308,27 @@ EXPORT_SYMBOL_GPL(snd_soc_info_xr_sx); | |||
3338 | int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, | 3308 | int snd_soc_get_xr_sx(struct snd_kcontrol *kcontrol, |
3339 | struct snd_ctl_elem_value *ucontrol) | 3309 | struct snd_ctl_elem_value *ucontrol) |
3340 | { | 3310 | { |
3311 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3341 | struct soc_mreg_control *mc = | 3312 | struct soc_mreg_control *mc = |
3342 | (struct soc_mreg_control *)kcontrol->private_value; | 3313 | (struct soc_mreg_control *)kcontrol->private_value; |
3343 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3344 | unsigned int regbase = mc->regbase; | 3314 | unsigned int regbase = mc->regbase; |
3345 | unsigned int regcount = mc->regcount; | 3315 | unsigned int regcount = mc->regcount; |
3346 | unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE; | 3316 | unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; |
3347 | unsigned int regwmask = (1<<regwshift)-1; | 3317 | unsigned int regwmask = (1<<regwshift)-1; |
3348 | unsigned int invert = mc->invert; | 3318 | unsigned int invert = mc->invert; |
3349 | unsigned long mask = (1UL<<mc->nbits)-1; | 3319 | unsigned long mask = (1UL<<mc->nbits)-1; |
3350 | long min = mc->min; | 3320 | long min = mc->min; |
3351 | long max = mc->max; | 3321 | long max = mc->max; |
3352 | long val = 0; | 3322 | long val = 0; |
3353 | unsigned long regval; | 3323 | unsigned int regval; |
3354 | unsigned int i; | 3324 | unsigned int i; |
3325 | int ret; | ||
3355 | 3326 | ||
3356 | for (i = 0; i < regcount; i++) { | 3327 | for (i = 0; i < regcount; i++) { |
3357 | regval = snd_soc_read(codec, regbase+i) & regwmask; | 3328 | ret = snd_soc_component_read(component, regbase+i, ®val); |
3358 | val |= regval << (regwshift*(regcount-i-1)); | 3329 | if (ret) |
3330 | return ret; | ||
3331 | val |= (regval & regwmask) << (regwshift*(regcount-i-1)); | ||
3359 | } | 3332 | } |
3360 | val &= mask; | 3333 | val &= mask; |
3361 | if (min < 0 && val > max) | 3334 | if (min < 0 && val > max) |
@@ -3384,12 +3357,12 @@ EXPORT_SYMBOL_GPL(snd_soc_get_xr_sx); | |||
3384 | int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, | 3357 | int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, |
3385 | struct snd_ctl_elem_value *ucontrol) | 3358 | struct snd_ctl_elem_value *ucontrol) |
3386 | { | 3359 | { |
3360 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3387 | struct soc_mreg_control *mc = | 3361 | struct soc_mreg_control *mc = |
3388 | (struct soc_mreg_control *)kcontrol->private_value; | 3362 | (struct soc_mreg_control *)kcontrol->private_value; |
3389 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3390 | unsigned int regbase = mc->regbase; | 3363 | unsigned int regbase = mc->regbase; |
3391 | unsigned int regcount = mc->regcount; | 3364 | unsigned int regcount = mc->regcount; |
3392 | unsigned int regwshift = codec->driver->reg_word_size * BITS_PER_BYTE; | 3365 | unsigned int regwshift = component->val_bytes * BITS_PER_BYTE; |
3393 | unsigned int regwmask = (1<<regwshift)-1; | 3366 | unsigned int regwmask = (1<<regwshift)-1; |
3394 | unsigned int invert = mc->invert; | 3367 | unsigned int invert = mc->invert; |
3395 | unsigned long mask = (1UL<<mc->nbits)-1; | 3368 | unsigned long mask = (1UL<<mc->nbits)-1; |
@@ -3404,7 +3377,7 @@ int snd_soc_put_xr_sx(struct snd_kcontrol *kcontrol, | |||
3404 | for (i = 0; i < regcount; i++) { | 3377 | for (i = 0; i < regcount; i++) { |
3405 | regval = (val >> (regwshift*(regcount-i-1))) & regwmask; | 3378 | regval = (val >> (regwshift*(regcount-i-1))) & regwmask; |
3406 | regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; | 3379 | regmask = (mask >> (regwshift*(regcount-i-1))) & regwmask; |
3407 | err = snd_soc_update_bits_locked(codec, regbase+i, | 3380 | err = snd_soc_component_update_bits(component, regbase+i, |
3408 | regmask, regval); | 3381 | regmask, regval); |
3409 | if (err < 0) | 3382 | if (err < 0) |
3410 | return err; | 3383 | return err; |
@@ -3426,14 +3399,21 @@ EXPORT_SYMBOL_GPL(snd_soc_put_xr_sx); | |||
3426 | int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, | 3399 | int snd_soc_get_strobe(struct snd_kcontrol *kcontrol, |
3427 | struct snd_ctl_elem_value *ucontrol) | 3400 | struct snd_ctl_elem_value *ucontrol) |
3428 | { | 3401 | { |
3402 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3429 | struct soc_mixer_control *mc = | 3403 | struct soc_mixer_control *mc = |
3430 | (struct soc_mixer_control *)kcontrol->private_value; | 3404 | (struct soc_mixer_control *)kcontrol->private_value; |
3431 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3432 | unsigned int reg = mc->reg; | 3405 | unsigned int reg = mc->reg; |
3433 | unsigned int shift = mc->shift; | 3406 | unsigned int shift = mc->shift; |
3434 | unsigned int mask = 1 << shift; | 3407 | unsigned int mask = 1 << shift; |
3435 | unsigned int invert = mc->invert != 0; | 3408 | unsigned int invert = mc->invert != 0; |
3436 | unsigned int val = snd_soc_read(codec, reg) & mask; | 3409 | unsigned int val; |
3410 | int ret; | ||
3411 | |||
3412 | ret = snd_soc_component_read(component, reg, &val); | ||
3413 | if (ret) | ||
3414 | return ret; | ||
3415 | |||
3416 | val &= mask; | ||
3437 | 3417 | ||
3438 | if (shift != 0 && val != 0) | 3418 | if (shift != 0 && val != 0) |
3439 | val = val >> shift; | 3419 | val = val >> shift; |
@@ -3456,9 +3436,9 @@ EXPORT_SYMBOL_GPL(snd_soc_get_strobe); | |||
3456 | int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, | 3436 | int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, |
3457 | struct snd_ctl_elem_value *ucontrol) | 3437 | struct snd_ctl_elem_value *ucontrol) |
3458 | { | 3438 | { |
3439 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); | ||
3459 | struct soc_mixer_control *mc = | 3440 | struct soc_mixer_control *mc = |
3460 | (struct soc_mixer_control *)kcontrol->private_value; | 3441 | (struct soc_mixer_control *)kcontrol->private_value; |
3461 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3462 | unsigned int reg = mc->reg; | 3442 | unsigned int reg = mc->reg; |
3463 | unsigned int shift = mc->shift; | 3443 | unsigned int shift = mc->shift; |
3464 | unsigned int mask = 1 << shift; | 3444 | unsigned int mask = 1 << shift; |
@@ -3468,12 +3448,11 @@ int snd_soc_put_strobe(struct snd_kcontrol *kcontrol, | |||
3468 | unsigned int val2 = (strobe ^ invert) ? 0 : mask; | 3448 | unsigned int val2 = (strobe ^ invert) ? 0 : mask; |
3469 | int err; | 3449 | int err; |
3470 | 3450 | ||
3471 | err = snd_soc_update_bits_locked(codec, reg, mask, val1); | 3451 | err = snd_soc_component_update_bits(component, reg, mask, val1); |
3472 | if (err < 0) | 3452 | if (err < 0) |
3473 | return err; | 3453 | return err; |
3474 | 3454 | ||
3475 | err = snd_soc_update_bits_locked(codec, reg, mask, val2); | 3455 | return snd_soc_component_update_bits(component, reg, mask, val2); |
3476 | return err; | ||
3477 | } | 3456 | } |
3478 | EXPORT_SYMBOL_GPL(snd_soc_put_strobe); | 3457 | EXPORT_SYMBOL_GPL(snd_soc_put_strobe); |
3479 | 3458 | ||
@@ -3821,7 +3800,6 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
3821 | for (i = 0; i < card->num_links; i++) | 3800 | for (i = 0; i < card->num_links; i++) |
3822 | card->rtd[i].dai_link = &card->dai_link[i]; | 3801 | card->rtd[i].dai_link = &card->dai_link[i]; |
3823 | 3802 | ||
3824 | INIT_LIST_HEAD(&card->list); | ||
3825 | INIT_LIST_HEAD(&card->dapm_dirty); | 3803 | INIT_LIST_HEAD(&card->dapm_dirty); |
3826 | card->instantiated = 0; | 3804 | card->instantiated = 0; |
3827 | mutex_init(&card->mutex); | 3805 | mutex_init(&card->mutex); |
@@ -4037,6 +4015,8 @@ __snd_soc_register_component(struct device *dev, | |||
4037 | return -ENOMEM; | 4015 | return -ENOMEM; |
4038 | } | 4016 | } |
4039 | 4017 | ||
4018 | mutex_init(&cmpnt->io_mutex); | ||
4019 | |||
4040 | cmpnt->name = fmt_single_name(dev, &cmpnt->id); | 4020 | cmpnt->name = fmt_single_name(dev, &cmpnt->id); |
4041 | if (!cmpnt->name) { | 4021 | if (!cmpnt->name) { |
4042 | dev_err(dev, "ASoC: Failed to simplifying name\n"); | 4022 | dev_err(dev, "ASoC: Failed to simplifying name\n"); |
@@ -4084,12 +4064,25 @@ int snd_soc_register_component(struct device *dev, | |||
4084 | } | 4064 | } |
4085 | 4065 | ||
4086 | cmpnt->ignore_pmdown_time = true; | 4066 | cmpnt->ignore_pmdown_time = true; |
4067 | cmpnt->registered_as_component = true; | ||
4087 | 4068 | ||
4088 | return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL, | 4069 | return __snd_soc_register_component(dev, cmpnt, cmpnt_drv, NULL, |
4089 | dai_drv, num_dai, true); | 4070 | dai_drv, num_dai, true); |
4090 | } | 4071 | } |
4091 | EXPORT_SYMBOL_GPL(snd_soc_register_component); | 4072 | EXPORT_SYMBOL_GPL(snd_soc_register_component); |
4092 | 4073 | ||
4074 | static void __snd_soc_unregister_component(struct snd_soc_component *cmpnt) | ||
4075 | { | ||
4076 | snd_soc_unregister_dais(cmpnt); | ||
4077 | |||
4078 | mutex_lock(&client_mutex); | ||
4079 | list_del(&cmpnt->list); | ||
4080 | mutex_unlock(&client_mutex); | ||
4081 | |||
4082 | dev_dbg(cmpnt->dev, "ASoC: Unregistered component '%s'\n", cmpnt->name); | ||
4083 | kfree(cmpnt->name); | ||
4084 | } | ||
4085 | |||
4093 | /** | 4086 | /** |
4094 | * snd_soc_unregister_component - Unregister a component from the ASoC core | 4087 | * snd_soc_unregister_component - Unregister a component from the ASoC core |
4095 | * | 4088 | * |
@@ -4099,22 +4092,33 @@ void snd_soc_unregister_component(struct device *dev) | |||
4099 | struct snd_soc_component *cmpnt; | 4092 | struct snd_soc_component *cmpnt; |
4100 | 4093 | ||
4101 | list_for_each_entry(cmpnt, &component_list, list) { | 4094 | list_for_each_entry(cmpnt, &component_list, list) { |
4102 | if (dev == cmpnt->dev) | 4095 | if (dev == cmpnt->dev && cmpnt->registered_as_component) |
4103 | goto found; | 4096 | goto found; |
4104 | } | 4097 | } |
4105 | return; | 4098 | return; |
4106 | 4099 | ||
4107 | found: | 4100 | found: |
4108 | snd_soc_unregister_dais(cmpnt); | 4101 | __snd_soc_unregister_component(cmpnt); |
4102 | } | ||
4103 | EXPORT_SYMBOL_GPL(snd_soc_unregister_component); | ||
4109 | 4104 | ||
4110 | mutex_lock(&client_mutex); | 4105 | static int snd_soc_platform_drv_write(struct snd_soc_component *component, |
4111 | list_del(&cmpnt->list); | 4106 | unsigned int reg, unsigned int val) |
4112 | mutex_unlock(&client_mutex); | 4107 | { |
4108 | struct snd_soc_platform *platform = snd_soc_component_to_platform(component); | ||
4113 | 4109 | ||
4114 | dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name); | 4110 | return platform->driver->write(platform, reg, val); |
4115 | kfree(cmpnt->name); | 4111 | } |
4112 | |||
4113 | static int snd_soc_platform_drv_read(struct snd_soc_component *component, | ||
4114 | unsigned int reg, unsigned int *val) | ||
4115 | { | ||
4116 | struct snd_soc_platform *platform = snd_soc_component_to_platform(component); | ||
4117 | |||
4118 | *val = platform->driver->read(platform, reg); | ||
4119 | |||
4120 | return 0; | ||
4116 | } | 4121 | } |
4117 | EXPORT_SYMBOL_GPL(snd_soc_unregister_component); | ||
4118 | 4122 | ||
4119 | /** | 4123 | /** |
4120 | * snd_soc_add_platform - Add a platform to the ASoC core | 4124 | * snd_soc_add_platform - Add a platform to the ASoC core |
@@ -4125,6 +4129,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_component); | |||
4125 | int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, | 4129 | int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, |
4126 | const struct snd_soc_platform_driver *platform_drv) | 4130 | const struct snd_soc_platform_driver *platform_drv) |
4127 | { | 4131 | { |
4132 | int ret; | ||
4133 | |||
4128 | /* create platform component name */ | 4134 | /* create platform component name */ |
4129 | platform->name = fmt_single_name(dev, &platform->id); | 4135 | platform->name = fmt_single_name(dev, &platform->id); |
4130 | if (platform->name == NULL) | 4136 | if (platform->name == NULL) |
@@ -4134,8 +4140,22 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform, | |||
4134 | platform->driver = platform_drv; | 4140 | platform->driver = platform_drv; |
4135 | platform->dapm.dev = dev; | 4141 | platform->dapm.dev = dev; |
4136 | platform->dapm.platform = platform; | 4142 | platform->dapm.platform = platform; |
4143 | platform->dapm.component = &platform->component; | ||
4137 | platform->dapm.stream_event = platform_drv->stream_event; | 4144 | platform->dapm.stream_event = platform_drv->stream_event; |
4138 | mutex_init(&platform->mutex); | 4145 | if (platform_drv->write) |
4146 | platform->component.write = snd_soc_platform_drv_write; | ||
4147 | if (platform_drv->read) | ||
4148 | platform->component.read = snd_soc_platform_drv_read; | ||
4149 | |||
4150 | /* register component */ | ||
4151 | ret = __snd_soc_register_component(dev, &platform->component, | ||
4152 | &platform_drv->component_driver, | ||
4153 | NULL, NULL, 0, false); | ||
4154 | if (ret < 0) { | ||
4155 | dev_err(platform->component.dev, | ||
4156 | "ASoC: Failed to register component: %d\n", ret); | ||
4157 | return ret; | ||
4158 | } | ||
4139 | 4159 | ||
4140 | mutex_lock(&client_mutex); | 4160 | mutex_lock(&client_mutex); |
4141 | list_add(&platform->list, &platform_list); | 4161 | list_add(&platform->list, &platform_list); |
@@ -4178,6 +4198,8 @@ EXPORT_SYMBOL_GPL(snd_soc_register_platform); | |||
4178 | */ | 4198 | */ |
4179 | void snd_soc_remove_platform(struct snd_soc_platform *platform) | 4199 | void snd_soc_remove_platform(struct snd_soc_platform *platform) |
4180 | { | 4200 | { |
4201 | __snd_soc_unregister_component(&platform->component); | ||
4202 | |||
4181 | mutex_lock(&client_mutex); | 4203 | mutex_lock(&client_mutex); |
4182 | list_del(&platform->list); | 4204 | list_del(&platform->list); |
4183 | mutex_unlock(&client_mutex); | 4205 | mutex_unlock(&client_mutex); |
@@ -4252,6 +4274,24 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) | |||
4252 | stream->formats |= codec_format_map[i]; | 4274 | stream->formats |= codec_format_map[i]; |
4253 | } | 4275 | } |
4254 | 4276 | ||
4277 | static int snd_soc_codec_drv_write(struct snd_soc_component *component, | ||
4278 | unsigned int reg, unsigned int val) | ||
4279 | { | ||
4280 | struct snd_soc_codec *codec = snd_soc_component_to_codec(component); | ||
4281 | |||
4282 | return codec->driver->write(codec, reg, val); | ||
4283 | } | ||
4284 | |||
4285 | static int snd_soc_codec_drv_read(struct snd_soc_component *component, | ||
4286 | unsigned int reg, unsigned int *val) | ||
4287 | { | ||
4288 | struct snd_soc_codec *codec = snd_soc_component_to_codec(component); | ||
4289 | |||
4290 | *val = codec->driver->read(codec, reg); | ||
4291 | |||
4292 | return 0; | ||
4293 | } | ||
4294 | |||
4255 | /** | 4295 | /** |
4256 | * snd_soc_register_codec - Register a codec with the ASoC core | 4296 | * snd_soc_register_codec - Register a codec with the ASoC core |
4257 | * | 4297 | * |
@@ -4263,6 +4303,7 @@ int snd_soc_register_codec(struct device *dev, | |||
4263 | int num_dai) | 4303 | int num_dai) |
4264 | { | 4304 | { |
4265 | struct snd_soc_codec *codec; | 4305 | struct snd_soc_codec *codec; |
4306 | struct regmap *regmap; | ||
4266 | int ret, i; | 4307 | int ret, i; |
4267 | 4308 | ||
4268 | dev_dbg(dev, "codec register %s\n", dev_name(dev)); | 4309 | dev_dbg(dev, "codec register %s\n", dev_name(dev)); |
@@ -4278,22 +4319,40 @@ int snd_soc_register_codec(struct device *dev, | |||
4278 | goto fail_codec; | 4319 | goto fail_codec; |
4279 | } | 4320 | } |
4280 | 4321 | ||
4281 | codec->write = codec_drv->write; | 4322 | if (codec_drv->write) |
4282 | codec->read = codec_drv->read; | 4323 | codec->component.write = snd_soc_codec_drv_write; |
4283 | codec->volatile_register = codec_drv->volatile_register; | 4324 | if (codec_drv->read) |
4284 | codec->readable_register = codec_drv->readable_register; | 4325 | codec->component.read = snd_soc_codec_drv_read; |
4285 | codec->writable_register = codec_drv->writable_register; | ||
4286 | codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; | 4326 | codec->component.ignore_pmdown_time = codec_drv->ignore_pmdown_time; |
4287 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | 4327 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; |
4288 | codec->dapm.dev = dev; | 4328 | codec->dapm.dev = dev; |
4289 | codec->dapm.codec = codec; | 4329 | codec->dapm.codec = codec; |
4330 | codec->dapm.component = &codec->component; | ||
4290 | codec->dapm.seq_notifier = codec_drv->seq_notifier; | 4331 | codec->dapm.seq_notifier = codec_drv->seq_notifier; |
4291 | codec->dapm.stream_event = codec_drv->stream_event; | 4332 | codec->dapm.stream_event = codec_drv->stream_event; |
4292 | codec->dev = dev; | 4333 | codec->dev = dev; |
4293 | codec->driver = codec_drv; | 4334 | codec->driver = codec_drv; |
4294 | codec->num_dai = num_dai; | 4335 | codec->component.val_bytes = codec_drv->reg_word_size; |
4295 | mutex_init(&codec->mutex); | 4336 | mutex_init(&codec->mutex); |
4296 | 4337 | ||
4338 | if (!codec->component.write) { | ||
4339 | if (codec_drv->get_regmap) | ||
4340 | regmap = codec_drv->get_regmap(dev); | ||
4341 | else | ||
4342 | regmap = dev_get_regmap(dev, NULL); | ||
4343 | |||
4344 | if (regmap) { | ||
4345 | ret = snd_soc_component_init_io(&codec->component, | ||
4346 | regmap); | ||
4347 | if (ret) { | ||
4348 | dev_err(codec->dev, | ||
4349 | "Failed to set cache I/O:%d\n", | ||
4350 | ret); | ||
4351 | return ret; | ||
4352 | } | ||
4353 | } | ||
4354 | } | ||
4355 | |||
4297 | for (i = 0; i < num_dai; i++) { | 4356 | for (i = 0; i < num_dai; i++) { |
4298 | fixup_codec_formats(&dai_drv[i].playback); | 4357 | fixup_codec_formats(&dai_drv[i].playback); |
4299 | fixup_codec_formats(&dai_drv[i].capture); | 4358 | fixup_codec_formats(&dai_drv[i].capture); |
@@ -4343,7 +4402,7 @@ void snd_soc_unregister_codec(struct device *dev) | |||
4343 | return; | 4402 | return; |
4344 | 4403 | ||
4345 | found: | 4404 | found: |
4346 | snd_soc_unregister_component(dev); | 4405 | __snd_soc_unregister_component(&codec->component); |
4347 | 4406 | ||
4348 | mutex_lock(&client_mutex); | 4407 | mutex_lock(&client_mutex); |
4349 | list_del(&codec->list); | 4408 | list_del(&codec->list); |
@@ -4554,7 +4613,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, | |||
4554 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing); | 4613 | EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing); |
4555 | 4614 | ||
4556 | unsigned int snd_soc_of_parse_daifmt(struct device_node *np, | 4615 | unsigned int snd_soc_of_parse_daifmt(struct device_node *np, |
4557 | const char *prefix) | 4616 | const char *prefix, |
4617 | struct device_node **bitclkmaster, | ||
4618 | struct device_node **framemaster) | ||
4558 | { | 4619 | { |
4559 | int ret, i; | 4620 | int ret, i; |
4560 | char prop[128]; | 4621 | char prop[128]; |
@@ -4637,9 +4698,13 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, | |||
4637 | */ | 4698 | */ |
4638 | snprintf(prop, sizeof(prop), "%sbitclock-master", prefix); | 4699 | snprintf(prop, sizeof(prop), "%sbitclock-master", prefix); |
4639 | bit = !!of_get_property(np, prop, NULL); | 4700 | bit = !!of_get_property(np, prop, NULL); |
4701 | if (bit && bitclkmaster) | ||
4702 | *bitclkmaster = of_parse_phandle(np, prop, 0); | ||
4640 | 4703 | ||
4641 | snprintf(prop, sizeof(prop), "%sframe-master", prefix); | 4704 | snprintf(prop, sizeof(prop), "%sframe-master", prefix); |
4642 | frame = !!of_get_property(np, prop, NULL); | 4705 | frame = !!of_get_property(np, prop, NULL); |
4706 | if (frame && framemaster) | ||
4707 | *framemaster = of_parse_phandle(np, prop, 0); | ||
4643 | 4708 | ||
4644 | switch ((bit << 4) + frame) { | 4709 | switch ((bit << 4) + frame) { |
4645 | case 0x11: | 4710 | case 0x11: |
@@ -4698,7 +4763,7 @@ int snd_soc_of_get_dai_name(struct device_node *of_node, | |||
4698 | 4763 | ||
4699 | if (id < 0 || id >= pos->num_dai) { | 4764 | if (id < 0 || id >= pos->num_dai) { |
4700 | ret = -EINVAL; | 4765 | ret = -EINVAL; |
4701 | break; | 4766 | continue; |
4702 | } | 4767 | } |
4703 | 4768 | ||
4704 | ret = 0; | 4769 | ret = 0; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6d6ceee447d5..a74b9bf23d9f 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -378,86 +378,24 @@ static void dapm_reset(struct snd_soc_card *card) | |||
378 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, | 378 | static int soc_widget_read(struct snd_soc_dapm_widget *w, int reg, |
379 | unsigned int *value) | 379 | unsigned int *value) |
380 | { | 380 | { |
381 | if (w->codec) { | 381 | if (!w->dapm->component) |
382 | *value = snd_soc_read(w->codec, reg); | 382 | return -EIO; |
383 | return 0; | 383 | return snd_soc_component_read(w->dapm->component, reg, value); |
384 | } else if (w->platform) { | ||
385 | *value = snd_soc_platform_read(w->platform, reg); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | dev_err(w->dapm->dev, "ASoC: no valid widget read method\n"); | ||
390 | return -1; | ||
391 | } | ||
392 | |||
393 | static int soc_widget_write(struct snd_soc_dapm_widget *w, int reg, | ||
394 | unsigned int val) | ||
395 | { | ||
396 | if (w->codec) | ||
397 | return snd_soc_write(w->codec, reg, val); | ||
398 | else if (w->platform) | ||
399 | return snd_soc_platform_write(w->platform, reg, val); | ||
400 | |||
401 | dev_err(w->dapm->dev, "ASoC: no valid widget write method\n"); | ||
402 | return -1; | ||
403 | } | ||
404 | |||
405 | static inline void soc_widget_lock(struct snd_soc_dapm_widget *w) | ||
406 | { | ||
407 | if (w->codec && !w->codec->using_regmap) | ||
408 | mutex_lock(&w->codec->mutex); | ||
409 | else if (w->platform) | ||
410 | mutex_lock(&w->platform->mutex); | ||
411 | } | 384 | } |
412 | 385 | ||
413 | static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w) | 386 | static int soc_widget_update_bits(struct snd_soc_dapm_widget *w, |
387 | int reg, unsigned int mask, unsigned int value) | ||
414 | { | 388 | { |
415 | if (w->codec && !w->codec->using_regmap) | 389 | if (!w->dapm->component) |
416 | mutex_unlock(&w->codec->mutex); | 390 | return -EIO; |
417 | else if (w->platform) | 391 | return snd_soc_component_update_bits_async(w->dapm->component, reg, |
418 | mutex_unlock(&w->platform->mutex); | 392 | mask, value); |
419 | } | 393 | } |
420 | 394 | ||
421 | static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) | 395 | static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) |
422 | { | 396 | { |
423 | if (dapm->codec && dapm->codec->using_regmap) | 397 | if (dapm->component) |
424 | regmap_async_complete(dapm->codec->control_data); | 398 | snd_soc_component_async_complete(dapm->component); |
425 | } | ||
426 | |||
427 | static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, | ||
428 | unsigned short reg, unsigned int mask, unsigned int value) | ||
429 | { | ||
430 | bool change; | ||
431 | unsigned int old, new; | ||
432 | int ret; | ||
433 | |||
434 | if (w->codec && w->codec->using_regmap) { | ||
435 | ret = regmap_update_bits_check_async(w->codec->control_data, | ||
436 | reg, mask, value, | ||
437 | &change); | ||
438 | if (ret != 0) | ||
439 | return ret; | ||
440 | } else { | ||
441 | soc_widget_lock(w); | ||
442 | ret = soc_widget_read(w, reg, &old); | ||
443 | if (ret < 0) { | ||
444 | soc_widget_unlock(w); | ||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | new = (old & ~mask) | (value & mask); | ||
449 | change = old != new; | ||
450 | if (change) { | ||
451 | ret = soc_widget_write(w, reg, new); | ||
452 | if (ret < 0) { | ||
453 | soc_widget_unlock(w); | ||
454 | return ret; | ||
455 | } | ||
456 | } | ||
457 | soc_widget_unlock(w); | ||
458 | } | ||
459 | |||
460 | return change; | ||
461 | } | 399 | } |
462 | 400 | ||
463 | /** | 401 | /** |
@@ -1120,26 +1058,6 @@ int snd_soc_dapm_dai_get_connected_widgets(struct snd_soc_dai *dai, int stream, | |||
1120 | } | 1058 | } |
1121 | 1059 | ||
1122 | /* | 1060 | /* |
1123 | * Handler for generic register modifier widget. | ||
1124 | */ | ||
1125 | int dapm_reg_event(struct snd_soc_dapm_widget *w, | ||
1126 | struct snd_kcontrol *kcontrol, int event) | ||
1127 | { | ||
1128 | unsigned int val; | ||
1129 | |||
1130 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
1131 | val = w->on_val; | ||
1132 | else | ||
1133 | val = w->off_val; | ||
1134 | |||
1135 | soc_widget_update_bits_locked(w, -(w->reg + 1), | ||
1136 | w->mask << w->shift, val << w->shift); | ||
1137 | |||
1138 | return 0; | ||
1139 | } | ||
1140 | EXPORT_SYMBOL_GPL(dapm_reg_event); | ||
1141 | |||
1142 | /* | ||
1143 | * Handler for regulator supply widget. | 1061 | * Handler for regulator supply widget. |
1144 | */ | 1062 | */ |
1145 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, | 1063 | int dapm_regulator_event(struct snd_soc_dapm_widget *w, |
@@ -1428,7 +1346,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_card *card, | |||
1428 | "pop test : Applying 0x%x/0x%x to %x in %dms\n", | 1346 | "pop test : Applying 0x%x/0x%x to %x in %dms\n", |
1429 | value, mask, reg, card->pop_time); | 1347 | value, mask, reg, card->pop_time); |
1430 | pop_wait(card->pop_time); | 1348 | pop_wait(card->pop_time); |
1431 | soc_widget_update_bits_locked(w, reg, mask, value); | 1349 | soc_widget_update_bits(w, reg, mask, value); |
1432 | } | 1350 | } |
1433 | 1351 | ||
1434 | list_for_each_entry(w, pending, power_list) { | 1352 | list_for_each_entry(w, pending, power_list) { |
@@ -1574,8 +1492,7 @@ static void dapm_widget_update(struct snd_soc_card *card) | |||
1574 | if (!w) | 1492 | if (!w) |
1575 | return; | 1493 | return; |
1576 | 1494 | ||
1577 | ret = soc_widget_update_bits_locked(w, update->reg, update->mask, | 1495 | ret = soc_widget_update_bits(w, update->reg, update->mask, update->val); |
1578 | update->val); | ||
1579 | if (ret < 0) | 1496 | if (ret < 0) |
1580 | dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", | 1497 | dev_err(w->dapm->dev, "ASoC: %s DAPM update failed: %d\n", |
1581 | w->name, ret); | 1498 | w->name, ret); |
@@ -2446,8 +2363,7 @@ err: | |||
2446 | } | 2363 | } |
2447 | 2364 | ||
2448 | static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | 2365 | static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, |
2449 | const struct snd_soc_dapm_route *route, | 2366 | const struct snd_soc_dapm_route *route) |
2450 | unsigned int is_prefixed) | ||
2451 | { | 2367 | { |
2452 | struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; | 2368 | struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; |
2453 | struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; | 2369 | struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; |
@@ -2457,7 +2373,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, | |||
2457 | char prefixed_source[80]; | 2373 | char prefixed_source[80]; |
2458 | int ret; | 2374 | int ret; |
2459 | 2375 | ||
2460 | if (dapm->codec && dapm->codec->name_prefix && !is_prefixed) { | 2376 | if (dapm->codec && dapm->codec->name_prefix) { |
2461 | snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", | 2377 | snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", |
2462 | dapm->codec->name_prefix, route->sink); | 2378 | dapm->codec->name_prefix, route->sink); |
2463 | sink = prefixed_sink; | 2379 | sink = prefixed_sink; |
@@ -2585,7 +2501,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, | |||
2585 | 2501 | ||
2586 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); | 2502 | mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); |
2587 | for (i = 0; i < num; i++) { | 2503 | for (i = 0; i < num; i++) { |
2588 | r = snd_soc_dapm_add_route(dapm, route, false); | 2504 | r = snd_soc_dapm_add_route(dapm, route); |
2589 | if (r < 0) { | 2505 | if (r < 0) { |
2590 | dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", | 2506 | dev_err(dapm->dev, "ASoC: Failed to add route %s -> %s -> %s\n", |
2591 | route->source, | 2507 | route->source, |
@@ -2857,22 +2773,19 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, | |||
2857 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); | 2773 | mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); |
2858 | 2774 | ||
2859 | change = dapm_kcontrol_set_value(kcontrol, val); | 2775 | change = dapm_kcontrol_set_value(kcontrol, val); |
2860 | |||
2861 | if (reg != SND_SOC_NOPM) { | ||
2862 | mask = mask << shift; | ||
2863 | val = val << shift; | ||
2864 | |||
2865 | change = snd_soc_test_bits(codec, reg, mask, val); | ||
2866 | } | ||
2867 | |||
2868 | if (change) { | 2776 | if (change) { |
2869 | if (reg != SND_SOC_NOPM) { | 2777 | if (reg != SND_SOC_NOPM) { |
2870 | update.kcontrol = kcontrol; | 2778 | mask = mask << shift; |
2871 | update.reg = reg; | 2779 | val = val << shift; |
2872 | update.mask = mask; | 2780 | |
2873 | update.val = val; | 2781 | if (snd_soc_test_bits(codec, reg, mask, val)) { |
2782 | update.kcontrol = kcontrol; | ||
2783 | update.reg = reg; | ||
2784 | update.mask = mask; | ||
2785 | update.val = val; | ||
2786 | card->update = &update; | ||
2787 | } | ||
2874 | 2788 | ||
2875 | card->update = &update; | ||
2876 | } | 2789 | } |
2877 | 2790 | ||
2878 | ret = soc_dapm_mixer_update_power(card, kcontrol, connect); | 2791 | ret = soc_dapm_mixer_update_power(card, kcontrol, connect); |
@@ -3311,11 +3224,11 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, | |||
3311 | struct snd_soc_dapm_widget *source, | 3224 | struct snd_soc_dapm_widget *source, |
3312 | struct snd_soc_dapm_widget *sink) | 3225 | struct snd_soc_dapm_widget *sink) |
3313 | { | 3226 | { |
3314 | struct snd_soc_dapm_route routes[2]; | ||
3315 | struct snd_soc_dapm_widget template; | 3227 | struct snd_soc_dapm_widget template; |
3316 | struct snd_soc_dapm_widget *w; | 3228 | struct snd_soc_dapm_widget *w; |
3317 | size_t len; | 3229 | size_t len; |
3318 | char *link_name; | 3230 | char *link_name; |
3231 | int ret; | ||
3319 | 3232 | ||
3320 | len = strlen(source->name) + strlen(sink->name) + 2; | 3233 | len = strlen(source->name) + strlen(sink->name) + 2; |
3321 | link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); | 3234 | link_name = devm_kzalloc(card->dev, len, GFP_KERNEL); |
@@ -3342,15 +3255,10 @@ int snd_soc_dapm_new_pcm(struct snd_soc_card *card, | |||
3342 | 3255 | ||
3343 | w->params = params; | 3256 | w->params = params; |
3344 | 3257 | ||
3345 | memset(&routes, 0, sizeof(routes)); | 3258 | ret = snd_soc_dapm_add_path(&card->dapm, source, w, NULL, NULL); |
3346 | 3259 | if (ret) | |
3347 | routes[0].source = source->name; | 3260 | return ret; |
3348 | routes[0].sink = link_name; | 3261 | return snd_soc_dapm_add_path(&card->dapm, w, sink, NULL, NULL); |
3349 | routes[1].source = link_name; | ||
3350 | routes[1].sink = sink->name; | ||
3351 | |||
3352 | return snd_soc_dapm_add_routes(&card->dapm, routes, | ||
3353 | ARRAY_SIZE(routes)); | ||
3354 | } | 3262 | } |
3355 | 3263 | ||
3356 | int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | 3264 | int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, |
@@ -3408,6 +3316,7 @@ int snd_soc_dapm_new_dai_widgets(struct snd_soc_dapm_context *dapm, | |||
3408 | int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | 3316 | int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) |
3409 | { | 3317 | { |
3410 | struct snd_soc_dapm_widget *dai_w, *w; | 3318 | struct snd_soc_dapm_widget *dai_w, *w; |
3319 | struct snd_soc_dapm_widget *src, *sink; | ||
3411 | struct snd_soc_dai *dai; | 3320 | struct snd_soc_dai *dai; |
3412 | 3321 | ||
3413 | /* For each DAI widget... */ | 3322 | /* For each DAI widget... */ |
@@ -3438,25 +3347,15 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | |||
3438 | if (!w->sname || !strstr(w->sname, dai_w->name)) | 3347 | if (!w->sname || !strstr(w->sname, dai_w->name)) |
3439 | continue; | 3348 | continue; |
3440 | 3349 | ||
3441 | if (dai->driver->playback.stream_name && | 3350 | if (dai_w->id == snd_soc_dapm_dai_in) { |
3442 | strstr(w->sname, | 3351 | src = dai_w; |
3443 | dai->driver->playback.stream_name)) { | 3352 | sink = w; |
3444 | dev_dbg(dai->dev, "%s -> %s\n", | 3353 | } else { |
3445 | dai->playback_widget->name, w->name); | 3354 | src = w; |
3446 | 3355 | sink = dai_w; | |
3447 | snd_soc_dapm_add_path(w->dapm, | ||
3448 | dai->playback_widget, w, NULL, NULL); | ||
3449 | } | ||
3450 | |||
3451 | if (dai->driver->capture.stream_name && | ||
3452 | strstr(w->sname, | ||
3453 | dai->driver->capture.stream_name)) { | ||
3454 | dev_dbg(dai->dev, "%s -> %s\n", | ||
3455 | w->name, dai->capture_widget->name); | ||
3456 | |||
3457 | snd_soc_dapm_add_path(w->dapm, w, | ||
3458 | dai->capture_widget, NULL, NULL); | ||
3459 | } | 3356 | } |
3357 | dev_dbg(dai->dev, "%s -> %s\n", src->name, sink->name); | ||
3358 | snd_soc_dapm_add_path(w->dapm, src, sink, NULL, NULL); | ||
3460 | } | 3359 | } |
3461 | } | 3360 | } |
3462 | 3361 | ||
@@ -3466,12 +3365,10 @@ int snd_soc_dapm_link_dai_widgets(struct snd_soc_card *card) | |||
3466 | void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) | 3365 | void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) |
3467 | { | 3366 | { |
3468 | struct snd_soc_pcm_runtime *rtd = card->rtd; | 3367 | struct snd_soc_pcm_runtime *rtd = card->rtd; |
3368 | struct snd_soc_dapm_widget *sink, *source; | ||
3469 | struct snd_soc_dai *cpu_dai, *codec_dai; | 3369 | struct snd_soc_dai *cpu_dai, *codec_dai; |
3470 | struct snd_soc_dapm_route r; | ||
3471 | int i; | 3370 | int i; |
3472 | 3371 | ||
3473 | memset(&r, 0, sizeof(r)); | ||
3474 | |||
3475 | /* for each BE DAI link... */ | 3372 | /* for each BE DAI link... */ |
3476 | for (i = 0; i < card->num_rtd; i++) { | 3373 | for (i = 0; i < card->num_rtd; i++) { |
3477 | rtd = &card->rtd[i]; | 3374 | rtd = &card->rtd[i]; |
@@ -3492,55 +3389,49 @@ void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card) | |||
3492 | 3389 | ||
3493 | /* connect BE DAI playback if widgets are valid */ | 3390 | /* connect BE DAI playback if widgets are valid */ |
3494 | if (codec_dai->playback_widget && cpu_dai->playback_widget) { | 3391 | if (codec_dai->playback_widget && cpu_dai->playback_widget) { |
3495 | r.source = cpu_dai->playback_widget->name; | 3392 | source = cpu_dai->playback_widget; |
3496 | r.sink = codec_dai->playback_widget->name; | 3393 | sink = codec_dai->playback_widget; |
3497 | dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", | 3394 | dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", |
3498 | cpu_dai->codec->name, r.source, | 3395 | cpu_dai->codec->name, source->name, |
3499 | codec_dai->platform->name, r.sink); | 3396 | codec_dai->platform->name, sink->name); |
3500 | 3397 | ||
3501 | snd_soc_dapm_add_route(&card->dapm, &r, true); | 3398 | snd_soc_dapm_add_path(&card->dapm, source, sink, |
3399 | NULL, NULL); | ||
3502 | } | 3400 | } |
3503 | 3401 | ||
3504 | /* connect BE DAI capture if widgets are valid */ | 3402 | /* connect BE DAI capture if widgets are valid */ |
3505 | if (codec_dai->capture_widget && cpu_dai->capture_widget) { | 3403 | if (codec_dai->capture_widget && cpu_dai->capture_widget) { |
3506 | r.source = codec_dai->capture_widget->name; | 3404 | source = codec_dai->capture_widget; |
3507 | r.sink = cpu_dai->capture_widget->name; | 3405 | sink = cpu_dai->capture_widget; |
3508 | dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", | 3406 | dev_dbg(rtd->dev, "connected DAI link %s:%s -> %s:%s\n", |
3509 | codec_dai->codec->name, r.source, | 3407 | codec_dai->codec->name, source->name, |
3510 | cpu_dai->platform->name, r.sink); | 3408 | cpu_dai->platform->name, sink->name); |
3511 | 3409 | ||
3512 | snd_soc_dapm_add_route(&card->dapm, &r, true); | 3410 | snd_soc_dapm_add_path(&card->dapm, source, sink, |
3411 | NULL, NULL); | ||
3513 | } | 3412 | } |
3514 | |||
3515 | } | 3413 | } |
3516 | } | 3414 | } |
3517 | 3415 | ||
3518 | static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, | 3416 | static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream, |
3519 | int event) | 3417 | int event) |
3520 | { | 3418 | { |
3419 | struct snd_soc_dapm_widget *w; | ||
3521 | 3420 | ||
3522 | struct snd_soc_dapm_widget *w_cpu, *w_codec; | 3421 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
3523 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 3422 | w = dai->playback_widget; |
3524 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 3423 | else |
3525 | 3424 | w = dai->capture_widget; | |
3526 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
3527 | w_cpu = cpu_dai->playback_widget; | ||
3528 | w_codec = codec_dai->playback_widget; | ||
3529 | } else { | ||
3530 | w_cpu = cpu_dai->capture_widget; | ||
3531 | w_codec = codec_dai->capture_widget; | ||
3532 | } | ||
3533 | |||
3534 | if (w_cpu) { | ||
3535 | 3425 | ||
3536 | dapm_mark_dirty(w_cpu, "stream event"); | 3426 | if (w) { |
3427 | dapm_mark_dirty(w, "stream event"); | ||
3537 | 3428 | ||
3538 | switch (event) { | 3429 | switch (event) { |
3539 | case SND_SOC_DAPM_STREAM_START: | 3430 | case SND_SOC_DAPM_STREAM_START: |
3540 | w_cpu->active = 1; | 3431 | w->active = 1; |
3541 | break; | 3432 | break; |
3542 | case SND_SOC_DAPM_STREAM_STOP: | 3433 | case SND_SOC_DAPM_STREAM_STOP: |
3543 | w_cpu->active = 0; | 3434 | w->active = 0; |
3544 | break; | 3435 | break; |
3545 | case SND_SOC_DAPM_STREAM_SUSPEND: | 3436 | case SND_SOC_DAPM_STREAM_SUSPEND: |
3546 | case SND_SOC_DAPM_STREAM_RESUME: | 3437 | case SND_SOC_DAPM_STREAM_RESUME: |
@@ -3549,25 +3440,13 @@ static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, | |||
3549 | break; | 3440 | break; |
3550 | } | 3441 | } |
3551 | } | 3442 | } |
3443 | } | ||
3552 | 3444 | ||
3553 | if (w_codec) { | 3445 | static void soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, int stream, |
3554 | 3446 | int event) | |
3555 | dapm_mark_dirty(w_codec, "stream event"); | 3447 | { |
3556 | 3448 | soc_dapm_dai_stream_event(rtd->cpu_dai, stream, event); | |
3557 | switch (event) { | 3449 | soc_dapm_dai_stream_event(rtd->codec_dai, stream, event); |
3558 | case SND_SOC_DAPM_STREAM_START: | ||
3559 | w_codec->active = 1; | ||
3560 | break; | ||
3561 | case SND_SOC_DAPM_STREAM_STOP: | ||
3562 | w_codec->active = 0; | ||
3563 | break; | ||
3564 | case SND_SOC_DAPM_STREAM_SUSPEND: | ||
3565 | case SND_SOC_DAPM_STREAM_RESUME: | ||
3566 | case SND_SOC_DAPM_STREAM_PAUSE_PUSH: | ||
3567 | case SND_SOC_DAPM_STREAM_PAUSE_RELEASE: | ||
3568 | break; | ||
3569 | } | ||
3570 | } | ||
3571 | 3450 | ||
3572 | dapm_power_widgets(rtd->card, event); | 3451 | dapm_power_widgets(rtd->card, event); |
3573 | } | 3452 | } |
diff --git a/sound/soc/soc-devres.c b/sound/soc/soc-devres.c index 7ac745df1412..057e5ef7dcce 100644 --- a/sound/soc/soc-devres.c +++ b/sound/soc/soc-devres.c | |||
@@ -52,6 +52,41 @@ int devm_snd_soc_register_component(struct device *dev, | |||
52 | } | 52 | } |
53 | EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); | 53 | EXPORT_SYMBOL_GPL(devm_snd_soc_register_component); |
54 | 54 | ||
55 | static void devm_platform_release(struct device *dev, void *res) | ||
56 | { | ||
57 | snd_soc_unregister_platform(*(struct device **)res); | ||
58 | } | ||
59 | |||
60 | /** | ||
61 | * devm_snd_soc_register_platform - resource managed platform registration | ||
62 | * @dev: Device used to manage platform | ||
63 | * @platform: platform to register | ||
64 | * | ||
65 | * Register a platform driver with automatic unregistration when the device is | ||
66 | * unregistered. | ||
67 | */ | ||
68 | int devm_snd_soc_register_platform(struct device *dev, | ||
69 | const struct snd_soc_platform_driver *platform_drv) | ||
70 | { | ||
71 | struct device **ptr; | ||
72 | int ret; | ||
73 | |||
74 | ptr = devres_alloc(devm_platform_release, sizeof(*ptr), GFP_KERNEL); | ||
75 | if (!ptr) | ||
76 | return -ENOMEM; | ||
77 | |||
78 | ret = snd_soc_register_platform(dev, platform_drv); | ||
79 | if (ret == 0) { | ||
80 | *ptr = dev; | ||
81 | devres_add(dev, ptr); | ||
82 | } else { | ||
83 | devres_free(ptr); | ||
84 | } | ||
85 | |||
86 | return ret; | ||
87 | } | ||
88 | EXPORT_SYMBOL_GPL(devm_snd_soc_register_platform); | ||
89 | |||
55 | static void devm_card_release(struct device *dev, void *res) | 90 | static void devm_card_release(struct device *dev, void *res) |
56 | { | 91 | { |
57 | snd_soc_unregister_card(*(struct snd_soc_card **)res); | 92 | snd_soc_unregister_card(*(struct snd_soc_card **)res); |
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index 260efc8466fc..7767fbd73eb7 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
@@ -17,77 +17,285 @@ | |||
17 | #include <linux/export.h> | 17 | #include <linux/export.h> |
18 | #include <sound/soc.h> | 18 | #include <sound/soc.h> |
19 | 19 | ||
20 | #include <trace/events/asoc.h> | 20 | /** |
21 | * snd_soc_component_read() - Read register value | ||
22 | * @component: Component to read from | ||
23 | * @reg: Register to read | ||
24 | * @val: Pointer to where the read value is stored | ||
25 | * | ||
26 | * Return: 0 on success, a negative error code otherwise. | ||
27 | */ | ||
28 | int snd_soc_component_read(struct snd_soc_component *component, | ||
29 | unsigned int reg, unsigned int *val) | ||
30 | { | ||
31 | int ret; | ||
32 | |||
33 | if (component->regmap) | ||
34 | ret = regmap_read(component->regmap, reg, val); | ||
35 | else if (component->read) | ||
36 | ret = component->read(component, reg, val); | ||
37 | else | ||
38 | ret = -EIO; | ||
39 | |||
40 | return ret; | ||
41 | } | ||
42 | EXPORT_SYMBOL_GPL(snd_soc_component_read); | ||
21 | 43 | ||
22 | #ifdef CONFIG_REGMAP | 44 | /** |
23 | static int hw_write(struct snd_soc_codec *codec, unsigned int reg, | 45 | * snd_soc_component_write() - Write register value |
24 | unsigned int value) | 46 | * @component: Component to write to |
47 | * @reg: Register to write | ||
48 | * @val: Value to write to the register | ||
49 | * | ||
50 | * Return: 0 on success, a negative error code otherwise. | ||
51 | */ | ||
52 | int snd_soc_component_write(struct snd_soc_component *component, | ||
53 | unsigned int reg, unsigned int val) | ||
25 | { | 54 | { |
26 | return regmap_write(codec->control_data, reg, value); | 55 | if (component->regmap) |
56 | return regmap_write(component->regmap, reg, val); | ||
57 | else if (component->write) | ||
58 | return component->write(component, reg, val); | ||
59 | else | ||
60 | return -EIO; | ||
27 | } | 61 | } |
62 | EXPORT_SYMBOL_GPL(snd_soc_component_write); | ||
28 | 63 | ||
29 | static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) | 64 | static int snd_soc_component_update_bits_legacy( |
65 | struct snd_soc_component *component, unsigned int reg, | ||
66 | unsigned int mask, unsigned int val, bool *change) | ||
30 | { | 67 | { |
68 | unsigned int old, new; | ||
31 | int ret; | 69 | int ret; |
32 | unsigned int val; | ||
33 | 70 | ||
34 | ret = regmap_read(codec->control_data, reg, &val); | 71 | if (!component->read || !component->write) |
35 | if (ret == 0) | 72 | return -EIO; |
36 | return val; | 73 | |
74 | mutex_lock(&component->io_mutex); | ||
75 | |||
76 | ret = component->read(component, reg, &old); | ||
77 | if (ret < 0) | ||
78 | goto out_unlock; | ||
79 | |||
80 | new = (old & ~mask) | (val & mask); | ||
81 | *change = old != new; | ||
82 | if (*change) | ||
83 | ret = component->write(component, reg, new); | ||
84 | out_unlock: | ||
85 | mutex_unlock(&component->io_mutex); | ||
86 | |||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * snd_soc_component_update_bits() - Perform read/modify/write cycle | ||
92 | * @component: Component to update | ||
93 | * @reg: Register to update | ||
94 | * @mask: Mask that specifies which bits to update | ||
95 | * @val: New value for the bits specified by mask | ||
96 | * | ||
97 | * Return: 1 if the operation was successful and the value of the register | ||
98 | * changed, 0 if the operation was successful, but the value did not change. | ||
99 | * Returns a negative error code otherwise. | ||
100 | */ | ||
101 | int snd_soc_component_update_bits(struct snd_soc_component *component, | ||
102 | unsigned int reg, unsigned int mask, unsigned int val) | ||
103 | { | ||
104 | bool change; | ||
105 | int ret; | ||
106 | |||
107 | if (component->regmap) | ||
108 | ret = regmap_update_bits_check(component->regmap, reg, mask, | ||
109 | val, &change); | ||
110 | else | ||
111 | ret = snd_soc_component_update_bits_legacy(component, reg, | ||
112 | mask, val, &change); | ||
113 | |||
114 | if (ret < 0) | ||
115 | return ret; | ||
116 | return change; | ||
117 | } | ||
118 | EXPORT_SYMBOL_GPL(snd_soc_component_update_bits); | ||
119 | |||
120 | /** | ||
121 | * snd_soc_component_update_bits_async() - Perform asynchronous | ||
122 | * read/modify/write cycle | ||
123 | * @component: Component to update | ||
124 | * @reg: Register to update | ||
125 | * @mask: Mask that specifies which bits to update | ||
126 | * @val: New value for the bits specified by mask | ||
127 | * | ||
128 | * This function is similar to snd_soc_component_update_bits(), but the update | ||
129 | * operation is scheduled asynchronously. This means it may not be completed | ||
130 | * when the function returns. To make sure that all scheduled updates have been | ||
131 | * completed snd_soc_component_async_complete() must be called. | ||
132 | * | ||
133 | * Return: 1 if the operation was successful and the value of the register | ||
134 | * changed, 0 if the operation was successful, but the value did not change. | ||
135 | * Returns a negative error code otherwise. | ||
136 | */ | ||
137 | int snd_soc_component_update_bits_async(struct snd_soc_component *component, | ||
138 | unsigned int reg, unsigned int mask, unsigned int val) | ||
139 | { | ||
140 | bool change; | ||
141 | int ret; | ||
142 | |||
143 | if (component->regmap) | ||
144 | ret = regmap_update_bits_check_async(component->regmap, reg, | ||
145 | mask, val, &change); | ||
37 | else | 146 | else |
147 | ret = snd_soc_component_update_bits_legacy(component, reg, | ||
148 | mask, val, &change); | ||
149 | |||
150 | if (ret < 0) | ||
151 | return ret; | ||
152 | return change; | ||
153 | } | ||
154 | EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async); | ||
155 | |||
156 | /** | ||
157 | * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed | ||
158 | * @component: Component for which to wait | ||
159 | * | ||
160 | * This function blocks until all asynchronous I/O which has previously been | ||
161 | * scheduled using snd_soc_component_update_bits_async() has completed. | ||
162 | */ | ||
163 | void snd_soc_component_async_complete(struct snd_soc_component *component) | ||
164 | { | ||
165 | if (component->regmap) | ||
166 | regmap_async_complete(component->regmap); | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(snd_soc_component_async_complete); | ||
169 | |||
170 | /** | ||
171 | * snd_soc_component_test_bits - Test register for change | ||
172 | * @component: component | ||
173 | * @reg: Register to test | ||
174 | * @mask: Mask that specifies which bits to test | ||
175 | * @value: Value to test against | ||
176 | * | ||
177 | * Tests a register with a new value and checks if the new value is | ||
178 | * different from the old value. | ||
179 | * | ||
180 | * Return: 1 for change, otherwise 0. | ||
181 | */ | ||
182 | int snd_soc_component_test_bits(struct snd_soc_component *component, | ||
183 | unsigned int reg, unsigned int mask, unsigned int value) | ||
184 | { | ||
185 | unsigned int old, new; | ||
186 | int ret; | ||
187 | |||
188 | ret = snd_soc_component_read(component, reg, &old); | ||
189 | if (ret < 0) | ||
190 | return ret; | ||
191 | new = (old & ~mask) | value; | ||
192 | return old != new; | ||
193 | } | ||
194 | EXPORT_SYMBOL_GPL(snd_soc_component_test_bits); | ||
195 | |||
196 | unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) | ||
197 | { | ||
198 | unsigned int val; | ||
199 | int ret; | ||
200 | |||
201 | ret = snd_soc_component_read(&codec->component, reg, &val); | ||
202 | if (ret < 0) | ||
38 | return -1; | 203 | return -1; |
204 | |||
205 | return val; | ||
39 | } | 206 | } |
207 | EXPORT_SYMBOL_GPL(snd_soc_read); | ||
208 | |||
209 | int snd_soc_write(struct snd_soc_codec *codec, unsigned int reg, | ||
210 | unsigned int val) | ||
211 | { | ||
212 | return snd_soc_component_write(&codec->component, reg, val); | ||
213 | } | ||
214 | EXPORT_SYMBOL_GPL(snd_soc_write); | ||
40 | 215 | ||
41 | /** | 216 | /** |
42 | * snd_soc_codec_set_cache_io: Set up standard I/O functions. | 217 | * snd_soc_update_bits - update codec register bits |
218 | * @codec: audio codec | ||
219 | * @reg: codec register | ||
220 | * @mask: register mask | ||
221 | * @value: new value | ||
43 | * | 222 | * |
44 | * @codec: CODEC to configure. | 223 | * Writes new register value. |
45 | * @map: Register map to write to | ||
46 | * | 224 | * |
47 | * Register formats are frequently shared between many I2C and SPI | 225 | * Returns 1 for change, 0 for no change, or negative error code. |
48 | * devices. In order to promote code reuse the ASoC core provides | 226 | */ |
49 | * some standard implementations of CODEC read and write operations | 227 | int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned int reg, |
50 | * which can be set up using this function. | 228 | unsigned int mask, unsigned int value) |
229 | { | ||
230 | return snd_soc_component_update_bits(&codec->component, reg, mask, | ||
231 | value); | ||
232 | } | ||
233 | EXPORT_SYMBOL_GPL(snd_soc_update_bits); | ||
234 | |||
235 | /** | ||
236 | * snd_soc_test_bits - test register for change | ||
237 | * @codec: audio codec | ||
238 | * @reg: codec register | ||
239 | * @mask: register mask | ||
240 | * @value: new value | ||
51 | * | 241 | * |
52 | * The caller is responsible for allocating and initialising the | 242 | * Tests a register with a new value and checks if the new value is |
53 | * actual cache. | 243 | * different from the old value. |
54 | * | 244 | * |
55 | * Note that at present this code cannot be used by CODECs with | 245 | * Returns 1 for change else 0. |
56 | * volatile registers. | ||
57 | */ | 246 | */ |
58 | int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | 247 | int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned int reg, |
59 | struct regmap *regmap) | 248 | unsigned int mask, unsigned int value) |
249 | { | ||
250 | return snd_soc_component_test_bits(&codec->component, reg, mask, value); | ||
251 | } | ||
252 | EXPORT_SYMBOL_GPL(snd_soc_test_bits); | ||
253 | |||
254 | int snd_soc_platform_read(struct snd_soc_platform *platform, | ||
255 | unsigned int reg) | ||
60 | { | 256 | { |
257 | unsigned int val; | ||
61 | int ret; | 258 | int ret; |
62 | 259 | ||
63 | /* Device has made its own regmap arrangements */ | 260 | ret = snd_soc_component_read(&platform->component, reg, &val); |
64 | if (!regmap) | 261 | if (ret < 0) |
65 | codec->control_data = dev_get_regmap(codec->dev, NULL); | 262 | return -1; |
66 | else | 263 | |
67 | codec->control_data = regmap; | 264 | return val; |
265 | } | ||
266 | EXPORT_SYMBOL_GPL(snd_soc_platform_read); | ||
267 | |||
268 | int snd_soc_platform_write(struct snd_soc_platform *platform, | ||
269 | unsigned int reg, unsigned int val) | ||
270 | { | ||
271 | return snd_soc_component_write(&platform->component, reg, val); | ||
272 | } | ||
273 | EXPORT_SYMBOL_GPL(snd_soc_platform_write); | ||
68 | 274 | ||
69 | if (IS_ERR(codec->control_data)) | 275 | /** |
70 | return PTR_ERR(codec->control_data); | 276 | * snd_soc_component_init_io() - Initialize regmap IO |
277 | * | ||
278 | * @component: component to initialize | ||
279 | * @regmap: regmap instance to use for IO operations | ||
280 | * | ||
281 | * Return: 0 on success, a negative error code otherwise | ||
282 | */ | ||
283 | int snd_soc_component_init_io(struct snd_soc_component *component, | ||
284 | struct regmap *regmap) | ||
285 | { | ||
286 | int ret; | ||
71 | 287 | ||
72 | codec->write = hw_write; | 288 | if (!regmap) |
73 | codec->read = hw_read; | 289 | return -EINVAL; |
74 | 290 | ||
75 | ret = regmap_get_val_bytes(codec->control_data); | 291 | ret = regmap_get_val_bytes(regmap); |
76 | /* Errors are legitimate for non-integer byte | 292 | /* Errors are legitimate for non-integer byte |
77 | * multiples */ | 293 | * multiples */ |
78 | if (ret > 0) | 294 | if (ret > 0) |
79 | codec->val_bytes = ret; | 295 | component->val_bytes = ret; |
80 | 296 | ||
81 | codec->using_regmap = true; | 297 | component->regmap = regmap; |
82 | 298 | ||
83 | return 0; | 299 | return 0; |
84 | } | 300 | } |
85 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); | 301 | EXPORT_SYMBOL_GPL(snd_soc_component_init_io); |
86 | #else | ||
87 | int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | ||
88 | struct regmap *regmap) | ||
89 | { | ||
90 | return -ENOTSUPP; | ||
91 | } | ||
92 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); | ||
93 | #endif | ||
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index a391de058037..54d18f22a33e 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
@@ -555,7 +555,6 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
555 | 555 | ||
556 | if (platform->driver->ops && platform->driver->ops->close) | 556 | if (platform->driver->ops && platform->driver->ops->close) |
557 | platform->driver->ops->close(substream); | 557 | platform->driver->ops->close(substream); |
558 | cpu_dai->runtime = NULL; | ||
559 | 558 | ||
560 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 559 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
561 | if (snd_soc_runtime_ignore_pmdown_time(rtd)) { | 560 | if (snd_soc_runtime_ignore_pmdown_time(rtd)) { |
@@ -819,6 +818,13 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
819 | if (ret < 0) | 818 | if (ret < 0) |
820 | return ret; | 819 | return ret; |
821 | } | 820 | } |
821 | |||
822 | if (rtd->dai_link->ops && rtd->dai_link->ops->trigger) { | ||
823 | ret = rtd->dai_link->ops->trigger(substream, cmd); | ||
824 | if (ret < 0) | ||
825 | return ret; | ||
826 | } | ||
827 | |||
822 | return 0; | 828 | return 0; |
823 | } | 829 | } |
824 | 830 | ||
@@ -1012,21 +1018,12 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card, | |||
1012 | } | 1018 | } |
1013 | 1019 | ||
1014 | static inline struct snd_soc_dapm_widget * | 1020 | static inline struct snd_soc_dapm_widget * |
1015 | rtd_get_cpu_widget(struct snd_soc_pcm_runtime *rtd, int stream) | 1021 | dai_get_widget(struct snd_soc_dai *dai, int stream) |
1016 | { | ||
1017 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1018 | return rtd->cpu_dai->playback_widget; | ||
1019 | else | ||
1020 | return rtd->cpu_dai->capture_widget; | ||
1021 | } | ||
1022 | |||
1023 | static inline struct snd_soc_dapm_widget * | ||
1024 | rtd_get_codec_widget(struct snd_soc_pcm_runtime *rtd, int stream) | ||
1025 | { | 1022 | { |
1026 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | 1023 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) |
1027 | return rtd->codec_dai->playback_widget; | 1024 | return dai->playback_widget; |
1028 | else | 1025 | else |
1029 | return rtd->codec_dai->capture_widget; | 1026 | return dai->capture_widget; |
1030 | } | 1027 | } |
1031 | 1028 | ||
1032 | static int widget_in_list(struct snd_soc_dapm_widget_list *list, | 1029 | static int widget_in_list(struct snd_soc_dapm_widget_list *list, |
@@ -1076,14 +1073,14 @@ static int dpcm_prune_paths(struct snd_soc_pcm_runtime *fe, int stream, | |||
1076 | list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { | 1073 | list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { |
1077 | 1074 | ||
1078 | /* is there a valid CPU DAI widget for this BE */ | 1075 | /* is there a valid CPU DAI widget for this BE */ |
1079 | widget = rtd_get_cpu_widget(dpcm->be, stream); | 1076 | widget = dai_get_widget(dpcm->be->cpu_dai, stream); |
1080 | 1077 | ||
1081 | /* prune the BE if it's no longer in our active list */ | 1078 | /* prune the BE if it's no longer in our active list */ |
1082 | if (widget && widget_in_list(list, widget)) | 1079 | if (widget && widget_in_list(list, widget)) |
1083 | continue; | 1080 | continue; |
1084 | 1081 | ||
1085 | /* is there a valid CODEC DAI widget for this BE */ | 1082 | /* is there a valid CODEC DAI widget for this BE */ |
1086 | widget = rtd_get_codec_widget(dpcm->be, stream); | 1083 | widget = dai_get_widget(dpcm->be->codec_dai, stream); |
1087 | 1084 | ||
1088 | /* prune the BE if it's no longer in our active list */ | 1085 | /* prune the BE if it's no longer in our active list */ |
1089 | if (widget && widget_in_list(list, widget)) | 1086 | if (widget && widget_in_list(list, widget)) |
diff --git a/sound/soc/tegra/tegra_wm9712.c b/sound/soc/tegra/tegra_wm9712.c index 25a7f8211ecf..de087ee3458a 100644 --- a/sound/soc/tegra/tegra_wm9712.c +++ b/sound/soc/tegra/tegra_wm9712.c | |||
@@ -50,9 +50,7 @@ static int tegra_wm9712_init(struct snd_soc_pcm_runtime *rtd) | |||
50 | struct snd_soc_codec *codec = codec_dai->codec; | 50 | struct snd_soc_codec *codec = codec_dai->codec; |
51 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 51 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
52 | 52 | ||
53 | snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); | 53 | return snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); |
54 | |||
55 | return snd_soc_dapm_sync(dapm); | ||
56 | } | 54 | } |
57 | 55 | ||
58 | static struct snd_soc_dai_link tegra_wm9712_dai = { | 56 | static struct snd_soc_dai_link tegra_wm9712_dai = { |
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c index 7e923ecf8901..be4f1ac7cd5e 100644 --- a/sound/soc/ux500/mop500_ab8500.c +++ b/sound/soc/ux500/mop500_ab8500.c | |||
@@ -411,7 +411,7 @@ int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd) | |||
411 | drvdata->mclk_sel = MCLK_ULPCLK; | 411 | drvdata->mclk_sel = MCLK_ULPCLK; |
412 | 412 | ||
413 | /* Add controls */ | 413 | /* Add controls */ |
414 | ret = snd_soc_add_card_controls(codec->card, mop500_ab8500_ctrls, | 414 | ret = snd_soc_add_card_controls(rtd->card, mop500_ab8500_ctrls, |
415 | ARRAY_SIZE(mop500_ab8500_ctrls)); | 415 | ARRAY_SIZE(mop500_ab8500_ctrls)); |
416 | if (ret < 0) { | 416 | if (ret < 0) { |
417 | pr_err("%s: Failed to add machine-controls (%d)!\n", | 417 | pr_err("%s: Failed to add machine-controls (%d)!\n", |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index e05a86b7c0da..d393153c474f 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -147,5 +147,18 @@ config SND_USB_HIFACE | |||
147 | To compile this driver as a module, choose M here: the module | 147 | To compile this driver as a module, choose M here: the module |
148 | will be called snd-usb-hiface. | 148 | will be called snd-usb-hiface. |
149 | 149 | ||
150 | config SND_BCD2000 | ||
151 | tristate "Behringer BCD2000 MIDI driver" | ||
152 | select SND_RAWMIDI | ||
153 | help | ||
154 | Say Y here to include MIDI support for the Behringer BCD2000 DJ | ||
155 | controller. | ||
156 | |||
157 | Audio support is still work-in-progress at | ||
158 | https://github.com/anyc/snd-usb-bcd2000 | ||
159 | |||
160 | To compile this driver as a module, choose M here: the module | ||
161 | will be called snd-bcd2000. | ||
162 | |||
150 | endif # SND_USB | 163 | endif # SND_USB |
151 | 164 | ||
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index abe668f660d1..2b92f0dcbc4c 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
@@ -23,4 +23,4 @@ obj-$(CONFIG_SND_USB_UA101) += snd-usbmidi-lib.o | |||
23 | obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o | 23 | obj-$(CONFIG_SND_USB_USX2Y) += snd-usbmidi-lib.o |
24 | obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o | 24 | obj-$(CONFIG_SND_USB_US122L) += snd-usbmidi-lib.o |
25 | 25 | ||
26 | obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ | 26 | obj-$(CONFIG_SND) += misc/ usx2y/ caiaq/ 6fire/ hiface/ bcd2000/ |
diff --git a/sound/usb/bcd2000/Makefile b/sound/usb/bcd2000/Makefile new file mode 100644 index 000000000000..f09ccc0af6ff --- /dev/null +++ b/sound/usb/bcd2000/Makefile | |||
@@ -0,0 +1,3 @@ | |||
1 | snd-bcd2000-y := bcd2000.o | ||
2 | |||
3 | obj-$(CONFIG_SND_BCD2000) += snd-bcd2000.o \ No newline at end of file | ||
diff --git a/sound/usb/bcd2000/bcd2000.c b/sound/usb/bcd2000/bcd2000.c new file mode 100644 index 000000000000..820d6ca8c458 --- /dev/null +++ b/sound/usb/bcd2000/bcd2000.c | |||
@@ -0,0 +1,461 @@ | |||
1 | /* | ||
2 | * Behringer BCD2000 driver | ||
3 | * | ||
4 | * Copyright (C) 2014 Mario Kicherer (dev@kicherer.org) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | */ | ||
16 | |||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/module.h> | ||
22 | #include <linux/bitmap.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include <linux/usb/audio.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/initval.h> | ||
27 | #include <sound/rawmidi.h> | ||
28 | |||
29 | #define PREFIX "snd-bcd2000: " | ||
30 | #define BUFSIZE 64 | ||
31 | |||
32 | static struct usb_device_id id_table[] = { | ||
33 | { USB_DEVICE(0x1397, 0x00bd) }, | ||
34 | { }, | ||
35 | }; | ||
36 | |||
37 | static unsigned char device_cmd_prefix[] = {0x03, 0x00}; | ||
38 | |||
39 | static unsigned char bcd2000_init_sequence[] = { | ||
40 | 0x07, 0x00, 0x00, 0x00, 0x78, 0x48, 0x1c, 0x81, | ||
41 | 0xc4, 0x00, 0x00, 0x00, 0x5e, 0x53, 0x4a, 0xf7, | ||
42 | 0x18, 0xfa, 0x11, 0xff, 0x6c, 0xf3, 0x90, 0xff, | ||
43 | 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, | ||
44 | 0x18, 0xfa, 0x11, 0xff, 0x14, 0x00, 0x00, 0x00, | ||
45 | 0x00, 0x00, 0x00, 0x00, 0xf2, 0x34, 0x4a, 0xf7, | ||
46 | 0x18, 0xfa, 0x11, 0xff | ||
47 | }; | ||
48 | |||
49 | struct bcd2000 { | ||
50 | struct usb_device *dev; | ||
51 | struct snd_card *card; | ||
52 | struct usb_interface *intf; | ||
53 | int card_index; | ||
54 | |||
55 | int midi_out_active; | ||
56 | struct snd_rawmidi *rmidi; | ||
57 | struct snd_rawmidi_substream *midi_receive_substream; | ||
58 | struct snd_rawmidi_substream *midi_out_substream; | ||
59 | |||
60 | unsigned char midi_in_buf[BUFSIZE]; | ||
61 | unsigned char midi_out_buf[BUFSIZE]; | ||
62 | |||
63 | struct urb *midi_out_urb; | ||
64 | struct urb *midi_in_urb; | ||
65 | |||
66 | struct usb_anchor anchor; | ||
67 | }; | ||
68 | |||
69 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
70 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
71 | |||
72 | static DEFINE_MUTEX(devices_mutex); | ||
73 | DECLARE_BITMAP(devices_used, SNDRV_CARDS); | ||
74 | static struct usb_driver bcd2000_driver; | ||
75 | |||
76 | #ifdef CONFIG_SND_DEBUG | ||
77 | static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) | ||
78 | { | ||
79 | print_hex_dump(KERN_DEBUG, prefix, | ||
80 | DUMP_PREFIX_NONE, 16, 1, | ||
81 | buf, len, false); | ||
82 | } | ||
83 | #else | ||
84 | static void bcd2000_dump_buffer(const char *prefix, const char *buf, int len) {} | ||
85 | #endif | ||
86 | |||
87 | static int bcd2000_midi_input_open(struct snd_rawmidi_substream *substream) | ||
88 | { | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static int bcd2000_midi_input_close(struct snd_rawmidi_substream *substream) | ||
93 | { | ||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | /* (de)register midi substream from client */ | ||
98 | static void bcd2000_midi_input_trigger(struct snd_rawmidi_substream *substream, | ||
99 | int up) | ||
100 | { | ||
101 | struct bcd2000 *bcd2k = substream->rmidi->private_data; | ||
102 | bcd2k->midi_receive_substream = up ? substream : NULL; | ||
103 | } | ||
104 | |||
105 | static void bcd2000_midi_handle_input(struct bcd2000 *bcd2k, | ||
106 | const unsigned char *buf, unsigned int buf_len) | ||
107 | { | ||
108 | unsigned int payload_length, tocopy; | ||
109 | struct snd_rawmidi_substream *midi_receive_substream; | ||
110 | |||
111 | midi_receive_substream = ACCESS_ONCE(bcd2k->midi_receive_substream); | ||
112 | if (!midi_receive_substream) | ||
113 | return; | ||
114 | |||
115 | bcd2000_dump_buffer(PREFIX "received from device: ", buf, buf_len); | ||
116 | |||
117 | if (buf_len < 2) | ||
118 | return; | ||
119 | |||
120 | payload_length = buf[0]; | ||
121 | |||
122 | /* ignore packets without payload */ | ||
123 | if (payload_length == 0) | ||
124 | return; | ||
125 | |||
126 | tocopy = min(payload_length, buf_len-1); | ||
127 | |||
128 | bcd2000_dump_buffer(PREFIX "sending to userspace: ", | ||
129 | &buf[1], tocopy); | ||
130 | |||
131 | snd_rawmidi_receive(midi_receive_substream, | ||
132 | &buf[1], tocopy); | ||
133 | } | ||
134 | |||
135 | static void bcd2000_midi_send(struct bcd2000 *bcd2k) | ||
136 | { | ||
137 | int len, ret; | ||
138 | struct snd_rawmidi_substream *midi_out_substream; | ||
139 | |||
140 | BUILD_BUG_ON(sizeof(device_cmd_prefix) >= BUFSIZE); | ||
141 | |||
142 | midi_out_substream = ACCESS_ONCE(bcd2k->midi_out_substream); | ||
143 | if (!midi_out_substream) | ||
144 | return; | ||
145 | |||
146 | /* copy command prefix bytes */ | ||
147 | memcpy(bcd2k->midi_out_buf, device_cmd_prefix, | ||
148 | sizeof(device_cmd_prefix)); | ||
149 | |||
150 | /* | ||
151 | * get MIDI packet and leave space for command prefix | ||
152 | * and payload length | ||
153 | */ | ||
154 | len = snd_rawmidi_transmit(midi_out_substream, | ||
155 | bcd2k->midi_out_buf + 3, BUFSIZE - 3); | ||
156 | |||
157 | if (len < 0) | ||
158 | dev_err(&bcd2k->dev->dev, "%s: snd_rawmidi_transmit error %d\n", | ||
159 | __func__, len); | ||
160 | |||
161 | if (len <= 0) | ||
162 | return; | ||
163 | |||
164 | /* set payload length */ | ||
165 | bcd2k->midi_out_buf[2] = len; | ||
166 | bcd2k->midi_out_urb->transfer_buffer_length = BUFSIZE; | ||
167 | |||
168 | bcd2000_dump_buffer(PREFIX "sending to device: ", | ||
169 | bcd2k->midi_out_buf, len+3); | ||
170 | |||
171 | /* send packet to the BCD2000 */ | ||
172 | ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_ATOMIC); | ||
173 | if (ret < 0) | ||
174 | dev_err(&bcd2k->dev->dev, PREFIX | ||
175 | "%s (%p): usb_submit_urb() failed, ret=%d, len=%d\n", | ||
176 | __func__, midi_out_substream, ret, len); | ||
177 | else | ||
178 | bcd2k->midi_out_active = 1; | ||
179 | } | ||
180 | |||
181 | static int bcd2000_midi_output_open(struct snd_rawmidi_substream *substream) | ||
182 | { | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | static int bcd2000_midi_output_close(struct snd_rawmidi_substream *substream) | ||
187 | { | ||
188 | struct bcd2000 *bcd2k = substream->rmidi->private_data; | ||
189 | |||
190 | if (bcd2k->midi_out_active) { | ||
191 | usb_kill_urb(bcd2k->midi_out_urb); | ||
192 | bcd2k->midi_out_active = 0; | ||
193 | } | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | /* (de)register midi substream from client */ | ||
199 | static void bcd2000_midi_output_trigger(struct snd_rawmidi_substream *substream, | ||
200 | int up) | ||
201 | { | ||
202 | struct bcd2000 *bcd2k = substream->rmidi->private_data; | ||
203 | |||
204 | if (up) { | ||
205 | bcd2k->midi_out_substream = substream; | ||
206 | /* check if there is data userspace wants to send */ | ||
207 | if (!bcd2k->midi_out_active) | ||
208 | bcd2000_midi_send(bcd2k); | ||
209 | } else { | ||
210 | bcd2k->midi_out_substream = NULL; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | static void bcd2000_output_complete(struct urb *urb) | ||
215 | { | ||
216 | struct bcd2000 *bcd2k = urb->context; | ||
217 | |||
218 | bcd2k->midi_out_active = 0; | ||
219 | |||
220 | if (urb->status) | ||
221 | dev_warn(&urb->dev->dev, | ||
222 | PREFIX "output urb->status: %d\n", urb->status); | ||
223 | |||
224 | if (urb->status == -ESHUTDOWN) | ||
225 | return; | ||
226 | |||
227 | /* check if there is more data userspace wants to send */ | ||
228 | bcd2000_midi_send(bcd2k); | ||
229 | } | ||
230 | |||
231 | static void bcd2000_input_complete(struct urb *urb) | ||
232 | { | ||
233 | int ret; | ||
234 | struct bcd2000 *bcd2k = urb->context; | ||
235 | |||
236 | if (urb->status) | ||
237 | dev_warn(&urb->dev->dev, | ||
238 | PREFIX "input urb->status: %i\n", urb->status); | ||
239 | |||
240 | if (!bcd2k || urb->status == -ESHUTDOWN) | ||
241 | return; | ||
242 | |||
243 | if (urb->actual_length > 0) | ||
244 | bcd2000_midi_handle_input(bcd2k, urb->transfer_buffer, | ||
245 | urb->actual_length); | ||
246 | |||
247 | /* return URB to device */ | ||
248 | ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_ATOMIC); | ||
249 | if (ret < 0) | ||
250 | dev_err(&bcd2k->dev->dev, PREFIX | ||
251 | "%s: usb_submit_urb() failed, ret=%d\n", | ||
252 | __func__, ret); | ||
253 | } | ||
254 | |||
255 | static struct snd_rawmidi_ops bcd2000_midi_output = { | ||
256 | .open = bcd2000_midi_output_open, | ||
257 | .close = bcd2000_midi_output_close, | ||
258 | .trigger = bcd2000_midi_output_trigger, | ||
259 | }; | ||
260 | |||
261 | static struct snd_rawmidi_ops bcd2000_midi_input = { | ||
262 | .open = bcd2000_midi_input_open, | ||
263 | .close = bcd2000_midi_input_close, | ||
264 | .trigger = bcd2000_midi_input_trigger, | ||
265 | }; | ||
266 | |||
267 | static void bcd2000_init_device(struct bcd2000 *bcd2k) | ||
268 | { | ||
269 | int ret; | ||
270 | |||
271 | init_usb_anchor(&bcd2k->anchor); | ||
272 | usb_anchor_urb(bcd2k->midi_out_urb, &bcd2k->anchor); | ||
273 | usb_anchor_urb(bcd2k->midi_in_urb, &bcd2k->anchor); | ||
274 | |||
275 | /* copy init sequence into buffer */ | ||
276 | memcpy(bcd2k->midi_out_buf, bcd2000_init_sequence, 52); | ||
277 | bcd2k->midi_out_urb->transfer_buffer_length = 52; | ||
278 | |||
279 | /* submit sequence */ | ||
280 | ret = usb_submit_urb(bcd2k->midi_out_urb, GFP_KERNEL); | ||
281 | if (ret < 0) | ||
282 | dev_err(&bcd2k->dev->dev, PREFIX | ||
283 | "%s: usb_submit_urb() out failed, ret=%d: ", | ||
284 | __func__, ret); | ||
285 | else | ||
286 | bcd2k->midi_out_active = 1; | ||
287 | |||
288 | /* pass URB to device to enable button and controller events */ | ||
289 | ret = usb_submit_urb(bcd2k->midi_in_urb, GFP_KERNEL); | ||
290 | if (ret < 0) | ||
291 | dev_err(&bcd2k->dev->dev, PREFIX | ||
292 | "%s: usb_submit_urb() in failed, ret=%d: ", | ||
293 | __func__, ret); | ||
294 | |||
295 | /* ensure initialization is finished */ | ||
296 | usb_wait_anchor_empty_timeout(&bcd2k->anchor, 1000); | ||
297 | } | ||
298 | |||
299 | static int bcd2000_init_midi(struct bcd2000 *bcd2k) | ||
300 | { | ||
301 | int ret; | ||
302 | struct snd_rawmidi *rmidi; | ||
303 | |||
304 | ret = snd_rawmidi_new(bcd2k->card, bcd2k->card->shortname, 0, | ||
305 | 1, /* output */ | ||
306 | 1, /* input */ | ||
307 | &rmidi); | ||
308 | |||
309 | if (ret < 0) | ||
310 | return ret; | ||
311 | |||
312 | strlcpy(rmidi->name, bcd2k->card->shortname, sizeof(rmidi->name)); | ||
313 | |||
314 | rmidi->info_flags = SNDRV_RAWMIDI_INFO_DUPLEX; | ||
315 | rmidi->private_data = bcd2k; | ||
316 | |||
317 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_OUTPUT; | ||
318 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, | ||
319 | &bcd2000_midi_output); | ||
320 | |||
321 | rmidi->info_flags |= SNDRV_RAWMIDI_INFO_INPUT; | ||
322 | snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT, | ||
323 | &bcd2000_midi_input); | ||
324 | |||
325 | bcd2k->rmidi = rmidi; | ||
326 | |||
327 | bcd2k->midi_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
328 | bcd2k->midi_out_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
329 | |||
330 | if (!bcd2k->midi_in_urb || !bcd2k->midi_out_urb) { | ||
331 | dev_err(&bcd2k->dev->dev, PREFIX "usb_alloc_urb failed\n"); | ||
332 | return -ENOMEM; | ||
333 | } | ||
334 | |||
335 | usb_fill_int_urb(bcd2k->midi_in_urb, bcd2k->dev, | ||
336 | usb_rcvintpipe(bcd2k->dev, 0x81), | ||
337 | bcd2k->midi_in_buf, BUFSIZE, | ||
338 | bcd2000_input_complete, bcd2k, 1); | ||
339 | |||
340 | usb_fill_int_urb(bcd2k->midi_out_urb, bcd2k->dev, | ||
341 | usb_sndintpipe(bcd2k->dev, 0x1), | ||
342 | bcd2k->midi_out_buf, BUFSIZE, | ||
343 | bcd2000_output_complete, bcd2k, 1); | ||
344 | |||
345 | bcd2000_init_device(bcd2k); | ||
346 | |||
347 | return 0; | ||
348 | } | ||
349 | |||
350 | static void bcd2000_free_usb_related_resources(struct bcd2000 *bcd2k, | ||
351 | struct usb_interface *interface) | ||
352 | { | ||
353 | /* usb_kill_urb not necessary, urb is aborted automatically */ | ||
354 | |||
355 | usb_free_urb(bcd2k->midi_out_urb); | ||
356 | usb_free_urb(bcd2k->midi_in_urb); | ||
357 | |||
358 | if (bcd2k->intf) { | ||
359 | usb_set_intfdata(bcd2k->intf, NULL); | ||
360 | bcd2k->intf = NULL; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | static int bcd2000_probe(struct usb_interface *interface, | ||
365 | const struct usb_device_id *usb_id) | ||
366 | { | ||
367 | struct snd_card *card; | ||
368 | struct bcd2000 *bcd2k; | ||
369 | unsigned int card_index; | ||
370 | char usb_path[32]; | ||
371 | int err; | ||
372 | |||
373 | mutex_lock(&devices_mutex); | ||
374 | |||
375 | for (card_index = 0; card_index < SNDRV_CARDS; ++card_index) | ||
376 | if (!test_bit(card_index, devices_used)) | ||
377 | break; | ||
378 | |||
379 | if (card_index >= SNDRV_CARDS) { | ||
380 | mutex_unlock(&devices_mutex); | ||
381 | return -ENOENT; | ||
382 | } | ||
383 | |||
384 | err = snd_card_new(&interface->dev, index[card_index], id[card_index], | ||
385 | THIS_MODULE, sizeof(*bcd2k), &card); | ||
386 | if (err < 0) { | ||
387 | mutex_unlock(&devices_mutex); | ||
388 | return err; | ||
389 | } | ||
390 | |||
391 | bcd2k = card->private_data; | ||
392 | bcd2k->dev = interface_to_usbdev(interface); | ||
393 | bcd2k->card = card; | ||
394 | bcd2k->card_index = card_index; | ||
395 | bcd2k->intf = interface; | ||
396 | |||
397 | snd_card_set_dev(card, &interface->dev); | ||
398 | |||
399 | strncpy(card->driver, "snd-bcd2000", sizeof(card->driver)); | ||
400 | strncpy(card->shortname, "BCD2000", sizeof(card->shortname)); | ||
401 | usb_make_path(bcd2k->dev, usb_path, sizeof(usb_path)); | ||
402 | snprintf(bcd2k->card->longname, sizeof(bcd2k->card->longname), | ||
403 | "Behringer BCD2000 at %s", | ||
404 | usb_path); | ||
405 | |||
406 | err = bcd2000_init_midi(bcd2k); | ||
407 | if (err < 0) | ||
408 | goto probe_error; | ||
409 | |||
410 | err = snd_card_register(card); | ||
411 | if (err < 0) | ||
412 | goto probe_error; | ||
413 | |||
414 | usb_set_intfdata(interface, bcd2k); | ||
415 | set_bit(card_index, devices_used); | ||
416 | |||
417 | mutex_unlock(&devices_mutex); | ||
418 | return 0; | ||
419 | |||
420 | probe_error: | ||
421 | dev_info(&bcd2k->dev->dev, PREFIX "error during probing"); | ||
422 | bcd2000_free_usb_related_resources(bcd2k, interface); | ||
423 | snd_card_free(card); | ||
424 | mutex_unlock(&devices_mutex); | ||
425 | return err; | ||
426 | } | ||
427 | |||
428 | static void bcd2000_disconnect(struct usb_interface *interface) | ||
429 | { | ||
430 | struct bcd2000 *bcd2k = usb_get_intfdata(interface); | ||
431 | |||
432 | if (!bcd2k) | ||
433 | return; | ||
434 | |||
435 | mutex_lock(&devices_mutex); | ||
436 | |||
437 | /* make sure that userspace cannot create new requests */ | ||
438 | snd_card_disconnect(bcd2k->card); | ||
439 | |||
440 | bcd2000_free_usb_related_resources(bcd2k, interface); | ||
441 | |||
442 | clear_bit(bcd2k->card_index, devices_used); | ||
443 | |||
444 | snd_card_free_when_closed(bcd2k->card); | ||
445 | |||
446 | mutex_unlock(&devices_mutex); | ||
447 | } | ||
448 | |||
449 | static struct usb_driver bcd2000_driver = { | ||
450 | .name = "snd-bcd2000", | ||
451 | .probe = bcd2000_probe, | ||
452 | .disconnect = bcd2000_disconnect, | ||
453 | .id_table = id_table, | ||
454 | }; | ||
455 | |||
456 | module_usb_driver(bcd2000_driver); | ||
457 | |||
458 | MODULE_DEVICE_TABLE(usb, id_table); | ||
459 | MODULE_AUTHOR("Mario Kicherer, dev@kicherer.org"); | ||
460 | MODULE_DESCRIPTION("Behringer BCD2000 driver"); | ||
461 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index d40a2850e270..0b728d886f0d 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
@@ -162,7 +162,7 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid, | |||
162 | { | 162 | { |
163 | const struct usbmix_selector_map *p; | 163 | const struct usbmix_selector_map *p; |
164 | 164 | ||
165 | if (! state->selector_map) | 165 | if (!state->selector_map) |
166 | return 0; | 166 | return 0; |
167 | for (p = state->selector_map; p->id; p++) { | 167 | for (p = state->selector_map; p->id; p++) { |
168 | if (p->id == unitid && index < p->count) | 168 | if (p->id == unitid && index < p->count) |
@@ -174,7 +174,8 @@ static int check_mapped_selector_name(struct mixer_build *state, int unitid, | |||
174 | /* | 174 | /* |
175 | * find an audio control unit with the given unit id | 175 | * find an audio control unit with the given unit id |
176 | */ | 176 | */ |
177 | static void *find_audio_control_unit(struct mixer_build *state, unsigned char unit) | 177 | static void *find_audio_control_unit(struct mixer_build *state, |
178 | unsigned char unit) | ||
178 | { | 179 | { |
179 | /* we just parse the header */ | 180 | /* we just parse the header */ |
180 | struct uac_feature_unit_descriptor *hdr = NULL; | 181 | struct uac_feature_unit_descriptor *hdr = NULL; |
@@ -194,7 +195,8 @@ static void *find_audio_control_unit(struct mixer_build *state, unsigned char un | |||
194 | /* | 195 | /* |
195 | * copy a string with the given id | 196 | * copy a string with the given id |
196 | */ | 197 | */ |
197 | static int snd_usb_copy_string_desc(struct mixer_build *state, int index, char *buf, int maxlen) | 198 | static int snd_usb_copy_string_desc(struct mixer_build *state, |
199 | int index, char *buf, int maxlen) | ||
198 | { | 200 | { |
199 | int len = usb_string(state->chip->dev, index, buf, maxlen - 1); | 201 | int len = usb_string(state->chip->dev, index, buf, maxlen - 1); |
200 | buf[len] = 0; | 202 | buf[len] = 0; |
@@ -253,7 +255,7 @@ static int convert_bytes_value(struct usb_mixer_elem_info *cval, int val) | |||
253 | 255 | ||
254 | static int get_relative_value(struct usb_mixer_elem_info *cval, int val) | 256 | static int get_relative_value(struct usb_mixer_elem_info *cval, int val) |
255 | { | 257 | { |
256 | if (! cval->res) | 258 | if (!cval->res) |
257 | cval->res = 1; | 259 | cval->res = 1; |
258 | if (val < cval->min) | 260 | if (val < cval->min) |
259 | return 0; | 261 | return 0; |
@@ -267,7 +269,7 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val) | |||
267 | { | 269 | { |
268 | if (val < 0) | 270 | if (val < 0) |
269 | return cval->min; | 271 | return cval->min; |
270 | if (! cval->res) | 272 | if (!cval->res) |
271 | cval->res = 1; | 273 | cval->res = 1; |
272 | val *= cval->res; | 274 | val *= cval->res; |
273 | val += cval->min; | 275 | val += cval->min; |
@@ -281,7 +283,8 @@ static int get_abs_value(struct usb_mixer_elem_info *cval, int val) | |||
281 | * retrieve a mixer value | 283 | * retrieve a mixer value |
282 | */ | 284 | */ |
283 | 285 | ||
284 | static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 286 | static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, |
287 | int validx, int *value_ret) | ||
285 | { | 288 | { |
286 | struct snd_usb_audio *chip = cval->mixer->chip; | 289 | struct snd_usb_audio *chip = cval->mixer->chip; |
287 | unsigned char buf[2]; | 290 | unsigned char buf[2]; |
@@ -292,6 +295,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v | |||
292 | err = snd_usb_autoresume(cval->mixer->chip); | 295 | err = snd_usb_autoresume(cval->mixer->chip); |
293 | if (err < 0) | 296 | if (err < 0) |
294 | return -EIO; | 297 | return -EIO; |
298 | |||
295 | down_read(&chip->shutdown_rwsem); | 299 | down_read(&chip->shutdown_rwsem); |
296 | while (timeout-- > 0) { | 300 | while (timeout-- > 0) { |
297 | if (chip->shutdown) | 301 | if (chip->shutdown) |
@@ -316,10 +320,11 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v | |||
316 | return err; | 320 | return err; |
317 | } | 321 | } |
318 | 322 | ||
319 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 323 | static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, |
324 | int validx, int *value_ret) | ||
320 | { | 325 | { |
321 | struct snd_usb_audio *chip = cval->mixer->chip; | 326 | struct snd_usb_audio *chip = cval->mixer->chip; |
322 | unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ | 327 | unsigned char buf[2 + 3 * sizeof(__u16)]; /* enough space for one range */ |
323 | unsigned char *val; | 328 | unsigned char *val; |
324 | int idx = 0, ret, size; | 329 | int idx = 0, ret, size; |
325 | __u8 bRequest; | 330 | __u8 bRequest; |
@@ -339,9 +344,9 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v | |||
339 | goto error; | 344 | goto error; |
340 | 345 | ||
341 | down_read(&chip->shutdown_rwsem); | 346 | down_read(&chip->shutdown_rwsem); |
342 | if (chip->shutdown) | 347 | if (chip->shutdown) { |
343 | ret = -ENODEV; | 348 | ret = -ENODEV; |
344 | else { | 349 | } else { |
345 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); | 350 | idx = snd_usb_ctrl_intf(chip) | (cval->id << 8); |
346 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, | 351 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, |
347 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 352 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
@@ -382,7 +387,8 @@ error: | |||
382 | return 0; | 387 | return 0; |
383 | } | 388 | } |
384 | 389 | ||
385 | static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) | 390 | static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, |
391 | int validx, int *value_ret) | ||
386 | { | 392 | { |
387 | validx += cval->idx_off; | 393 | validx += cval->idx_off; |
388 | 394 | ||
@@ -391,7 +397,8 @@ static int get_ctl_value(struct usb_mixer_elem_info *cval, int request, int vali | |||
391 | get_ctl_value_v2(cval, request, validx, value_ret); | 397 | get_ctl_value_v2(cval, request, validx, value_ret); |
392 | } | 398 | } |
393 | 399 | ||
394 | static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int *value) | 400 | static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, |
401 | int validx, int *value) | ||
395 | { | 402 | { |
396 | return get_ctl_value(cval, UAC_GET_CUR, validx, value); | 403 | return get_ctl_value(cval, UAC_GET_CUR, validx, value); |
397 | } | 404 | } |
@@ -400,7 +407,9 @@ static int get_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int * | |||
400 | static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval, | 407 | static inline int get_cur_mix_raw(struct usb_mixer_elem_info *cval, |
401 | int channel, int *value) | 408 | int channel, int *value) |
402 | { | 409 | { |
403 | return get_ctl_value(cval, UAC_GET_CUR, (cval->control << 8) | channel, value); | 410 | return get_ctl_value(cval, UAC_GET_CUR, |
411 | (cval->control << 8) | channel, | ||
412 | value); | ||
404 | } | 413 | } |
405 | 414 | ||
406 | static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | 415 | static int get_cur_mix_value(struct usb_mixer_elem_info *cval, |
@@ -417,7 +426,7 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | |||
417 | if (!cval->mixer->ignore_ctl_error) | 426 | if (!cval->mixer->ignore_ctl_error) |
418 | usb_audio_dbg(cval->mixer->chip, | 427 | usb_audio_dbg(cval->mixer->chip, |
419 | "cannot get current value for control %d ch %d: err = %d\n", | 428 | "cannot get current value for control %d ch %d: err = %d\n", |
420 | cval->control, channel, err); | 429 | cval->control, channel, err); |
421 | return err; | 430 | return err; |
422 | } | 431 | } |
423 | cval->cached |= 1 << channel; | 432 | cval->cached |= 1 << channel; |
@@ -425,7 +434,6 @@ static int get_cur_mix_value(struct usb_mixer_elem_info *cval, | |||
425 | return 0; | 434 | return 0; |
426 | } | 435 | } |
427 | 436 | ||
428 | |||
429 | /* | 437 | /* |
430 | * set a mixer value | 438 | * set a mixer value |
431 | */ | 439 | */ |
@@ -474,7 +482,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
474 | } | 482 | } |
475 | } | 483 | } |
476 | usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", | 484 | usb_audio_dbg(chip, "cannot set ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d, data = %#x/%#x\n", |
477 | request, validx, idx, cval->val_type, buf[0], buf[1]); | 485 | request, validx, idx, cval->val_type, buf[0], buf[1]); |
478 | err = -EINVAL; | 486 | err = -EINVAL; |
479 | 487 | ||
480 | out: | 488 | out: |
@@ -483,7 +491,8 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
483 | return err; | 491 | return err; |
484 | } | 492 | } |
485 | 493 | ||
486 | static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, int validx, int value) | 494 | static int set_cur_ctl_value(struct usb_mixer_elem_info *cval, |
495 | int validx, int value) | ||
487 | { | 496 | { |
488 | return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value); | 497 | return snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, validx, value); |
489 | } | 498 | } |
@@ -503,8 +512,9 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel, | |||
503 | return 0; | 512 | return 0; |
504 | } | 513 | } |
505 | 514 | ||
506 | err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel, | 515 | err = snd_usb_mixer_set_ctl_value(cval, |
507 | value); | 516 | UAC_SET_CUR, (cval->control << 8) | channel, |
517 | value); | ||
508 | if (err < 0) | 518 | if (err < 0) |
509 | return err; | 519 | return err; |
510 | cval->cached |= 1 << channel; | 520 | cval->cached |= 1 << channel; |
@@ -541,13 +551,13 @@ static int parse_audio_unit(struct mixer_build *state, int unitid); | |||
541 | * check if the input/output channel routing is enabled on the given bitmap. | 551 | * check if the input/output channel routing is enabled on the given bitmap. |
542 | * used for mixer unit parser | 552 | * used for mixer unit parser |
543 | */ | 553 | */ |
544 | static int check_matrix_bitmap(unsigned char *bmap, int ich, int och, int num_outs) | 554 | static int check_matrix_bitmap(unsigned char *bmap, |
555 | int ich, int och, int num_outs) | ||
545 | { | 556 | { |
546 | int idx = ich * num_outs + och; | 557 | int idx = ich * num_outs + och; |
547 | return bmap[idx >> 3] & (0x80 >> (idx & 7)); | 558 | return bmap[idx >> 3] & (0x80 >> (idx & 7)); |
548 | } | 559 | } |
549 | 560 | ||
550 | |||
551 | /* | 561 | /* |
552 | * add an alsa control element | 562 | * add an alsa control element |
553 | * search and increment the index until an empty slot is found. | 563 | * search and increment the index until an empty slot is found. |
@@ -564,7 +574,8 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | |||
564 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) | 574 | while (snd_ctl_find_id(mixer->chip->card, &kctl->id)) |
565 | kctl->id.index++; | 575 | kctl->id.index++; |
566 | if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) { | 576 | if ((err = snd_ctl_add(mixer->chip->card, kctl)) < 0) { |
567 | usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", err); | 577 | usb_audio_dbg(mixer->chip, "cannot add control (err = %d)\n", |
578 | err); | ||
568 | return err; | 579 | return err; |
569 | } | 580 | } |
570 | cval->elem_id = &kctl->id; | 581 | cval->elem_id = &kctl->id; |
@@ -573,7 +584,6 @@ int snd_usb_mixer_add_control(struct usb_mixer_interface *mixer, | |||
573 | return 0; | 584 | return 0; |
574 | } | 585 | } |
575 | 586 | ||
576 | |||
577 | /* | 587 | /* |
578 | * get a terminal name string | 588 | * get a terminal name string |
579 | */ | 589 | */ |
@@ -627,7 +637,8 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
627 | struct iterm_name_combo *names; | 637 | struct iterm_name_combo *names; |
628 | 638 | ||
629 | if (iterm->name) | 639 | if (iterm->name) |
630 | return snd_usb_copy_string_desc(state, iterm->name, name, maxlen); | 640 | return snd_usb_copy_string_desc(state, iterm->name, |
641 | name, maxlen); | ||
631 | 642 | ||
632 | /* virtual type - not a real terminal */ | 643 | /* virtual type - not a real terminal */ |
633 | if (iterm->type >> 16) { | 644 | if (iterm->type >> 16) { |
@@ -635,13 +646,17 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
635 | return 0; | 646 | return 0; |
636 | switch (iterm->type >> 16) { | 647 | switch (iterm->type >> 16) { |
637 | case UAC_SELECTOR_UNIT: | 648 | case UAC_SELECTOR_UNIT: |
638 | strcpy(name, "Selector"); return 8; | 649 | strcpy(name, "Selector"); |
650 | return 8; | ||
639 | case UAC1_PROCESSING_UNIT: | 651 | case UAC1_PROCESSING_UNIT: |
640 | strcpy(name, "Process Unit"); return 12; | 652 | strcpy(name, "Process Unit"); |
653 | return 12; | ||
641 | case UAC1_EXTENSION_UNIT: | 654 | case UAC1_EXTENSION_UNIT: |
642 | strcpy(name, "Ext Unit"); return 8; | 655 | strcpy(name, "Ext Unit"); |
656 | return 8; | ||
643 | case UAC_MIXER_UNIT: | 657 | case UAC_MIXER_UNIT: |
644 | strcpy(name, "Mixer"); return 5; | 658 | strcpy(name, "Mixer"); |
659 | return 5; | ||
645 | default: | 660 | default: |
646 | return sprintf(name, "Unit %d", iterm->id); | 661 | return sprintf(name, "Unit %d", iterm->id); |
647 | } | 662 | } |
@@ -649,29 +664,35 @@ static int get_term_name(struct mixer_build *state, struct usb_audio_term *iterm | |||
649 | 664 | ||
650 | switch (iterm->type & 0xff00) { | 665 | switch (iterm->type & 0xff00) { |
651 | case 0x0100: | 666 | case 0x0100: |
652 | strcpy(name, "PCM"); return 3; | 667 | strcpy(name, "PCM"); |
668 | return 3; | ||
653 | case 0x0200: | 669 | case 0x0200: |
654 | strcpy(name, "Mic"); return 3; | 670 | strcpy(name, "Mic"); |
671 | return 3; | ||
655 | case 0x0400: | 672 | case 0x0400: |
656 | strcpy(name, "Headset"); return 7; | 673 | strcpy(name, "Headset"); |
674 | return 7; | ||
657 | case 0x0500: | 675 | case 0x0500: |
658 | strcpy(name, "Phone"); return 5; | 676 | strcpy(name, "Phone"); |
677 | return 5; | ||
659 | } | 678 | } |
660 | 679 | ||
661 | for (names = iterm_names; names->type; names++) | 680 | for (names = iterm_names; names->type; names++) { |
662 | if (names->type == iterm->type) { | 681 | if (names->type == iterm->type) { |
663 | strcpy(name, names->name); | 682 | strcpy(name, names->name); |
664 | return strlen(names->name); | 683 | return strlen(names->name); |
665 | } | 684 | } |
685 | } | ||
686 | |||
666 | return 0; | 687 | return 0; |
667 | } | 688 | } |
668 | 689 | ||
669 | |||
670 | /* | 690 | /* |
671 | * parse the source unit recursively until it reaches to a terminal | 691 | * parse the source unit recursively until it reaches to a terminal |
672 | * or a branched unit. | 692 | * or a branched unit. |
673 | */ | 693 | */ |
674 | static int check_input_term(struct mixer_build *state, int id, struct usb_audio_term *term) | 694 | static int check_input_term(struct mixer_build *state, int id, |
695 | struct usb_audio_term *term) | ||
675 | { | 696 | { |
676 | int err; | 697 | int err; |
677 | void *p1; | 698 | void *p1; |
@@ -766,7 +787,6 @@ static int check_input_term(struct mixer_build *state, int id, struct usb_audio_ | |||
766 | return -ENODEV; | 787 | return -ENODEV; |
767 | } | 788 | } |
768 | 789 | ||
769 | |||
770 | /* | 790 | /* |
771 | * Feature Unit | 791 | * Feature Unit |
772 | */ | 792 | */ |
@@ -794,7 +814,6 @@ static struct usb_feature_control_info audio_feature_info[] = { | |||
794 | { "Phase Inverter Control", USB_MIXER_BOOLEAN }, | 814 | { "Phase Inverter Control", USB_MIXER_BOOLEAN }, |
795 | }; | 815 | }; |
796 | 816 | ||
797 | |||
798 | /* private_free callback */ | 817 | /* private_free callback */ |
799 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | 818 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) |
800 | { | 819 | { |
@@ -802,7 +821,6 @@ static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | |||
802 | kctl->private_data = NULL; | 821 | kctl->private_data = NULL; |
803 | } | 822 | } |
804 | 823 | ||
805 | |||
806 | /* | 824 | /* |
807 | * interface to ALSA control for feature/mixer units | 825 | * interface to ALSA control for feature/mixer units |
808 | */ | 826 | */ |
@@ -906,7 +924,6 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval, | |||
906 | cval->res = 384; | 924 | cval->res = 384; |
907 | } | 925 | } |
908 | break; | 926 | break; |
909 | |||
910 | } | 927 | } |
911 | } | 928 | } |
912 | 929 | ||
@@ -939,21 +956,26 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, | |||
939 | get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { | 956 | get_ctl_value(cval, UAC_GET_MIN, (cval->control << 8) | minchn, &cval->min) < 0) { |
940 | usb_audio_err(cval->mixer->chip, | 957 | usb_audio_err(cval->mixer->chip, |
941 | "%d:%d: cannot get min/max values for control %d (id %d)\n", | 958 | "%d:%d: cannot get min/max values for control %d (id %d)\n", |
942 | cval->id, snd_usb_ctrl_intf(cval->mixer->chip), cval->control, cval->id); | 959 | cval->id, snd_usb_ctrl_intf(cval->mixer->chip), |
960 | cval->control, cval->id); | ||
943 | return -EINVAL; | 961 | return -EINVAL; |
944 | } | 962 | } |
945 | if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) { | 963 | if (get_ctl_value(cval, UAC_GET_RES, |
964 | (cval->control << 8) | minchn, | ||
965 | &cval->res) < 0) { | ||
946 | cval->res = 1; | 966 | cval->res = 1; |
947 | } else { | 967 | } else { |
948 | int last_valid_res = cval->res; | 968 | int last_valid_res = cval->res; |
949 | 969 | ||
950 | while (cval->res > 1) { | 970 | while (cval->res > 1) { |
951 | if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES, | 971 | if (snd_usb_mixer_set_ctl_value(cval, UAC_SET_RES, |
952 | (cval->control << 8) | minchn, cval->res / 2) < 0) | 972 | (cval->control << 8) | minchn, |
973 | cval->res / 2) < 0) | ||
953 | break; | 974 | break; |
954 | cval->res /= 2; | 975 | cval->res /= 2; |
955 | } | 976 | } |
956 | if (get_ctl_value(cval, UAC_GET_RES, (cval->control << 8) | minchn, &cval->res) < 0) | 977 | if (get_ctl_value(cval, UAC_GET_RES, |
978 | (cval->control << 8) | minchn, &cval->res) < 0) | ||
957 | cval->res = last_valid_res; | 979 | cval->res = last_valid_res; |
958 | } | 980 | } |
959 | if (cval->res == 0) | 981 | if (cval->res == 0) |
@@ -1017,7 +1039,8 @@ static int get_min_max_with_quirks(struct usb_mixer_elem_info *cval, | |||
1017 | #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) | 1039 | #define get_min_max(cval, def) get_min_max_with_quirks(cval, def, NULL) |
1018 | 1040 | ||
1019 | /* get a feature/mixer unit info */ | 1041 | /* get a feature/mixer unit info */ |
1020 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1042 | static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, |
1043 | struct snd_ctl_elem_info *uinfo) | ||
1021 | { | 1044 | { |
1022 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1045 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1023 | 1046 | ||
@@ -1051,7 +1074,8 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1051 | } | 1074 | } |
1052 | 1075 | ||
1053 | /* get the current value from feature/mixer unit */ | 1076 | /* get the current value from feature/mixer unit */ |
1054 | static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1077 | static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, |
1078 | struct snd_ctl_elem_value *ucontrol) | ||
1055 | { | 1079 | { |
1056 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1080 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1057 | int c, cnt, val, err; | 1081 | int c, cnt, val, err; |
@@ -1082,7 +1106,8 @@ static int mixer_ctl_feature_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
1082 | } | 1106 | } |
1083 | 1107 | ||
1084 | /* put the current value to feature/mixer unit */ | 1108 | /* put the current value to feature/mixer unit */ |
1085 | static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1109 | static int mixer_ctl_feature_put(struct snd_kcontrol *kcontrol, |
1110 | struct snd_ctl_elem_value *ucontrol) | ||
1086 | { | 1111 | { |
1087 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1112 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1088 | int c, cnt, val, oval, err; | 1113 | int c, cnt, val, oval, err; |
@@ -1136,22 +1161,25 @@ static struct snd_kcontrol_new usb_feature_unit_ctl_ro = { | |||
1136 | .put = NULL, | 1161 | .put = NULL, |
1137 | }; | 1162 | }; |
1138 | 1163 | ||
1139 | /* This symbol is exported in order to allow the mixer quirks to | 1164 | /* |
1140 | * hook up to the standard feature unit control mechanism */ | 1165 | * This symbol is exported in order to allow the mixer quirks to |
1166 | * hook up to the standard feature unit control mechanism | ||
1167 | */ | ||
1141 | struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl; | 1168 | struct snd_kcontrol_new *snd_usb_feature_unit_ctl = &usb_feature_unit_ctl; |
1142 | 1169 | ||
1143 | /* | 1170 | /* |
1144 | * build a feature control | 1171 | * build a feature control |
1145 | */ | 1172 | */ |
1146 | |||
1147 | static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str) | 1173 | static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str) |
1148 | { | 1174 | { |
1149 | return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); | 1175 | return strlcat(kctl->id.name, str, sizeof(kctl->id.name)); |
1150 | } | 1176 | } |
1151 | 1177 | ||
1152 | /* A lot of headsets/headphones have a "Speaker" mixer. Make sure we | 1178 | /* |
1153 | rename it to "Headphone". We determine if something is a headphone | 1179 | * A lot of headsets/headphones have a "Speaker" mixer. Make sure we |
1154 | similar to how udev determines form factor. */ | 1180 | * rename it to "Headphone". We determine if something is a headphone |
1181 | * similar to how udev determines form factor. | ||
1182 | */ | ||
1155 | static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, | 1183 | static void check_no_speaker_on_headset(struct snd_kcontrol *kctl, |
1156 | struct snd_card *card) | 1184 | struct snd_card *card) |
1157 | { | 1185 | { |
@@ -1201,10 +1229,8 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1201 | return; | 1229 | return; |
1202 | 1230 | ||
1203 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1231 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1204 | if (! cval) { | 1232 | if (!cval) |
1205 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | ||
1206 | return; | 1233 | return; |
1207 | } | ||
1208 | cval->mixer = state->mixer; | 1234 | cval->mixer = state->mixer; |
1209 | cval->id = unitid; | 1235 | cval->id = unitid; |
1210 | cval->control = control; | 1236 | cval->control = control; |
@@ -1222,15 +1248,17 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1222 | cval->ch_readonly = readonly_mask; | 1248 | cval->ch_readonly = readonly_mask; |
1223 | } | 1249 | } |
1224 | 1250 | ||
1225 | /* if all channels in the mask are marked read-only, make the control | 1251 | /* |
1252 | * If all channels in the mask are marked read-only, make the control | ||
1226 | * read-only. set_cur_mix_value() will check the mask again and won't | 1253 | * read-only. set_cur_mix_value() will check the mask again and won't |
1227 | * issue write commands to read-only channels. */ | 1254 | * issue write commands to read-only channels. |
1255 | */ | ||
1228 | if (cval->channels == readonly_mask) | 1256 | if (cval->channels == readonly_mask) |
1229 | kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); | 1257 | kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval); |
1230 | else | 1258 | else |
1231 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); | 1259 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); |
1232 | 1260 | ||
1233 | if (! kctl) { | 1261 | if (!kctl) { |
1234 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | 1262 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); |
1235 | kfree(cval); | 1263 | kfree(cval); |
1236 | return; | 1264 | return; |
@@ -1239,48 +1267,53 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1239 | 1267 | ||
1240 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); | 1268 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
1241 | mapped_name = len != 0; | 1269 | mapped_name = len != 0; |
1242 | if (! len && nameid) | 1270 | if (!len && nameid) |
1243 | len = snd_usb_copy_string_desc(state, nameid, | 1271 | len = snd_usb_copy_string_desc(state, nameid, |
1244 | kctl->id.name, sizeof(kctl->id.name)); | 1272 | kctl->id.name, sizeof(kctl->id.name)); |
1245 | 1273 | ||
1246 | switch (control) { | 1274 | switch (control) { |
1247 | case UAC_FU_MUTE: | 1275 | case UAC_FU_MUTE: |
1248 | case UAC_FU_VOLUME: | 1276 | case UAC_FU_VOLUME: |
1249 | /* determine the control name. the rule is: | 1277 | /* |
1278 | * determine the control name. the rule is: | ||
1250 | * - if a name id is given in descriptor, use it. | 1279 | * - if a name id is given in descriptor, use it. |
1251 | * - if the connected input can be determined, then use the name | 1280 | * - if the connected input can be determined, then use the name |
1252 | * of terminal type. | 1281 | * of terminal type. |
1253 | * - if the connected output can be determined, use it. | 1282 | * - if the connected output can be determined, use it. |
1254 | * - otherwise, anonymous name. | 1283 | * - otherwise, anonymous name. |
1255 | */ | 1284 | */ |
1256 | if (! len) { | 1285 | if (!len) { |
1257 | len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 1); | 1286 | len = get_term_name(state, iterm, kctl->id.name, |
1258 | if (! len) | 1287 | sizeof(kctl->id.name), 1); |
1259 | len = get_term_name(state, &state->oterm, kctl->id.name, sizeof(kctl->id.name), 1); | 1288 | if (!len) |
1260 | if (! len) | 1289 | len = get_term_name(state, &state->oterm, |
1261 | len = snprintf(kctl->id.name, sizeof(kctl->id.name), | 1290 | kctl->id.name, |
1291 | sizeof(kctl->id.name), 1); | ||
1292 | if (!len) | ||
1293 | len = snprintf(kctl->id.name, | ||
1294 | sizeof(kctl->id.name), | ||
1262 | "Feature %d", unitid); | 1295 | "Feature %d", unitid); |
1263 | } | 1296 | } |
1264 | 1297 | ||
1265 | if (!mapped_name) | 1298 | if (!mapped_name) |
1266 | check_no_speaker_on_headset(kctl, state->mixer->chip->card); | 1299 | check_no_speaker_on_headset(kctl, state->mixer->chip->card); |
1267 | 1300 | ||
1268 | /* determine the stream direction: | 1301 | /* |
1302 | * determine the stream direction: | ||
1269 | * if the connected output is USB stream, then it's likely a | 1303 | * if the connected output is USB stream, then it's likely a |
1270 | * capture stream. otherwise it should be playback (hopefully :) | 1304 | * capture stream. otherwise it should be playback (hopefully :) |
1271 | */ | 1305 | */ |
1272 | if (! mapped_name && ! (state->oterm.type >> 16)) { | 1306 | if (!mapped_name && !(state->oterm.type >> 16)) { |
1273 | if ((state->oterm.type & 0xff00) == 0x0100) { | 1307 | if ((state->oterm.type & 0xff00) == 0x0100) |
1274 | len = append_ctl_name(kctl, " Capture"); | 1308 | len = append_ctl_name(kctl, " Capture"); |
1275 | } else { | 1309 | else |
1276 | len = append_ctl_name(kctl, " Playback"); | 1310 | len = append_ctl_name(kctl, " Playback"); |
1277 | } | ||
1278 | } | 1311 | } |
1279 | append_ctl_name(kctl, control == UAC_FU_MUTE ? | 1312 | append_ctl_name(kctl, control == UAC_FU_MUTE ? |
1280 | " Switch" : " Volume"); | 1313 | " Switch" : " Volume"); |
1281 | break; | 1314 | break; |
1282 | default: | 1315 | default: |
1283 | if (! len) | 1316 | if (!len) |
1284 | strlcpy(kctl->id.name, audio_feature_info[control-1].name, | 1317 | strlcpy(kctl->id.name, audio_feature_info[control-1].name, |
1285 | sizeof(kctl->id.name)); | 1318 | sizeof(kctl->id.name)); |
1286 | break; | 1319 | break; |
@@ -1300,33 +1333,35 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1300 | } | 1333 | } |
1301 | 1334 | ||
1302 | range = (cval->max - cval->min) / cval->res; | 1335 | range = (cval->max - cval->min) / cval->res; |
1303 | /* Are there devices with volume range more than 255? I use a bit more | 1336 | /* |
1337 | * Are there devices with volume range more than 255? I use a bit more | ||
1304 | * to be sure. 384 is a resolution magic number found on Logitech | 1338 | * to be sure. 384 is a resolution magic number found on Logitech |
1305 | * devices. It will definitively catch all buggy Logitech devices. | 1339 | * devices. It will definitively catch all buggy Logitech devices. |
1306 | */ | 1340 | */ |
1307 | if (range > 384) { | 1341 | if (range > 384) { |
1308 | usb_audio_warn(state->chip, "Warning! Unlikely big " | 1342 | usb_audio_warn(state->chip, |
1309 | "volume range (=%u), cval->res is probably wrong.", | 1343 | "Warning! Unlikely big volume range (=%u), " |
1310 | range); | 1344 | "cval->res is probably wrong.", |
1345 | range); | ||
1311 | usb_audio_warn(state->chip, "[%d] FU [%s] ch = %d, " | 1346 | usb_audio_warn(state->chip, "[%d] FU [%s] ch = %d, " |
1312 | "val = %d/%d/%d", cval->id, | 1347 | "val = %d/%d/%d", cval->id, |
1313 | kctl->id.name, cval->channels, | 1348 | kctl->id.name, cval->channels, |
1314 | cval->min, cval->max, cval->res); | 1349 | cval->min, cval->max, cval->res); |
1315 | } | 1350 | } |
1316 | 1351 | ||
1317 | usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", | 1352 | usb_audio_dbg(state->chip, "[%d] FU [%s] ch = %d, val = %d/%d/%d\n", |
1318 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max, cval->res); | 1353 | cval->id, kctl->id.name, cval->channels, |
1354 | cval->min, cval->max, cval->res); | ||
1319 | snd_usb_mixer_add_control(state->mixer, kctl); | 1355 | snd_usb_mixer_add_control(state->mixer, kctl); |
1320 | } | 1356 | } |
1321 | 1357 | ||
1322 | |||
1323 | |||
1324 | /* | 1358 | /* |
1325 | * parse a feature unit | 1359 | * parse a feature unit |
1326 | * | 1360 | * |
1327 | * most of controls are defined here. | 1361 | * most of controls are defined here. |
1328 | */ | 1362 | */ |
1329 | static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void *_ftr) | 1363 | static int parse_audio_feature_unit(struct mixer_build *state, int unitid, |
1364 | void *_ftr) | ||
1330 | { | 1365 | { |
1331 | int channels, i, j; | 1366 | int channels, i, j; |
1332 | struct usb_audio_term iterm; | 1367 | struct usb_audio_term iterm; |
@@ -1400,15 +1435,25 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1400 | for (i = 0; i < 10; i++) { | 1435 | for (i = 0; i < 10; i++) { |
1401 | unsigned int ch_bits = 0; | 1436 | unsigned int ch_bits = 0; |
1402 | for (j = 0; j < channels; j++) { | 1437 | for (j = 0; j < channels; j++) { |
1403 | unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); | 1438 | unsigned int mask; |
1439 | |||
1440 | mask = snd_usb_combine_bytes(bmaControls + | ||
1441 | csize * (j+1), csize); | ||
1404 | if (mask & (1 << i)) | 1442 | if (mask & (1 << i)) |
1405 | ch_bits |= (1 << j); | 1443 | ch_bits |= (1 << j); |
1406 | } | 1444 | } |
1407 | /* audio class v1 controls are never read-only */ | 1445 | /* audio class v1 controls are never read-only */ |
1408 | if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ | 1446 | |
1409 | build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, 0); | 1447 | /* |
1448 | * The first channel must be set | ||
1449 | * (for ease of programming). | ||
1450 | */ | ||
1451 | if (ch_bits & 1) | ||
1452 | build_feature_ctl(state, _ftr, ch_bits, i, | ||
1453 | &iterm, unitid, 0); | ||
1410 | if (master_bits & (1 << i)) | 1454 | if (master_bits & (1 << i)) |
1411 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); | 1455 | build_feature_ctl(state, _ftr, 0, i, &iterm, |
1456 | unitid, 0); | ||
1412 | } | 1457 | } |
1413 | } else { /* UAC_VERSION_2 */ | 1458 | } else { /* UAC_VERSION_2 */ |
1414 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { | 1459 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { |
@@ -1416,7 +1461,10 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1416 | unsigned int ch_read_only = 0; | 1461 | unsigned int ch_read_only = 0; |
1417 | 1462 | ||
1418 | for (j = 0; j < channels; j++) { | 1463 | for (j = 0; j < channels; j++) { |
1419 | unsigned int mask = snd_usb_combine_bytes(bmaControls + csize * (j+1), csize); | 1464 | unsigned int mask; |
1465 | |||
1466 | mask = snd_usb_combine_bytes(bmaControls + | ||
1467 | csize * (j+1), csize); | ||
1420 | if (uac2_control_is_readable(mask, i)) { | 1468 | if (uac2_control_is_readable(mask, i)) { |
1421 | ch_bits |= (1 << j); | 1469 | ch_bits |= (1 << j); |
1422 | if (!uac2_control_is_writeable(mask, i)) | 1470 | if (!uac2_control_is_writeable(mask, i)) |
@@ -1424,12 +1472,22 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1424 | } | 1472 | } |
1425 | } | 1473 | } |
1426 | 1474 | ||
1427 | /* NOTE: build_feature_ctl() will mark the control read-only if all channels | 1475 | /* |
1428 | * are marked read-only in the descriptors. Otherwise, the control will be | 1476 | * NOTE: build_feature_ctl() will mark the control |
1429 | * reported as writeable, but the driver will not actually issue a write | 1477 | * read-only if all channels are marked read-only in |
1430 | * command for read-only channels */ | 1478 | * the descriptors. Otherwise, the control will be |
1431 | if (ch_bits & 1) /* the first channel must be set (for ease of programming) */ | 1479 | * reported as writeable, but the driver will not |
1432 | build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only); | 1480 | * actually issue a write command for read-only |
1481 | * channels. | ||
1482 | */ | ||
1483 | |||
1484 | /* | ||
1485 | * The first channel must be set | ||
1486 | * (for ease of programming). | ||
1487 | */ | ||
1488 | if (ch_bits & 1) | ||
1489 | build_feature_ctl(state, _ftr, ch_bits, i, | ||
1490 | &iterm, unitid, ch_read_only); | ||
1433 | if (uac2_control_is_readable(master_bits, i)) | 1491 | if (uac2_control_is_readable(master_bits, i)) |
1434 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, | 1492 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, |
1435 | !uac2_control_is_writeable(master_bits, i)); | 1493 | !uac2_control_is_writeable(master_bits, i)); |
@@ -1439,7 +1497,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1439 | return 0; | 1497 | return 0; |
1440 | } | 1498 | } |
1441 | 1499 | ||
1442 | |||
1443 | /* | 1500 | /* |
1444 | * Mixer Unit | 1501 | * Mixer Unit |
1445 | */ | 1502 | */ |
@@ -1450,7 +1507,6 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
1450 | * the callbacks are identical with feature unit. | 1507 | * the callbacks are identical with feature unit. |
1451 | * input channel number (zero based) is given in control field instead. | 1508 | * input channel number (zero based) is given in control field instead. |
1452 | */ | 1509 | */ |
1453 | |||
1454 | static void build_mixer_unit_ctl(struct mixer_build *state, | 1510 | static void build_mixer_unit_ctl(struct mixer_build *state, |
1455 | struct uac_mixer_unit_descriptor *desc, | 1511 | struct uac_mixer_unit_descriptor *desc, |
1456 | int in_pin, int in_ch, int unitid, | 1512 | int in_pin, int in_ch, int unitid, |
@@ -1467,7 +1523,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1467 | return; | 1523 | return; |
1468 | 1524 | ||
1469 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1525 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1470 | if (! cval) | 1526 | if (!cval) |
1471 | return; | 1527 | return; |
1472 | 1528 | ||
1473 | cval->mixer = state->mixer; | 1529 | cval->mixer = state->mixer; |
@@ -1475,7 +1531,9 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1475 | cval->control = in_ch + 1; /* based on 1 */ | 1531 | cval->control = in_ch + 1; /* based on 1 */ |
1476 | cval->val_type = USB_MIXER_S16; | 1532 | cval->val_type = USB_MIXER_S16; |
1477 | for (i = 0; i < num_outs; i++) { | 1533 | for (i = 0; i < num_outs; i++) { |
1478 | if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), in_ch, i, num_outs)) { | 1534 | __u8 *c = uac_mixer_unit_bmControls(desc, state->mixer->protocol); |
1535 | |||
1536 | if (check_matrix_bitmap(c, in_ch, i, num_outs)) { | ||
1479 | cval->cmask |= (1 << i); | 1537 | cval->cmask |= (1 << i); |
1480 | cval->channels++; | 1538 | cval->channels++; |
1481 | } | 1539 | } |
@@ -1485,7 +1543,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1485 | get_min_max(cval, 0); | 1543 | get_min_max(cval, 0); |
1486 | 1544 | ||
1487 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); | 1545 | kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval); |
1488 | if (! kctl) { | 1546 | if (!kctl) { |
1489 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | 1547 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); |
1490 | kfree(cval); | 1548 | kfree(cval); |
1491 | return; | 1549 | return; |
@@ -1493,9 +1551,10 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1493 | kctl->private_free = usb_mixer_elem_free; | 1551 | kctl->private_free = usb_mixer_elem_free; |
1494 | 1552 | ||
1495 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); | 1553 | len = check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name)); |
1496 | if (! len) | 1554 | if (!len) |
1497 | len = get_term_name(state, iterm, kctl->id.name, sizeof(kctl->id.name), 0); | 1555 | len = get_term_name(state, iterm, kctl->id.name, |
1498 | if (! len) | 1556 | sizeof(kctl->id.name), 0); |
1557 | if (!len) | ||
1499 | len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); | 1558 | len = sprintf(kctl->id.name, "Mixer Source %d", in_ch + 1); |
1500 | append_ctl_name(kctl, " Volume"); | 1559 | append_ctl_name(kctl, " Volume"); |
1501 | 1560 | ||
@@ -1504,24 +1563,28 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1504 | snd_usb_mixer_add_control(state->mixer, kctl); | 1563 | snd_usb_mixer_add_control(state->mixer, kctl); |
1505 | } | 1564 | } |
1506 | 1565 | ||
1507 | |||
1508 | /* | 1566 | /* |
1509 | * parse a mixer unit | 1567 | * parse a mixer unit |
1510 | */ | 1568 | */ |
1511 | static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *raw_desc) | 1569 | static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, |
1570 | void *raw_desc) | ||
1512 | { | 1571 | { |
1513 | struct uac_mixer_unit_descriptor *desc = raw_desc; | 1572 | struct uac_mixer_unit_descriptor *desc = raw_desc; |
1514 | struct usb_audio_term iterm; | 1573 | struct usb_audio_term iterm; |
1515 | int input_pins, num_ins, num_outs; | 1574 | int input_pins, num_ins, num_outs; |
1516 | int pin, ich, err; | 1575 | int pin, ich, err; |
1517 | 1576 | ||
1518 | if (desc->bLength < 11 || ! (input_pins = desc->bNrInPins) || ! (num_outs = uac_mixer_unit_bNrChannels(desc))) { | 1577 | if (desc->bLength < 11 || !(input_pins = desc->bNrInPins) || |
1519 | usb_audio_err(state->chip, "invalid MIXER UNIT descriptor %d\n", unitid); | 1578 | !(num_outs = uac_mixer_unit_bNrChannels(desc))) { |
1579 | usb_audio_err(state->chip, | ||
1580 | "invalid MIXER UNIT descriptor %d\n", | ||
1581 | unitid); | ||
1520 | return -EINVAL; | 1582 | return -EINVAL; |
1521 | } | 1583 | } |
1522 | /* no bmControls field (e.g. Maya44) -> ignore */ | 1584 | /* no bmControls field (e.g. Maya44) -> ignore */ |
1523 | if (desc->bLength <= 10 + input_pins) { | 1585 | if (desc->bLength <= 10 + input_pins) { |
1524 | usb_audio_dbg(state->chip, "MU %d has no bmControls field\n", unitid); | 1586 | usb_audio_dbg(state->chip, "MU %d has no bmControls field\n", |
1587 | unitid); | ||
1525 | return 0; | 1588 | return 0; |
1526 | } | 1589 | } |
1527 | 1590 | ||
@@ -1535,12 +1598,14 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r | |||
1535 | if (err < 0) | 1598 | if (err < 0) |
1536 | return err; | 1599 | return err; |
1537 | num_ins += iterm.channels; | 1600 | num_ins += iterm.channels; |
1538 | for (; ich < num_ins; ++ich) { | 1601 | for (; ich < num_ins; ich++) { |
1539 | int och, ich_has_controls = 0; | 1602 | int och, ich_has_controls = 0; |
1540 | 1603 | ||
1541 | for (och = 0; och < num_outs; ++och) { | 1604 | for (och = 0; och < num_outs; och++) { |
1542 | if (check_matrix_bitmap(uac_mixer_unit_bmControls(desc, state->mixer->protocol), | 1605 | __u8 *c = uac_mixer_unit_bmControls(desc, |
1543 | ich, och, num_outs)) { | 1606 | state->mixer->protocol); |
1607 | |||
1608 | if (check_matrix_bitmap(c, ich, och, num_outs)) { | ||
1544 | ich_has_controls = 1; | 1609 | ich_has_controls = 1; |
1545 | break; | 1610 | break; |
1546 | } | 1611 | } |
@@ -1553,13 +1618,13 @@ static int parse_audio_mixer_unit(struct mixer_build *state, int unitid, void *r | |||
1553 | return 0; | 1618 | return 0; |
1554 | } | 1619 | } |
1555 | 1620 | ||
1556 | |||
1557 | /* | 1621 | /* |
1558 | * Processing Unit / Extension Unit | 1622 | * Processing Unit / Extension Unit |
1559 | */ | 1623 | */ |
1560 | 1624 | ||
1561 | /* get callback for processing/extension unit */ | 1625 | /* get callback for processing/extension unit */ |
1562 | static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1626 | static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, |
1627 | struct snd_ctl_elem_value *ucontrol) | ||
1563 | { | 1628 | { |
1564 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1629 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1565 | int err, val; | 1630 | int err, val; |
@@ -1577,7 +1642,8 @@ static int mixer_ctl_procunit_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1577 | } | 1642 | } |
1578 | 1643 | ||
1579 | /* put callback for processing/extension unit */ | 1644 | /* put callback for processing/extension unit */ |
1580 | static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1645 | static int mixer_ctl_procunit_put(struct snd_kcontrol *kcontrol, |
1646 | struct snd_ctl_elem_value *ucontrol) | ||
1581 | { | 1647 | { |
1582 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1648 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1583 | int val, oval, err; | 1649 | int val, oval, err; |
@@ -1606,7 +1672,6 @@ static struct snd_kcontrol_new mixer_procunit_ctl = { | |||
1606 | .put = mixer_ctl_procunit_put, | 1672 | .put = mixer_ctl_procunit_put, |
1607 | }; | 1673 | }; |
1608 | 1674 | ||
1609 | |||
1610 | /* | 1675 | /* |
1611 | * predefined data for processing units | 1676 | * predefined data for processing units |
1612 | */ | 1677 | */ |
@@ -1697,10 +1762,13 @@ static struct procunit_info extunits[] = { | |||
1697 | { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info }, | 1762 | { USB_XU_DEVICE_OPTIONS, "AnalogueIn Soft Limit", soft_limit_xu_info }, |
1698 | { 0 } | 1763 | { 0 } |
1699 | }; | 1764 | }; |
1765 | |||
1700 | /* | 1766 | /* |
1701 | * build a processing/extension unit | 1767 | * build a processing/extension unit |
1702 | */ | 1768 | */ |
1703 | static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw_desc, struct procunit_info *list, char *name) | 1769 | static int build_audio_procunit(struct mixer_build *state, int unitid, |
1770 | void *raw_desc, struct procunit_info *list, | ||
1771 | char *name) | ||
1704 | { | 1772 | { |
1705 | struct uac_processing_unit_descriptor *desc = raw_desc; | 1773 | struct uac_processing_unit_descriptor *desc = raw_desc; |
1706 | int num_ins = desc->bNrInPins; | 1774 | int num_ins = desc->bNrInPins; |
@@ -1733,22 +1801,20 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
1733 | for (info = list; info && info->type; info++) | 1801 | for (info = list; info && info->type; info++) |
1734 | if (info->type == type) | 1802 | if (info->type == type) |
1735 | break; | 1803 | break; |
1736 | if (! info || ! info->type) | 1804 | if (!info || !info->type) |
1737 | info = &default_info; | 1805 | info = &default_info; |
1738 | 1806 | ||
1739 | for (valinfo = info->values; valinfo->control; valinfo++) { | 1807 | for (valinfo = info->values; valinfo->control; valinfo++) { |
1740 | __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol); | 1808 | __u8 *controls = uac_processing_unit_bmControls(desc, state->mixer->protocol); |
1741 | 1809 | ||
1742 | if (! (controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) | 1810 | if (!(controls[valinfo->control / 8] & (1 << ((valinfo->control % 8) - 1)))) |
1743 | continue; | 1811 | continue; |
1744 | map = find_map(state, unitid, valinfo->control); | 1812 | map = find_map(state, unitid, valinfo->control); |
1745 | if (check_ignored_ctl(map)) | 1813 | if (check_ignored_ctl(map)) |
1746 | continue; | 1814 | continue; |
1747 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 1815 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1748 | if (! cval) { | 1816 | if (!cval) |
1749 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | ||
1750 | return -ENOMEM; | 1817 | return -ENOMEM; |
1751 | } | ||
1752 | cval->mixer = state->mixer; | 1818 | cval->mixer = state->mixer; |
1753 | cval->id = unitid; | 1819 | cval->id = unitid; |
1754 | cval->control = valinfo->control; | 1820 | cval->control = valinfo->control; |
@@ -1765,7 +1831,8 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
1765 | cval->initialized = 1; | 1831 | cval->initialized = 1; |
1766 | } else { | 1832 | } else { |
1767 | if (type == USB_XU_CLOCK_RATE) { | 1833 | if (type == USB_XU_CLOCK_RATE) { |
1768 | /* E-Mu USB 0404/0202/TrackerPre/0204 | 1834 | /* |
1835 | * E-Mu USB 0404/0202/TrackerPre/0204 | ||
1769 | * samplerate control quirk | 1836 | * samplerate control quirk |
1770 | */ | 1837 | */ |
1771 | cval->min = 0; | 1838 | cval->min = 0; |
@@ -1777,60 +1844,69 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
1777 | } | 1844 | } |
1778 | 1845 | ||
1779 | kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); | 1846 | kctl = snd_ctl_new1(&mixer_procunit_ctl, cval); |
1780 | if (! kctl) { | 1847 | if (!kctl) { |
1781 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | ||
1782 | kfree(cval); | 1848 | kfree(cval); |
1783 | return -ENOMEM; | 1849 | return -ENOMEM; |
1784 | } | 1850 | } |
1785 | kctl->private_free = usb_mixer_elem_free; | 1851 | kctl->private_free = usb_mixer_elem_free; |
1786 | 1852 | ||
1787 | if (check_mapped_name(map, kctl->id.name, | 1853 | if (check_mapped_name(map, kctl->id.name, sizeof(kctl->id.name))) { |
1788 | sizeof(kctl->id.name))) | ||
1789 | /* nothing */ ; | 1854 | /* nothing */ ; |
1790 | else if (info->name) | 1855 | } else if (info->name) { |
1791 | strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); | 1856 | strlcpy(kctl->id.name, info->name, sizeof(kctl->id.name)); |
1792 | else { | 1857 | } else { |
1793 | nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); | 1858 | nameid = uac_processing_unit_iProcessing(desc, state->mixer->protocol); |
1794 | len = 0; | 1859 | len = 0; |
1795 | if (nameid) | 1860 | if (nameid) |
1796 | len = snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); | 1861 | len = snd_usb_copy_string_desc(state, nameid, |
1797 | if (! len) | 1862 | kctl->id.name, |
1863 | sizeof(kctl->id.name)); | ||
1864 | if (!len) | ||
1798 | strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); | 1865 | strlcpy(kctl->id.name, name, sizeof(kctl->id.name)); |
1799 | } | 1866 | } |
1800 | append_ctl_name(kctl, " "); | 1867 | append_ctl_name(kctl, " "); |
1801 | append_ctl_name(kctl, valinfo->suffix); | 1868 | append_ctl_name(kctl, valinfo->suffix); |
1802 | 1869 | ||
1803 | usb_audio_dbg(state->chip, | 1870 | usb_audio_dbg(state->chip, |
1804 | "[%d] PU [%s] ch = %d, val = %d/%d\n", | 1871 | "[%d] PU [%s] ch = %d, val = %d/%d\n", |
1805 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); | 1872 | cval->id, kctl->id.name, cval->channels, |
1806 | if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) | 1873 | cval->min, cval->max); |
1874 | |||
1875 | err = snd_usb_mixer_add_control(state->mixer, kctl); | ||
1876 | if (err < 0) | ||
1807 | return err; | 1877 | return err; |
1808 | } | 1878 | } |
1809 | return 0; | 1879 | return 0; |
1810 | } | 1880 | } |
1811 | 1881 | ||
1812 | 1882 | static int parse_audio_processing_unit(struct mixer_build *state, int unitid, | |
1813 | static int parse_audio_processing_unit(struct mixer_build *state, int unitid, void *raw_desc) | 1883 | void *raw_desc) |
1814 | { | 1884 | { |
1815 | return build_audio_procunit(state, unitid, raw_desc, procunits, "Processing Unit"); | 1885 | return build_audio_procunit(state, unitid, raw_desc, |
1886 | procunits, "Processing Unit"); | ||
1816 | } | 1887 | } |
1817 | 1888 | ||
1818 | static int parse_audio_extension_unit(struct mixer_build *state, int unitid, void *raw_desc) | 1889 | static int parse_audio_extension_unit(struct mixer_build *state, int unitid, |
1890 | void *raw_desc) | ||
1819 | { | 1891 | { |
1820 | /* Note that we parse extension units with processing unit descriptors. | 1892 | /* |
1821 | * That's ok as the layout is the same */ | 1893 | * Note that we parse extension units with processing unit descriptors. |
1822 | return build_audio_procunit(state, unitid, raw_desc, extunits, "Extension Unit"); | 1894 | * That's ok as the layout is the same. |
1895 | */ | ||
1896 | return build_audio_procunit(state, unitid, raw_desc, | ||
1897 | extunits, "Extension Unit"); | ||
1823 | } | 1898 | } |
1824 | 1899 | ||
1825 | |||
1826 | /* | 1900 | /* |
1827 | * Selector Unit | 1901 | * Selector Unit |
1828 | */ | 1902 | */ |
1829 | 1903 | ||
1830 | /* info callback for selector unit | 1904 | /* |
1905 | * info callback for selector unit | ||
1831 | * use an enumerator type for routing | 1906 | * use an enumerator type for routing |
1832 | */ | 1907 | */ |
1833 | static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1908 | static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, |
1909 | struct snd_ctl_elem_info *uinfo) | ||
1834 | { | 1910 | { |
1835 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1911 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1836 | const char **itemlist = (const char **)kcontrol->private_value; | 1912 | const char **itemlist = (const char **)kcontrol->private_value; |
@@ -1841,7 +1917,8 @@ static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl | |||
1841 | } | 1917 | } |
1842 | 1918 | ||
1843 | /* get callback for selector unit */ | 1919 | /* get callback for selector unit */ |
1844 | static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1920 | static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, |
1921 | struct snd_ctl_elem_value *ucontrol) | ||
1845 | { | 1922 | { |
1846 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1923 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1847 | int val, err; | 1924 | int val, err; |
@@ -1860,7 +1937,8 @@ static int mixer_ctl_selector_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1860 | } | 1937 | } |
1861 | 1938 | ||
1862 | /* put callback for selector unit */ | 1939 | /* put callback for selector unit */ |
1863 | static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 1940 | static int mixer_ctl_selector_put(struct snd_kcontrol *kcontrol, |
1941 | struct snd_ctl_elem_value *ucontrol) | ||
1864 | { | 1942 | { |
1865 | struct usb_mixer_elem_info *cval = kcontrol->private_data; | 1943 | struct usb_mixer_elem_info *cval = kcontrol->private_data; |
1866 | int val, oval, err; | 1944 | int val, oval, err; |
@@ -1889,8 +1967,8 @@ static struct snd_kcontrol_new mixer_selectunit_ctl = { | |||
1889 | .put = mixer_ctl_selector_put, | 1967 | .put = mixer_ctl_selector_put, |
1890 | }; | 1968 | }; |
1891 | 1969 | ||
1892 | 1970 | /* | |
1893 | /* private free callback. | 1971 | * private free callback. |
1894 | * free both private_data and private_value | 1972 | * free both private_data and private_value |
1895 | */ | 1973 | */ |
1896 | static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl) | 1974 | static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl) |
@@ -1915,7 +1993,8 @@ static void usb_mixer_selector_elem_free(struct snd_kcontrol *kctl) | |||
1915 | /* | 1993 | /* |
1916 | * parse a selector unit | 1994 | * parse a selector unit |
1917 | */ | 1995 | */ |
1918 | static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void *raw_desc) | 1996 | static int parse_audio_selector_unit(struct mixer_build *state, int unitid, |
1997 | void *raw_desc) | ||
1919 | { | 1998 | { |
1920 | struct uac_selector_unit_descriptor *desc = raw_desc; | 1999 | struct uac_selector_unit_descriptor *desc = raw_desc; |
1921 | unsigned int i, nameid, len; | 2000 | unsigned int i, nameid, len; |
@@ -1944,10 +2023,8 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1944 | return 0; | 2023 | return 0; |
1945 | 2024 | ||
1946 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); | 2025 | cval = kzalloc(sizeof(*cval), GFP_KERNEL); |
1947 | if (! cval) { | 2026 | if (!cval) |
1948 | usb_audio_err(state->chip, "cannot malloc kcontrol\n"); | ||
1949 | return -ENOMEM; | 2027 | return -ENOMEM; |
1950 | } | ||
1951 | cval->mixer = state->mixer; | 2028 | cval->mixer = state->mixer; |
1952 | cval->id = unitid; | 2029 | cval->id = unitid; |
1953 | cval->val_type = USB_MIXER_U8; | 2030 | cval->val_type = USB_MIXER_U8; |
@@ -1963,8 +2040,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1963 | cval->control = 0; | 2040 | cval->control = 0; |
1964 | 2041 | ||
1965 | namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); | 2042 | namelist = kmalloc(sizeof(char *) * desc->bNrInPins, GFP_KERNEL); |
1966 | if (! namelist) { | 2043 | if (!namelist) { |
1967 | usb_audio_err(state->chip, "cannot malloc\n"); | ||
1968 | kfree(cval); | 2044 | kfree(cval); |
1969 | return -ENOMEM; | 2045 | return -ENOMEM; |
1970 | } | 2046 | } |
@@ -1973,8 +2049,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1973 | struct usb_audio_term iterm; | 2049 | struct usb_audio_term iterm; |
1974 | len = 0; | 2050 | len = 0; |
1975 | namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); | 2051 | namelist[i] = kmalloc(MAX_ITEM_NAME_LEN, GFP_KERNEL); |
1976 | if (! namelist[i]) { | 2052 | if (!namelist[i]) { |
1977 | usb_audio_err(state->chip, "cannot malloc\n"); | ||
1978 | while (i--) | 2053 | while (i--) |
1979 | kfree(namelist[i]); | 2054 | kfree(namelist[i]); |
1980 | kfree(namelist); | 2055 | kfree(namelist); |
@@ -1986,7 +2061,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1986 | if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0) | 2061 | if (! len && check_input_term(state, desc->baSourceID[i], &iterm) >= 0) |
1987 | len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); | 2062 | len = get_term_name(state, &iterm, namelist[i], MAX_ITEM_NAME_LEN, 0); |
1988 | if (! len) | 2063 | if (! len) |
1989 | sprintf(namelist[i], "Input %d", i); | 2064 | sprintf(namelist[i], "Input %u", i); |
1990 | } | 2065 | } |
1991 | 2066 | ||
1992 | kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval); | 2067 | kctl = snd_ctl_new1(&mixer_selectunit_ctl, cval); |
@@ -2004,11 +2079,12 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
2004 | if (len) | 2079 | if (len) |
2005 | ; | 2080 | ; |
2006 | else if (nameid) | 2081 | else if (nameid) |
2007 | snd_usb_copy_string_desc(state, nameid, kctl->id.name, sizeof(kctl->id.name)); | 2082 | snd_usb_copy_string_desc(state, nameid, kctl->id.name, |
2083 | sizeof(kctl->id.name)); | ||
2008 | else { | 2084 | else { |
2009 | len = get_term_name(state, &state->oterm, | 2085 | len = get_term_name(state, &state->oterm, |
2010 | kctl->id.name, sizeof(kctl->id.name), 0); | 2086 | kctl->id.name, sizeof(kctl->id.name), 0); |
2011 | if (! len) | 2087 | if (!len) |
2012 | strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); | 2088 | strlcpy(kctl->id.name, "USB", sizeof(kctl->id.name)); |
2013 | 2089 | ||
2014 | if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) | 2090 | if (desc->bDescriptorSubtype == UAC2_CLOCK_SELECTOR) |
@@ -2027,7 +2103,6 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
2027 | return 0; | 2103 | return 0; |
2028 | } | 2104 | } |
2029 | 2105 | ||
2030 | |||
2031 | /* | 2106 | /* |
2032 | * parse an audio unit recursively | 2107 | * parse an audio unit recursively |
2033 | */ | 2108 | */ |
@@ -2125,14 +2200,16 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2125 | } | 2200 | } |
2126 | 2201 | ||
2127 | p = NULL; | 2202 | p = NULL; |
2128 | while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, mixer->hostif->extralen, | 2203 | while ((p = snd_usb_find_csint_desc(mixer->hostif->extra, |
2204 | mixer->hostif->extralen, | ||
2129 | p, UAC_OUTPUT_TERMINAL)) != NULL) { | 2205 | p, UAC_OUTPUT_TERMINAL)) != NULL) { |
2130 | if (mixer->protocol == UAC_VERSION_1) { | 2206 | if (mixer->protocol == UAC_VERSION_1) { |
2131 | struct uac1_output_terminal_descriptor *desc = p; | 2207 | struct uac1_output_terminal_descriptor *desc = p; |
2132 | 2208 | ||
2133 | if (desc->bLength < sizeof(*desc)) | 2209 | if (desc->bLength < sizeof(*desc)) |
2134 | continue; /* invalid descriptor? */ | 2210 | continue; /* invalid descriptor? */ |
2135 | set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */ | 2211 | /* mark terminal ID as visited */ |
2212 | set_bit(desc->bTerminalID, state.unitbitmap); | ||
2136 | state.oterm.id = desc->bTerminalID; | 2213 | state.oterm.id = desc->bTerminalID; |
2137 | state.oterm.type = le16_to_cpu(desc->wTerminalType); | 2214 | state.oterm.type = le16_to_cpu(desc->wTerminalType); |
2138 | state.oterm.name = desc->iTerminal; | 2215 | state.oterm.name = desc->iTerminal; |
@@ -2144,7 +2221,8 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2144 | 2221 | ||
2145 | if (desc->bLength < sizeof(*desc)) | 2222 | if (desc->bLength < sizeof(*desc)) |
2146 | continue; /* invalid descriptor? */ | 2223 | continue; /* invalid descriptor? */ |
2147 | set_bit(desc->bTerminalID, state.unitbitmap); /* mark terminal ID as visited */ | 2224 | /* mark terminal ID as visited */ |
2225 | set_bit(desc->bTerminalID, state.unitbitmap); | ||
2148 | state.oterm.id = desc->bTerminalID; | 2226 | state.oterm.id = desc->bTerminalID; |
2149 | state.oterm.type = le16_to_cpu(desc->wTerminalType); | 2227 | state.oterm.type = le16_to_cpu(desc->wTerminalType); |
2150 | state.oterm.name = desc->iTerminal; | 2228 | state.oterm.name = desc->iTerminal; |
@@ -2152,7 +2230,10 @@ static int snd_usb_mixer_controls(struct usb_mixer_interface *mixer) | |||
2152 | if (err < 0 && err != -EINVAL) | 2230 | if (err < 0 && err != -EINVAL) |
2153 | return err; | 2231 | return err; |
2154 | 2232 | ||
2155 | /* for UAC2, use the same approach to also add the clock selectors */ | 2233 | /* |
2234 | * For UAC2, use the same approach to also add the | ||
2235 | * clock selectors | ||
2236 | */ | ||
2156 | err = parse_audio_unit(&state, desc->bCSourceID); | 2237 | err = parse_audio_unit(&state, desc->bCSourceID); |
2157 | if (err < 0 && err != -EINVAL) | 2238 | if (err < 0 && err != -EINVAL) |
2158 | return err; | 2239 | return err; |
@@ -2306,7 +2387,9 @@ static void snd_usb_mixer_interrupt(struct urb *urb) | |||
2306 | } | 2387 | } |
2307 | 2388 | ||
2308 | requeue: | 2389 | requeue: |
2309 | if (ustatus != -ENOENT && ustatus != -ECONNRESET && ustatus != -ESHUTDOWN) { | 2390 | if (ustatus != -ENOENT && |
2391 | ustatus != -ECONNRESET && | ||
2392 | ustatus != -ESHUTDOWN) { | ||
2310 | urb->dev = mixer->chip->dev; | 2393 | urb->dev = mixer->chip->dev; |
2311 | usb_submit_urb(urb, GFP_ATOMIC); | 2394 | usb_submit_urb(urb, GFP_ATOMIC); |
2312 | } | 2395 | } |