diff options
389 files changed, 25739 insertions, 12181 deletions
diff --git a/Documentation/DocBook/writing-an-alsa-driver.tmpl b/Documentation/DocBook/writing-an-alsa-driver.tmpl index 598c22f3b3ac..5de23c007078 100644 --- a/Documentation/DocBook/writing-an-alsa-driver.tmpl +++ b/Documentation/DocBook/writing-an-alsa-driver.tmpl | |||
| @@ -4288,7 +4288,7 @@ struct _snd_pcm_runtime { | |||
| 4288 | <![CDATA[ | 4288 | <![CDATA[ |
| 4289 | struct snd_rawmidi *rmidi; | 4289 | struct snd_rawmidi *rmidi; |
| 4290 | snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags, | 4290 | snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port, info_flags, |
| 4291 | irq, irq_flags, &rmidi); | 4291 | irq, &rmidi); |
| 4292 | ]]> | 4292 | ]]> |
| 4293 | </programlisting> | 4293 | </programlisting> |
| 4294 | </informalexample> | 4294 | </informalexample> |
| @@ -4343,6 +4343,13 @@ struct _snd_pcm_runtime { | |||
| 4343 | by itself to start processing the output stream in the irq handler. | 4343 | by itself to start processing the output stream in the irq handler. |
| 4344 | </para> | 4344 | </para> |
| 4345 | 4345 | ||
| 4346 | <para> | ||
| 4347 | If the MPU-401 interface shares its interrupt with the other logical | ||
| 4348 | devices on the card, set <constant>MPU401_INFO_IRQ_HOOK</constant> | ||
| 4349 | (see <link linkend="midi-interface-interrupt-handler"><citetitle> | ||
| 4350 | below</citetitle></link>). | ||
| 4351 | </para> | ||
| 4352 | |||
| 4346 | <para> | 4353 | <para> |
| 4347 | Usually, the port address corresponds to the command port and | 4354 | Usually, the port address corresponds to the command port and |
| 4348 | port + 1 corresponds to the data port. If not, you may change | 4355 | port + 1 corresponds to the data port. If not, you may change |
| @@ -4375,14 +4382,12 @@ struct _snd_pcm_runtime { | |||
| 4375 | </para> | 4382 | </para> |
| 4376 | 4383 | ||
| 4377 | <para> | 4384 | <para> |
| 4378 | The 6th argument specifies the irq number for UART. If the irq | 4385 | The 6th argument specifies the ISA irq number that will be |
| 4379 | is already allocated, pass 0 to the 7th argument | 4386 | allocated. If no interrupt is to be allocated (because your |
| 4380 | (<parameter>irq_flags</parameter>). Otherwise, pass the flags | 4387 | code is already allocating a shared interrupt, or because the |
| 4381 | for irq allocation | 4388 | device does not use interrupts), pass -1 instead. |
| 4382 | (<constant>SA_XXX</constant> bits) to it, and the irq will be | 4389 | For a MPU-401 device without an interrupt, a polling timer |
| 4383 | reserved by the mpu401-uart layer. If the card doesn't generate | 4390 | will be used instead. |
| 4384 | UART interrupts, pass -1 as the irq number. Then a timer | ||
| 4385 | interrupt will be invoked for polling. | ||
| 4386 | </para> | 4391 | </para> |
| 4387 | </section> | 4392 | </section> |
| 4388 | 4393 | ||
| @@ -4390,12 +4395,13 @@ struct _snd_pcm_runtime { | |||
| 4390 | <title>Interrupt Handler</title> | 4395 | <title>Interrupt Handler</title> |
| 4391 | <para> | 4396 | <para> |
| 4392 | When the interrupt is allocated in | 4397 | When the interrupt is allocated in |
| 4393 | <function>snd_mpu401_uart_new()</function>, the private | 4398 | <function>snd_mpu401_uart_new()</function>, an exclusive ISA |
| 4394 | interrupt handler is used, hence you don't have anything else to do | 4399 | interrupt handler is automatically used, hence you don't have |
| 4395 | than creating the mpu401 stuff. Otherwise, you have to call | 4400 | anything else to do than creating the mpu401 stuff. Otherwise, you |
| 4396 | <function>snd_mpu401_uart_interrupt()</function> explicitly when | 4401 | have to set <constant>MPU401_INFO_IRQ_HOOK</constant>, and call |
| 4397 | a UART interrupt is invoked and checked in your own interrupt | 4402 | <function>snd_mpu401_uart_interrupt()</function> explicitly from your |
| 4398 | handler. | 4403 | own interrupt handler when it has determined that a UART interrupt |
| 4404 | has occurred. | ||
| 4399 | </para> | 4405 | </para> |
| 4400 | 4406 | ||
| 4401 | <para> | 4407 | <para> |
diff --git a/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt b/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt new file mode 100644 index 000000000000..2c3cd413f042 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/soc/codecs/fsl-sgtl5000.txt | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | * Freescale SGTL5000 Stereo Codec | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : "fsl,sgtl5000". | ||
| 5 | |||
| 6 | Example: | ||
| 7 | |||
| 8 | codec: sgtl5000@0a { | ||
| 9 | compatible = "fsl,sgtl5000"; | ||
| 10 | reg = <0x0a>; | ||
| 11 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8510.txt b/Documentation/devicetree/bindings/sound/wm8510.txt new file mode 100644 index 000000000000..fa1a32b85577 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8510.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8510 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8510" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8510@1a { | ||
| 16 | compatible = "wlf,wm8510"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8523.txt b/Documentation/devicetree/bindings/sound/wm8523.txt new file mode 100644 index 000000000000..04746186b283 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8523.txt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | WM8523 audio CODEC | ||
| 2 | |||
| 3 | This device supports I2C only. | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | |||
| 7 | - compatible : "wlf,wm8523" | ||
| 8 | |||
| 9 | - reg : the I2C address of the device. | ||
| 10 | |||
| 11 | Example: | ||
| 12 | |||
| 13 | codec: wm8523@1a { | ||
| 14 | compatible = "wlf,wm8523"; | ||
| 15 | reg = <0x1a>; | ||
| 16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8580.txt b/Documentation/devicetree/bindings/sound/wm8580.txt new file mode 100644 index 000000000000..7d9821f348da --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8580.txt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | WM8580 audio CODEC | ||
| 2 | |||
| 3 | This device supports I2C only. | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | |||
| 7 | - compatible : "wlf,wm8580" | ||
| 8 | |||
| 9 | - reg : the I2C address of the device. | ||
| 10 | |||
| 11 | Example: | ||
| 12 | |||
| 13 | codec: wm8580@1a { | ||
| 14 | compatible = "wlf,wm8580"; | ||
| 15 | reg = <0x1a>; | ||
| 16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8711.txt b/Documentation/devicetree/bindings/sound/wm8711.txt new file mode 100644 index 000000000000..8ed9998cd23c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8711.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8711 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8711" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8711@1a { | ||
| 16 | compatible = "wlf,wm8711"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8728.txt b/Documentation/devicetree/bindings/sound/wm8728.txt new file mode 100644 index 000000000000..a8b5c3668e60 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8728.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8728 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8728" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8728@1a { | ||
| 16 | compatible = "wlf,wm8728"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8731.txt b/Documentation/devicetree/bindings/sound/wm8731.txt new file mode 100644 index 000000000000..15f70048469b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8731.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8731 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8731" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8731@1a { | ||
| 16 | compatible = "wlf,wm8731"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8737.txt b/Documentation/devicetree/bindings/sound/wm8737.txt new file mode 100644 index 000000000000..4bc2cea3b140 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8737.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8737 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8737" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8737@1a { | ||
| 16 | compatible = "wlf,wm8737"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8741.txt b/Documentation/devicetree/bindings/sound/wm8741.txt new file mode 100644 index 000000000000..74bda58c1bcf --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8741.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8741 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8741" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8741@1a { | ||
| 16 | compatible = "wlf,wm8741"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8750.txt b/Documentation/devicetree/bindings/sound/wm8750.txt new file mode 100644 index 000000000000..8db239fd5ecd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8750.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8750 and WM8987 audio CODECs | ||
| 2 | |||
| 3 | These devices support both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8750" or "wlf,wm8987" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8750@1a { | ||
| 16 | compatible = "wlf,wm8750"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8753.txt b/Documentation/devicetree/bindings/sound/wm8753.txt new file mode 100644 index 000000000000..e65277a0fb60 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8753.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8753 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8753" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8737@1a { | ||
| 16 | compatible = "wlf,wm8753"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8770.txt b/Documentation/devicetree/bindings/sound/wm8770.txt new file mode 100644 index 000000000000..866e00ca150b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8770.txt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | WM8770 audio CODEC | ||
| 2 | |||
| 3 | This device supports SPI. | ||
| 4 | |||
| 5 | Required properties: | ||
| 6 | |||
| 7 | - compatible : "wlf,wm8770" | ||
| 8 | |||
| 9 | - reg : the chip select number. | ||
| 10 | |||
| 11 | Example: | ||
| 12 | |||
| 13 | codec: wm8770@1 { | ||
| 14 | compatible = "wlf,wm8770"; | ||
| 15 | reg = <1>; | ||
| 16 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8776.txt b/Documentation/devicetree/bindings/sound/wm8776.txt new file mode 100644 index 000000000000..3b9ca49abc2b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8776.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8776 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8776" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8776@1a { | ||
| 16 | compatible = "wlf,wm8776"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/devicetree/bindings/sound/wm8804.txt b/Documentation/devicetree/bindings/sound/wm8804.txt new file mode 100644 index 000000000000..4d3a56f38adc --- /dev/null +++ b/Documentation/devicetree/bindings/sound/wm8804.txt | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | WM8804 audio CODEC | ||
| 2 | |||
| 3 | This device supports both I2C and SPI (configured with pin strapping | ||
| 4 | on the board). | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | |||
| 8 | - compatible : "wlf,wm8804" | ||
| 9 | |||
| 10 | - reg : the I2C address of the device for I2C, the chip select | ||
| 11 | number for SPI. | ||
| 12 | |||
| 13 | Example: | ||
| 14 | |||
| 15 | codec: wm8804@1a { | ||
| 16 | compatible = "wlf,wm8804"; | ||
| 17 | reg = <0x1a>; | ||
| 18 | }; | ||
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index 89757012c7ff..936699e4f04b 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
| @@ -886,6 +886,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
| 886 | disable) | 886 | disable) |
| 887 | power_save_controller - Reset HD-audio controller in power-saving mode | 887 | power_save_controller - Reset HD-audio controller in power-saving mode |
| 888 | (default = on) | 888 | (default = on) |
| 889 | align_buffer_size - Force rounding of buffer/period sizes to multiples | ||
| 890 | of 128 bytes. This is more efficient in terms of memory | ||
| 891 | access but isn't required by the HDA spec and prevents | ||
| 892 | users from specifying exact period/buffer sizes. | ||
| 893 | (default = on) | ||
| 894 | snoop - Enable/disable snooping (default = on) | ||
| 889 | 895 | ||
| 890 | This module supports multiple cards and autoprobe. | 896 | This module supports multiple cards and autoprobe. |
| 891 | 897 | ||
diff --git a/Documentation/sound/alsa/HD-Audio-Controls.txt b/Documentation/sound/alsa/HD-Audio-Controls.txt index 1482035243e6..e9621e349e17 100644 --- a/Documentation/sound/alsa/HD-Audio-Controls.txt +++ b/Documentation/sound/alsa/HD-Audio-Controls.txt | |||
| @@ -98,3 +98,19 @@ Conexant codecs | |||
| 98 | 98 | ||
| 99 | * Auto-Mute Mode | 99 | * Auto-Mute Mode |
| 100 | See Reatek codecs. | 100 | See Reatek codecs. |
| 101 | |||
| 102 | |||
| 103 | Analog codecs | ||
| 104 | -------------- | ||
| 105 | |||
| 106 | * Channel Mode | ||
| 107 | This is an enum control to change the surround-channel setup, | ||
| 108 | appears only when the surround channels are available. | ||
| 109 | It gives the number of channels to be used, "2ch", "4ch" and "6ch". | ||
| 110 | According to the configuration, this also controls the | ||
| 111 | jack-retasking of multi-I/O jacks. | ||
| 112 | |||
| 113 | * Independent HP | ||
| 114 | When this enum control is enabled, the headphone output is routed | ||
| 115 | from an individual stream (the third PCM such as hw:0,2) instead of | ||
| 116 | the primary stream. | ||
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index d70c93bdcadf..4f3443230d89 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
| @@ -29,9 +29,6 @@ ALC880 | |||
| 29 | 29 | ||
| 30 | ALC260 | 30 | ALC260 |
| 31 | ====== | 31 | ====== |
| 32 | hp HP machines | ||
| 33 | hp-3013 HP machines (3013-variant) | ||
| 34 | hp-dc7600 HP DC7600 | ||
| 35 | fujitsu Fujitsu S7020 | 32 | fujitsu Fujitsu S7020 |
| 36 | acer Acer TravelMate | 33 | acer Acer TravelMate |
| 37 | will Will laptops (PB V7900) | 34 | will Will laptops (PB V7900) |
| @@ -46,15 +43,10 @@ ALC260 | |||
| 46 | ALC262 | 43 | ALC262 |
| 47 | ====== | 44 | ====== |
| 48 | fujitsu Fujitsu Laptop | 45 | fujitsu Fujitsu Laptop |
| 49 | hp-bpc HP xw4400/6400/8400/9400 laptops | ||
| 50 | hp-bpc-d7000 HP BPC D7000 | ||
| 51 | hp-tc-t5735 HP Thin Client T5735 | ||
| 52 | hp-rp5700 HP RP5700 | ||
| 53 | benq Benq ED8 | 46 | benq Benq ED8 |
| 54 | benq-t31 Benq T31 | 47 | benq-t31 Benq T31 |
| 55 | hippo Hippo (ATI) with jack detection, Sony UX-90s | 48 | hippo Hippo (ATI) with jack detection, Sony UX-90s |
| 56 | hippo_1 Hippo (Benq) with jack detection | 49 | hippo_1 Hippo (Benq) with jack detection |
| 57 | sony-assamd Sony ASSAMD | ||
| 58 | toshiba-s06 Toshiba S06 | 50 | toshiba-s06 Toshiba S06 |
| 59 | toshiba-rx1 Toshiba RX1 | 51 | toshiba-rx1 Toshiba RX1 |
| 60 | tyan Tyan Thunder n6650W (S2915-E) | 52 | tyan Tyan Thunder n6650W (S2915-E) |
| @@ -66,43 +58,15 @@ ALC262 | |||
| 66 | 58 | ||
| 67 | ALC267/268 | 59 | ALC267/268 |
| 68 | ========== | 60 | ========== |
| 69 | quanta-il1 Quanta IL1 mini-notebook | 61 | N/A |
| 70 | 3stack 3-stack model | ||
| 71 | toshiba Toshiba A205 | ||
| 72 | acer Acer laptops | ||
| 73 | acer-dmic Acer laptops with digital-mic | ||
| 74 | acer-aspire Acer Aspire One | ||
| 75 | dell Dell OEM laptops (Vostro 1200) | ||
| 76 | zepto Zepto laptops | ||
| 77 | test for testing/debugging purpose, almost all controls can | ||
| 78 | adjusted. Appearing only when compiled with | ||
| 79 | $CONFIG_SND_DEBUG=y | ||
| 80 | auto auto-config reading BIOS (default) | ||
| 81 | 62 | ||
| 82 | ALC269 | 63 | ALC269 |
| 83 | ====== | 64 | ====== |
| 84 | basic Basic preset | ||
| 85 | quanta Quanta FL1 | ||
| 86 | laptop-amic Laptops with analog-mic input | 65 | laptop-amic Laptops with analog-mic input |
| 87 | laptop-dmic Laptops with digital-mic input | 66 | laptop-dmic Laptops with digital-mic input |
| 88 | fujitsu FSC Amilo | ||
| 89 | lifebook Fujitsu Lifebook S6420 | ||
| 90 | auto auto-config reading BIOS (default) | ||
| 91 | 67 | ||
| 92 | ALC662/663/272 | 68 | ALC662/663/272 |
| 93 | ============== | 69 | ============== |
| 94 | 3stack-dig 3-stack (2-channel) with SPDIF | ||
| 95 | 3stack-6ch 3-stack (6-channel) | ||
| 96 | 3stack-6ch-dig 3-stack (6-channel) with SPDIF | ||
| 97 | 5stack-dig 5-stack with SPDIF | ||
| 98 | lenovo-101e Lenovo laptop | ||
| 99 | eeepc-p701 ASUS Eeepc P701 | ||
| 100 | eeepc-ep20 ASUS Eeepc EP20 | ||
| 101 | ecs ECS/Foxconn mobo | ||
| 102 | m51va ASUS M51VA | ||
| 103 | g71v ASUS G71V | ||
| 104 | h13 ASUS H13 | ||
| 105 | g50v ASUS G50V | ||
| 106 | asus-mode1 ASUS | 70 | asus-mode1 ASUS |
| 107 | asus-mode2 ASUS | 71 | asus-mode2 ASUS |
| 108 | asus-mode3 ASUS | 72 | asus-mode3 ASUS |
| @@ -111,15 +75,10 @@ ALC662/663/272 | |||
| 111 | asus-mode6 ASUS | 75 | asus-mode6 ASUS |
| 112 | asus-mode7 ASUS | 76 | asus-mode7 ASUS |
| 113 | asus-mode8 ASUS | 77 | asus-mode8 ASUS |
| 114 | dell Dell with ALC272 | ||
| 115 | dell-zm1 Dell ZM1 with ALC272 | ||
| 116 | samsung-nc10 Samsung NC10 mini notebook | ||
| 117 | auto auto-config reading BIOS (default) | ||
| 118 | 78 | ||
| 119 | ALC680 | 79 | ALC680 |
| 120 | ====== | 80 | ====== |
| 121 | base Base model (ASUS NX90) | 81 | N/A |
| 122 | auto auto-config reading BIOS (default) | ||
| 123 | 82 | ||
| 124 | ALC882/883/885/888/889 | 83 | ALC882/883/885/888/889 |
| 125 | ====================== | 84 | ====================== |
| @@ -175,28 +134,11 @@ ALC882/883/885/888/889 | |||
| 175 | 134 | ||
| 176 | ALC861/660 | 135 | ALC861/660 |
| 177 | ========== | 136 | ========== |
| 178 | 3stack 3-jack | 137 | N/A |
| 179 | 3stack-dig 3-jack with SPDIF I/O | ||
| 180 | 6stack-dig 6-jack with SPDIF I/O | ||
| 181 | 3stack-660 3-jack (for ALC660) | ||
| 182 | uniwill-m31 Uniwill M31 laptop | ||
| 183 | toshiba Toshiba laptop support | ||
| 184 | asus Asus laptop support | ||
| 185 | asus-laptop ASUS F2/F3 laptops | ||
| 186 | auto auto-config reading BIOS (default) | ||
| 187 | 138 | ||
| 188 | ALC861VD/660VD | 139 | ALC861VD/660VD |
| 189 | ============== | 140 | ============== |
| 190 | 3stack 3-jack | 141 | N/A |
| 191 | 3stack-dig 3-jack with SPDIF OUT | ||
| 192 | 6stack-dig 6-jack with SPDIF OUT | ||
| 193 | 3stack-660 3-jack (for ALC660VD) | ||
| 194 | 3stack-660-digout 3-jack with SPDIF OUT (for ALC660VD) | ||
| 195 | lenovo Lenovo 3000 C200 | ||
| 196 | dallas Dallas laptops | ||
| 197 | hp HP TX1000 | ||
| 198 | asus-v1s ASUS V1Sn | ||
| 199 | auto auto-config reading BIOS (default) | ||
| 200 | 142 | ||
| 201 | CMI9880 | 143 | CMI9880 |
| 202 | ======= | 144 | ======= |
| @@ -289,7 +231,6 @@ Conexant 5051 | |||
| 289 | hp-dv6736 HP dv6736 | 231 | hp-dv6736 HP dv6736 |
| 290 | hp-f700 HP Compaq Presario F700 | 232 | hp-f700 HP Compaq Presario F700 |
| 291 | ideapad Lenovo IdeaPad laptop | 233 | ideapad Lenovo IdeaPad laptop |
| 292 | lenovo-x200 Lenovo X200 laptop | ||
| 293 | toshiba Toshiba Satellite M300 | 234 | toshiba Toshiba Satellite M300 |
| 294 | 235 | ||
| 295 | Conexant 5066 | 236 | Conexant 5066 |
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt index c82beb007634..03e2771ddeef 100644 --- a/Documentation/sound/alsa/HD-Audio.txt +++ b/Documentation/sound/alsa/HD-Audio.txt | |||
| @@ -447,7 +447,10 @@ The file needs to have a line `[codec]`. The next line should contain | |||
| 447 | three numbers indicating the codec vendor-id (0x12345678 in the | 447 | three numbers indicating the codec vendor-id (0x12345678 in the |
| 448 | example), the codec subsystem-id (0xabcd1234) and the address (2) of | 448 | example), the codec subsystem-id (0xabcd1234) and the address (2) of |
| 449 | the codec. The rest patch entries are applied to this specified codec | 449 | the codec. The rest patch entries are applied to this specified codec |
| 450 | until another codec entry is given. | 450 | until another codec entry is given. Passing 0 or a negative number to |
| 451 | the first or the second value will make the check of the corresponding | ||
| 452 | field be skipped. It'll be useful for really broken devices that don't | ||
| 453 | initialize SSID properly. | ||
| 451 | 454 | ||
| 452 | The `[model]` line allows to change the model name of the each codec. | 455 | The `[model]` line allows to change the model name of the each codec. |
| 453 | In the example above, it will be changed to model=auto. | 456 | In the example above, it will be changed to model=auto. |
| @@ -491,7 +494,7 @@ Also, the codec chip name can be rewritten via `[chip_name]` line. | |||
| 491 | The hd-audio driver reads the file via request_firmware(). Thus, | 494 | The hd-audio driver reads the file via request_firmware(). Thus, |
| 492 | a patch file has to be located on the appropriate firmware path, | 495 | a patch file has to be located on the appropriate firmware path, |
| 493 | typically, /lib/firmware. For example, when you pass the option | 496 | typically, /lib/firmware. For example, when you pass the option |
| 494 | `patch=hda-init.fw`, the file /lib/firmware/hda-init-fw must be | 497 | `patch=hda-init.fw`, the file /lib/firmware/hda-init.fw must be |
| 495 | present. | 498 | present. |
| 496 | 499 | ||
| 497 | The patch module option is specific to each card instance, and you | 500 | The patch module option is specific to each card instance, and you |
| @@ -524,6 +527,54 @@ power-saving. See /sys/module/snd_hda_intel/parameters/power_save to | |||
| 524 | check the current value. If it's non-zero, the feature is turned on. | 527 | check the current value. If it's non-zero, the feature is turned on. |
| 525 | 528 | ||
| 526 | 529 | ||
| 530 | Tracepoints | ||
| 531 | ~~~~~~~~~~~ | ||
| 532 | The hd-audio driver gives a few basic tracepoints. | ||
| 533 | `hda:hda_send_cmd` traces each CORB write while `hda:hda_get_response` | ||
| 534 | traces the response from RIRB (only when read from the codec driver). | ||
| 535 | `hda:hda_bus_reset` traces the bus-reset due to fatal error, etc, | ||
| 536 | `hda:hda_unsol_event` traces the unsolicited events, and | ||
| 537 | `hda:hda_power_down` and `hda:hda_power_up` trace the power down/up | ||
| 538 | via power-saving behavior. | ||
| 539 | |||
| 540 | Enabling all tracepoints can be done like | ||
| 541 | ------------------------------------------------------------------------ | ||
| 542 | # echo 1 > /sys/kernel/debug/tracing/events/hda/enable | ||
| 543 | ------------------------------------------------------------------------ | ||
| 544 | then after some commands, you can traces from | ||
| 545 | /sys/kernel/debug/tracing/trace file. For example, when you want to | ||
| 546 | trace what codec command is sent, enable the tracepoint like: | ||
| 547 | ------------------------------------------------------------------------ | ||
| 548 | # cat /sys/kernel/debug/tracing/trace | ||
| 549 | # tracer: nop | ||
| 550 | # | ||
| 551 | # TASK-PID CPU# TIMESTAMP FUNCTION | ||
| 552 | # | | | | | | ||
| 553 | <...>-7807 [002] 105147.774889: hda_send_cmd: [0:0] val=e3a019 | ||
| 554 | <...>-7807 [002] 105147.774893: hda_send_cmd: [0:0] val=e39019 | ||
| 555 | <...>-7807 [002] 105147.999542: hda_send_cmd: [0:0] val=e3a01a | ||
| 556 | <...>-7807 [002] 105147.999543: hda_send_cmd: [0:0] val=e3901a | ||
| 557 | <...>-26764 [001] 349222.837143: hda_send_cmd: [0:0] val=e3a019 | ||
| 558 | <...>-26764 [001] 349222.837148: hda_send_cmd: [0:0] val=e39019 | ||
| 559 | <...>-26764 [001] 349223.058539: hda_send_cmd: [0:0] val=e3a01a | ||
| 560 | <...>-26764 [001] 349223.058541: hda_send_cmd: [0:0] val=e3901a | ||
| 561 | ------------------------------------------------------------------------ | ||
| 562 | Here `[0:0]` indicates the card number and the codec address, and | ||
| 563 | `val` shows the value sent to the codec, respectively. The value is | ||
| 564 | a packed value, and you can decode it via hda-decode-verb program | ||
| 565 | included in hda-emu package below. For example, the value e3a019 is | ||
| 566 | to set the left output-amp value to 25. | ||
| 567 | ------------------------------------------------------------------------ | ||
| 568 | % hda-decode-verb 0xe3a019 | ||
| 569 | raw value = 0x00e3a019 | ||
| 570 | cid = 0, nid = 0x0e, verb = 0x3a0, parm = 0x19 | ||
| 571 | raw value: verb = 0x3a0, parm = 0x19 | ||
| 572 | verbname = set_amp_gain_mute | ||
| 573 | amp raw val = 0xa019 | ||
| 574 | output, left, idx=0, mute=0, val=25 | ||
| 575 | ------------------------------------------------------------------------ | ||
| 576 | |||
| 577 | |||
| 527 | Development Tree | 578 | Development Tree |
| 528 | ~~~~~~~~~~~~~~~~ | 579 | ~~~~~~~~~~~~~~~~ |
| 529 | The latest development codes for HD-audio are found on sound git tree: | 580 | The latest development codes for HD-audio are found on sound git tree: |
diff --git a/MAINTAINERS b/MAINTAINERS index 506fe49a4c78..07e5dbd14273 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -529,6 +529,7 @@ S: Maintained | |||
| 529 | F: drivers/infiniband/hw/amso1100/ | 529 | F: drivers/infiniband/hw/amso1100/ |
| 530 | 530 | ||
| 531 | ANALOG DEVICES INC ASOC CODEC DRIVERS | 531 | ANALOG DEVICES INC ASOC CODEC DRIVERS |
| 532 | M: Lars-Peter Clausen <lars@metafoo.de> | ||
| 532 | L: device-drivers-devel@blackfin.uclinux.org | 533 | L: device-drivers-devel@blackfin.uclinux.org |
| 533 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 534 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 534 | W: http://wiki.analog.com/ | 535 | W: http://wiki.analog.com/ |
| @@ -6038,7 +6039,7 @@ M: Jaroslav Kysela <perex@perex.cz> | |||
| 6038 | M: Takashi Iwai <tiwai@suse.de> | 6039 | M: Takashi Iwai <tiwai@suse.de> |
| 6039 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 6040 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
| 6040 | W: http://www.alsa-project.org/ | 6041 | W: http://www.alsa-project.org/ |
| 6041 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6.git | 6042 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git |
| 6042 | T: git git://git.alsa-project.org/alsa-kernel.git | 6043 | T: git git://git.alsa-project.org/alsa-kernel.git |
| 6043 | S: Maintained | 6044 | S: Maintained |
| 6044 | F: Documentation/sound/ | 6045 | F: Documentation/sound/ |
| @@ -7259,6 +7260,7 @@ T: git git://opensource.wolfsonmicro.com/linux-2.6-audioplus | |||
| 7259 | W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices | 7260 | W: http://opensource.wolfsonmicro.com/content/linux-drivers-wolfson-devices |
| 7260 | S: Supported | 7261 | S: Supported |
| 7261 | F: Documentation/hwmon/wm83?? | 7262 | F: Documentation/hwmon/wm83?? |
| 7263 | F: arch/arm/mach-s3c64xx/mach-crag6410* | ||
| 7262 | F: drivers/leds/leds-wm83*.c | 7264 | F: drivers/leds/leds-wm83*.c |
| 7263 | F: drivers/input/misc/wm831x-on.c | 7265 | F: drivers/input/misc/wm831x-on.c |
| 7264 | F: drivers/input/touchscreen/wm831x-ts.c | 7266 | F: drivers/input/touchscreen/wm831x-ts.c |
diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c index c63a5ec1a8e3..70ef8c527d27 100644 --- a/arch/arm/mach-ep93xx/edb93xx.c +++ b/arch/arm/mach-ep93xx/edb93xx.c | |||
| @@ -160,6 +160,11 @@ static void __init edb93xx_register_spi(void) | |||
| 160 | /************************************************************************* | 160 | /************************************************************************* |
| 161 | * EDB93xx I2S | 161 | * EDB93xx I2S |
| 162 | *************************************************************************/ | 162 | *************************************************************************/ |
| 163 | static struct platform_device edb93xx_audio_device = { | ||
| 164 | .name = "edb93xx-audio", | ||
| 165 | .id = -1, | ||
| 166 | }; | ||
| 167 | |||
| 163 | static int __init edb93xx_has_audio(void) | 168 | static int __init edb93xx_has_audio(void) |
| 164 | { | 169 | { |
| 165 | return (machine_is_edb9301() || machine_is_edb9302() || | 170 | return (machine_is_edb9301() || machine_is_edb9302() || |
| @@ -171,6 +176,7 @@ static void __init edb93xx_register_i2s(void) | |||
| 171 | { | 176 | { |
| 172 | if (edb93xx_has_audio()) { | 177 | if (edb93xx_has_audio()) { |
| 173 | ep93xx_register_i2s(); | 178 | ep93xx_register_i2s(); |
| 179 | platform_device_register(&edb93xx_audio_device); | ||
| 174 | } | 180 | } |
| 175 | } | 181 | } |
| 176 | 182 | ||
diff --git a/arch/arm/mach-ep93xx/simone.c b/arch/arm/mach-ep93xx/simone.c index d6f286b4db9c..52e090dc9d27 100644 --- a/arch/arm/mach-ep93xx/simone.c +++ b/arch/arm/mach-ep93xx/simone.c | |||
| @@ -53,6 +53,17 @@ static struct i2c_board_info __initdata simone_i2c_board_info[] = { | |||
| 53 | }, | 53 | }, |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | static struct platform_device simone_audio_device = { | ||
| 57 | .name = "simone-audio", | ||
| 58 | .id = -1, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static void __init simone_register_audio(void) | ||
| 62 | { | ||
| 63 | ep93xx_register_ac97(); | ||
| 64 | platform_device_register(&simone_audio_device); | ||
| 65 | } | ||
| 66 | |||
| 56 | static void __init simone_init_machine(void) | 67 | static void __init simone_init_machine(void) |
| 57 | { | 68 | { |
| 58 | ep93xx_init_devices(); | 69 | ep93xx_init_devices(); |
| @@ -61,7 +72,7 @@ static void __init simone_init_machine(void) | |||
| 61 | ep93xx_register_fb(&simone_fb_info); | 72 | ep93xx_register_fb(&simone_fb_info); |
| 62 | ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info, | 73 | ep93xx_register_i2c(&simone_i2c_gpio_data, simone_i2c_board_info, |
| 63 | ARRAY_SIZE(simone_i2c_board_info)); | 74 | ARRAY_SIZE(simone_i2c_board_info)); |
| 64 | ep93xx_register_ac97(); | 75 | simone_register_audio(); |
| 65 | } | 76 | } |
| 66 | 77 | ||
| 67 | MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") | 78 | MACHINE_START(SIM_ONE, "Simplemachines Sim.One Board") |
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index 2b4d4b0201df..8121e3aedc0a 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c | |||
| @@ -150,6 +150,17 @@ static struct ep93xxfb_mach_info __initdata snappercl15_fb_info = { | |||
| 150 | .bpp = 16, | 150 | .bpp = 16, |
| 151 | }; | 151 | }; |
| 152 | 152 | ||
| 153 | static struct platform_device snappercl15_audio_device = { | ||
| 154 | .name = "snappercl15-audio", | ||
| 155 | .id = -1, | ||
| 156 | }; | ||
| 157 | |||
| 158 | static void __init snappercl15_register_audio(void) | ||
| 159 | { | ||
| 160 | ep93xx_register_i2s(); | ||
| 161 | platform_device_register(&snappercl15_audio_device); | ||
| 162 | } | ||
| 163 | |||
| 153 | static void __init snappercl15_init_machine(void) | 164 | static void __init snappercl15_init_machine(void) |
| 154 | { | 165 | { |
| 155 | ep93xx_init_devices(); | 166 | ep93xx_init_devices(); |
| @@ -157,7 +168,7 @@ static void __init snappercl15_init_machine(void) | |||
| 157 | ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data, | 168 | ep93xx_register_i2c(&snappercl15_i2c_gpio_data, snappercl15_i2c_data, |
| 158 | ARRAY_SIZE(snappercl15_i2c_data)); | 169 | ARRAY_SIZE(snappercl15_i2c_data)); |
| 159 | ep93xx_register_fb(&snappercl15_fb_info); | 170 | ep93xx_register_fb(&snappercl15_fb_info); |
| 160 | ep93xx_register_i2s(); | 171 | snappercl15_register_audio(); |
| 161 | platform_device_register(&snappercl15_nand_device); | 172 | platform_device_register(&snappercl15_nand_device); |
| 162 | } | 173 | } |
| 163 | 174 | ||
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 5a886cd2c598..ba1aa07bdb29 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
| @@ -900,7 +900,6 @@ static struct twl4030_platform_data rx51_twldata __initdata = { | |||
| 900 | }; | 900 | }; |
| 901 | 901 | ||
| 902 | static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = { | 902 | static struct tpa6130a2_platform_data rx51_tpa6130a2_data __initdata_or_module = { |
| 903 | .id = TPA6130A2, | ||
| 904 | .power_gpio = 98, | 903 | .power_gpio = 98, |
| 905 | }; | 904 | }; |
| 906 | 905 | ||
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 5391079c8689..ae8ea5b3b1a0 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
| @@ -329,6 +329,38 @@ static void omap_init_audio(void) | |||
| 329 | static inline void omap_init_audio(void) {} | 329 | static inline void omap_init_audio(void) {} |
| 330 | #endif | 330 | #endif |
| 331 | 331 | ||
| 332 | #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \ | ||
| 333 | defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE) | ||
| 334 | |||
| 335 | static struct omap_device_pm_latency omap_mcpdm_latency[] = { | ||
| 336 | { | ||
| 337 | .deactivate_func = omap_device_idle_hwmods, | ||
| 338 | .activate_func = omap_device_enable_hwmods, | ||
| 339 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
| 340 | }, | ||
| 341 | }; | ||
| 342 | |||
| 343 | static void omap_init_mcpdm(void) | ||
| 344 | { | ||
| 345 | struct omap_hwmod *oh; | ||
| 346 | struct omap_device *od; | ||
| 347 | |||
| 348 | oh = omap_hwmod_lookup("mcpdm"); | ||
| 349 | if (!oh) { | ||
| 350 | printk(KERN_ERR "Could not look up mcpdm hw_mod\n"); | ||
| 351 | return; | ||
| 352 | } | ||
| 353 | |||
| 354 | od = omap_device_build("omap-mcpdm", -1, oh, NULL, 0, | ||
| 355 | omap_mcpdm_latency, | ||
| 356 | ARRAY_SIZE(omap_mcpdm_latency), 0); | ||
| 357 | if (IS_ERR(od)) | ||
| 358 | printk(KERN_ERR "Could not build omap_device for omap-mcpdm-dai\n"); | ||
| 359 | } | ||
| 360 | #else | ||
| 361 | static inline void omap_init_mcpdm(void) {} | ||
| 362 | #endif | ||
| 363 | |||
| 332 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) | 364 | #if defined(CONFIG_SPI_OMAP24XX) || defined(CONFIG_SPI_OMAP24XX_MODULE) |
| 333 | 365 | ||
| 334 | #include <plat/mcspi.h> | 366 | #include <plat/mcspi.h> |
| @@ -682,6 +714,7 @@ static int __init omap2_init_devices(void) | |||
| 682 | * in alphabetical order so they're easier to sort through. | 714 | * in alphabetical order so they're easier to sort through. |
| 683 | */ | 715 | */ |
| 684 | omap_init_audio(); | 716 | omap_init_audio(); |
| 717 | omap_init_mcpdm(); | ||
| 685 | omap_init_camera(); | 718 | omap_init_camera(); |
| 686 | omap_init_mbox(); | 719 | omap_init_mbox(); |
| 687 | omap_init_mcspi(); | 720 | omap_init_mcspi(); |
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 6201422c0606..79325c65c23c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c | |||
| @@ -5430,7 +5430,7 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = { | |||
| 5430 | &omap44xx_mcbsp4_hwmod, | 5430 | &omap44xx_mcbsp4_hwmod, |
| 5431 | 5431 | ||
| 5432 | /* mcpdm class */ | 5432 | /* mcpdm class */ |
| 5433 | /* &omap44xx_mcpdm_hwmod, */ | 5433 | &omap44xx_mcpdm_hwmod, |
| 5434 | 5434 | ||
| 5435 | /* mcspi class */ | 5435 | /* mcspi class */ |
| 5436 | &omap44xx_mcspi1_hwmod, | 5436 | &omap44xx_mcspi1_hwmod, |
diff --git a/arch/arm/plat-omap/devices.c b/arch/arm/plat-omap/devices.c index 64c3bd4aa54e..c46c47afa090 100644 --- a/arch/arm/plat-omap/devices.c +++ b/arch/arm/plat-omap/devices.c | |||
| @@ -73,41 +73,6 @@ void omap_mcbsp_register_board_cfg(struct resource *res, int res_count, | |||
| 73 | 73 | ||
| 74 | /*-------------------------------------------------------------------------*/ | 74 | /*-------------------------------------------------------------------------*/ |
| 75 | 75 | ||
| 76 | #if defined(CONFIG_SND_OMAP_SOC_MCPDM) || \ | ||
| 77 | defined(CONFIG_SND_OMAP_SOC_MCPDM_MODULE) | ||
| 78 | |||
| 79 | static struct resource mcpdm_resources[] = { | ||
| 80 | { | ||
| 81 | .name = "mcpdm_mem", | ||
| 82 | .start = OMAP44XX_MCPDM_BASE, | ||
| 83 | .end = OMAP44XX_MCPDM_BASE + SZ_4K, | ||
| 84 | .flags = IORESOURCE_MEM, | ||
| 85 | }, | ||
| 86 | { | ||
| 87 | .name = "mcpdm_irq", | ||
| 88 | .start = OMAP44XX_IRQ_MCPDM, | ||
| 89 | .end = OMAP44XX_IRQ_MCPDM, | ||
| 90 | .flags = IORESOURCE_IRQ, | ||
| 91 | }, | ||
| 92 | }; | ||
| 93 | |||
| 94 | static struct platform_device omap_mcpdm_device = { | ||
| 95 | .name = "omap-mcpdm", | ||
| 96 | .id = -1, | ||
| 97 | .num_resources = ARRAY_SIZE(mcpdm_resources), | ||
| 98 | .resource = mcpdm_resources, | ||
| 99 | }; | ||
| 100 | |||
| 101 | static void omap_init_mcpdm(void) | ||
| 102 | { | ||
| 103 | (void) platform_device_register(&omap_mcpdm_device); | ||
| 104 | } | ||
| 105 | #else | ||
| 106 | static inline void omap_init_mcpdm(void) {} | ||
| 107 | #endif | ||
| 108 | |||
| 109 | /*-------------------------------------------------------------------------*/ | ||
| 110 | |||
| 111 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ | 76 | #if defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \ |
| 112 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) | 77 | defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE) |
| 113 | 78 | ||
| @@ -290,7 +255,6 @@ static int __init omap_init_devices(void) | |||
| 290 | * in alphabetical order so they're easier to sort through. | 255 | * in alphabetical order so they're easier to sort through. |
| 291 | */ | 256 | */ |
| 292 | omap_init_rng(); | 257 | omap_init_rng(); |
| 293 | omap_init_mcpdm(); | ||
| 294 | omap_init_uwire(); | 258 | omap_init_uwire(); |
| 295 | return 0; | 259 | return 0; |
| 296 | } | 260 | } |
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200/platform.c index fbb55935b99e..dda090bf74e6 100644 --- a/arch/mips/alchemy/devboards/db1200/platform.c +++ b/arch/mips/alchemy/devboards/db1200/platform.c | |||
| @@ -422,6 +422,7 @@ static struct resource au1200_psc1_res[] = { | |||
| 422 | }, | 422 | }, |
| 423 | }; | 423 | }; |
| 424 | 424 | ||
| 425 | /* AC97 or I2S device */ | ||
| 425 | static struct platform_device db1200_audio_dev = { | 426 | static struct platform_device db1200_audio_dev = { |
| 426 | /* name assigned later based on switch setting */ | 427 | /* name assigned later based on switch setting */ |
| 427 | .id = 1, /* PSC ID */ | 428 | .id = 1, /* PSC ID */ |
| @@ -429,19 +430,32 @@ static struct platform_device db1200_audio_dev = { | |||
| 429 | .resource = au1200_psc1_res, | 430 | .resource = au1200_psc1_res, |
| 430 | }; | 431 | }; |
| 431 | 432 | ||
| 433 | /* DB1200 ASoC card device */ | ||
| 434 | static struct platform_device db1200_sound_dev = { | ||
| 435 | /* name assigned later based on switch setting */ | ||
| 436 | .id = 1, /* PSC ID */ | ||
| 437 | }; | ||
| 438 | |||
| 432 | static struct platform_device db1200_stac_dev = { | 439 | static struct platform_device db1200_stac_dev = { |
| 433 | .name = "ac97-codec", | 440 | .name = "ac97-codec", |
| 434 | .id = 1, /* on PSC1 */ | 441 | .id = 1, /* on PSC1 */ |
| 435 | }; | 442 | }; |
| 436 | 443 | ||
| 444 | static struct platform_device db1200_audiodma_dev = { | ||
| 445 | .name = "au1xpsc-pcm", | ||
| 446 | .id = 1, /* PSC ID */ | ||
| 447 | }; | ||
| 448 | |||
| 437 | static struct platform_device *db1200_devs[] __initdata = { | 449 | static struct platform_device *db1200_devs[] __initdata = { |
| 438 | NULL, /* PSC0, selected by S6.8 */ | 450 | NULL, /* PSC0, selected by S6.8 */ |
| 439 | &db1200_ide_dev, | 451 | &db1200_ide_dev, |
| 440 | &db1200_eth_dev, | 452 | &db1200_eth_dev, |
| 441 | &db1200_rtc_dev, | 453 | &db1200_rtc_dev, |
| 442 | &db1200_nand_dev, | 454 | &db1200_nand_dev, |
| 455 | &db1200_audiodma_dev, | ||
| 443 | &db1200_audio_dev, | 456 | &db1200_audio_dev, |
| 444 | &db1200_stac_dev, | 457 | &db1200_stac_dev, |
| 458 | &db1200_sound_dev, | ||
| 445 | }; | 459 | }; |
| 446 | 460 | ||
| 447 | static int __init db1200_dev_init(void) | 461 | static int __init db1200_dev_init(void) |
| @@ -501,10 +515,12 @@ static int __init db1200_dev_init(void) | |||
| 501 | if (sw == BCSR_SWITCHES_DIP_8) { | 515 | if (sw == BCSR_SWITCHES_DIP_8) { |
| 502 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX); | 516 | bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_PSC1MUX); |
| 503 | db1200_audio_dev.name = "au1xpsc_i2s"; | 517 | db1200_audio_dev.name = "au1xpsc_i2s"; |
| 518 | db1200_sound_dev.name = "db1200-i2s"; | ||
| 504 | printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n"); | 519 | printk(KERN_INFO " S6.7 ON : PSC1 mode I2S\n"); |
| 505 | } else { | 520 | } else { |
| 506 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0); | 521 | bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC1MUX, 0); |
| 507 | db1200_audio_dev.name = "au1xpsc_ac97"; | 522 | db1200_audio_dev.name = "au1xpsc_ac97"; |
| 523 | db1200_sound_dev.name = "db1200-ac97"; | ||
| 508 | printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n"); | 524 | printk(KERN_INFO " S6.7 OFF: PSC1 mode AC97\n"); |
| 509 | } | 525 | } |
| 510 | 526 | ||
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c index 978d5ab3d678..7057d28f7301 100644 --- a/arch/mips/alchemy/devboards/db1x00/platform.c +++ b/arch/mips/alchemy/devboards/db1x00/platform.c | |||
| @@ -19,8 +19,11 @@ | |||
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
| 22 | #include <linux/interrupt.h> | ||
| 22 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 23 | 24 | ||
| 25 | #include <asm/mach-au1x00/au1000.h> | ||
| 26 | #include <asm/mach-au1x00/au1000_dma.h> | ||
| 24 | #include <asm/mach-au1x00/au1xxx.h> | 27 | #include <asm/mach-au1x00/au1xxx.h> |
| 25 | #include <asm/mach-db1x00/bcsr.h> | 28 | #include <asm/mach-db1x00/bcsr.h> |
| 26 | #include "../platform.h" | 29 | #include "../platform.h" |
| @@ -85,6 +88,45 @@ | |||
| 85 | #endif | 88 | #endif |
| 86 | #endif | 89 | #endif |
| 87 | 90 | ||
| 91 | static struct resource alchemy_ac97c_res[] = { | ||
| 92 | [0] = { | ||
| 93 | .start = AU1000_AC97_PHYS_ADDR, | ||
| 94 | .end = AU1000_AC97_PHYS_ADDR + 0xfff, | ||
| 95 | .flags = IORESOURCE_MEM, | ||
| 96 | }, | ||
| 97 | [1] = { | ||
| 98 | .start = DMA_ID_AC97C_TX, | ||
| 99 | .end = DMA_ID_AC97C_TX, | ||
| 100 | .flags = IORESOURCE_DMA, | ||
| 101 | }, | ||
| 102 | [2] = { | ||
| 103 | .start = DMA_ID_AC97C_RX, | ||
| 104 | .end = DMA_ID_AC97C_RX, | ||
| 105 | .flags = IORESOURCE_DMA, | ||
| 106 | }, | ||
| 107 | }; | ||
| 108 | |||
| 109 | static struct platform_device alchemy_ac97c_dev = { | ||
| 110 | .name = "alchemy-ac97c", | ||
| 111 | .id = -1, | ||
| 112 | .resource = alchemy_ac97c_res, | ||
| 113 | .num_resources = ARRAY_SIZE(alchemy_ac97c_res), | ||
| 114 | }; | ||
| 115 | |||
| 116 | static struct platform_device alchemy_ac97c_dma_dev = { | ||
| 117 | .name = "alchemy-pcm-dma", | ||
| 118 | .id = 0, | ||
| 119 | }; | ||
| 120 | |||
| 121 | static struct platform_device db1x00_codec_dev = { | ||
| 122 | .name = "ac97-codec", | ||
| 123 | .id = -1, | ||
| 124 | }; | ||
| 125 | |||
| 126 | static struct platform_device db1x00_audio_dev = { | ||
| 127 | .name = "db1000-audio", | ||
| 128 | }; | ||
| 129 | |||
| 88 | static int __init db1xxx_dev_init(void) | 130 | static int __init db1xxx_dev_init(void) |
| 89 | { | 131 | { |
| 90 | #ifdef DB1XXX_HAS_PCMCIA | 132 | #ifdef DB1XXX_HAS_PCMCIA |
| @@ -113,6 +155,12 @@ static int __init db1xxx_dev_init(void) | |||
| 113 | 1); | 155 | 1); |
| 114 | #endif | 156 | #endif |
| 115 | db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); | 157 | db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED); |
| 158 | |||
| 159 | platform_device_register(&db1x00_codec_dev); | ||
| 160 | platform_device_register(&alchemy_ac97c_dma_dev); | ||
| 161 | platform_device_register(&alchemy_ac97c_dev); | ||
| 162 | platform_device_register(&db1x00_audio_dev); | ||
| 163 | |||
| 116 | return 0; | 164 | return 0; |
| 117 | } | 165 | } |
| 118 | device_initcall(db1xxx_dev_init); | 166 | device_initcall(db1xxx_dev_init); |
diff --git a/drivers/input/misc/twl6040-vibra.c b/drivers/input/misc/twl6040-vibra.c index 23855e12a30b..ad153a417eed 100644 --- a/drivers/input/misc/twl6040-vibra.c +++ b/drivers/input/misc/twl6040-vibra.c | |||
| @@ -74,12 +74,12 @@ static irqreturn_t twl6040_vib_irq_handler(int irq, void *data) | |||
| 74 | if (status & TWL6040_VIBLOCDET) { | 74 | if (status & TWL6040_VIBLOCDET) { |
| 75 | dev_warn(info->dev, "Left Vibrator overcurrent detected\n"); | 75 | dev_warn(info->dev, "Left Vibrator overcurrent detected\n"); |
| 76 | twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLL, | 76 | twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLL, |
| 77 | TWL6040_VIBENAL); | 77 | TWL6040_VIBENA); |
| 78 | } | 78 | } |
| 79 | if (status & TWL6040_VIBROCDET) { | 79 | if (status & TWL6040_VIBROCDET) { |
| 80 | dev_warn(info->dev, "Right Vibrator overcurrent detected\n"); | 80 | dev_warn(info->dev, "Right Vibrator overcurrent detected\n"); |
| 81 | twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLR, | 81 | twl6040_clear_bits(twl6040, TWL6040_REG_VIBCTLR, |
| 82 | TWL6040_VIBENAR); | 82 | TWL6040_VIBENA); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | return IRQ_HANDLED; | 85 | return IRQ_HANDLED; |
| @@ -97,23 +97,23 @@ static void twl6040_vibra_enable(struct vibra_info *info) | |||
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | twl6040_power(info->twl6040, 1); | 99 | twl6040_power(info->twl6040, 1); |
| 100 | if (twl6040->rev <= TWL6040_REV_ES1_1) { | 100 | if (twl6040_get_revid(twl6040) <= TWL6040_REV_ES1_1) { |
| 101 | /* | 101 | /* |
| 102 | * ERRATA: Disable overcurrent protection for at least | 102 | * ERRATA: Disable overcurrent protection for at least |
| 103 | * 3ms when enabling vibrator drivers to avoid false | 103 | * 3ms when enabling vibrator drivers to avoid false |
| 104 | * overcurrent detection | 104 | * overcurrent detection |
| 105 | */ | 105 | */ |
| 106 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, | 106 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, |
| 107 | TWL6040_VIBENAL | TWL6040_VIBCTRLL); | 107 | TWL6040_VIBENA | TWL6040_VIBCTRL); |
| 108 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, | 108 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, |
| 109 | TWL6040_VIBENAR | TWL6040_VIBCTRLR); | 109 | TWL6040_VIBENA | TWL6040_VIBCTRL); |
| 110 | usleep_range(3000, 3500); | 110 | usleep_range(3000, 3500); |
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, | 113 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLL, |
| 114 | TWL6040_VIBENAL); | 114 | TWL6040_VIBENA); |
| 115 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, | 115 | twl6040_reg_write(twl6040, TWL6040_REG_VIBCTLR, |
| 116 | TWL6040_VIBENAR); | 116 | TWL6040_VIBENA); |
| 117 | 117 | ||
| 118 | info->enabled = true; | 118 | info->enabled = true; |
| 119 | } | 119 | } |
| @@ -201,6 +201,13 @@ static int vibra_play(struct input_dev *input, void *data, | |||
| 201 | struct vibra_info *info = input_get_drvdata(input); | 201 | struct vibra_info *info = input_get_drvdata(input); |
| 202 | int ret; | 202 | int ret; |
| 203 | 203 | ||
| 204 | /* Do not allow effect, while the routing is set to use audio */ | ||
| 205 | ret = twl6040_get_vibralr_status(info->twl6040); | ||
| 206 | if (ret & TWL6040_VIBSEL) { | ||
| 207 | dev_info(&input->dev, "Vibra is configured for audio\n"); | ||
| 208 | return -EBUSY; | ||
| 209 | } | ||
| 210 | |||
| 204 | info->weak_speed = effect->u.rumble.weak_magnitude; | 211 | info->weak_speed = effect->u.rumble.weak_magnitude; |
| 205 | info->strong_speed = effect->u.rumble.strong_magnitude; | 212 | info->strong_speed = effect->u.rumble.strong_magnitude; |
| 206 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1; | 213 | info->direction = effect->direction < EFFECT_DIR_180_DEG ? 1 : -1; |
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c index 24d436c2fe4a..268f80fd0439 100644 --- a/drivers/mfd/twl6040-core.c +++ b/drivers/mfd/twl6040-core.c | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | #include <linux/mfd/core.h> | 34 | #include <linux/mfd/core.h> |
| 35 | #include <linux/mfd/twl6040.h> | 35 | #include <linux/mfd/twl6040.h> |
| 36 | 36 | ||
| 37 | static struct platform_device *twl6040_dev; | 37 | #define VIBRACTRL_MEMBER(reg) ((reg == TWL6040_REG_VIBCTLL) ? 0 : 1) |
| 38 | 38 | ||
| 39 | int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) | 39 | int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) |
| 40 | { | 40 | { |
| @@ -42,10 +42,16 @@ int twl6040_reg_read(struct twl6040 *twl6040, unsigned int reg) | |||
| 42 | u8 val = 0; | 42 | u8 val = 0; |
| 43 | 43 | ||
| 44 | mutex_lock(&twl6040->io_mutex); | 44 | mutex_lock(&twl6040->io_mutex); |
| 45 | ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); | 45 | /* Vibra control registers from cache */ |
| 46 | if (ret < 0) { | 46 | if (unlikely(reg == TWL6040_REG_VIBCTLL || |
| 47 | mutex_unlock(&twl6040->io_mutex); | 47 | reg == TWL6040_REG_VIBCTLR)) { |
| 48 | return ret; | 48 | val = twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)]; |
| 49 | } else { | ||
| 50 | ret = twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &val, reg); | ||
| 51 | if (ret < 0) { | ||
| 52 | mutex_unlock(&twl6040->io_mutex); | ||
| 53 | return ret; | ||
| 54 | } | ||
| 49 | } | 55 | } |
| 50 | mutex_unlock(&twl6040->io_mutex); | 56 | mutex_unlock(&twl6040->io_mutex); |
| 51 | 57 | ||
| @@ -59,6 +65,9 @@ int twl6040_reg_write(struct twl6040 *twl6040, unsigned int reg, u8 val) | |||
| 59 | 65 | ||
| 60 | mutex_lock(&twl6040->io_mutex); | 66 | mutex_lock(&twl6040->io_mutex); |
| 61 | ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); | 67 | ret = twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, val, reg); |
| 68 | /* Cache the vibra control registers */ | ||
| 69 | if (reg == TWL6040_REG_VIBCTLL || reg == TWL6040_REG_VIBCTLR) | ||
| 70 | twl6040->vibra_ctrl_cache[VIBRACTRL_MEMBER(reg)] = val; | ||
| 62 | mutex_unlock(&twl6040->io_mutex); | 71 | mutex_unlock(&twl6040->io_mutex); |
| 63 | 72 | ||
| 64 | return ret; | 73 | return ret; |
| @@ -203,11 +212,11 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data) | |||
| 203 | if (intid & TWL6040_THINT) { | 212 | if (intid & TWL6040_THINT) { |
| 204 | status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS); | 213 | status = twl6040_reg_read(twl6040, TWL6040_REG_STATUS); |
| 205 | if (status & TWL6040_TSHUTDET) { | 214 | if (status & TWL6040_TSHUTDET) { |
| 206 | dev_warn(&twl6040_dev->dev, | 215 | dev_warn(twl6040->dev, |
| 207 | "Thermal shutdown, powering-off"); | 216 | "Thermal shutdown, powering-off"); |
| 208 | twl6040_power(twl6040, 0); | 217 | twl6040_power(twl6040, 0); |
| 209 | } else { | 218 | } else { |
| 210 | dev_warn(&twl6040_dev->dev, | 219 | dev_warn(twl6040->dev, |
| 211 | "Leaving thermal shutdown, powering-on"); | 220 | "Leaving thermal shutdown, powering-on"); |
| 212 | twl6040_power(twl6040, 1); | 221 | twl6040_power(twl6040, 1); |
| 213 | } | 222 | } |
| @@ -227,7 +236,7 @@ static int twl6040_power_up_completion(struct twl6040 *twl6040, | |||
| 227 | if (!time_left) { | 236 | if (!time_left) { |
| 228 | intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); | 237 | intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); |
| 229 | if (!(intid & TWL6040_READYINT)) { | 238 | if (!(intid & TWL6040_READYINT)) { |
| 230 | dev_err(&twl6040_dev->dev, | 239 | dev_err(twl6040->dev, |
| 231 | "timeout waiting for READYINT\n"); | 240 | "timeout waiting for READYINT\n"); |
| 232 | return -ETIMEDOUT; | 241 | return -ETIMEDOUT; |
| 233 | } | 242 | } |
| @@ -255,7 +264,7 @@ int twl6040_power(struct twl6040 *twl6040, int on) | |||
| 255 | /* wait for power-up completion */ | 264 | /* wait for power-up completion */ |
| 256 | ret = twl6040_power_up_completion(twl6040, naudint); | 265 | ret = twl6040_power_up_completion(twl6040, naudint); |
| 257 | if (ret) { | 266 | if (ret) { |
| 258 | dev_err(&twl6040_dev->dev, | 267 | dev_err(twl6040->dev, |
| 259 | "automatic power-down failed\n"); | 268 | "automatic power-down failed\n"); |
| 260 | twl6040->power_count = 0; | 269 | twl6040->power_count = 0; |
| 261 | goto out; | 270 | goto out; |
| @@ -264,7 +273,7 @@ int twl6040_power(struct twl6040 *twl6040, int on) | |||
| 264 | /* use manual power-up sequence */ | 273 | /* use manual power-up sequence */ |
| 265 | ret = twl6040_power_up(twl6040); | 274 | ret = twl6040_power_up(twl6040); |
| 266 | if (ret) { | 275 | if (ret) { |
| 267 | dev_err(&twl6040_dev->dev, | 276 | dev_err(twl6040->dev, |
| 268 | "manual power-up failed\n"); | 277 | "manual power-up failed\n"); |
| 269 | twl6040->power_count = 0; | 278 | twl6040->power_count = 0; |
| 270 | goto out; | 279 | goto out; |
| @@ -276,7 +285,7 @@ int twl6040_power(struct twl6040 *twl6040, int on) | |||
| 276 | } else { | 285 | } else { |
| 277 | /* already powered-down */ | 286 | /* already powered-down */ |
| 278 | if (!twl6040->power_count) { | 287 | if (!twl6040->power_count) { |
| 279 | dev_err(&twl6040_dev->dev, | 288 | dev_err(twl6040->dev, |
| 280 | "device is already powered-off\n"); | 289 | "device is already powered-off\n"); |
| 281 | ret = -EPERM; | 290 | ret = -EPERM; |
| 282 | goto out; | 291 | goto out; |
| @@ -326,7 +335,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
| 326 | lppllctl &= ~TWL6040_LPLLFIN; | 335 | lppllctl &= ~TWL6040_LPLLFIN; |
| 327 | break; | 336 | break; |
| 328 | default: | 337 | default: |
| 329 | dev_err(&twl6040_dev->dev, | 338 | dev_err(twl6040->dev, |
| 330 | "freq_out %d not supported\n", freq_out); | 339 | "freq_out %d not supported\n", freq_out); |
| 331 | ret = -EINVAL; | 340 | ret = -EINVAL; |
| 332 | goto pll_out; | 341 | goto pll_out; |
| @@ -347,7 +356,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
| 347 | hppllctl); | 356 | hppllctl); |
| 348 | break; | 357 | break; |
| 349 | default: | 358 | default: |
| 350 | dev_err(&twl6040_dev->dev, | 359 | dev_err(twl6040->dev, |
| 351 | "freq_in %d not supported\n", freq_in); | 360 | "freq_in %d not supported\n", freq_in); |
| 352 | ret = -EINVAL; | 361 | ret = -EINVAL; |
| 353 | goto pll_out; | 362 | goto pll_out; |
| @@ -356,7 +365,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
| 356 | case TWL6040_SYSCLK_SEL_HPPLL: | 365 | case TWL6040_SYSCLK_SEL_HPPLL: |
| 357 | /* high-performance PLL can provide only 19.2 MHz */ | 366 | /* high-performance PLL can provide only 19.2 MHz */ |
| 358 | if (freq_out != 19200000) { | 367 | if (freq_out != 19200000) { |
| 359 | dev_err(&twl6040_dev->dev, | 368 | dev_err(twl6040->dev, |
| 360 | "freq_out %d not supported\n", freq_out); | 369 | "freq_out %d not supported\n", freq_out); |
| 361 | ret = -EINVAL; | 370 | ret = -EINVAL; |
| 362 | goto pll_out; | 371 | goto pll_out; |
| @@ -389,7 +398,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
| 389 | TWL6040_HPLLENA; | 398 | TWL6040_HPLLENA; |
| 390 | break; | 399 | break; |
| 391 | default: | 400 | default: |
| 392 | dev_err(&twl6040_dev->dev, | 401 | dev_err(twl6040->dev, |
| 393 | "freq_in %d not supported\n", freq_in); | 402 | "freq_in %d not supported\n", freq_in); |
| 394 | ret = -EINVAL; | 403 | ret = -EINVAL; |
| 395 | goto pll_out; | 404 | goto pll_out; |
| @@ -406,7 +415,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, | |||
| 406 | twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); | 415 | twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); |
| 407 | break; | 416 | break; |
| 408 | default: | 417 | default: |
| 409 | dev_err(&twl6040_dev->dev, "unknown pll id %d\n", pll_id); | 418 | dev_err(twl6040->dev, "unknown pll id %d\n", pll_id); |
| 410 | ret = -EINVAL; | 419 | ret = -EINVAL; |
| 411 | goto pll_out; | 420 | goto pll_out; |
| 412 | } | 421 | } |
| @@ -435,6 +444,18 @@ unsigned int twl6040_get_sysclk(struct twl6040 *twl6040) | |||
| 435 | } | 444 | } |
| 436 | EXPORT_SYMBOL(twl6040_get_sysclk); | 445 | EXPORT_SYMBOL(twl6040_get_sysclk); |
| 437 | 446 | ||
| 447 | /* Get the combined status of the vibra control register */ | ||
| 448 | int twl6040_get_vibralr_status(struct twl6040 *twl6040) | ||
| 449 | { | ||
| 450 | u8 status; | ||
| 451 | |||
| 452 | status = twl6040->vibra_ctrl_cache[0] | twl6040->vibra_ctrl_cache[1]; | ||
| 453 | status &= (TWL6040_VIBENA | TWL6040_VIBSEL); | ||
| 454 | |||
| 455 | return status; | ||
| 456 | } | ||
| 457 | EXPORT_SYMBOL(twl6040_get_vibralr_status); | ||
| 458 | |||
| 438 | static struct resource twl6040_vibra_rsrc[] = { | 459 | static struct resource twl6040_vibra_rsrc[] = { |
| 439 | { | 460 | { |
| 440 | .flags = IORESOURCE_IRQ, | 461 | .flags = IORESOURCE_IRQ, |
| @@ -471,9 +492,7 @@ static int __devinit twl6040_probe(struct platform_device *pdev) | |||
| 471 | 492 | ||
| 472 | platform_set_drvdata(pdev, twl6040); | 493 | platform_set_drvdata(pdev, twl6040); |
| 473 | 494 | ||
| 474 | twl6040_dev = pdev; | ||
| 475 | twl6040->dev = &pdev->dev; | 495 | twl6040->dev = &pdev->dev; |
| 476 | twl6040->audpwron = pdata->audpwron_gpio; | ||
| 477 | twl6040->irq = pdata->naudint_irq; | 496 | twl6040->irq = pdata->naudint_irq; |
| 478 | twl6040->irq_base = pdata->irq_base; | 497 | twl6040->irq_base = pdata->irq_base; |
| 479 | 498 | ||
| @@ -483,6 +502,12 @@ static int __devinit twl6040_probe(struct platform_device *pdev) | |||
| 483 | 502 | ||
| 484 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); | 503 | twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); |
| 485 | 504 | ||
| 505 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ | ||
| 506 | if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) | ||
| 507 | twl6040->audpwron = pdata->audpwron_gpio; | ||
| 508 | else | ||
| 509 | twl6040->audpwron = -EINVAL; | ||
| 510 | |||
| 486 | if (gpio_is_valid(twl6040->audpwron)) { | 511 | if (gpio_is_valid(twl6040->audpwron)) { |
| 487 | ret = gpio_request(twl6040->audpwron, "audpwron"); | 512 | ret = gpio_request(twl6040->audpwron, "audpwron"); |
| 488 | if (ret) | 513 | if (ret) |
| @@ -493,10 +518,6 @@ static int __devinit twl6040_probe(struct platform_device *pdev) | |||
| 493 | goto gpio2_err; | 518 | goto gpio2_err; |
| 494 | } | 519 | } |
| 495 | 520 | ||
| 496 | /* ERRATA: Automatic power-up is not possible in ES1.0 */ | ||
| 497 | if (twl6040->rev == TWL6040_REV_ES1_0) | ||
| 498 | twl6040->audpwron = -EINVAL; | ||
| 499 | |||
| 500 | /* codec interrupt */ | 521 | /* codec interrupt */ |
| 501 | ret = twl6040_irq_init(twl6040); | 522 | ret = twl6040_irq_init(twl6040); |
| 502 | if (ret) | 523 | if (ret) |
| @@ -566,7 +587,6 @@ gpio2_err: | |||
| 566 | gpio1_err: | 587 | gpio1_err: |
| 567 | platform_set_drvdata(pdev, NULL); | 588 | platform_set_drvdata(pdev, NULL); |
| 568 | kfree(twl6040); | 589 | kfree(twl6040); |
| 569 | twl6040_dev = NULL; | ||
| 570 | return ret; | 590 | return ret; |
| 571 | } | 591 | } |
| 572 | 592 | ||
| @@ -586,7 +606,6 @@ static int __devexit twl6040_remove(struct platform_device *pdev) | |||
| 586 | mfd_remove_devices(&pdev->dev); | 606 | mfd_remove_devices(&pdev->dev); |
| 587 | platform_set_drvdata(pdev, NULL); | 607 | platform_set_drvdata(pdev, NULL); |
| 588 | kfree(twl6040); | 608 | kfree(twl6040); |
| 589 | twl6040_dev = NULL; | ||
| 590 | 609 | ||
| 591 | return 0; | 610 | return 0; |
| 592 | } | 611 | } |
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index bfde4e8ec638..b03be1d4e0ca 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c | |||
| @@ -167,6 +167,18 @@ static struct mfd_cell wm8994_devs[] = { | |||
| 167 | * and should be handled via the standard regulator API supply | 167 | * and should be handled via the standard regulator API supply |
| 168 | * management. | 168 | * management. |
| 169 | */ | 169 | */ |
| 170 | static const char *wm1811_main_supplies[] = { | ||
| 171 | "DBVDD1", | ||
| 172 | "DBVDD2", | ||
| 173 | "DBVDD3", | ||
| 174 | "DCVDD", | ||
| 175 | "AVDD1", | ||
| 176 | "AVDD2", | ||
| 177 | "CPVDD", | ||
| 178 | "SPKVDD1", | ||
| 179 | "SPKVDD2", | ||
| 180 | }; | ||
| 181 | |||
| 170 | static const char *wm8994_main_supplies[] = { | 182 | static const char *wm8994_main_supplies[] = { |
| 171 | "DBVDD", | 183 | "DBVDD", |
| 172 | "DCVDD", | 184 | "DCVDD", |
| @@ -329,6 +341,9 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
| 329 | } | 341 | } |
| 330 | 342 | ||
| 331 | switch (wm8994->type) { | 343 | switch (wm8994->type) { |
| 344 | case WM1811: | ||
| 345 | wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies); | ||
| 346 | break; | ||
| 332 | case WM8994: | 347 | case WM8994: |
| 333 | wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); | 348 | wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); |
| 334 | break; | 349 | break; |
| @@ -349,6 +364,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
| 349 | } | 364 | } |
| 350 | 365 | ||
| 351 | switch (wm8994->type) { | 366 | switch (wm8994->type) { |
| 367 | case WM1811: | ||
| 368 | for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++) | ||
| 369 | wm8994->supplies[i].supply = wm1811_main_supplies[i]; | ||
| 370 | break; | ||
| 352 | case WM8994: | 371 | case WM8994: |
| 353 | for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) | 372 | for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) |
| 354 | wm8994->supplies[i].supply = wm8994_main_supplies[i]; | 373 | wm8994->supplies[i].supply = wm8994_main_supplies[i]; |
| @@ -382,6 +401,13 @@ static int wm8994_device_init(struct wm8994 *wm8994, int irq) | |||
| 382 | goto err_enable; | 401 | goto err_enable; |
| 383 | } | 402 | } |
| 384 | switch (ret) { | 403 | switch (ret) { |
| 404 | case 0x1811: | ||
| 405 | devname = "WM1811"; | ||
| 406 | if (wm8994->type != WM1811) | ||
| 407 | dev_warn(wm8994->dev, "Device registered as type %d\n", | ||
| 408 | wm8994->type); | ||
| 409 | wm8994->type = WM1811; | ||
| 410 | break; | ||
| 385 | case 0x8994: | 411 | case 0x8994: |
| 386 | devname = "WM8994"; | 412 | devname = "WM8994"; |
| 387 | if (wm8994->type != WM8994) | 413 | if (wm8994->type != WM8994) |
| @@ -539,6 +565,7 @@ static int wm8994_i2c_remove(struct i2c_client *i2c) | |||
| 539 | } | 565 | } |
| 540 | 566 | ||
| 541 | static const struct i2c_device_id wm8994_i2c_id[] = { | 567 | static const struct i2c_device_id wm8994_i2c_id[] = { |
| 568 | { "wm1811", WM1811 }, | ||
| 542 | { "wm8994", WM8994 }, | 569 | { "wm8994", WM8994 }, |
| 543 | { "wm8958", WM8958 }, | 570 | { "wm8958", WM8958 }, |
| 544 | { } | 571 | { } |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index d8e6a429e8ba..9e4c123c4028 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
| @@ -1552,6 +1552,68 @@ int regulator_force_disable(struct regulator *regulator) | |||
| 1552 | } | 1552 | } |
| 1553 | EXPORT_SYMBOL_GPL(regulator_force_disable); | 1553 | EXPORT_SYMBOL_GPL(regulator_force_disable); |
| 1554 | 1554 | ||
| 1555 | static void regulator_disable_work(struct work_struct *work) | ||
| 1556 | { | ||
| 1557 | struct regulator_dev *rdev = container_of(work, struct regulator_dev, | ||
| 1558 | disable_work.work); | ||
| 1559 | int count, i, ret; | ||
| 1560 | |||
| 1561 | mutex_lock(&rdev->mutex); | ||
| 1562 | |||
| 1563 | BUG_ON(!rdev->deferred_disables); | ||
| 1564 | |||
| 1565 | count = rdev->deferred_disables; | ||
| 1566 | rdev->deferred_disables = 0; | ||
| 1567 | |||
| 1568 | for (i = 0; i < count; i++) { | ||
| 1569 | ret = _regulator_disable(rdev); | ||
| 1570 | if (ret != 0) | ||
| 1571 | rdev_err(rdev, "Deferred disable failed: %d\n", ret); | ||
| 1572 | } | ||
| 1573 | |||
| 1574 | mutex_unlock(&rdev->mutex); | ||
| 1575 | |||
| 1576 | if (rdev->supply) { | ||
| 1577 | for (i = 0; i < count; i++) { | ||
| 1578 | ret = regulator_disable(rdev->supply); | ||
| 1579 | if (ret != 0) { | ||
| 1580 | rdev_err(rdev, | ||
| 1581 | "Supply disable failed: %d\n", ret); | ||
| 1582 | } | ||
| 1583 | } | ||
| 1584 | } | ||
| 1585 | } | ||
| 1586 | |||
| 1587 | /** | ||
| 1588 | * regulator_disable_deferred - disable regulator output with delay | ||
| 1589 | * @regulator: regulator source | ||
| 1590 | * @ms: miliseconds until the regulator is disabled | ||
| 1591 | * | ||
| 1592 | * Execute regulator_disable() on the regulator after a delay. This | ||
| 1593 | * is intended for use with devices that require some time to quiesce. | ||
| 1594 | * | ||
| 1595 | * NOTE: this will only disable the regulator output if no other consumer | ||
| 1596 | * devices have it enabled, the regulator device supports disabling and | ||
| 1597 | * machine constraints permit this operation. | ||
| 1598 | */ | ||
| 1599 | int regulator_disable_deferred(struct regulator *regulator, int ms) | ||
| 1600 | { | ||
| 1601 | struct regulator_dev *rdev = regulator->rdev; | ||
| 1602 | int ret; | ||
| 1603 | |||
| 1604 | mutex_lock(&rdev->mutex); | ||
| 1605 | rdev->deferred_disables++; | ||
| 1606 | mutex_unlock(&rdev->mutex); | ||
| 1607 | |||
| 1608 | ret = schedule_delayed_work(&rdev->disable_work, | ||
| 1609 | msecs_to_jiffies(ms)); | ||
| 1610 | if (ret < 0) | ||
| 1611 | return ret; | ||
| 1612 | else | ||
| 1613 | return 0; | ||
| 1614 | } | ||
| 1615 | EXPORT_SYMBOL_GPL(regulator_disable_deferred); | ||
| 1616 | |||
| 1555 | static int _regulator_is_enabled(struct regulator_dev *rdev) | 1617 | static int _regulator_is_enabled(struct regulator_dev *rdev) |
| 1556 | { | 1618 | { |
| 1557 | /* If we don't know then assume that the regulator is always on */ | 1619 | /* If we don't know then assume that the regulator is always on */ |
| @@ -2622,6 +2684,7 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
| 2622 | INIT_LIST_HEAD(&rdev->consumer_list); | 2684 | INIT_LIST_HEAD(&rdev->consumer_list); |
| 2623 | INIT_LIST_HEAD(&rdev->list); | 2685 | INIT_LIST_HEAD(&rdev->list); |
| 2624 | BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); | 2686 | BLOCKING_INIT_NOTIFIER_HEAD(&rdev->notifier); |
| 2687 | INIT_DELAYED_WORK(&rdev->disable_work, regulator_disable_work); | ||
| 2625 | 2688 | ||
| 2626 | /* preform any regulator specific init */ | 2689 | /* preform any regulator specific init */ |
| 2627 | if (init_data->regulator_init) { | 2690 | if (init_data->regulator_init) { |
| @@ -2729,6 +2792,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
| 2729 | #ifdef CONFIG_DEBUG_FS | 2792 | #ifdef CONFIG_DEBUG_FS |
| 2730 | debugfs_remove_recursive(rdev->debugfs); | 2793 | debugfs_remove_recursive(rdev->debugfs); |
| 2731 | #endif | 2794 | #endif |
| 2795 | flush_work_sync(&rdev->disable_work.work); | ||
| 2732 | WARN_ON(rdev->open_count); | 2796 | WARN_ON(rdev->open_count); |
| 2733 | unset_regulator_supplies(rdev); | 2797 | unset_regulator_supplies(rdev); |
| 2734 | list_del(&rdev->list); | 2798 | list_del(&rdev->list); |
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 1a6a690f24db..b87bf5c841f8 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
| @@ -140,6 +140,14 @@ static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, | |||
| 140 | return (selector * 100000) + 900000; | 140 | return (selector * 100000) + 900000; |
| 141 | case WM8958: | 141 | case WM8958: |
| 142 | return (selector * 100000) + 1000000; | 142 | return (selector * 100000) + 1000000; |
| 143 | case WM1811: | ||
| 144 | switch (selector) { | ||
| 145 | case 0: | ||
| 146 | return -EINVAL; | ||
| 147 | default: | ||
| 148 | return (selector * 100000) + 950000; | ||
| 149 | } | ||
| 150 | break; | ||
| 143 | default: | 151 | default: |
| 144 | return -EINVAL; | 152 | return -EINVAL; |
| 145 | } | 153 | } |
| @@ -170,6 +178,11 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev, | |||
| 170 | case WM8958: | 178 | case WM8958: |
| 171 | selector = (min_uV - 1000000) / 100000; | 179 | selector = (min_uV - 1000000) / 100000; |
| 172 | break; | 180 | break; |
| 181 | case WM1811: | ||
| 182 | selector = (min_uV - 950000) / 100000; | ||
| 183 | if (selector == 0) | ||
| 184 | selector = 1; | ||
| 185 | break; | ||
| 173 | default: | 186 | default: |
| 174 | return -EINVAL; | 187 | return -EINVAL; |
| 175 | } | 188 | } |
diff --git a/include/linux/input.h b/include/linux/input.h index 6d5eddb18c82..3862e32c4eeb 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
| @@ -815,6 +815,7 @@ struct input_keymap_entry { | |||
| 815 | #define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ | 815 | #define SW_KEYPAD_SLIDE 0x0a /* set = keypad slide out */ |
| 816 | #define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ | 816 | #define SW_FRONT_PROXIMITY 0x0b /* set = front proximity sensor active */ |
| 817 | #define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */ | 817 | #define SW_ROTATE_LOCK 0x0c /* set = rotate locked/disabled */ |
| 818 | #define SW_LINEIN_INSERT 0x0d /* set = inserted */ | ||
| 818 | #define SW_MAX 0x0f | 819 | #define SW_MAX 0x0f |
| 819 | #define SW_CNT (SW_MAX+1) | 820 | #define SW_CNT (SW_MAX+1) |
| 820 | 821 | ||
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h index 4c806f6d663e..2463c2619596 100644 --- a/include/linux/mfd/twl6040.h +++ b/include/linux/mfd/twl6040.h | |||
| @@ -68,11 +68,6 @@ | |||
| 68 | #define TWL6040_REG_ACCCTL 0x2D | 68 | #define TWL6040_REG_ACCCTL 0x2D |
| 69 | #define TWL6040_REG_STATUS 0x2E | 69 | #define TWL6040_REG_STATUS 0x2E |
| 70 | 70 | ||
| 71 | #define TWL6040_CACHEREGNUM (TWL6040_REG_STATUS + 1) | ||
| 72 | |||
| 73 | #define TWL6040_VIOREGNUM 18 | ||
| 74 | #define TWL6040_VDDREGNUM 21 | ||
| 75 | |||
| 76 | /* INTID (0x03) fields */ | 71 | /* INTID (0x03) fields */ |
| 77 | 72 | ||
| 78 | #define TWL6040_THINT 0x01 | 73 | #define TWL6040_THINT 0x01 |
| @@ -125,34 +120,24 @@ | |||
| 125 | #define TWL6040_LPLLFIN 0x08 | 120 | #define TWL6040_LPLLFIN 0x08 |
| 126 | #define TWL6040_HPLLSEL 0x10 | 121 | #define TWL6040_HPLLSEL 0x10 |
| 127 | 122 | ||
| 128 | /* HSLCTL (0x10) fields */ | 123 | /* HSLCTL/R (0x10/0x11) fields */ |
| 129 | |||
| 130 | #define TWL6040_HSDACMODEL 0x02 | ||
| 131 | #define TWL6040_HSDRVMODEL 0x08 | ||
| 132 | |||
| 133 | /* HSRCTL (0x11) fields */ | ||
| 134 | 124 | ||
| 135 | #define TWL6040_HSDACMODER 0x02 | 125 | #define TWL6040_HSDACENA (1 << 0) |
| 136 | #define TWL6040_HSDRVMODER 0x08 | 126 | #define TWL6040_HSDACMODE (1 << 1) |
| 127 | #define TWL6040_HSDRVMODE (1 << 3) | ||
| 137 | 128 | ||
| 138 | /* VIBCTLL (0x18) fields */ | 129 | /* VIBCTLL/R (0x18/0x1A) fields */ |
| 139 | 130 | ||
| 140 | #define TWL6040_VIBENAL 0x01 | 131 | #define TWL6040_VIBENA (1 << 0) |
| 141 | #define TWL6040_VIBCTRLL 0x04 | 132 | #define TWL6040_VIBSEL (1 << 1) |
| 142 | #define TWL6040_VIBCTRLLP 0x08 | 133 | #define TWL6040_VIBCTRL (1 << 2) |
| 143 | #define TWL6040_VIBCTRLLN 0x10 | 134 | #define TWL6040_VIBCTRL_P (1 << 3) |
| 135 | #define TWL6040_VIBCTRL_N (1 << 4) | ||
| 144 | 136 | ||
| 145 | /* VIBDATL (0x19) fields */ | 137 | /* VIBDATL/R (0x19/0x1B) fields */ |
| 146 | 138 | ||
| 147 | #define TWL6040_VIBDAT_MAX 0x64 | 139 | #define TWL6040_VIBDAT_MAX 0x64 |
| 148 | 140 | ||
| 149 | /* VIBCTLR (0x1A) fields */ | ||
| 150 | |||
| 151 | #define TWL6040_VIBENAR 0x01 | ||
| 152 | #define TWL6040_VIBCTRLR 0x04 | ||
| 153 | #define TWL6040_VIBCTRLRP 0x08 | ||
| 154 | #define TWL6040_VIBCTRLRN 0x10 | ||
| 155 | |||
| 156 | /* GPOCTL (0x1E) fields */ | 141 | /* GPOCTL (0x1E) fields */ |
| 157 | 142 | ||
| 158 | #define TWL6040_GPO1 0x01 | 143 | #define TWL6040_GPO1 0x01 |
| @@ -200,6 +185,7 @@ struct twl6040 { | |||
| 200 | int audpwron; | 185 | int audpwron; |
| 201 | int power_count; | 186 | int power_count; |
| 202 | int rev; | 187 | int rev; |
| 188 | u8 vibra_ctrl_cache[2]; | ||
| 203 | 189 | ||
| 204 | int pll; | 190 | int pll; |
| 205 | unsigned int sysclk; | 191 | unsigned int sysclk; |
| @@ -224,5 +210,13 @@ int twl6040_get_pll(struct twl6040 *twl6040); | |||
| 224 | unsigned int twl6040_get_sysclk(struct twl6040 *twl6040); | 210 | unsigned int twl6040_get_sysclk(struct twl6040 *twl6040); |
| 225 | int twl6040_irq_init(struct twl6040 *twl6040); | 211 | int twl6040_irq_init(struct twl6040 *twl6040); |
| 226 | void twl6040_irq_exit(struct twl6040 *twl6040); | 212 | void twl6040_irq_exit(struct twl6040 *twl6040); |
| 213 | /* Get the combined status of the vibra control register */ | ||
| 214 | int twl6040_get_vibralr_status(struct twl6040 *twl6040); | ||
| 215 | |||
| 216 | static inline int twl6040_get_revid(struct twl6040 *twl6040) | ||
| 217 | { | ||
| 218 | return twl6040->rev; | ||
| 219 | } | ||
| 220 | |||
| 227 | 221 | ||
| 228 | #endif /* End of __TWL6040_CODEC_H__ */ | 222 | #endif /* End of __TWL6040_CODEC_H__ */ |
diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index 45df450d869f..626809147624 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | enum wm8994_type { | 20 | enum wm8994_type { |
| 21 | WM8994 = 0, | 21 | WM8994 = 0, |
| 22 | WM8958 = 1, | 22 | WM8958 = 1, |
| 23 | WM1811 = 2, | ||
| 23 | }; | 24 | }; |
| 24 | 25 | ||
| 25 | struct regulator_dev; | 26 | struct regulator_dev; |
diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index f3ee84284670..fae295048a8b 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h | |||
| @@ -72,6 +72,7 @@ | |||
| 72 | #define WM8994_DC_SERVO_2 0x55 | 72 | #define WM8994_DC_SERVO_2 0x55 |
| 73 | #define WM8994_DC_SERVO_4 0x57 | 73 | #define WM8994_DC_SERVO_4 0x57 |
| 74 | #define WM8994_DC_SERVO_READBACK 0x58 | 74 | #define WM8994_DC_SERVO_READBACK 0x58 |
| 75 | #define WM8994_DC_SERVO_4E 0x59 | ||
| 75 | #define WM8994_ANALOGUE_HP_1 0x60 | 76 | #define WM8994_ANALOGUE_HP_1 0x60 |
| 76 | #define WM8958_MIC_DETECT_1 0xD0 | 77 | #define WM8958_MIC_DETECT_1 0xD0 |
| 77 | #define WM8958_MIC_DETECT_2 0xD1 | 78 | #define WM8958_MIC_DETECT_2 0xD1 |
| @@ -133,6 +134,8 @@ | |||
| 133 | #define WM8994_AIF1_DAC1_FILTERS_2 0x421 | 134 | #define WM8994_AIF1_DAC1_FILTERS_2 0x421 |
| 134 | #define WM8994_AIF1_DAC2_FILTERS_1 0x422 | 135 | #define WM8994_AIF1_DAC2_FILTERS_1 0x422 |
| 135 | #define WM8994_AIF1_DAC2_FILTERS_2 0x423 | 136 | #define WM8994_AIF1_DAC2_FILTERS_2 0x423 |
| 137 | #define WM8958_AIF1_DAC1_NOISE_GATE 0x430 | ||
| 138 | #define WM8958_AIF1_DAC2_NOISE_GATE 0x431 | ||
| 136 | #define WM8994_AIF1_DRC1_1 0x440 | 139 | #define WM8994_AIF1_DRC1_1 0x440 |
| 137 | #define WM8994_AIF1_DRC1_2 0x441 | 140 | #define WM8994_AIF1_DRC1_2 0x441 |
| 138 | #define WM8994_AIF1_DRC1_3 0x442 | 141 | #define WM8994_AIF1_DRC1_3 0x442 |
| @@ -190,6 +193,7 @@ | |||
| 190 | #define WM8994_AIF2_ADC_FILTERS 0x510 | 193 | #define WM8994_AIF2_ADC_FILTERS 0x510 |
| 191 | #define WM8994_AIF2_DAC_FILTERS_1 0x520 | 194 | #define WM8994_AIF2_DAC_FILTERS_1 0x520 |
| 192 | #define WM8994_AIF2_DAC_FILTERS_2 0x521 | 195 | #define WM8994_AIF2_DAC_FILTERS_2 0x521 |
| 196 | #define WM8958_AIF2_DAC_NOISE_GATE 0x530 | ||
| 193 | #define WM8994_AIF2_DRC_1 0x540 | 197 | #define WM8994_AIF2_DRC_1 0x540 |
| 194 | #define WM8994_AIF2_DRC_2 0x541 | 198 | #define WM8994_AIF2_DRC_2 0x541 |
| 195 | #define WM8994_AIF2_DRC_3 0x542 | 199 | #define WM8994_AIF2_DRC_3 0x542 |
| @@ -1921,6 +1925,44 @@ | |||
| 1921 | #define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ | 1925 | #define WM8994_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ |
| 1922 | 1926 | ||
| 1923 | /* | 1927 | /* |
| 1928 | * R61 (0x3D) - MICBIAS1 | ||
| 1929 | */ | ||
| 1930 | #define WM8958_MICB1_RATE 0x0020 /* MICB1_RATE */ | ||
| 1931 | #define WM8958_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ | ||
| 1932 | #define WM8958_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ | ||
| 1933 | #define WM8958_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ | ||
| 1934 | #define WM8958_MICB1_MODE 0x0010 /* MICB1_MODE */ | ||
| 1935 | #define WM8958_MICB1_MODE_MASK 0x0010 /* MICB1_MODE */ | ||
| 1936 | #define WM8958_MICB1_MODE_SHIFT 4 /* MICB1_MODE */ | ||
| 1937 | #define WM8958_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ | ||
| 1938 | #define WM8958_MICB1_LVL_MASK 0x000E /* MICB1_LVL - [3:1] */ | ||
| 1939 | #define WM8958_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [3:1] */ | ||
| 1940 | #define WM8958_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [3:1] */ | ||
| 1941 | #define WM8958_MICB1_DISCH 0x0001 /* MICB1_DISCH */ | ||
| 1942 | #define WM8958_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */ | ||
| 1943 | #define WM8958_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */ | ||
| 1944 | #define WM8958_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ | ||
| 1945 | |||
| 1946 | /* | ||
| 1947 | * R62 (0x3E) - MICBIAS2 | ||
| 1948 | */ | ||
| 1949 | #define WM8958_MICB2_RATE 0x0020 /* MICB2_RATE */ | ||
| 1950 | #define WM8958_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ | ||
| 1951 | #define WM8958_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ | ||
| 1952 | #define WM8958_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ | ||
| 1953 | #define WM8958_MICB2_MODE 0x0010 /* MICB2_MODE */ | ||
| 1954 | #define WM8958_MICB2_MODE_MASK 0x0010 /* MICB2_MODE */ | ||
| 1955 | #define WM8958_MICB2_MODE_SHIFT 4 /* MICB2_MODE */ | ||
| 1956 | #define WM8958_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ | ||
| 1957 | #define WM8958_MICB2_LVL_MASK 0x000E /* MICB2_LVL - [3:1] */ | ||
| 1958 | #define WM8958_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [3:1] */ | ||
| 1959 | #define WM8958_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [3:1] */ | ||
| 1960 | #define WM8958_MICB2_DISCH 0x0001 /* MICB2_DISCH */ | ||
| 1961 | #define WM8958_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */ | ||
| 1962 | #define WM8958_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */ | ||
| 1963 | #define WM8958_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ | ||
| 1964 | |||
| 1965 | /* | ||
| 1924 | * R76 (0x4C) - Charge Pump (1) | 1966 | * R76 (0x4C) - Charge Pump (1) |
| 1925 | */ | 1967 | */ |
| 1926 | #define WM8994_CP_ENA 0x8000 /* CP_ENA */ | 1968 | #define WM8994_CP_ENA 0x8000 /* CP_ENA */ |
| @@ -2027,6 +2069,10 @@ | |||
| 2027 | /* | 2069 | /* |
| 2028 | * R96 (0x60) - Analogue HP (1) | 2070 | * R96 (0x60) - Analogue HP (1) |
| 2029 | */ | 2071 | */ |
| 2072 | #define WM1811_HPOUT1_ATTN 0x0100 /* HPOUT1_ATTN */ | ||
| 2073 | #define WM1811_HPOUT1_ATTN_MASK 0x0100 /* HPOUT1_ATTN */ | ||
| 2074 | #define WM1811_HPOUT1_ATTN_SHIFT 8 /* HPOUT1_ATTN */ | ||
| 2075 | #define WM1811_HPOUT1_ATTN_WIDTH 1 /* HPOUT1_ATTN */ | ||
| 2030 | #define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ | 2076 | #define WM8994_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ |
| 2031 | #define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ | 2077 | #define WM8994_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ |
| 2032 | #define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ | 2078 | #define WM8994_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ |
| @@ -2949,6 +2995,34 @@ | |||
| 2949 | #define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */ | 2995 | #define WM8994_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */ |
| 2950 | 2996 | ||
| 2951 | /* | 2997 | /* |
| 2998 | * R1072 (0x430) - AIF1 DAC1 Noise Gate | ||
| 2999 | */ | ||
| 3000 | #define WM8958_AIF1DAC1_NG_HLD_MASK 0x0060 /* AIF1DAC1_NG_HLD - [6:5] */ | ||
| 3001 | #define WM8958_AIF1DAC1_NG_HLD_SHIFT 5 /* AIF1DAC1_NG_HLD - [6:5] */ | ||
| 3002 | #define WM8958_AIF1DAC1_NG_HLD_WIDTH 2 /* AIF1DAC1_NG_HLD - [6:5] */ | ||
| 3003 | #define WM8958_AIF1DAC1_NG_THR_MASK 0x000E /* AIF1DAC1_NG_THR - [3:1] */ | ||
| 3004 | #define WM8958_AIF1DAC1_NG_THR_SHIFT 1 /* AIF1DAC1_NG_THR - [3:1] */ | ||
| 3005 | #define WM8958_AIF1DAC1_NG_THR_WIDTH 3 /* AIF1DAC1_NG_THR - [3:1] */ | ||
| 3006 | #define WM8958_AIF1DAC1_NG_ENA 0x0001 /* AIF1DAC1_NG_ENA */ | ||
| 3007 | #define WM8958_AIF1DAC1_NG_ENA_MASK 0x0001 /* AIF1DAC1_NG_ENA */ | ||
| 3008 | #define WM8958_AIF1DAC1_NG_ENA_SHIFT 0 /* AIF1DAC1_NG_ENA */ | ||
| 3009 | #define WM8958_AIF1DAC1_NG_ENA_WIDTH 1 /* AIF1DAC1_NG_ENA */ | ||
| 3010 | |||
| 3011 | /* | ||
| 3012 | * R1073 (0x431) - AIF1 DAC2 Noise Gate | ||
| 3013 | */ | ||
| 3014 | #define WM8958_AIF1DAC2_NG_HLD_MASK 0x0060 /* AIF1DAC2_NG_HLD - [6:5] */ | ||
| 3015 | #define WM8958_AIF1DAC2_NG_HLD_SHIFT 5 /* AIF1DAC2_NG_HLD - [6:5] */ | ||
| 3016 | #define WM8958_AIF1DAC2_NG_HLD_WIDTH 2 /* AIF1DAC2_NG_HLD - [6:5] */ | ||
| 3017 | #define WM8958_AIF1DAC2_NG_THR_MASK 0x000E /* AIF1DAC2_NG_THR - [3:1] */ | ||
| 3018 | #define WM8958_AIF1DAC2_NG_THR_SHIFT 1 /* AIF1DAC2_NG_THR - [3:1] */ | ||
| 3019 | #define WM8958_AIF1DAC2_NG_THR_WIDTH 3 /* AIF1DAC2_NG_THR - [3:1] */ | ||
| 3020 | #define WM8958_AIF1DAC2_NG_ENA 0x0001 /* AIF1DAC2_NG_ENA */ | ||
| 3021 | #define WM8958_AIF1DAC2_NG_ENA_MASK 0x0001 /* AIF1DAC2_NG_ENA */ | ||
| 3022 | #define WM8958_AIF1DAC2_NG_ENA_SHIFT 0 /* AIF1DAC2_NG_ENA */ | ||
| 3023 | #define WM8958_AIF1DAC2_NG_ENA_WIDTH 1 /* AIF1DAC2_NG_ENA */ | ||
| 3024 | |||
| 3025 | /* | ||
| 2952 | * R1088 (0x440) - AIF1 DRC1 (1) | 3026 | * R1088 (0x440) - AIF1 DRC1 (1) |
| 2953 | */ | 3027 | */ |
| 2954 | #define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ | 3028 | #define WM8994_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ |
| @@ -3560,6 +3634,20 @@ | |||
| 3560 | #define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */ | 3634 | #define WM8994_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */ |
| 3561 | 3635 | ||
| 3562 | /* | 3636 | /* |
| 3637 | * R1328 (0x530) - AIF2 DAC Noise Gate | ||
| 3638 | */ | ||
| 3639 | #define WM8958_AIF2DAC_NG_HLD_MASK 0x0060 /* AIF2DAC_NG_HLD - [6:5] */ | ||
| 3640 | #define WM8958_AIF2DAC_NG_HLD_SHIFT 5 /* AIF2DAC_NG_HLD - [6:5] */ | ||
| 3641 | #define WM8958_AIF2DAC_NG_HLD_WIDTH 2 /* AIF2DAC_NG_HLD - [6:5] */ | ||
| 3642 | #define WM8958_AIF2DAC_NG_THR_MASK 0x000E /* AIF2DAC_NG_THR - [3:1] */ | ||
| 3643 | #define WM8958_AIF2DAC_NG_THR_SHIFT 1 /* AIF2DAC_NG_THR - [3:1] */ | ||
| 3644 | #define WM8958_AIF2DAC_NG_THR_WIDTH 3 /* AIF2DAC_NG_THR - [3:1] */ | ||
| 3645 | #define WM8958_AIF2DAC_NG_ENA 0x0001 /* AIF2DAC_NG_ENA */ | ||
| 3646 | #define WM8958_AIF2DAC_NG_ENA_MASK 0x0001 /* AIF2DAC_NG_ENA */ | ||
| 3647 | #define WM8958_AIF2DAC_NG_ENA_SHIFT 0 /* AIF2DAC_NG_ENA */ | ||
| 3648 | #define WM8958_AIF2DAC_NG_ENA_WIDTH 1 /* AIF2DAC_NG_ENA */ | ||
| 3649 | |||
| 3650 | /* | ||
| 3563 | * R1344 (0x540) - AIF2 DRC (1) | 3651 | * R1344 (0x540) - AIF2 DRC (1) |
| 3564 | */ | 3652 | */ |
| 3565 | #define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */ | 3653 | #define WM8994_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */ |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index b47771aa5718..f7756d146c61 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
| @@ -141,6 +141,7 @@ int regulator_enable(struct regulator *regulator); | |||
| 141 | int regulator_disable(struct regulator *regulator); | 141 | int regulator_disable(struct regulator *regulator); |
| 142 | int regulator_force_disable(struct regulator *regulator); | 142 | int regulator_force_disable(struct regulator *regulator); |
| 143 | int regulator_is_enabled(struct regulator *regulator); | 143 | int regulator_is_enabled(struct regulator *regulator); |
| 144 | int regulator_disable_deferred(struct regulator *regulator, int ms); | ||
| 144 | 145 | ||
| 145 | int regulator_bulk_get(struct device *dev, int num_consumers, | 146 | int regulator_bulk_get(struct device *dev, int num_consumers, |
| 146 | struct regulator_bulk_data *consumers); | 147 | struct regulator_bulk_data *consumers); |
| @@ -211,6 +212,12 @@ static inline int regulator_disable(struct regulator *regulator) | |||
| 211 | return 0; | 212 | return 0; |
| 212 | } | 213 | } |
| 213 | 214 | ||
| 215 | static inline int regulator_disable_deferred(struct regulator *regulator, | ||
| 216 | int ms) | ||
| 217 | { | ||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 214 | static inline int regulator_is_enabled(struct regulator *regulator) | 221 | static inline int regulator_is_enabled(struct regulator *regulator) |
| 215 | { | 222 | { |
| 216 | return 1; | 223 | return 1; |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 1a80bc77517d..12a1aa04b720 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
| @@ -199,6 +199,9 @@ struct regulator_dev { | |||
| 199 | struct regulation_constraints *constraints; | 199 | struct regulation_constraints *constraints; |
| 200 | struct regulator *supply; /* for tree */ | 200 | struct regulator *supply; /* for tree */ |
| 201 | 201 | ||
| 202 | struct delayed_work disable_work; | ||
| 203 | int deferred_disables; | ||
| 204 | |||
| 202 | void *reg_data; /* regulator_dev data */ | 205 | void *reg_data; /* regulator_dev data */ |
| 203 | 206 | ||
| 204 | #ifdef CONFIG_DEBUG_FS | 207 | #ifdef CONFIG_DEBUG_FS |
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h index f32a64e57f97..d5da6c68c250 100644 --- a/include/linux/usb/ch9.h +++ b/include/linux/usb/ch9.h | |||
| @@ -383,12 +383,6 @@ struct usb_endpoint_descriptor { | |||
| 383 | #define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ | 383 | #define USB_ENDPOINT_NUMBER_MASK 0x0f /* in bEndpointAddress */ |
| 384 | #define USB_ENDPOINT_DIR_MASK 0x80 | 384 | #define USB_ENDPOINT_DIR_MASK 0x80 |
| 385 | 385 | ||
| 386 | #define USB_ENDPOINT_SYNCTYPE 0x0c | ||
| 387 | #define USB_ENDPOINT_SYNC_NONE (0 << 2) | ||
| 388 | #define USB_ENDPOINT_SYNC_ASYNC (1 << 2) | ||
| 389 | #define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2) | ||
| 390 | #define USB_ENDPOINT_SYNC_SYNC (3 << 2) | ||
| 391 | |||
| 392 | #define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ | 386 | #define USB_ENDPOINT_XFERTYPE_MASK 0x03 /* in bmAttributes */ |
| 393 | #define USB_ENDPOINT_XFER_CONTROL 0 | 387 | #define USB_ENDPOINT_XFER_CONTROL 0 |
| 394 | #define USB_ENDPOINT_XFER_ISOC 1 | 388 | #define USB_ENDPOINT_XFER_ISOC 1 |
| @@ -396,6 +390,17 @@ struct usb_endpoint_descriptor { | |||
| 396 | #define USB_ENDPOINT_XFER_INT 3 | 390 | #define USB_ENDPOINT_XFER_INT 3 |
| 397 | #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 | 391 | #define USB_ENDPOINT_MAX_ADJUSTABLE 0x80 |
| 398 | 392 | ||
| 393 | #define USB_ENDPOINT_SYNCTYPE 0x0c | ||
| 394 | #define USB_ENDPOINT_SYNC_NONE (0 << 2) | ||
| 395 | #define USB_ENDPOINT_SYNC_ASYNC (1 << 2) | ||
| 396 | #define USB_ENDPOINT_SYNC_ADAPTIVE (2 << 2) | ||
| 397 | #define USB_ENDPOINT_SYNC_SYNC (3 << 2) | ||
| 398 | |||
| 399 | #define USB_ENDPOINT_USAGE_MASK 0x30 | ||
| 400 | #define USB_ENDPOINT_USAGE_DATA 0x00 | ||
| 401 | #define USB_ENDPOINT_USAGE_FEEDBACK 0x10 | ||
| 402 | #define USB_ENDPOINT_USAGE_IMPLICIT_FB 0x20 /* Implicit feedback Data endpoint */ | ||
| 403 | |||
| 399 | /*-------------------------------------------------------------------------*/ | 404 | /*-------------------------------------------------------------------------*/ |
| 400 | 405 | ||
| 401 | /** | 406 | /** |
diff --git a/include/sound/adau1373.h b/include/sound/adau1373.h new file mode 100644 index 000000000000..1b19c7666574 --- /dev/null +++ b/include/sound/adau1373.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* | ||
| 2 | * Analog Devices ADAU1373 Audio Codec drive | ||
| 3 | * | ||
| 4 | * Copyright 2011 Analog Devices Inc. | ||
| 5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
| 6 | * | ||
| 7 | * Licensed under the GPL-2 or later. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #ifndef __SOUND_ADAU1373_H__ | ||
| 11 | #define __SOUND_ADAU1373_H__ | ||
| 12 | |||
| 13 | enum adau1373_micbias_voltage { | ||
| 14 | ADAU1373_MICBIAS_2_9V = 0, | ||
| 15 | ADAU1373_MICBIAS_2_2V = 1, | ||
| 16 | ADAU1373_MICBIAS_2_6V = 2, | ||
| 17 | ADAU1373_MICBIAS_1_8V = 3, | ||
| 18 | }; | ||
| 19 | |||
| 20 | #define ADAU1373_DRC_SIZE 13 | ||
| 21 | |||
| 22 | struct adau1373_platform_data { | ||
| 23 | bool input_differential[4]; | ||
| 24 | bool lineout_differential; | ||
| 25 | bool lineout_ground_sense; | ||
| 26 | |||
| 27 | unsigned int num_drc; | ||
| 28 | uint8_t drc_setting[3][ADAU1373_DRC_SIZE]; | ||
| 29 | |||
| 30 | enum adau1373_micbias_voltage micbias1; | ||
| 31 | enum adau1373_micbias_voltage micbias2; | ||
| 32 | }; | ||
| 33 | |||
| 34 | #endif | ||
diff --git a/include/sound/asound.h b/include/sound/asound.h index 5d6074faa279..a2e4ff5ba9e9 100644 --- a/include/sound/asound.h +++ b/include/sound/asound.h | |||
| @@ -706,7 +706,7 @@ struct snd_timer_tread { | |||
| 706 | * * | 706 | * * |
| 707 | ****************************************************************************/ | 707 | ****************************************************************************/ |
| 708 | 708 | ||
| 709 | #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 6) | 709 | #define SNDRV_CTL_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) |
| 710 | 710 | ||
| 711 | struct snd_ctl_card_info { | 711 | struct snd_ctl_card_info { |
| 712 | int card; /* card number */ | 712 | int card; /* card number */ |
| @@ -803,6 +803,8 @@ struct snd_ctl_elem_info { | |||
| 803 | unsigned int items; /* R: number of items */ | 803 | unsigned int items; /* R: number of items */ |
| 804 | unsigned int item; /* W: item number */ | 804 | unsigned int item; /* W: item number */ |
| 805 | char name[64]; /* R: value name */ | 805 | char name[64]; /* R: value name */ |
| 806 | __u64 names_ptr; /* W: names list (ELEM_ADD only) */ | ||
| 807 | unsigned int names_length; | ||
| 806 | } enumerated; | 808 | } enumerated; |
| 807 | unsigned char reserved[128]; | 809 | unsigned char reserved[128]; |
| 808 | } value; | 810 | } value; |
diff --git a/include/sound/initval.h b/include/sound/initval.h index 1daa6dff8297..f99a0d2ddfe7 100644 --- a/include/sound/initval.h +++ b/include/sound/initval.h | |||
| @@ -62,7 +62,7 @@ static int snd_legacy_find_free_irq(int *irq_table) | |||
| 62 | { | 62 | { |
| 63 | while (*irq_table != -1) { | 63 | while (*irq_table != -1) { |
| 64 | if (!request_irq(*irq_table, snd_legacy_empty_irq_handler, | 64 | if (!request_irq(*irq_table, snd_legacy_empty_irq_handler, |
| 65 | IRQF_DISABLED | IRQF_PROBE_SHARED, "ALSA Test IRQ", | 65 | IRQF_PROBE_SHARED, "ALSA Test IRQ", |
| 66 | (void *) irq_table)) { | 66 | (void *) irq_table)) { |
| 67 | free_irq(*irq_table, (void *) irq_table); | 67 | free_irq(*irq_table, (void *) irq_table); |
| 68 | return *irq_table; | 68 | return *irq_table; |
diff --git a/include/sound/jack.h b/include/sound/jack.h index c140fc7cbd3f..63c790742db4 100644 --- a/include/sound/jack.h +++ b/include/sound/jack.h | |||
| @@ -42,6 +42,7 @@ enum snd_jack_types { | |||
| 42 | SND_JACK_MECHANICAL = 0x0008, /* If detected separately */ | 42 | SND_JACK_MECHANICAL = 0x0008, /* If detected separately */ |
| 43 | SND_JACK_VIDEOOUT = 0x0010, | 43 | SND_JACK_VIDEOOUT = 0x0010, |
| 44 | SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT, | 44 | SND_JACK_AVOUT = SND_JACK_LINEOUT | SND_JACK_VIDEOOUT, |
| 45 | SND_JACK_LINEIN = 0x0020, | ||
| 45 | 46 | ||
| 46 | /* Kept separate from switches to facilitate implementation */ | 47 | /* Kept separate from switches to facilitate implementation */ |
| 47 | SND_JACK_BTN_0 = 0x4000, | 48 | SND_JACK_BTN_0 = 0x4000, |
diff --git a/include/sound/mpu401.h b/include/sound/mpu401.h index 1f1d53f8830b..20230db00ef1 100644 --- a/include/sound/mpu401.h +++ b/include/sound/mpu401.h | |||
| @@ -50,7 +50,10 @@ | |||
| 50 | #define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */ | 50 | #define MPU401_INFO_INTEGRATED (1 << 2) /* integrated h/w port */ |
| 51 | #define MPU401_INFO_MMIO (1 << 3) /* MMIO access */ | 51 | #define MPU401_INFO_MMIO (1 << 3) /* MMIO access */ |
| 52 | #define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */ | 52 | #define MPU401_INFO_TX_IRQ (1 << 4) /* independent TX irq */ |
| 53 | #define MPU401_INFO_IRQ_HOOK (1 << 5) /* mpu401 irq handler is called | ||
| 54 | from driver irq handler */ | ||
| 53 | #define MPU401_INFO_NO_ACK (1 << 6) /* No ACK cmd needed */ | 55 | #define MPU401_INFO_NO_ACK (1 << 6) /* No ACK cmd needed */ |
| 56 | #define MPU401_INFO_USE_TIMER (1 << 15) /* internal */ | ||
| 54 | 57 | ||
| 55 | #define MPU401_MODE_BIT_INPUT 0 | 58 | #define MPU401_MODE_BIT_INPUT 0 |
| 56 | #define MPU401_MODE_BIT_OUTPUT 1 | 59 | #define MPU401_MODE_BIT_OUTPUT 1 |
| @@ -73,8 +76,7 @@ struct snd_mpu401 { | |||
| 73 | unsigned long port; /* base port of MPU-401 chip */ | 76 | unsigned long port; /* base port of MPU-401 chip */ |
| 74 | unsigned long cport; /* port + 1 (usually) */ | 77 | unsigned long cport; /* port + 1 (usually) */ |
| 75 | struct resource *res; /* port resource */ | 78 | struct resource *res; /* port resource */ |
| 76 | int irq; /* IRQ number of MPU-401 chip (-1 = poll) */ | 79 | int irq; /* IRQ number of MPU-401 chip */ |
| 77 | int irq_flags; | ||
| 78 | 80 | ||
| 79 | unsigned long mode; /* MPU401_MODE_XXXX */ | 81 | unsigned long mode; /* MPU401_MODE_XXXX */ |
| 80 | int timer_invoked; | 82 | int timer_invoked; |
| @@ -131,7 +133,6 @@ int snd_mpu401_uart_new(struct snd_card *card, | |||
| 131 | unsigned long port, | 133 | unsigned long port, |
| 132 | unsigned int info_flags, | 134 | unsigned int info_flags, |
| 133 | int irq, | 135 | int irq, |
| 134 | int irq_flags, | ||
| 135 | struct snd_rawmidi ** rrawmidi); | 136 | struct snd_rawmidi ** rrawmidi); |
| 136 | 137 | ||
| 137 | #endif /* __SOUND_MPU401_H */ | 138 | #endif /* __SOUND_MPU401_H */ |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index 54cb079b7bf1..0cf91b2f08ca 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
| @@ -825,6 +825,8 @@ int snd_pcm_hw_constraint_step(struct snd_pcm_runtime *runtime, | |||
| 825 | int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, | 825 | int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, |
| 826 | unsigned int cond, | 826 | unsigned int cond, |
| 827 | snd_pcm_hw_param_t var); | 827 | snd_pcm_hw_param_t var); |
| 828 | int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime, | ||
| 829 | unsigned int base_rate); | ||
| 828 | int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, | 830 | int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, |
| 829 | unsigned int cond, | 831 | unsigned int cond, |
| 830 | int var, | 832 | int var, |
| @@ -1035,6 +1037,8 @@ static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) | |||
| 1035 | atomic_dec(&substream->mmap_count); | 1037 | atomic_dec(&substream->mmap_count); |
| 1036 | } | 1038 | } |
| 1037 | 1039 | ||
| 1040 | int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, | ||
| 1041 | struct vm_area_struct *area); | ||
| 1038 | /* mmap for io-memory area */ | 1042 | /* mmap for io-memory area */ |
| 1039 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA) | 1043 | #if defined(CONFIG_X86) || defined(CONFIG_PPC) || defined(CONFIG_ALPHA) |
| 1040 | #define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP | 1044 | #define SNDRV_PCM_INFO_MMAP_IOMEM SNDRV_PCM_INFO_MMAP |
diff --git a/include/sound/saif.h b/include/sound/saif.h new file mode 100644 index 000000000000..d0e0de7984ec --- /dev/null +++ b/include/sound/saif.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License version 2 as | ||
| 6 | * published by the Free Software Foundation. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __SOUND_SAIF_H__ | ||
| 10 | #define __SOUND_SAIF_H__ | ||
| 11 | |||
| 12 | struct mxs_saif_platform_data { | ||
| 13 | int (*init) (void); | ||
| 14 | int (*get_master_id) (unsigned int saif_id); | ||
| 15 | }; | ||
| 16 | #endif | ||
diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 5ad5f3a50c68..2413acc54883 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h | |||
| @@ -24,13 +24,13 @@ struct snd_pcm_substream; | |||
| 24 | * Describes the physical PCM data formating and clocking. Add new formats | 24 | * Describes the physical PCM data formating and clocking. Add new formats |
| 25 | * to the end. | 25 | * to the end. |
| 26 | */ | 26 | */ |
| 27 | #define SND_SOC_DAIFMT_I2S 0 /* I2S mode */ | 27 | #define SND_SOC_DAIFMT_I2S 1 /* I2S mode */ |
| 28 | #define SND_SOC_DAIFMT_RIGHT_J 1 /* Right Justified mode */ | 28 | #define SND_SOC_DAIFMT_RIGHT_J 2 /* Right Justified mode */ |
| 29 | #define SND_SOC_DAIFMT_LEFT_J 2 /* Left Justified mode */ | 29 | #define SND_SOC_DAIFMT_LEFT_J 3 /* Left Justified mode */ |
| 30 | #define SND_SOC_DAIFMT_DSP_A 3 /* L data MSB after FRM LRC */ | 30 | #define SND_SOC_DAIFMT_DSP_A 4 /* L data MSB after FRM LRC */ |
| 31 | #define SND_SOC_DAIFMT_DSP_B 4 /* L data MSB during FRM LRC */ | 31 | #define SND_SOC_DAIFMT_DSP_B 5 /* L data MSB during FRM LRC */ |
| 32 | #define SND_SOC_DAIFMT_AC97 5 /* AC97 */ | 32 | #define SND_SOC_DAIFMT_AC97 6 /* AC97 */ |
| 33 | #define SND_SOC_DAIFMT_PDM 6 /* Pulse density modulation */ | 33 | #define SND_SOC_DAIFMT_PDM 7 /* Pulse density modulation */ |
| 34 | 34 | ||
| 35 | /* left and right justified also known as MSB and LSB respectively */ | 35 | /* left and right justified also known as MSB and LSB respectively */ |
| 36 | #define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J | 36 | #define SND_SOC_DAIFMT_MSB SND_SOC_DAIFMT_LEFT_J |
| @@ -42,8 +42,8 @@ struct snd_pcm_substream; | |||
| 42 | * DAI bit clocks can be be gated (disabled) when the DAI is not | 42 | * DAI bit clocks can be be gated (disabled) when the DAI is not |
| 43 | * sending or receiving PCM data in a frame. This can be used to save power. | 43 | * sending or receiving PCM data in a frame. This can be used to save power. |
| 44 | */ | 44 | */ |
| 45 | #define SND_SOC_DAIFMT_CONT (0 << 4) /* continuous clock */ | 45 | #define SND_SOC_DAIFMT_CONT (1 << 4) /* continuous clock */ |
| 46 | #define SND_SOC_DAIFMT_GATED (1 << 4) /* clock is gated */ | 46 | #define SND_SOC_DAIFMT_GATED (2 << 4) /* clock is gated */ |
| 47 | 47 | ||
| 48 | /* | 48 | /* |
| 49 | * DAI hardware signal inversions. | 49 | * DAI hardware signal inversions. |
| @@ -51,10 +51,10 @@ struct snd_pcm_substream; | |||
| 51 | * Specifies whether the DAI can also support inverted clocks for the specified | 51 | * Specifies whether the DAI can also support inverted clocks for the specified |
| 52 | * format. | 52 | * format. |
| 53 | */ | 53 | */ |
| 54 | #define SND_SOC_DAIFMT_NB_NF (0 << 8) /* normal bit clock + frame */ | 54 | #define SND_SOC_DAIFMT_NB_NF (1 << 8) /* normal bit clock + frame */ |
| 55 | #define SND_SOC_DAIFMT_NB_IF (1 << 8) /* normal BCLK + inv FRM */ | 55 | #define SND_SOC_DAIFMT_NB_IF (2 << 8) /* normal BCLK + inv FRM */ |
| 56 | #define SND_SOC_DAIFMT_IB_NF (2 << 8) /* invert BCLK + nor FRM */ | 56 | #define SND_SOC_DAIFMT_IB_NF (3 << 8) /* invert BCLK + nor FRM */ |
| 57 | #define SND_SOC_DAIFMT_IB_IF (3 << 8) /* invert BCLK + FRM */ | 57 | #define SND_SOC_DAIFMT_IB_IF (4 << 8) /* invert BCLK + FRM */ |
| 58 | 58 | ||
| 59 | /* | 59 | /* |
| 60 | * DAI hardware clock masters. | 60 | * DAI hardware clock masters. |
| @@ -63,10 +63,10 @@ struct snd_pcm_substream; | |||
| 63 | * i.e. if the codec is clk and FRM master then the interface is | 63 | * i.e. if the codec is clk and FRM master then the interface is |
| 64 | * clk and frame slave. | 64 | * clk and frame slave. |
| 65 | */ | 65 | */ |
| 66 | #define SND_SOC_DAIFMT_CBM_CFM (0 << 12) /* codec clk & FRM master */ | 66 | #define SND_SOC_DAIFMT_CBM_CFM (1 << 12) /* codec clk & FRM master */ |
| 67 | #define SND_SOC_DAIFMT_CBS_CFM (1 << 12) /* codec clk slave & FRM master */ | 67 | #define SND_SOC_DAIFMT_CBS_CFM (2 << 12) /* codec clk slave & FRM master */ |
| 68 | #define SND_SOC_DAIFMT_CBM_CFS (2 << 12) /* codec clk master & frame slave */ | 68 | #define SND_SOC_DAIFMT_CBM_CFS (3 << 12) /* codec clk master & frame slave */ |
| 69 | #define SND_SOC_DAIFMT_CBS_CFS (3 << 12) /* codec clk & FRM slave */ | 69 | #define SND_SOC_DAIFMT_CBS_CFS (4 << 12) /* codec clk & FRM slave */ |
| 70 | 70 | ||
| 71 | #define SND_SOC_DAIFMT_FORMAT_MASK 0x000f | 71 | #define SND_SOC_DAIFMT_FORMAT_MASK 0x000f |
| 72 | #define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 | 72 | #define SND_SOC_DAIFMT_CLOCK_MASK 0x00f0 |
| @@ -242,6 +242,9 @@ struct snd_soc_dai { | |||
| 242 | void *playback_dma_data; | 242 | void *playback_dma_data; |
| 243 | void *capture_dma_data; | 243 | void *capture_dma_data; |
| 244 | 244 | ||
| 245 | /* Symmetry data - only valid if symmetry is being enforced */ | ||
| 246 | unsigned int rate; | ||
| 247 | |||
| 245 | /* parent platform/codec */ | 248 | /* parent platform/codec */ |
| 246 | union { | 249 | union { |
| 247 | struct snd_soc_platform *platform; | 250 | struct snd_soc_platform *platform; |
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index e0583b7769cb..17a4c17f19f5 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h | |||
| @@ -381,6 +381,9 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | |||
| 381 | int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, | 381 | int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, |
| 382 | const char *pin); | 382 | const char *pin); |
| 383 | 383 | ||
| 384 | /* Mostly internal - should not normally be used */ | ||
| 385 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason); | ||
| 386 | |||
| 384 | /* dapm widget types */ | 387 | /* dapm widget types */ |
| 385 | enum snd_soc_dapm_type { | 388 | enum snd_soc_dapm_type { |
| 386 | snd_soc_dapm_input = 0, /* input pin */ | 389 | snd_soc_dapm_input = 0, /* input pin */ |
| @@ -473,6 +476,8 @@ struct snd_soc_dapm_widget { | |||
| 473 | unsigned char ext:1; /* has external widgets */ | 476 | unsigned char ext:1; /* has external widgets */ |
| 474 | unsigned char force:1; /* force state */ | 477 | unsigned char force:1; /* force state */ |
| 475 | unsigned char ignore_suspend:1; /* kept enabled over suspend */ | 478 | unsigned char ignore_suspend:1; /* kept enabled over suspend */ |
| 479 | unsigned char new_power:1; /* power from this run */ | ||
| 480 | unsigned char power_checked:1; /* power checked this run */ | ||
| 476 | int subseq; /* sort within widget type */ | 481 | int subseq; /* sort within widget type */ |
| 477 | 482 | ||
| 478 | int (*power_check)(struct snd_soc_dapm_widget *w); | 483 | int (*power_check)(struct snd_soc_dapm_widget *w); |
| @@ -492,6 +497,9 @@ struct snd_soc_dapm_widget { | |||
| 492 | 497 | ||
| 493 | /* used during DAPM updates */ | 498 | /* used during DAPM updates */ |
| 494 | struct list_head power_list; | 499 | struct list_head power_list; |
| 500 | struct list_head dirty; | ||
| 501 | int inputs; | ||
| 502 | int outputs; | ||
| 495 | }; | 503 | }; |
| 496 | 504 | ||
| 497 | struct snd_soc_dapm_update { | 505 | struct snd_soc_dapm_update { |
| @@ -524,6 +532,8 @@ struct snd_soc_dapm_context { | |||
| 524 | enum snd_soc_bias_level target_bias_level; | 532 | enum snd_soc_bias_level target_bias_level; |
| 525 | struct list_head list; | 533 | struct list_head list; |
| 526 | 534 | ||
| 535 | int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); | ||
| 536 | |||
| 527 | #ifdef CONFIG_DEBUG_FS | 537 | #ifdef CONFIG_DEBUG_FS |
| 528 | struct dentry *debugfs_dapm; | 538 | struct dentry *debugfs_dapm; |
| 529 | #endif | 539 | #endif |
| @@ -535,4 +545,10 @@ struct snd_soc_dapm_widget_list { | |||
| 535 | struct snd_soc_dapm_widget *widgets[0]; | 545 | struct snd_soc_dapm_widget *widgets[0]; |
| 536 | }; | 546 | }; |
| 537 | 547 | ||
| 548 | struct snd_soc_dapm_stats { | ||
| 549 | int power_checks; | ||
| 550 | int path_checks; | ||
| 551 | int neighbour_checks; | ||
| 552 | }; | ||
| 553 | |||
| 538 | #endif | 554 | #endif |
diff --git a/include/sound/soc.h b/include/sound/soc.h index aa19f5a32ba8..11cfb5953e06 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/workqueue.h> | 19 | #include <linux/workqueue.h> |
| 20 | #include <linux/interrupt.h> | 20 | #include <linux/interrupt.h> |
| 21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
| 22 | #include <linux/regmap.h> | ||
| 22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
| 23 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
| 24 | #include <sound/control.h> | 25 | #include <sound/control.h> |
| @@ -27,13 +28,20 @@ | |||
| 27 | /* | 28 | /* |
| 28 | * Convenience kcontrol builders | 29 | * Convenience kcontrol builders |
| 29 | */ | 30 | */ |
| 30 | #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ | 31 | #define SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, xmax, xinvert) \ |
| 31 | ((unsigned long)&(struct soc_mixer_control) \ | 32 | ((unsigned long)&(struct soc_mixer_control) \ |
| 32 | {.reg = xreg, .shift = xshift, .rshift = xshift, .max = xmax, \ | 33 | {.reg = xreg, .rreg = xreg, .shift = shift_left, \ |
| 33 | .platform_max = xmax, .invert = xinvert}) | 34 | .rshift = shift_right, .max = xmax, .platform_max = xmax, \ |
| 35 | .invert = xinvert}) | ||
| 36 | #define SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) \ | ||
| 37 | SOC_DOUBLE_VALUE(xreg, xshift, xshift, xmax, xinvert) | ||
| 34 | #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ | 38 | #define SOC_SINGLE_VALUE_EXT(xreg, xmax, xinvert) \ |
| 35 | ((unsigned long)&(struct soc_mixer_control) \ | 39 | ((unsigned long)&(struct soc_mixer_control) \ |
| 36 | {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert}) | 40 | {.reg = xreg, .max = xmax, .platform_max = xmax, .invert = xinvert}) |
| 41 | #define SOC_DOUBLE_R_VALUE(xlreg, xrreg, xshift, xmax, xinvert) \ | ||
| 42 | ((unsigned long)&(struct soc_mixer_control) \ | ||
| 43 | {.reg = xlreg, .rreg = xrreg, .shift = xshift, .rshift = xshift, \ | ||
| 44 | .max = xmax, .platform_max = xmax, .invert = xinvert}) | ||
| 37 | #define SOC_SINGLE(xname, reg, shift, max, invert) \ | 45 | #define SOC_SINGLE(xname, reg, shift, max, invert) \ |
| 38 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 46 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
| 39 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ | 47 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ |
| @@ -47,40 +55,36 @@ | |||
| 47 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ | 55 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw,\ |
| 48 | .put = snd_soc_put_volsw, \ | 56 | .put = snd_soc_put_volsw, \ |
| 49 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | 57 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } |
| 50 | #define SOC_DOUBLE(xname, xreg, shift_left, shift_right, xmax, xinvert) \ | 58 | #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \ |
| 51 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 59 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
| 52 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ | 60 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ |
| 53 | .put = snd_soc_put_volsw, \ | 61 | .put = snd_soc_put_volsw, \ |
| 54 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 62 | .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ |
| 55 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ | 63 | max, invert) } |
| 56 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 57 | #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ | 64 | #define SOC_DOUBLE_R(xname, reg_left, reg_right, xshift, xmax, xinvert) \ |
| 58 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 65 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
| 59 | .info = snd_soc_info_volsw_2r, \ | 66 | .info = snd_soc_info_volsw, \ |
| 60 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ | 67 | .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ |
| 61 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 68 | .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ |
| 62 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | 69 | xmax, xinvert) } |
| 63 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | 70 | #define SOC_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, tlv_array) \ |
| 64 | #define SOC_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax, xinvert, tlv_array) \ | ||
| 65 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 71 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
| 66 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 72 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
| 67 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | 73 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ |
| 68 | .tlv.p = (tlv_array), \ | 74 | .tlv.p = (tlv_array), \ |
| 69 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ | 75 | .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \ |
| 70 | .put = snd_soc_put_volsw, \ | 76 | .put = snd_soc_put_volsw, \ |
| 71 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 77 | .private_value = SOC_DOUBLE_VALUE(reg, shift_left, shift_right, \ |
| 72 | {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ | 78 | max, invert) } |
| 73 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 74 | #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ | 79 | #define SOC_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert, tlv_array) \ |
| 75 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 80 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
| 76 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | 81 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ |
| 77 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | 82 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ |
| 78 | .tlv.p = (tlv_array), \ | 83 | .tlv.p = (tlv_array), \ |
| 79 | .info = snd_soc_info_volsw_2r, \ | 84 | .info = snd_soc_info_volsw, \ |
| 80 | .get = snd_soc_get_volsw_2r, .put = snd_soc_put_volsw_2r, \ | 85 | .get = snd_soc_get_volsw, .put = snd_soc_put_volsw, \ |
| 81 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 86 | .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ |
| 82 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | 87 | xmax, xinvert) } |
| 83 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 84 | #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ | 88 | #define SOC_DOUBLE_S8_TLV(xname, xreg, xmin, xmax, tlv_array) \ |
| 85 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
| 86 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | 90 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ |
| @@ -120,14 +124,13 @@ | |||
| 120 | .info = snd_soc_info_volsw, \ | 124 | .info = snd_soc_info_volsw, \ |
| 121 | .get = xhandler_get, .put = xhandler_put, \ | 125 | .get = xhandler_get, .put = xhandler_put, \ |
| 122 | .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } | 126 | .private_value = SOC_SINGLE_VALUE(xreg, xshift, xmax, xinvert) } |
| 123 | #define SOC_DOUBLE_EXT(xname, xreg, shift_left, shift_right, xmax, xinvert,\ | 127 | #define SOC_DOUBLE_EXT(xname, reg, shift_left, shift_right, max, invert,\ |
| 124 | xhandler_get, xhandler_put) \ | 128 | xhandler_get, xhandler_put) \ |
| 125 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | 129 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ |
| 126 | .info = snd_soc_info_volsw, \ | 130 | .info = snd_soc_info_volsw, \ |
| 127 | .get = xhandler_get, .put = xhandler_put, \ | 131 | .get = xhandler_get, .put = xhandler_put, \ |
| 128 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 132 | .private_value = \ |
| 129 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ | 133 | SOC_DOUBLE_VALUE(reg, shift_left, shift_right, max, invert) } |
| 130 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 131 | #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ | 134 | #define SOC_SINGLE_EXT_TLV(xname, xreg, xshift, xmax, xinvert,\ |
| 132 | xhandler_get, xhandler_put, tlv_array) \ | 135 | xhandler_get, xhandler_put, tlv_array) \ |
| 133 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 136 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
| @@ -145,20 +148,18 @@ | |||
| 145 | .tlv.p = (tlv_array), \ | 148 | .tlv.p = (tlv_array), \ |
| 146 | .info = snd_soc_info_volsw, \ | 149 | .info = snd_soc_info_volsw, \ |
| 147 | .get = xhandler_get, .put = xhandler_put, \ | 150 | .get = xhandler_get, .put = xhandler_put, \ |
| 148 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 151 | .private_value = SOC_DOUBLE_VALUE(xreg, shift_left, shift_right, \ |
| 149 | {.reg = xreg, .shift = shift_left, .rshift = shift_right, \ | 152 | xmax, xinvert) } |
| 150 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 151 | #define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ | 153 | #define SOC_DOUBLE_R_EXT_TLV(xname, reg_left, reg_right, xshift, xmax, xinvert,\ |
| 152 | xhandler_get, xhandler_put, tlv_array) \ | 154 | xhandler_get, xhandler_put, tlv_array) \ |
| 153 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | 155 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ |
| 154 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | 156 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ |
| 155 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | 157 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ |
| 156 | .tlv.p = (tlv_array), \ | 158 | .tlv.p = (tlv_array), \ |
| 157 | .info = snd_soc_info_volsw_2r, \ | 159 | .info = snd_soc_info_volsw, \ |
| 158 | .get = xhandler_get, .put = xhandler_put, \ | 160 | .get = xhandler_get, .put = xhandler_put, \ |
| 159 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | 161 | .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ |
| 160 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | 162 | xmax, xinvert) } |
| 161 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 162 | #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ | 163 | #define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \ |
| 163 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 164 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
| 164 | .info = snd_soc_info_bool_ext, \ | 165 | .info = snd_soc_info_bool_ext, \ |
| @@ -260,6 +261,7 @@ extern struct snd_ac97_bus_ops soc_ac97_ops; | |||
| 260 | enum snd_soc_control_type { | 261 | enum snd_soc_control_type { |
| 261 | SND_SOC_I2C = 1, | 262 | SND_SOC_I2C = 1, |
| 262 | SND_SOC_SPI, | 263 | SND_SOC_SPI, |
| 264 | SND_SOC_REGMAP, | ||
| 263 | }; | 265 | }; |
| 264 | 266 | ||
| 265 | enum snd_soc_compress_type { | 267 | enum snd_soc_compress_type { |
| @@ -274,7 +276,7 @@ enum snd_soc_pcm_subclass { | |||
| 274 | }; | 276 | }; |
| 275 | 277 | ||
| 276 | int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 278 | int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
| 277 | unsigned int freq, int dir); | 279 | int source, unsigned int freq, int dir); |
| 278 | int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, | 280 | int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source, |
| 279 | unsigned int freq_in, unsigned int freq_out); | 281 | unsigned int freq_in, unsigned int freq_out); |
| 280 | 282 | ||
| @@ -391,12 +393,8 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
| 391 | struct snd_ctl_elem_value *ucontrol); | 393 | struct snd_ctl_elem_value *ucontrol); |
| 392 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | 394 | int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, |
| 393 | struct snd_ctl_elem_value *ucontrol); | 395 | struct snd_ctl_elem_value *ucontrol); |
| 394 | int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, | 396 | #define snd_soc_get_volsw_2r snd_soc_get_volsw |
| 395 | struct snd_ctl_elem_info *uinfo); | 397 | #define snd_soc_put_volsw_2r snd_soc_put_volsw |
| 396 | int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, | ||
| 397 | struct snd_ctl_elem_value *ucontrol); | ||
| 398 | int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, | ||
| 399 | struct snd_ctl_elem_value *ucontrol); | ||
| 400 | int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, | 398 | int snd_soc_info_volsw_s8(struct snd_kcontrol *kcontrol, |
| 401 | struct snd_ctl_elem_info *uinfo); | 399 | struct snd_ctl_elem_info *uinfo); |
| 402 | int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, | 400 | int snd_soc_get_volsw_s8(struct snd_kcontrol *kcontrol, |
| @@ -576,9 +574,11 @@ struct snd_soc_codec { | |||
| 576 | const void *reg_def_copy; | 574 | const void *reg_def_copy; |
| 577 | const struct snd_soc_cache_ops *cache_ops; | 575 | const struct snd_soc_cache_ops *cache_ops; |
| 578 | struct mutex cache_rw_mutex; | 576 | struct mutex cache_rw_mutex; |
| 577 | int val_bytes; | ||
| 579 | 578 | ||
| 580 | /* dapm */ | 579 | /* dapm */ |
| 581 | struct snd_soc_dapm_context dapm; | 580 | struct snd_soc_dapm_context dapm; |
| 581 | unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */ | ||
| 582 | 582 | ||
| 583 | #ifdef CONFIG_DEBUG_FS | 583 | #ifdef CONFIG_DEBUG_FS |
| 584 | struct dentry *debugfs_codec_root; | 584 | struct dentry *debugfs_codec_root; |
| @@ -607,7 +607,7 @@ struct snd_soc_codec_driver { | |||
| 607 | 607 | ||
| 608 | /* codec wide operations */ | 608 | /* codec wide operations */ |
| 609 | int (*set_sysclk)(struct snd_soc_codec *codec, | 609 | int (*set_sysclk)(struct snd_soc_codec *codec, |
| 610 | int clk_id, unsigned int freq, int dir); | 610 | int clk_id, int source, unsigned int freq, int dir); |
| 611 | int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, | 611 | int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source, |
| 612 | unsigned int freq_in, unsigned int freq_out); | 612 | unsigned int freq_in, unsigned int freq_out); |
| 613 | 613 | ||
| @@ -619,7 +619,7 @@ struct snd_soc_codec_driver { | |||
| 619 | int (*volatile_register)(struct snd_soc_codec *, unsigned int); | 619 | int (*volatile_register)(struct snd_soc_codec *, unsigned int); |
| 620 | int (*readable_register)(struct snd_soc_codec *, unsigned int); | 620 | int (*readable_register)(struct snd_soc_codec *, unsigned int); |
| 621 | int (*writable_register)(struct snd_soc_codec *, unsigned int); | 621 | int (*writable_register)(struct snd_soc_codec *, unsigned int); |
| 622 | short reg_cache_size; | 622 | unsigned int reg_cache_size; |
| 623 | short reg_cache_step; | 623 | short reg_cache_step; |
| 624 | short reg_word_size; | 624 | short reg_word_size; |
| 625 | const void *reg_cache_default; | 625 | const void *reg_cache_default; |
| @@ -630,10 +630,14 @@ struct snd_soc_codec_driver { | |||
| 630 | /* codec bias level */ | 630 | /* codec bias level */ |
| 631 | int (*set_bias_level)(struct snd_soc_codec *, | 631 | int (*set_bias_level)(struct snd_soc_codec *, |
| 632 | enum snd_soc_bias_level level); | 632 | enum snd_soc_bias_level level); |
| 633 | bool idle_bias_off; | ||
| 633 | 634 | ||
| 634 | void (*seq_notifier)(struct snd_soc_dapm_context *, | 635 | void (*seq_notifier)(struct snd_soc_dapm_context *, |
| 635 | enum snd_soc_dapm_type, int); | 636 | enum snd_soc_dapm_type, int); |
| 636 | 637 | ||
| 638 | /* codec stream completion event */ | ||
| 639 | int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); | ||
| 640 | |||
| 637 | /* probe ordering - for components with runtime dependencies */ | 641 | /* probe ordering - for components with runtime dependencies */ |
| 638 | int probe_order; | 642 | int probe_order; |
| 639 | int remove_order; | 643 | int remove_order; |
| @@ -669,6 +673,9 @@ struct snd_soc_platform_driver { | |||
| 669 | /* platform stream ops */ | 673 | /* platform stream ops */ |
| 670 | struct snd_pcm_ops *ops; | 674 | struct snd_pcm_ops *ops; |
| 671 | 675 | ||
| 676 | /* platform stream completion event */ | ||
| 677 | int (*stream_event)(struct snd_soc_dapm_context *dapm, int event); | ||
| 678 | |||
| 672 | /* probe ordering - for components with runtime dependencies */ | 679 | /* probe ordering - for components with runtime dependencies */ |
| 673 | int probe_order; | 680 | int probe_order; |
| 674 | int remove_order; | 681 | int remove_order; |
| @@ -703,6 +710,8 @@ struct snd_soc_dai_link { | |||
| 703 | const char *cpu_dai_name; | 710 | const char *cpu_dai_name; |
| 704 | const char *codec_dai_name; | 711 | const char *codec_dai_name; |
| 705 | 712 | ||
| 713 | unsigned int dai_fmt; /* format to set on init */ | ||
| 714 | |||
| 706 | /* Keep DAI active over suspend */ | 715 | /* Keep DAI active over suspend */ |
| 707 | unsigned int ignore_suspend:1; | 716 | unsigned int ignore_suspend:1; |
| 708 | 717 | ||
| @@ -815,9 +824,11 @@ struct snd_soc_card { | |||
| 815 | struct list_head widgets; | 824 | struct list_head widgets; |
| 816 | struct list_head paths; | 825 | struct list_head paths; |
| 817 | struct list_head dapm_list; | 826 | struct list_head dapm_list; |
| 827 | struct list_head dapm_dirty; | ||
| 818 | 828 | ||
| 819 | /* Generic DAPM context for the card */ | 829 | /* Generic DAPM context for the card */ |
| 820 | struct snd_soc_dapm_context dapm; | 830 | struct snd_soc_dapm_context dapm; |
| 831 | struct snd_soc_dapm_stats dapm_stats; | ||
| 821 | 832 | ||
| 822 | #ifdef CONFIG_DEBUG_FS | 833 | #ifdef CONFIG_DEBUG_FS |
| 823 | struct dentry *debugfs_card_root; | 834 | struct dentry *debugfs_card_root; |
| @@ -840,8 +851,6 @@ struct snd_soc_pcm_runtime { | |||
| 840 | unsigned int complete:1; | 851 | unsigned int complete:1; |
| 841 | unsigned int dev_registered:1; | 852 | unsigned int dev_registered:1; |
| 842 | 853 | ||
| 843 | /* Symmetry data - only valid if symmetry is being enforced */ | ||
| 844 | unsigned int rate; | ||
| 845 | long pmdown_time; | 854 | long pmdown_time; |
| 846 | 855 | ||
| 847 | /* runtime devices */ | 856 | /* runtime devices */ |
| @@ -936,6 +945,18 @@ static inline void snd_soc_initialize_card_lists(struct snd_soc_card *card) | |||
| 936 | INIT_LIST_HEAD(&card->dapm_list); | 945 | INIT_LIST_HEAD(&card->dapm_list); |
| 937 | } | 946 | } |
| 938 | 947 | ||
| 948 | static inline bool snd_soc_volsw_is_stereo(struct soc_mixer_control *mc) | ||
| 949 | { | ||
| 950 | if (mc->reg == mc->rreg && mc->shift == mc->rshift) | ||
| 951 | return 0; | ||
| 952 | /* | ||
| 953 | * mc->reg == mc->rreg && mc->shift != mc->rshift, or | ||
| 954 | * mc->reg != mc->rreg means that the control is | ||
| 955 | * stereo (bits in one register or in two registers) | ||
| 956 | */ | ||
| 957 | return 1; | ||
| 958 | } | ||
| 959 | |||
| 939 | int snd_soc_util_init(void); | 960 | int snd_soc_util_init(void); |
| 940 | void snd_soc_util_exit(void); | 961 | void snd_soc_util_exit(void); |
| 941 | 962 | ||
diff --git a/include/sound/tpa6130a2-plat.h b/include/sound/tpa6130a2-plat.h index 89beccb57edd..4cc1093844c8 100644 --- a/include/sound/tpa6130a2-plat.h +++ b/include/sound/tpa6130a2-plat.h | |||
| @@ -23,13 +23,7 @@ | |||
| 23 | #ifndef TPA6130A2_PLAT_H | 23 | #ifndef TPA6130A2_PLAT_H |
| 24 | #define TPA6130A2_PLAT_H | 24 | #define TPA6130A2_PLAT_H |
| 25 | 25 | ||
| 26 | enum tpa_model { | ||
| 27 | TPA6130A2, | ||
| 28 | TPA6140A2, | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct tpa6130a2_platform_data { | 26 | struct tpa6130a2_platform_data { |
| 32 | enum tpa_model id; | ||
| 33 | int power_gpio; | 27 | int power_gpio; |
| 34 | }; | 28 | }; |
| 35 | 29 | ||
diff --git a/include/sound/wm1250-ev1.h b/include/sound/wm1250-ev1.h new file mode 100644 index 000000000000..7dff82834123 --- /dev/null +++ b/include/sound/wm1250-ev1.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /* | ||
| 2 | * linux/sound/wm1250-ev1.h - Platform data for WM1250-EV1 | ||
| 3 | * | ||
| 4 | * Copyright 2011 Wolfson Microelectronics. PLC. | ||
| 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_WM1250_EV1_H | ||
| 12 | #define __LINUX_SND_WM1250_EV1_H | ||
| 13 | |||
| 14 | #define WM1250_EV1_NUM_GPIOS 5 | ||
| 15 | |||
| 16 | #define WM1250_EV1_GPIO_CLK_ENA 0 | ||
| 17 | #define WM1250_EV1_GPIO_CLK_SEL0 1 | ||
| 18 | #define WM1250_EV1_GPIO_CLK_SEL1 2 | ||
| 19 | #define WM1250_EV1_GPIO_OSR 3 | ||
| 20 | #define WM1250_EV1_GPIO_MASTER 4 | ||
| 21 | |||
| 22 | |||
| 23 | struct wm1250_ev1_pdata { | ||
| 24 | int gpios[WM1250_EV1_NUM_GPIOS]; | ||
| 25 | }; | ||
| 26 | |||
| 27 | #endif | ||
diff --git a/include/sound/wm5100.h b/include/sound/wm5100.h new file mode 100644 index 000000000000..617d0c4a159f --- /dev/null +++ b/include/sound/wm5100.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* | ||
| 2 | * linux/sound/wm5100.h -- Platform data for WM5100 | ||
| 3 | * | ||
| 4 | * Copyright 2011 Wolfson Microelectronics. PLC. | ||
| 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_WM5100_H | ||
| 12 | #define __LINUX_SND_WM5100_H | ||
| 13 | |||
| 14 | enum wm5100_in_mode { | ||
| 15 | WM5100_IN_SE = 0, | ||
| 16 | WM5100_IN_DIFF = 1, | ||
| 17 | WM5100_IN_DMIC = 2, | ||
| 18 | }; | ||
| 19 | |||
| 20 | enum wm5100_dmic_sup { | ||
| 21 | WM5100_DMIC_SUP_MICVDD = 0, | ||
| 22 | WM5100_DMIC_SUP_MICBIAS1 = 1, | ||
| 23 | WM5100_DMIC_SUP_MICBIAS2 = 2, | ||
| 24 | WM5100_DMIC_SUP_MICBIAS3 = 3, | ||
| 25 | }; | ||
| 26 | |||
| 27 | enum wm5100_micdet_bias { | ||
| 28 | WM5100_MICDET_MICBIAS1 = 0, | ||
| 29 | WM5100_MICDET_MICBIAS2 = 1, | ||
| 30 | WM5100_MICDET_MICBIAS3 = 2, | ||
| 31 | }; | ||
| 32 | |||
| 33 | struct wm5100_jack_mode { | ||
| 34 | enum wm5100_micdet_bias bias; | ||
| 35 | int hp_pol; | ||
| 36 | int micd_src; | ||
| 37 | }; | ||
| 38 | |||
| 39 | #define WM5100_GPIO_SET 0x10000 | ||
| 40 | |||
| 41 | struct wm5100_pdata { | ||
| 42 | int reset; /** GPIO controlling /RESET, if any */ | ||
| 43 | int ldo_ena; /** GPIO controlling LODENA, if any */ | ||
| 44 | int hp_pol; /** GPIO controlling headset polarity, if any */ | ||
| 45 | int irq_flags; | ||
| 46 | int gpio_base; | ||
| 47 | |||
| 48 | struct wm5100_jack_mode jack_modes[2]; | ||
| 49 | |||
| 50 | /* Input pin mode selection */ | ||
| 51 | enum wm5100_in_mode in_mode[4]; | ||
| 52 | |||
| 53 | /* DMIC supply selection */ | ||
| 54 | enum wm5100_dmic_sup dmic_sup[4]; | ||
| 55 | |||
| 56 | int gpio_defaults[6]; | ||
| 57 | }; | ||
| 58 | |||
| 59 | #endif | ||
diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index 603f5a0f0365..ab26f8aa3c78 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h | |||
| @@ -216,6 +216,31 @@ DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, | |||
| 216 | 216 | ||
| 217 | ); | 217 | ); |
| 218 | 218 | ||
| 219 | TRACE_EVENT(snd_soc_dapm_walk_done, | ||
| 220 | |||
| 221 | TP_PROTO(struct snd_soc_card *card), | ||
| 222 | |||
| 223 | TP_ARGS(card), | ||
| 224 | |||
| 225 | TP_STRUCT__entry( | ||
| 226 | __string( name, card->name ) | ||
| 227 | __field( int, power_checks ) | ||
| 228 | __field( int, path_checks ) | ||
| 229 | __field( int, neighbour_checks ) | ||
| 230 | ), | ||
| 231 | |||
| 232 | TP_fast_assign( | ||
| 233 | __assign_str(name, card->name); | ||
| 234 | __entry->power_checks = card->dapm_stats.power_checks; | ||
| 235 | __entry->path_checks = card->dapm_stats.path_checks; | ||
| 236 | __entry->neighbour_checks = card->dapm_stats.neighbour_checks; | ||
| 237 | ), | ||
| 238 | |||
| 239 | TP_printk("%s: checks %d power, %d path, %d neighbour", | ||
| 240 | __get_str(name), (int)__entry->power_checks, | ||
| 241 | (int)__entry->path_checks, (int)__entry->neighbour_checks) | ||
| 242 | ); | ||
| 243 | |||
| 219 | TRACE_EVENT(snd_soc_jack_irq, | 244 | TRACE_EVENT(snd_soc_jack_irq, |
| 220 | 245 | ||
| 221 | TP_PROTO(const char *name), | 246 | TP_PROTO(const char *name), |
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 3687a6cc9881..762af68c8996 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c | |||
| @@ -1067,7 +1067,6 @@ static int onyx_i2c_probe(struct i2c_client *client, | |||
| 1067 | printk(KERN_DEBUG PFX "created and attached onyx instance\n"); | 1067 | printk(KERN_DEBUG PFX "created and attached onyx instance\n"); |
| 1068 | return 0; | 1068 | return 0; |
| 1069 | fail: | 1069 | fail: |
| 1070 | i2c_set_clientdata(client, NULL); | ||
| 1071 | kfree(onyx); | 1070 | kfree(onyx); |
| 1072 | return -ENODEV; | 1071 | return -ENODEV; |
| 1073 | } | 1072 | } |
| @@ -1112,8 +1111,7 @@ static int onyx_i2c_remove(struct i2c_client *client) | |||
| 1112 | 1111 | ||
| 1113 | aoa_codec_unregister(&onyx->codec); | 1112 | aoa_codec_unregister(&onyx->codec); |
| 1114 | of_node_put(onyx->codec.node); | 1113 | of_node_put(onyx->codec.node); |
| 1115 | if (onyx->codec_info) | 1114 | kfree(onyx->codec_info); |
| 1116 | kfree(onyx->codec_info); | ||
| 1117 | kfree(onyx); | 1115 | kfree(onyx); |
| 1118 | return 0; | 1116 | return 0; |
| 1119 | } | 1117 | } |
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index d0cead38d5fb..e518d38b1c74 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
| @@ -443,7 +443,7 @@ static int aaci_pcm_open(struct snd_pcm_substream *substream) | |||
| 443 | mutex_lock(&aaci->irq_lock); | 443 | mutex_lock(&aaci->irq_lock); |
| 444 | if (!aaci->users++) { | 444 | if (!aaci->users++) { |
| 445 | ret = request_irq(aaci->dev->irq[0], aaci_irq, | 445 | ret = request_irq(aaci->dev->irq[0], aaci_irq, |
| 446 | IRQF_SHARED | IRQF_DISABLED, DRIVER_NAME, aaci); | 446 | IRQF_SHARED, DRIVER_NAME, aaci); |
| 447 | if (ret != 0) | 447 | if (ret != 0) |
| 448 | aaci->users--; | 448 | aaci->users--; |
| 449 | } | 449 | } |
diff --git a/sound/arm/pxa2xx-ac97-lib.c b/sound/arm/pxa2xx-ac97-lib.c index 88eec3847df2..8ad65352bf91 100644 --- a/sound/arm/pxa2xx-ac97-lib.c +++ b/sound/arm/pxa2xx-ac97-lib.c | |||
| @@ -359,7 +359,7 @@ int __devinit pxa2xx_ac97_hw_probe(struct platform_device *dev) | |||
| 359 | if (ret) | 359 | if (ret) |
| 360 | goto err_clk2; | 360 | goto err_clk2; |
| 361 | 361 | ||
| 362 | ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, IRQF_DISABLED, "AC97", NULL); | 362 | ret = request_irq(IRQ_AC97, pxa2xx_ac97_irq, 0, "AC97", NULL); |
| 363 | if (ret < 0) | 363 | if (ret < 0) |
| 364 | goto err_irq; | 364 | goto err_irq; |
| 365 | 365 | ||
diff --git a/sound/core/control.c b/sound/core/control.c index f8c5be464510..978fe1a8e9f0 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
| @@ -989,7 +989,6 @@ struct user_element { | |||
| 989 | void *tlv_data; /* TLV data */ | 989 | void *tlv_data; /* TLV data */ |
| 990 | unsigned long tlv_data_size; /* TLV data size */ | 990 | unsigned long tlv_data_size; /* TLV data size */ |
| 991 | void *priv_data; /* private data (like strings for enumerated type) */ | 991 | void *priv_data; /* private data (like strings for enumerated type) */ |
| 992 | unsigned long priv_data_size; /* size of private data in bytes */ | ||
| 993 | }; | 992 | }; |
| 994 | 993 | ||
| 995 | static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol, | 994 | static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol, |
| @@ -1001,6 +1000,28 @@ static int snd_ctl_elem_user_info(struct snd_kcontrol *kcontrol, | |||
| 1001 | return 0; | 1000 | return 0; |
| 1002 | } | 1001 | } |
| 1003 | 1002 | ||
| 1003 | static int snd_ctl_elem_user_enum_info(struct snd_kcontrol *kcontrol, | ||
| 1004 | struct snd_ctl_elem_info *uinfo) | ||
| 1005 | { | ||
| 1006 | struct user_element *ue = kcontrol->private_data; | ||
| 1007 | const char *names; | ||
| 1008 | unsigned int item; | ||
| 1009 | |||
| 1010 | item = uinfo->value.enumerated.item; | ||
| 1011 | |||
| 1012 | *uinfo = ue->info; | ||
| 1013 | |||
| 1014 | item = min(item, uinfo->value.enumerated.items - 1); | ||
| 1015 | uinfo->value.enumerated.item = item; | ||
| 1016 | |||
| 1017 | names = ue->priv_data; | ||
| 1018 | for (; item > 0; --item) | ||
| 1019 | names += strlen(names) + 1; | ||
| 1020 | strcpy(uinfo->value.enumerated.name, names); | ||
| 1021 | |||
| 1022 | return 0; | ||
| 1023 | } | ||
| 1024 | |||
| 1004 | static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, | 1025 | static int snd_ctl_elem_user_get(struct snd_kcontrol *kcontrol, |
| 1005 | struct snd_ctl_elem_value *ucontrol) | 1026 | struct snd_ctl_elem_value *ucontrol) |
| 1006 | { | 1027 | { |
| @@ -1055,11 +1076,46 @@ static int snd_ctl_elem_user_tlv(struct snd_kcontrol *kcontrol, | |||
| 1055 | return change; | 1076 | return change; |
| 1056 | } | 1077 | } |
| 1057 | 1078 | ||
| 1079 | static int snd_ctl_elem_init_enum_names(struct user_element *ue) | ||
| 1080 | { | ||
| 1081 | char *names, *p; | ||
| 1082 | size_t buf_len, name_len; | ||
| 1083 | unsigned int i; | ||
| 1084 | |||
| 1085 | if (ue->info.value.enumerated.names_length > 64 * 1024) | ||
| 1086 | return -EINVAL; | ||
| 1087 | |||
| 1088 | names = memdup_user( | ||
| 1089 | (const void __user *)ue->info.value.enumerated.names_ptr, | ||
| 1090 | ue->info.value.enumerated.names_length); | ||
| 1091 | if (IS_ERR(names)) | ||
| 1092 | return PTR_ERR(names); | ||
| 1093 | |||
| 1094 | /* check that there are enough valid names */ | ||
| 1095 | buf_len = ue->info.value.enumerated.names_length; | ||
| 1096 | p = names; | ||
| 1097 | for (i = 0; i < ue->info.value.enumerated.items; ++i) { | ||
| 1098 | name_len = strnlen(p, buf_len); | ||
| 1099 | if (name_len == 0 || name_len >= 64 || name_len == buf_len) { | ||
| 1100 | kfree(names); | ||
| 1101 | return -EINVAL; | ||
| 1102 | } | ||
| 1103 | p += name_len + 1; | ||
| 1104 | buf_len -= name_len + 1; | ||
| 1105 | } | ||
| 1106 | |||
| 1107 | ue->priv_data = names; | ||
| 1108 | ue->info.value.enumerated.names_ptr = 0; | ||
| 1109 | |||
| 1110 | return 0; | ||
| 1111 | } | ||
| 1112 | |||
| 1058 | static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol) | 1113 | static void snd_ctl_elem_user_free(struct snd_kcontrol *kcontrol) |
| 1059 | { | 1114 | { |
| 1060 | struct user_element *ue = kcontrol->private_data; | 1115 | struct user_element *ue = kcontrol->private_data; |
| 1061 | if (ue->tlv_data) | 1116 | |
| 1062 | kfree(ue->tlv_data); | 1117 | kfree(ue->tlv_data); |
| 1118 | kfree(ue->priv_data); | ||
| 1063 | kfree(ue); | 1119 | kfree(ue); |
| 1064 | } | 1120 | } |
| 1065 | 1121 | ||
| @@ -1072,8 +1128,8 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1072 | long private_size; | 1128 | long private_size; |
| 1073 | struct user_element *ue; | 1129 | struct user_element *ue; |
| 1074 | int idx, err; | 1130 | int idx, err; |
| 1075 | 1131 | ||
| 1076 | if (card->user_ctl_count >= MAX_USER_CONTROLS) | 1132 | if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS) |
| 1077 | return -ENOMEM; | 1133 | return -ENOMEM; |
| 1078 | if (info->count < 1) | 1134 | if (info->count < 1) |
| 1079 | return -EINVAL; | 1135 | return -EINVAL; |
| @@ -1101,7 +1157,10 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1101 | memcpy(&kctl.id, &info->id, sizeof(info->id)); | 1157 | memcpy(&kctl.id, &info->id, sizeof(info->id)); |
| 1102 | kctl.count = info->owner ? info->owner : 1; | 1158 | kctl.count = info->owner ? info->owner : 1; |
| 1103 | access |= SNDRV_CTL_ELEM_ACCESS_USER; | 1159 | access |= SNDRV_CTL_ELEM_ACCESS_USER; |
| 1104 | kctl.info = snd_ctl_elem_user_info; | 1160 | if (info->type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) |
| 1161 | kctl.info = snd_ctl_elem_user_enum_info; | ||
| 1162 | else | ||
| 1163 | kctl.info = snd_ctl_elem_user_info; | ||
| 1105 | if (access & SNDRV_CTL_ELEM_ACCESS_READ) | 1164 | if (access & SNDRV_CTL_ELEM_ACCESS_READ) |
| 1106 | kctl.get = snd_ctl_elem_user_get; | 1165 | kctl.get = snd_ctl_elem_user_get; |
| 1107 | if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) | 1166 | if (access & SNDRV_CTL_ELEM_ACCESS_WRITE) |
| @@ -1122,6 +1181,11 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1122 | if (info->count > 64) | 1181 | if (info->count > 64) |
| 1123 | return -EINVAL; | 1182 | return -EINVAL; |
| 1124 | break; | 1183 | break; |
| 1184 | case SNDRV_CTL_ELEM_TYPE_ENUMERATED: | ||
| 1185 | private_size = sizeof(unsigned int); | ||
| 1186 | if (info->count > 128 || info->value.enumerated.items == 0) | ||
| 1187 | return -EINVAL; | ||
| 1188 | break; | ||
| 1125 | case SNDRV_CTL_ELEM_TYPE_BYTES: | 1189 | case SNDRV_CTL_ELEM_TYPE_BYTES: |
| 1126 | private_size = sizeof(unsigned char); | 1190 | private_size = sizeof(unsigned char); |
| 1127 | if (info->count > 512) | 1191 | if (info->count > 512) |
| @@ -1143,9 +1207,17 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file, | |||
| 1143 | ue->info.access = 0; | 1207 | ue->info.access = 0; |
| 1144 | ue->elem_data = (char *)ue + sizeof(*ue); | 1208 | ue->elem_data = (char *)ue + sizeof(*ue); |
| 1145 | ue->elem_data_size = private_size; | 1209 | ue->elem_data_size = private_size; |
| 1210 | if (ue->info.type == SNDRV_CTL_ELEM_TYPE_ENUMERATED) { | ||
| 1211 | err = snd_ctl_elem_init_enum_names(ue); | ||
| 1212 | if (err < 0) { | ||
| 1213 | kfree(ue); | ||
| 1214 | return err; | ||
| 1215 | } | ||
| 1216 | } | ||
| 1146 | kctl.private_free = snd_ctl_elem_user_free; | 1217 | kctl.private_free = snd_ctl_elem_user_free; |
| 1147 | _kctl = snd_ctl_new(&kctl, access); | 1218 | _kctl = snd_ctl_new(&kctl, access); |
| 1148 | if (_kctl == NULL) { | 1219 | if (_kctl == NULL) { |
| 1220 | kfree(ue->priv_data); | ||
| 1149 | kfree(ue); | 1221 | kfree(ue); |
| 1150 | return -ENOMEM; | 1222 | return -ENOMEM; |
| 1151 | } | 1223 | } |
diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c index 426874429a5e..2bb95a7a8809 100644 --- a/sound/core/control_compat.c +++ b/sound/core/control_compat.c | |||
| @@ -83,6 +83,8 @@ struct snd_ctl_elem_info32 { | |||
| 83 | u32 items; | 83 | u32 items; |
| 84 | u32 item; | 84 | u32 item; |
| 85 | char name[64]; | 85 | char name[64]; |
| 86 | u64 names_ptr; | ||
| 87 | u32 names_length; | ||
| 86 | } enumerated; | 88 | } enumerated; |
| 87 | unsigned char reserved[128]; | 89 | unsigned char reserved[128]; |
| 88 | } value; | 90 | } value; |
| @@ -372,6 +374,8 @@ static int snd_ctl_elem_add_compat(struct snd_ctl_file *file, | |||
| 372 | &data32->value.enumerated, | 374 | &data32->value.enumerated, |
| 373 | sizeof(data->value.enumerated))) | 375 | sizeof(data->value.enumerated))) |
| 374 | goto error; | 376 | goto error; |
| 377 | data->value.enumerated.names_ptr = | ||
| 378 | (uintptr_t)compat_ptr(data->value.enumerated.names_ptr); | ||
| 375 | break; | 379 | break; |
| 376 | default: | 380 | default: |
| 377 | break; | 381 | break; |
diff --git a/sound/core/jack.c b/sound/core/jack.c index 53b53e97c896..240a3e13470d 100644 --- a/sound/core/jack.c +++ b/sound/core/jack.c | |||
| @@ -30,6 +30,7 @@ static int jack_switch_types[] = { | |||
| 30 | SW_LINEOUT_INSERT, | 30 | SW_LINEOUT_INSERT, |
| 31 | SW_JACK_PHYSICAL_INSERT, | 31 | SW_JACK_PHYSICAL_INSERT, |
| 32 | SW_VIDEOOUT_INSERT, | 32 | SW_VIDEOOUT_INSERT, |
| 33 | SW_LINEIN_INSERT, | ||
| 33 | }; | 34 | }; |
| 34 | 35 | ||
| 35 | static int snd_jack_dev_free(struct snd_device *device) | 36 | static int snd_jack_dev_free(struct snd_device *device) |
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index d8359cfeca15..1b5e0c49a0ad 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c | |||
| @@ -499,7 +499,7 @@ static struct snd_kcontrol *snd_mixer_oss_test_id(struct snd_mixer_oss *mixer, c | |||
| 499 | 499 | ||
| 500 | memset(&id, 0, sizeof(id)); | 500 | memset(&id, 0, sizeof(id)); |
| 501 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 501 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
| 502 | strcpy(id.name, name); | 502 | strlcpy(id.name, name, sizeof(id.name)); |
| 503 | id.index = index; | 503 | id.index = index; |
| 504 | return snd_ctl_find_id(card, &id); | 504 | return snd_ctl_find_id(card, &id); |
| 505 | } | 505 | } |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 62e90b862a0d..95d1e789715f 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
| @@ -1399,6 +1399,32 @@ int snd_pcm_hw_constraint_pow2(struct snd_pcm_runtime *runtime, | |||
| 1399 | 1399 | ||
| 1400 | EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); | 1400 | EXPORT_SYMBOL(snd_pcm_hw_constraint_pow2); |
| 1401 | 1401 | ||
| 1402 | static int snd_pcm_hw_rule_noresample_func(struct snd_pcm_hw_params *params, | ||
| 1403 | struct snd_pcm_hw_rule *rule) | ||
| 1404 | { | ||
| 1405 | unsigned int base_rate = (unsigned int)(uintptr_t)rule->private; | ||
| 1406 | struct snd_interval *rate; | ||
| 1407 | |||
| 1408 | rate = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); | ||
| 1409 | return snd_interval_list(rate, 1, &base_rate, 0); | ||
| 1410 | } | ||
| 1411 | |||
| 1412 | /** | ||
| 1413 | * snd_pcm_hw_rule_noresample - add a rule to allow disabling hw resampling | ||
| 1414 | * @runtime: PCM runtime instance | ||
| 1415 | * @base_rate: the rate at which the hardware does not resample | ||
| 1416 | */ | ||
| 1417 | int snd_pcm_hw_rule_noresample(struct snd_pcm_runtime *runtime, | ||
| 1418 | unsigned int base_rate) | ||
| 1419 | { | ||
| 1420 | return snd_pcm_hw_rule_add(runtime, SNDRV_PCM_HW_PARAMS_NORESAMPLE, | ||
| 1421 | SNDRV_PCM_HW_PARAM_RATE, | ||
| 1422 | snd_pcm_hw_rule_noresample_func, | ||
| 1423 | (void *)(uintptr_t)base_rate, | ||
| 1424 | SNDRV_PCM_HW_PARAM_RATE, -1); | ||
| 1425 | } | ||
| 1426 | EXPORT_SYMBOL(snd_pcm_hw_rule_noresample); | ||
| 1427 | |||
| 1402 | static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, | 1428 | static void _snd_pcm_hw_param_any(struct snd_pcm_hw_params *params, |
| 1403 | snd_pcm_hw_param_t var) | 1429 | snd_pcm_hw_param_t var) |
| 1404 | { | 1430 | { |
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index c74e228731ed..d7d2179c0363 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c | |||
| @@ -2058,16 +2058,12 @@ EXPORT_SYMBOL(snd_pcm_open_substream); | |||
| 2058 | 2058 | ||
| 2059 | static int snd_pcm_open_file(struct file *file, | 2059 | static int snd_pcm_open_file(struct file *file, |
| 2060 | struct snd_pcm *pcm, | 2060 | struct snd_pcm *pcm, |
| 2061 | int stream, | 2061 | int stream) |
| 2062 | struct snd_pcm_file **rpcm_file) | ||
| 2063 | { | 2062 | { |
| 2064 | struct snd_pcm_file *pcm_file; | 2063 | struct snd_pcm_file *pcm_file; |
| 2065 | struct snd_pcm_substream *substream; | 2064 | struct snd_pcm_substream *substream; |
| 2066 | int err; | 2065 | int err; |
| 2067 | 2066 | ||
| 2068 | if (rpcm_file) | ||
| 2069 | *rpcm_file = NULL; | ||
| 2070 | |||
| 2071 | err = snd_pcm_open_substream(pcm, stream, file, &substream); | 2067 | err = snd_pcm_open_substream(pcm, stream, file, &substream); |
| 2072 | if (err < 0) | 2068 | if (err < 0) |
| 2073 | return err; | 2069 | return err; |
| @@ -2083,8 +2079,7 @@ static int snd_pcm_open_file(struct file *file, | |||
| 2083 | substream->pcm_release = pcm_release_private; | 2079 | substream->pcm_release = pcm_release_private; |
| 2084 | } | 2080 | } |
| 2085 | file->private_data = pcm_file; | 2081 | file->private_data = pcm_file; |
| 2086 | if (rpcm_file) | 2082 | |
| 2087 | *rpcm_file = pcm_file; | ||
| 2088 | return 0; | 2083 | return 0; |
| 2089 | } | 2084 | } |
| 2090 | 2085 | ||
| @@ -2113,7 +2108,6 @@ static int snd_pcm_capture_open(struct inode *inode, struct file *file) | |||
| 2113 | static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) | 2108 | static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) |
| 2114 | { | 2109 | { |
| 2115 | int err; | 2110 | int err; |
| 2116 | struct snd_pcm_file *pcm_file; | ||
| 2117 | wait_queue_t wait; | 2111 | wait_queue_t wait; |
| 2118 | 2112 | ||
| 2119 | if (pcm == NULL) { | 2113 | if (pcm == NULL) { |
| @@ -2131,7 +2125,7 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream) | |||
| 2131 | add_wait_queue(&pcm->open_wait, &wait); | 2125 | add_wait_queue(&pcm->open_wait, &wait); |
| 2132 | mutex_lock(&pcm->open_mutex); | 2126 | mutex_lock(&pcm->open_mutex); |
| 2133 | while (1) { | 2127 | while (1) { |
| 2134 | err = snd_pcm_open_file(file, pcm, stream, &pcm_file); | 2128 | err = snd_pcm_open_file(file, pcm, stream); |
| 2135 | if (err >= 0) | 2129 | if (err >= 0) |
| 2136 | break; | 2130 | break; |
| 2137 | if (err == -EAGAIN) { | 2131 | if (err == -EAGAIN) { |
| @@ -3156,8 +3150,8 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { | |||
| 3156 | /* | 3150 | /* |
| 3157 | * mmap the DMA buffer on RAM | 3151 | * mmap the DMA buffer on RAM |
| 3158 | */ | 3152 | */ |
| 3159 | static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, | 3153 | int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, |
| 3160 | struct vm_area_struct *area) | 3154 | struct vm_area_struct *area) |
| 3161 | { | 3155 | { |
| 3162 | area->vm_flags |= VM_RESERVED; | 3156 | area->vm_flags |= VM_RESERVED; |
| 3163 | #ifdef ARCH_HAS_DMA_MMAP_COHERENT | 3157 | #ifdef ARCH_HAS_DMA_MMAP_COHERENT |
| @@ -3177,6 +3171,7 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, | |||
| 3177 | area->vm_ops = &snd_pcm_vm_ops_data_fault; | 3171 | area->vm_ops = &snd_pcm_vm_ops_data_fault; |
| 3178 | return 0; | 3172 | return 0; |
| 3179 | } | 3173 | } |
| 3174 | EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); | ||
| 3180 | 3175 | ||
| 3181 | /* | 3176 | /* |
| 3182 | * mmap the DMA buffer on I/O memory area | 3177 | * mmap the DMA buffer on I/O memory area |
| @@ -3242,7 +3237,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file, | |||
| 3242 | if (substream->ops->mmap) | 3237 | if (substream->ops->mmap) |
| 3243 | err = substream->ops->mmap(substream, area); | 3238 | err = substream->ops->mmap(substream, area); |
| 3244 | else | 3239 | else |
| 3245 | err = snd_pcm_default_mmap(substream, area); | 3240 | err = snd_pcm_lib_default_mmap(substream, area); |
| 3246 | if (!err) | 3241 | if (!err) |
| 3247 | atomic_inc(&substream->mmap_count); | 3242 | atomic_inc(&substream->mmap_count); |
| 3248 | return err; | 3243 | return err; |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index a0da7755fcea..4067f1548949 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
| @@ -575,7 +575,8 @@ static void loopback_runtime_free(struct snd_pcm_runtime *runtime) | |||
| 575 | static int loopback_hw_params(struct snd_pcm_substream *substream, | 575 | static int loopback_hw_params(struct snd_pcm_substream *substream, |
| 576 | struct snd_pcm_hw_params *params) | 576 | struct snd_pcm_hw_params *params) |
| 577 | { | 577 | { |
| 578 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | 578 | return snd_pcm_lib_alloc_vmalloc_buffer(substream, |
| 579 | params_buffer_bytes(params)); | ||
| 579 | } | 580 | } |
| 580 | 581 | ||
| 581 | static int loopback_hw_free(struct snd_pcm_substream *substream) | 582 | static int loopback_hw_free(struct snd_pcm_substream *substream) |
| @@ -587,7 +588,7 @@ static int loopback_hw_free(struct snd_pcm_substream *substream) | |||
| 587 | mutex_lock(&dpcm->loopback->cable_lock); | 588 | mutex_lock(&dpcm->loopback->cable_lock); |
| 588 | cable->valid &= ~(1 << substream->stream); | 589 | cable->valid &= ~(1 << substream->stream); |
| 589 | mutex_unlock(&dpcm->loopback->cable_lock); | 590 | mutex_unlock(&dpcm->loopback->cable_lock); |
| 590 | return snd_pcm_lib_free_pages(substream); | 591 | return snd_pcm_lib_free_vmalloc_buffer(substream); |
| 591 | } | 592 | } |
| 592 | 593 | ||
| 593 | static unsigned int get_cable_index(struct snd_pcm_substream *substream) | 594 | static unsigned int get_cable_index(struct snd_pcm_substream *substream) |
| @@ -740,6 +741,8 @@ static struct snd_pcm_ops loopback_playback_ops = { | |||
| 740 | .prepare = loopback_prepare, | 741 | .prepare = loopback_prepare, |
| 741 | .trigger = loopback_trigger, | 742 | .trigger = loopback_trigger, |
| 742 | .pointer = loopback_pointer, | 743 | .pointer = loopback_pointer, |
| 744 | .page = snd_pcm_lib_get_vmalloc_page, | ||
| 745 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
| 743 | }; | 746 | }; |
| 744 | 747 | ||
| 745 | static struct snd_pcm_ops loopback_capture_ops = { | 748 | static struct snd_pcm_ops loopback_capture_ops = { |
| @@ -751,6 +754,8 @@ static struct snd_pcm_ops loopback_capture_ops = { | |||
| 751 | .prepare = loopback_prepare, | 754 | .prepare = loopback_prepare, |
| 752 | .trigger = loopback_trigger, | 755 | .trigger = loopback_trigger, |
| 753 | .pointer = loopback_pointer, | 756 | .pointer = loopback_pointer, |
| 757 | .page = snd_pcm_lib_get_vmalloc_page, | ||
| 758 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
| 754 | }; | 759 | }; |
| 755 | 760 | ||
| 756 | static int __devinit loopback_pcm_new(struct loopback *loopback, | 761 | static int __devinit loopback_pcm_new(struct loopback *loopback, |
| @@ -771,10 +776,6 @@ static int __devinit loopback_pcm_new(struct loopback *loopback, | |||
| 771 | strcpy(pcm->name, "Loopback PCM"); | 776 | strcpy(pcm->name, "Loopback PCM"); |
| 772 | 777 | ||
| 773 | loopback->pcm[device] = pcm; | 778 | loopback->pcm[device] = pcm; |
| 774 | |||
| 775 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, | ||
| 776 | snd_dma_continuous_data(GFP_KERNEL), | ||
| 777 | 0, 2 * 1024 * 1024); | ||
| 778 | return 0; | 779 | return 0; |
| 779 | } | 780 | } |
| 780 | 781 | ||
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index 5cfcb908c430..2c7a7636f472 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c | |||
| @@ -1153,7 +1153,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev, | |||
| 1153 | "0x%x done\n", (unsigned int)ml403_ac97cr->port); | 1153 | "0x%x done\n", (unsigned int)ml403_ac97cr->port); |
| 1154 | /* get irq */ | 1154 | /* get irq */ |
| 1155 | irq = platform_get_irq(pfdev, 0); | 1155 | irq = platform_get_irq(pfdev, 0); |
| 1156 | if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED, | 1156 | if (request_irq(irq, snd_ml403_ac97cr_irq, 0, |
| 1157 | dev_name(&pfdev->dev), (void *)ml403_ac97cr)) { | 1157 | dev_name(&pfdev->dev), (void *)ml403_ac97cr)) { |
| 1158 | snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " | 1158 | snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " |
| 1159 | "unable to grab IRQ %d\n", | 1159 | "unable to grab IRQ %d\n", |
| @@ -1166,7 +1166,7 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev, | |||
| 1166 | "request (playback) irq %d done\n", | 1166 | "request (playback) irq %d done\n", |
| 1167 | ml403_ac97cr->irq); | 1167 | ml403_ac97cr->irq); |
| 1168 | irq = platform_get_irq(pfdev, 1); | 1168 | irq = platform_get_irq(pfdev, 1); |
| 1169 | if (request_irq(irq, snd_ml403_ac97cr_irq, IRQF_DISABLED, | 1169 | if (request_irq(irq, snd_ml403_ac97cr_irq, 0, |
| 1170 | dev_name(&pfdev->dev), (void *)ml403_ac97cr)) { | 1170 | dev_name(&pfdev->dev), (void *)ml403_ac97cr)) { |
| 1171 | snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " | 1171 | snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " |
| 1172 | "unable to grab IRQ %d\n", | 1172 | "unable to grab IRQ %d\n", |
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c index 149d05a8202d..1c02852aceea 100644 --- a/sound/drivers/mpu401/mpu401.c +++ b/sound/drivers/mpu401/mpu401.c | |||
| @@ -86,8 +86,7 @@ static int snd_mpu401_create(int dev, struct snd_card **rcard) | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0, | 88 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, port[dev], 0, |
| 89 | irq[dev], irq[dev] >= 0 ? IRQF_DISABLED : 0, | 89 | irq[dev], NULL); |
| 90 | NULL); | ||
| 91 | if (err < 0) { | 90 | if (err < 0) { |
| 92 | printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); | 91 | printk(KERN_ERR "MPU401 not detected at 0x%lx\n", port[dev]); |
| 93 | goto _err; | 92 | goto _err; |
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 2af09996a3d0..e91698a634b2 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * Routines for control of MPU-401 in UART mode | 3 | * Routines for control of MPU-401 in UART mode |
| 4 | * | 4 | * |
| 5 | * MPU-401 supports UART mode which is not capable generate transmit | 5 | * MPU-401 supports UART mode which is not capable generate transmit |
| 6 | * interrupts thus output is done via polling. Also, if irq < 0, then | 6 | * interrupts thus output is done via polling. Without interrupt, |
| 7 | * input is done also via polling. Do not expect good performance. | 7 | * input is done also via polling. Do not expect good performance. |
| 8 | * | 8 | * |
| 9 | * | 9 | * |
| @@ -374,7 +374,7 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) | |||
| 374 | /* first time - flush FIFO */ | 374 | /* first time - flush FIFO */ |
| 375 | while (max-- > 0) | 375 | while (max-- > 0) |
| 376 | mpu->read(mpu, MPU401D(mpu)); | 376 | mpu->read(mpu, MPU401D(mpu)); |
| 377 | if (mpu->irq < 0) | 377 | if (mpu->info_flags & MPU401_INFO_USE_TIMER) |
| 378 | snd_mpu401_uart_add_timer(mpu, 1); | 378 | snd_mpu401_uart_add_timer(mpu, 1); |
| 379 | } | 379 | } |
| 380 | 380 | ||
| @@ -383,7 +383,7 @@ snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substream, int up) | |||
| 383 | snd_mpu401_uart_input_read(mpu); | 383 | snd_mpu401_uart_input_read(mpu); |
| 384 | spin_unlock_irqrestore(&mpu->input_lock, flags); | 384 | spin_unlock_irqrestore(&mpu->input_lock, flags); |
| 385 | } else { | 385 | } else { |
| 386 | if (mpu->irq < 0) | 386 | if (mpu->info_flags & MPU401_INFO_USE_TIMER) |
| 387 | snd_mpu401_uart_remove_timer(mpu, 1); | 387 | snd_mpu401_uart_remove_timer(mpu, 1); |
| 388 | clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); | 388 | clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); |
| 389 | } | 389 | } |
| @@ -496,7 +496,7 @@ static struct snd_rawmidi_ops snd_mpu401_uart_input = | |||
| 496 | static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi) | 496 | static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi) |
| 497 | { | 497 | { |
| 498 | struct snd_mpu401 *mpu = rmidi->private_data; | 498 | struct snd_mpu401 *mpu = rmidi->private_data; |
| 499 | if (mpu->irq_flags && mpu->irq >= 0) | 499 | if (mpu->irq >= 0) |
| 500 | free_irq(mpu->irq, (void *) mpu); | 500 | free_irq(mpu->irq, (void *) mpu); |
| 501 | release_and_free_resource(mpu->res); | 501 | release_and_free_resource(mpu->res); |
| 502 | kfree(mpu); | 502 | kfree(mpu); |
| @@ -509,8 +509,7 @@ static void snd_mpu401_uart_free(struct snd_rawmidi *rmidi) | |||
| 509 | * @hardware: the hardware type, MPU401_HW_XXXX | 509 | * @hardware: the hardware type, MPU401_HW_XXXX |
| 510 | * @port: the base address of MPU401 port | 510 | * @port: the base address of MPU401 port |
| 511 | * @info_flags: bitflags MPU401_INFO_XXX | 511 | * @info_flags: bitflags MPU401_INFO_XXX |
| 512 | * @irq: the irq number, -1 if no interrupt for mpu | 512 | * @irq: the ISA irq number, -1 if not to be allocated |
| 513 | * @irq_flags: the irq request flags (SA_XXX), 0 if irq was already reserved. | ||
| 514 | * @rrawmidi: the pointer to store the new rawmidi instance | 513 | * @rrawmidi: the pointer to store the new rawmidi instance |
| 515 | * | 514 | * |
| 516 | * Creates a new MPU-401 instance. | 515 | * Creates a new MPU-401 instance. |
| @@ -525,7 +524,7 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, | |||
| 525 | unsigned short hardware, | 524 | unsigned short hardware, |
| 526 | unsigned long port, | 525 | unsigned long port, |
| 527 | unsigned int info_flags, | 526 | unsigned int info_flags, |
| 528 | int irq, int irq_flags, | 527 | int irq, |
| 529 | struct snd_rawmidi ** rrawmidi) | 528 | struct snd_rawmidi ** rrawmidi) |
| 530 | { | 529 | { |
| 531 | struct snd_mpu401 *mpu; | 530 | struct snd_mpu401 *mpu; |
| @@ -577,8 +576,8 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, | |||
| 577 | mpu->cport = port + 2; | 576 | mpu->cport = port + 2; |
| 578 | else | 577 | else |
| 579 | mpu->cport = port + 1; | 578 | mpu->cport = port + 1; |
| 580 | if (irq >= 0 && irq_flags) { | 579 | if (irq >= 0) { |
| 581 | if (request_irq(irq, snd_mpu401_uart_interrupt, irq_flags, | 580 | if (request_irq(irq, snd_mpu401_uart_interrupt, 0, |
| 582 | "MPU401 UART", (void *) mpu)) { | 581 | "MPU401 UART", (void *) mpu)) { |
| 583 | snd_printk(KERN_ERR "mpu401_uart: " | 582 | snd_printk(KERN_ERR "mpu401_uart: " |
| 584 | "unable to grab IRQ %d\n", irq); | 583 | "unable to grab IRQ %d\n", irq); |
| @@ -586,9 +585,10 @@ int snd_mpu401_uart_new(struct snd_card *card, int device, | |||
| 586 | return -EBUSY; | 585 | return -EBUSY; |
| 587 | } | 586 | } |
| 588 | } | 587 | } |
| 588 | if (irq < 0 && !(info_flags & MPU401_INFO_IRQ_HOOK)) | ||
| 589 | info_flags |= MPU401_INFO_USE_TIMER; | ||
| 589 | mpu->info_flags = info_flags; | 590 | mpu->info_flags = info_flags; |
| 590 | mpu->irq = irq; | 591 | mpu->irq = irq; |
| 591 | mpu->irq_flags = irq_flags; | ||
| 592 | if (card->shortname[0]) | 592 | if (card->shortname[0]) |
| 593 | snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", | 593 | snprintf(rmidi->name, sizeof(rmidi->name), "%s MIDI", |
| 594 | card->shortname); | 594 | card->shortname); |
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c index 5c426df87678..1eef4ccebe4b 100644 --- a/sound/drivers/mtpav.c +++ b/sound/drivers/mtpav.c | |||
| @@ -589,7 +589,7 @@ static int __devinit snd_mtpav_get_ISA(struct mtpav * mcard) | |||
| 589 | return -EBUSY; | 589 | return -EBUSY; |
| 590 | } | 590 | } |
| 591 | mcard->port = port; | 591 | mcard->port = port; |
| 592 | if (request_irq(irq, snd_mtpav_irqh, IRQF_DISABLED, "MOTU MTPAV", mcard)) { | 592 | if (request_irq(irq, snd_mtpav_irqh, 0, "MOTU MTPAV", mcard)) { |
| 593 | snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq); | 593 | snd_printk(KERN_ERR "MTVAP IRQ %d busy\n", irq); |
| 594 | return -EBUSY; | 594 | return -EBUSY; |
| 595 | } | 595 | } |
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c index a25fb7b1f441..fc1d822802c3 100644 --- a/sound/drivers/serial-u16550.c +++ b/sound/drivers/serial-u16550.c | |||
| @@ -816,7 +816,7 @@ static int __devinit snd_uart16550_create(struct snd_card *card, | |||
| 816 | 816 | ||
| 817 | if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { | 817 | if (irq >= 0 && irq != SNDRV_AUTO_IRQ) { |
| 818 | if (request_irq(irq, snd_uart16550_interrupt, | 818 | if (request_irq(irq, snd_uart16550_interrupt, |
| 819 | IRQF_DISABLED, "Serial MIDI", uart)) { | 819 | 0, "Serial MIDI", uart)) { |
| 820 | snd_printk(KERN_WARNING | 820 | snd_printk(KERN_WARNING |
| 821 | "irq %d busy. Using Polling.\n", irq); | 821 | "irq %d busy. Using Polling.\n", irq); |
| 822 | } else { | 822 | } else { |
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 440030818db7..cd094ecaca3b 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c | |||
| @@ -51,7 +51,6 @@ struct isight { | |||
| 51 | struct fw_unit *unit; | 51 | struct fw_unit *unit; |
| 52 | struct fw_device *device; | 52 | struct fw_device *device; |
| 53 | u64 audio_base; | 53 | u64 audio_base; |
| 54 | struct fw_address_handler iris_handler; | ||
| 55 | struct snd_pcm_substream *pcm; | 54 | struct snd_pcm_substream *pcm; |
| 56 | struct mutex mutex; | 55 | struct mutex mutex; |
| 57 | struct iso_packets_buffer buffer; | 56 | struct iso_packets_buffer buffer; |
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 3fc257da180c..cbe6bb9e53b6 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c | |||
| @@ -778,9 +778,10 @@ static int __devexit fwspk_remove(struct device *dev) | |||
| 778 | { | 778 | { |
| 779 | struct fwspk *fwspk = dev_get_drvdata(dev); | 779 | struct fwspk *fwspk = dev_get_drvdata(dev); |
| 780 | 780 | ||
| 781 | mutex_lock(&fwspk->mutex); | ||
| 782 | amdtp_out_stream_pcm_abort(&fwspk->stream); | 781 | amdtp_out_stream_pcm_abort(&fwspk->stream); |
| 783 | snd_card_disconnect(fwspk->card); | 782 | snd_card_disconnect(fwspk->card); |
| 783 | |||
| 784 | mutex_lock(&fwspk->mutex); | ||
| 784 | fwspk_stop_stream(fwspk); | 785 | fwspk_stop_stream(fwspk); |
| 785 | mutex_unlock(&fwspk->mutex); | 786 | mutex_unlock(&fwspk->mutex); |
| 786 | 787 | ||
| @@ -796,8 +797,8 @@ static void fwspk_bus_reset(struct fw_unit *unit) | |||
| 796 | fcp_bus_reset(fwspk->unit); | 797 | fcp_bus_reset(fwspk->unit); |
| 797 | 798 | ||
| 798 | if (cmp_connection_update(&fwspk->connection) < 0) { | 799 | if (cmp_connection_update(&fwspk->connection) < 0) { |
| 799 | mutex_lock(&fwspk->mutex); | ||
| 800 | amdtp_out_stream_pcm_abort(&fwspk->stream); | 800 | amdtp_out_stream_pcm_abort(&fwspk->stream); |
| 801 | mutex_lock(&fwspk->mutex); | ||
| 801 | fwspk_stop_stream(fwspk); | 802 | fwspk_stop_stream(fwspk); |
| 802 | mutex_unlock(&fwspk->mutex); | 803 | mutex_unlock(&fwspk->mutex); |
| 803 | return; | 804 | return; |
diff --git a/sound/isa/ad1816a/ad1816a.c b/sound/isa/ad1816a/ad1816a.c index 3cb75bc97699..a87a2b566e19 100644 --- a/sound/isa/ad1816a/ad1816a.c +++ b/sound/isa/ad1816a/ad1816a.c | |||
| @@ -204,7 +204,7 @@ static int __devinit snd_card_ad1816a_probe(int dev, struct pnp_card_link *pcard | |||
| 204 | 204 | ||
| 205 | if (mpu_port[dev] > 0) { | 205 | if (mpu_port[dev] > 0) { |
| 206 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 206 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 207 | mpu_port[dev], 0, mpu_irq[dev], IRQF_DISABLED, | 207 | mpu_port[dev], 0, mpu_irq[dev], |
| 208 | NULL) < 0) | 208 | NULL) < 0) |
| 209 | printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]); | 209 | printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", mpu_port[dev]); |
| 210 | } | 210 | } |
diff --git a/sound/isa/ad1816a/ad1816a_lib.c b/sound/isa/ad1816a/ad1816a_lib.c index 05aef8b97e96..177eed3271bc 100644 --- a/sound/isa/ad1816a/ad1816a_lib.c +++ b/sound/isa/ad1816a/ad1816a_lib.c | |||
| @@ -595,7 +595,7 @@ int __devinit snd_ad1816a_create(struct snd_card *card, | |||
| 595 | snd_ad1816a_free(chip); | 595 | snd_ad1816a_free(chip); |
| 596 | return -EBUSY; | 596 | return -EBUSY; |
| 597 | } | 597 | } |
| 598 | if (request_irq(irq, snd_ad1816a_interrupt, IRQF_DISABLED, "AD1816A", (void *) chip)) { | 598 | if (request_irq(irq, snd_ad1816a_interrupt, 0, "AD1816A", (void *) chip)) { |
| 599 | snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq); | 599 | snd_printk(KERN_ERR "ad1816a: can't grab IRQ %d\n", irq); |
| 600 | snd_ad1816a_free(chip); | 600 | snd_ad1816a_free(chip); |
| 601 | return -EBUSY; | 601 | return -EBUSY; |
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index 20becc89f6f6..706effd6b3cd 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
| @@ -256,7 +256,6 @@ static int __devinit snd_card_als100_probe(int dev, | |||
| 256 | mpu_type, | 256 | mpu_type, |
| 257 | mpu_port[dev], 0, | 257 | mpu_port[dev], 0, |
| 258 | mpu_irq[dev], | 258 | mpu_irq[dev], |
| 259 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, | ||
| 260 | NULL) < 0) | 259 | NULL) < 0) |
| 261 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); | 260 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); |
| 262 | } | 261 | } |
diff --git a/sound/isa/azt2320.c b/sound/isa/azt2320.c index aac8dc15c2fe..b7bdbf307740 100644 --- a/sound/isa/azt2320.c +++ b/sound/isa/azt2320.c | |||
| @@ -234,8 +234,7 @@ static int __devinit snd_card_azt2320_probe(int dev, | |||
| 234 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | 234 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { |
| 235 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320, | 235 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_AZT2320, |
| 236 | mpu_port[dev], 0, | 236 | mpu_port[dev], 0, |
| 237 | mpu_irq[dev], IRQF_DISABLED, | 237 | mpu_irq[dev], NULL) < 0) |
| 238 | NULL) < 0) | ||
| 239 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); | 238 | snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]); |
| 240 | } | 239 | } |
| 241 | 240 | ||
diff --git a/sound/isa/cmi8330.c b/sound/isa/cmi8330.c index fe79a169acb5..dca69f80305f 100644 --- a/sound/isa/cmi8330.c +++ b/sound/isa/cmi8330.c | |||
| @@ -597,7 +597,7 @@ static int __devinit snd_cmi8330_probe(struct snd_card *card, int dev) | |||
| 597 | if (mpuport[dev] != SNDRV_AUTO_PORT) { | 597 | if (mpuport[dev] != SNDRV_AUTO_PORT) { |
| 598 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 598 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 599 | mpuport[dev], 0, mpuirq[dev], | 599 | mpuport[dev], 0, mpuirq[dev], |
| 600 | IRQF_DISABLED, NULL) < 0) | 600 | NULL) < 0) |
| 601 | printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", | 601 | printk(KERN_ERR PFX "no MPU-401 device at 0x%lx.\n", |
| 602 | mpuport[dev]); | 602 | mpuport[dev]); |
| 603 | } | 603 | } |
diff --git a/sound/isa/cs423x/cs4231.c b/sound/isa/cs423x/cs4231.c index cb9153e75b82..409fa0ad7843 100644 --- a/sound/isa/cs423x/cs4231.c +++ b/sound/isa/cs423x/cs4231.c | |||
| @@ -131,7 +131,6 @@ static int __devinit snd_cs4231_probe(struct device *dev, unsigned int n) | |||
| 131 | mpu_irq[n] = -1; | 131 | mpu_irq[n] = -1; |
| 132 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, | 132 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, |
| 133 | mpu_port[n], 0, mpu_irq[n], | 133 | mpu_port[n], 0, mpu_irq[n], |
| 134 | mpu_irq[n] >= 0 ? IRQF_DISABLED : 0, | ||
| 135 | NULL) < 0) | 134 | NULL) < 0) |
| 136 | dev_warn(dev, "MPU401 not detected\n"); | 135 | dev_warn(dev, "MPU401 not detected\n"); |
| 137 | } | 136 | } |
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c index 999dc1e0fdbd..0dbde461e6c1 100644 --- a/sound/isa/cs423x/cs4236.c +++ b/sound/isa/cs423x/cs4236.c | |||
| @@ -449,8 +449,7 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev) | |||
| 449 | mpu_irq[dev] = -1; | 449 | mpu_irq[dev] = -1; |
| 450 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, | 450 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_CS4232, |
| 451 | mpu_port[dev], 0, | 451 | mpu_port[dev], 0, |
| 452 | mpu_irq[dev], | 452 | mpu_irq[dev], NULL) < 0) |
| 453 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, NULL) < 0) | ||
| 454 | printk(KERN_WARNING IDENT ": MPU401 not detected\n"); | 453 | printk(KERN_WARNING IDENT ": MPU401 not detected\n"); |
| 455 | } | 454 | } |
| 456 | 455 | ||
diff --git a/sound/isa/es1688/es1688.c b/sound/isa/es1688/es1688.c index 0cde8131a575..5493e9e4bcd5 100644 --- a/sound/isa/es1688/es1688.c +++ b/sound/isa/es1688/es1688.c | |||
| @@ -174,7 +174,7 @@ static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n) | |||
| 174 | chip->mpu_port > 0) { | 174 | chip->mpu_port > 0) { |
| 175 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, | 175 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, |
| 176 | chip->mpu_port, 0, | 176 | chip->mpu_port, 0, |
| 177 | mpu_irq[n], IRQF_DISABLED, NULL); | 177 | mpu_irq[n], NULL); |
| 178 | if (error < 0) | 178 | if (error < 0) |
| 179 | return error; | 179 | return error; |
| 180 | } | 180 | } |
diff --git a/sound/isa/es1688/es1688_lib.c b/sound/isa/es1688/es1688_lib.c index 07676200496a..d3eab6fb0866 100644 --- a/sound/isa/es1688/es1688_lib.c +++ b/sound/isa/es1688/es1688_lib.c | |||
| @@ -661,7 +661,7 @@ int snd_es1688_create(struct snd_card *card, | |||
| 661 | snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); | 661 | snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4); |
| 662 | return -EBUSY; | 662 | return -EBUSY; |
| 663 | } | 663 | } |
| 664 | if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) { | 664 | if (request_irq(irq, snd_es1688_interrupt, 0, "ES1688", (void *) chip)) { |
| 665 | snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); | 665 | snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq); |
| 666 | return -EBUSY; | 666 | return -EBUSY; |
| 667 | } | 667 | } |
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index fb4d6b34bbca..bf6ad0bf51c6 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
| @@ -1805,7 +1805,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card, | |||
| 1805 | return -EBUSY; | 1805 | return -EBUSY; |
| 1806 | } | 1806 | } |
| 1807 | 1807 | ||
| 1808 | if (request_irq(irq, snd_es18xx_interrupt, IRQF_DISABLED, "ES18xx", | 1808 | if (request_irq(irq, snd_es18xx_interrupt, 0, "ES18xx", |
| 1809 | (void *) card)) { | 1809 | (void *) card)) { |
| 1810 | snd_es18xx_free(card); | 1810 | snd_es18xx_free(card); |
| 1811 | snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq); | 1811 | snd_printk(KERN_ERR PFX "unable to grap IRQ %d\n", irq); |
| @@ -2160,8 +2160,8 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) | |||
| 2160 | 2160 | ||
| 2161 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | 2161 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { |
| 2162 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, | 2162 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, |
| 2163 | mpu_port[dev], 0, | 2163 | mpu_port[dev], MPU401_INFO_IRQ_HOOK, |
| 2164 | irq[dev], 0, &chip->rmidi); | 2164 | -1, &chip->rmidi); |
| 2165 | if (err < 0) | 2165 | if (err < 0) |
| 2166 | return err; | 2166 | return err; |
| 2167 | } | 2167 | } |
diff --git a/sound/isa/galaxy/galaxy.c b/sound/isa/galaxy/galaxy.c index ee54df082b9c..e51d3244742a 100644 --- a/sound/isa/galaxy/galaxy.c +++ b/sound/isa/galaxy/galaxy.c | |||
| @@ -585,8 +585,7 @@ static int __devinit snd_galaxy_probe(struct device *dev, unsigned int n) | |||
| 585 | 585 | ||
| 586 | if (mpu_port[n] >= 0) { | 586 | if (mpu_port[n] >= 0) { |
| 587 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 587 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 588 | mpu_port[n], 0, mpu_irq[n], | 588 | mpu_port[n], 0, mpu_irq[n], NULL); |
| 589 | IRQF_DISABLED, NULL); | ||
| 590 | if (err < 0) | 589 | if (err < 0) |
| 591 | goto error; | 590 | goto error; |
| 592 | } | 591 | } |
diff --git a/sound/isa/gus/gus_main.c b/sound/isa/gus/gus_main.c index 12eb98f2f931..3167e5ac3699 100644 --- a/sound/isa/gus/gus_main.c +++ b/sound/isa/gus/gus_main.c | |||
| @@ -180,7 +180,7 @@ int snd_gus_create(struct snd_card *card, | |||
| 180 | snd_gus_free(gus); | 180 | snd_gus_free(gus); |
| 181 | return -EBUSY; | 181 | return -EBUSY; |
| 182 | } | 182 | } |
| 183 | if (irq >= 0 && request_irq(irq, snd_gus_interrupt, IRQF_DISABLED, "GUS GF1", (void *) gus)) { | 183 | if (irq >= 0 && request_irq(irq, snd_gus_interrupt, 0, "GUS GF1", (void *) gus)) { |
| 184 | snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq); | 184 | snd_printk(KERN_ERR "gus: can't grab irq %d\n", irq); |
| 185 | snd_gus_free(gus); | 185 | snd_gus_free(gus); |
| 186 | return -EBUSY; | 186 | return -EBUSY; |
diff --git a/sound/isa/gus/gusextreme.c b/sound/isa/gus/gusextreme.c index 008e8e5bfa37..c4733c08b60b 100644 --- a/sound/isa/gus/gusextreme.c +++ b/sound/isa/gus/gusextreme.c | |||
| @@ -317,8 +317,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n) | |||
| 317 | 317 | ||
| 318 | if (es1688->mpu_port >= 0x300) { | 318 | if (es1688->mpu_port >= 0x300) { |
| 319 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, | 319 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_ES1688, |
| 320 | es1688->mpu_port, 0, | 320 | es1688->mpu_port, 0, mpu_irq[n], NULL); |
| 321 | mpu_irq[n], IRQF_DISABLED, NULL); | ||
| 322 | if (error < 0) | 321 | if (error < 0) |
| 323 | goto out; | 322 | goto out; |
| 324 | } | 323 | } |
diff --git a/sound/isa/gus/gusmax.c b/sound/isa/gus/gusmax.c index 3e4a58b72913..c43faa057ff6 100644 --- a/sound/isa/gus/gusmax.c +++ b/sound/isa/gus/gusmax.c | |||
| @@ -291,7 +291,7 @@ static int __devinit snd_gusmax_probe(struct device *pdev, unsigned int dev) | |||
| 291 | goto _err; | 291 | goto _err; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| 294 | if (request_irq(xirq, snd_gusmax_interrupt, IRQF_DISABLED, "GUS MAX", (void *)maxcard)) { | 294 | if (request_irq(xirq, snd_gusmax_interrupt, 0, "GUS MAX", (void *)maxcard)) { |
| 295 | snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); | 295 | snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); |
| 296 | err = -EBUSY; | 296 | err = -EBUSY; |
| 297 | goto _err; | 297 | goto _err; |
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c index c7b80e4730fc..5f869a32b48c 100644 --- a/sound/isa/gus/interwave.c +++ b/sound/isa/gus/interwave.c | |||
| @@ -684,7 +684,7 @@ static int __devinit snd_interwave_probe(struct snd_card *card, int dev) | |||
| 684 | if ((err = snd_gus_initialize(gus)) < 0) | 684 | if ((err = snd_gus_initialize(gus)) < 0) |
| 685 | return err; | 685 | return err; |
| 686 | 686 | ||
| 687 | if (request_irq(xirq, snd_interwave_interrupt, IRQF_DISABLED, | 687 | if (request_irq(xirq, snd_interwave_interrupt, 0, |
| 688 | "InterWave", iwcard)) { | 688 | "InterWave", iwcard)) { |
| 689 | snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); | 689 | snd_printk(KERN_ERR PFX "unable to grab IRQ %d\n", xirq); |
| 690 | return -EBUSY; | 690 | return -EBUSY; |
diff --git a/sound/isa/msnd/msnd_pinnacle.c b/sound/isa/msnd/msnd_pinnacle.c index 91d6023a63e5..0961e2cf20ca 100644 --- a/sound/isa/msnd/msnd_pinnacle.c +++ b/sound/isa/msnd/msnd_pinnacle.c | |||
| @@ -600,7 +600,7 @@ static int __devinit snd_msnd_attach(struct snd_card *card) | |||
| 600 | mpu_io[0], | 600 | mpu_io[0], |
| 601 | MPU401_MODE_INPUT | | 601 | MPU401_MODE_INPUT | |
| 602 | MPU401_MODE_OUTPUT, | 602 | MPU401_MODE_OUTPUT, |
| 603 | mpu_irq[0], IRQF_DISABLED, | 603 | mpu_irq[0], |
| 604 | &chip->rmidi); | 604 | &chip->rmidi); |
| 605 | if (err < 0) { | 605 | if (err < 0) { |
| 606 | printk(KERN_ERR LOGNAME | 606 | printk(KERN_ERR LOGNAME |
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 9b915e27b5bd..bbafb0b543ea 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c | |||
| @@ -667,7 +667,7 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) | |||
| 667 | err = snd_opl3sa2_detect(card); | 667 | err = snd_opl3sa2_detect(card); |
| 668 | if (err < 0) | 668 | if (err < 0) |
| 669 | return err; | 669 | return err; |
| 670 | err = request_irq(xirq, snd_opl3sa2_interrupt, IRQF_DISABLED, | 670 | err = request_irq(xirq, snd_opl3sa2_interrupt, 0, |
| 671 | "OPL3-SA2", card); | 671 | "OPL3-SA2", card); |
| 672 | if (err) { | 672 | if (err) { |
| 673 | snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); | 673 | snd_printk(KERN_ERR PFX "can't grab IRQ %d\n", xirq); |
| @@ -707,8 +707,9 @@ static int __devinit snd_opl3sa2_probe(struct snd_card *card, int dev) | |||
| 707 | } | 707 | } |
| 708 | if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) { | 708 | if (midi_port[dev] >= 0x300 && midi_port[dev] < 0x340) { |
| 709 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2, | 709 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_OPL3SA2, |
| 710 | midi_port[dev], 0, | 710 | midi_port[dev], |
| 711 | xirq, 0, &chip->rmidi)) < 0) | 711 | MPU401_INFO_IRQ_HOOK, -1, |
| 712 | &chip->rmidi)) < 0) | ||
| 712 | return err; | 713 | return err; |
| 713 | } | 714 | } |
| 714 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", | 715 | sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d", |
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c index 8c24102d0d93..d94d0f35cb76 100644 --- a/sound/isa/opti9xx/miro.c +++ b/sound/isa/opti9xx/miro.c | |||
| @@ -1377,8 +1377,7 @@ static int __devinit snd_miro_probe(struct snd_card *card) | |||
| 1377 | rmidi = NULL; | 1377 | rmidi = NULL; |
| 1378 | else { | 1378 | else { |
| 1379 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 1379 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 1380 | mpu_port, 0, miro->mpu_irq, IRQF_DISABLED, | 1380 | mpu_port, 0, miro->mpu_irq, &rmidi); |
| 1381 | &rmidi); | ||
| 1382 | if (error < 0) | 1381 | if (error < 0) |
| 1383 | snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", | 1382 | snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", |
| 1384 | mpu_port); | 1383 | mpu_port); |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index c35dc68930dc..6dbbfa76b440 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
| @@ -892,7 +892,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
| 892 | #endif | 892 | #endif |
| 893 | #ifdef OPTi93X | 893 | #ifdef OPTi93X |
| 894 | error = request_irq(irq, snd_opti93x_interrupt, | 894 | error = request_irq(irq, snd_opti93x_interrupt, |
| 895 | IRQF_DISABLED, DEV_NAME" - WSS", chip); | 895 | 0, DEV_NAME" - WSS", chip); |
| 896 | if (error < 0) { | 896 | if (error < 0) { |
| 897 | snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq); | 897 | snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq); |
| 898 | return error; | 898 | return error; |
| @@ -914,7 +914,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
| 914 | rmidi = NULL; | 914 | rmidi = NULL; |
| 915 | else { | 915 | else { |
| 916 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 916 | error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 917 | mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi); | 917 | mpu_port, 0, mpu_irq, &rmidi); |
| 918 | if (error) | 918 | if (error) |
| 919 | snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", | 919 | snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", |
| 920 | mpu_port); | 920 | mpu_port); |
diff --git a/sound/isa/sb/jazz16.c b/sound/isa/sb/jazz16.c index 8ccbcddf08e1..54e3c2c18060 100644 --- a/sound/isa/sb/jazz16.c +++ b/sound/isa/sb/jazz16.c | |||
| @@ -322,7 +322,6 @@ static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev) | |||
| 322 | MPU401_HW_MPU401, | 322 | MPU401_HW_MPU401, |
| 323 | mpu_port[dev], 0, | 323 | mpu_port[dev], 0, |
| 324 | mpu_irq[dev], | 324 | mpu_irq[dev], |
| 325 | mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0, | ||
| 326 | NULL) < 0) | 325 | NULL) < 0) |
| 327 | snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", | 326 | snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n", |
| 328 | mpu_port[dev]); | 327 | mpu_port[dev]); |
diff --git a/sound/isa/sb/sb16.c b/sound/isa/sb/sb16.c index 4d1c5a300ff8..237f8bd7fbe4 100644 --- a/sound/isa/sb/sb16.c +++ b/sound/isa/sb/sb16.c | |||
| @@ -394,8 +394,9 @@ static int __devinit snd_sb16_probe(struct snd_card *card, int dev) | |||
| 394 | 394 | ||
| 395 | if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { | 395 | if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { |
| 396 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB, | 396 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SB, |
| 397 | chip->mpu_port, 0, | 397 | chip->mpu_port, |
| 398 | xirq, 0, &chip->rmidi)) < 0) | 398 | MPU401_INFO_IRQ_HOOK, -1, |
| 399 | &chip->rmidi)) < 0) | ||
| 399 | return err; | 400 | return err; |
| 400 | chip->rmidi_callback = snd_mpu401_uart_interrupt; | 401 | chip->rmidi_callback = snd_mpu401_uart_interrupt; |
| 401 | } | 402 | } |
diff --git a/sound/isa/sb/sb_common.c b/sound/isa/sb/sb_common.c index eae6c1c0eff9..d2e19215813e 100644 --- a/sound/isa/sb/sb_common.c +++ b/sound/isa/sb/sb_common.c | |||
| @@ -240,7 +240,7 @@ int snd_sbdsp_create(struct snd_card *card, | |||
| 240 | if (request_irq(irq, irq_handler, | 240 | if (request_irq(irq, irq_handler, |
| 241 | (hardware == SB_HW_ALS4000 || | 241 | (hardware == SB_HW_ALS4000 || |
| 242 | hardware == SB_HW_CS5530) ? | 242 | hardware == SB_HW_CS5530) ? |
| 243 | IRQF_SHARED : IRQF_DISABLED, | 243 | IRQF_SHARED : 0, |
| 244 | "SoundBlaster", (void *) chip)) { | 244 | "SoundBlaster", (void *) chip)) { |
| 245 | snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq); | 245 | snd_printk(KERN_ERR "sb: can't grab irq %d\n", irq); |
| 246 | snd_sbdsp_free(chip); | 246 | snd_sbdsp_free(chip); |
diff --git a/sound/isa/sc6000.c b/sound/isa/sc6000.c index 9a8bbf6dd62a..207c161f100c 100644 --- a/sound/isa/sc6000.c +++ b/sound/isa/sc6000.c | |||
| @@ -658,8 +658,7 @@ static int __devinit snd_sc6000_probe(struct device *devptr, unsigned int dev) | |||
| 658 | if (snd_mpu401_uart_new(card, 0, | 658 | if (snd_mpu401_uart_new(card, 0, |
| 659 | MPU401_HW_MPU401, | 659 | MPU401_HW_MPU401, |
| 660 | mpu_port[dev], 0, | 660 | mpu_port[dev], 0, |
| 661 | mpu_irq[dev], IRQF_DISABLED, | 661 | mpu_irq[dev], NULL) < 0) |
| 662 | NULL) < 0) | ||
| 663 | snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n", | 662 | snd_printk(KERN_ERR "no MPU-401 device at 0x%lx ?\n", |
| 664 | mpu_port[dev]); | 663 | mpu_port[dev]); |
| 665 | } | 664 | } |
diff --git a/sound/isa/sscape.c b/sound/isa/sscape.c index e2d5d2d3ed96..f2379e102b63 100644 --- a/sound/isa/sscape.c +++ b/sound/isa/sscape.c | |||
| @@ -825,8 +825,7 @@ static int __devinit create_mpu401(struct snd_card *card, int devnum, | |||
| 825 | int err; | 825 | int err; |
| 826 | 826 | ||
| 827 | err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port, | 827 | err = snd_mpu401_uart_new(card, devnum, MPU401_HW_MPU401, port, |
| 828 | MPU401_INFO_INTEGRATED, irq, IRQF_DISABLED, | 828 | MPU401_INFO_INTEGRATED, irq, &rawmidi); |
| 829 | &rawmidi); | ||
| 830 | if (err == 0) { | 829 | if (err == 0) { |
| 831 | struct snd_mpu401 *mpu = rawmidi->private_data; | 830 | struct snd_mpu401 *mpu = rawmidi->private_data; |
| 832 | mpu->open_input = mpu401_open; | 831 | mpu->open_input = mpu401_open; |
diff --git a/sound/isa/wavefront/wavefront.c b/sound/isa/wavefront/wavefront.c index 711670e4a425..87142977335a 100644 --- a/sound/isa/wavefront/wavefront.c +++ b/sound/isa/wavefront/wavefront.c | |||
| @@ -418,7 +418,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) | |||
| 418 | return -EBUSY; | 418 | return -EBUSY; |
| 419 | } | 419 | } |
| 420 | if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt, | 420 | if (request_irq(ics2115_irq[dev], snd_wavefront_ics2115_interrupt, |
| 421 | IRQF_DISABLED, "ICS2115", acard)) { | 421 | 0, "ICS2115", acard)) { |
| 422 | snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]); | 422 | snd_printk(KERN_ERR "unable to use ICS2115 IRQ %d\n", ics2115_irq[dev]); |
| 423 | return -EBUSY; | 423 | return -EBUSY; |
| 424 | } | 424 | } |
| @@ -449,8 +449,7 @@ snd_wavefront_probe (struct snd_card *card, int dev) | |||
| 449 | if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) { | 449 | if (cs4232_mpu_port[dev] > 0 && cs4232_mpu_port[dev] != SNDRV_AUTO_PORT) { |
| 450 | err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232, | 450 | err = snd_mpu401_uart_new(card, midi_dev, MPU401_HW_CS4232, |
| 451 | cs4232_mpu_port[dev], 0, | 451 | cs4232_mpu_port[dev], 0, |
| 452 | cs4232_mpu_irq[dev], IRQF_DISABLED, | 452 | cs4232_mpu_irq[dev], NULL); |
| 453 | NULL); | ||
| 454 | if (err < 0) { | 453 | if (err < 0) { |
| 455 | snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n"); | 454 | snd_printk (KERN_ERR "can't allocate CS4232 MPU-401 device\n"); |
| 456 | return err; | 455 | return err; |
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 2a42cc377957..7277c5b7df6c 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
| @@ -1833,7 +1833,7 @@ int snd_wss_create(struct snd_card *card, | |||
| 1833 | } | 1833 | } |
| 1834 | chip->cport = cport; | 1834 | chip->cport = cport; |
| 1835 | if (!(hwshare & WSS_HWSHARE_IRQ)) | 1835 | if (!(hwshare & WSS_HWSHARE_IRQ)) |
| 1836 | if (request_irq(irq, snd_wss_interrupt, IRQF_DISABLED, | 1836 | if (request_irq(irq, snd_wss_interrupt, 0, |
| 1837 | "WSS", (void *) chip)) { | 1837 | "WSS", (void *) chip)) { |
| 1838 | snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq); | 1838 | snd_printk(KERN_ERR "wss: can't grab IRQ %d\n", irq); |
| 1839 | snd_wss_free(chip); | 1839 | snd_wss_free(chip); |
diff --git a/sound/mips/Kconfig b/sound/mips/Kconfig index a9823fad85c2..77dd0a13aecc 100644 --- a/sound/mips/Kconfig +++ b/sound/mips/Kconfig | |||
| @@ -23,12 +23,15 @@ config SND_SGI_HAL2 | |||
| 23 | 23 | ||
| 24 | 24 | ||
| 25 | config SND_AU1X00 | 25 | config SND_AU1X00 |
| 26 | tristate "Au1x00 AC97 Port Driver" | 26 | tristate "Au1x00 AC97 Port Driver (DEPRECATED)" |
| 27 | depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 | 27 | depends on SOC_AU1000 || SOC_AU1100 || SOC_AU1500 |
| 28 | select SND_PCM | 28 | select SND_PCM |
| 29 | select SND_AC97_CODEC | 29 | select SND_AC97_CODEC |
| 30 | help | 30 | help |
| 31 | ALSA Sound driver for the Au1x00's AC97 port. | 31 | ALSA Sound driver for the Au1x00's AC97 port. |
| 32 | 32 | ||
| 33 | Newer drivers for ASoC are available, please do not use | ||
| 34 | this driver as it will be removed in the future. | ||
| 35 | |||
| 33 | endif # SND_MIPS | 36 | endif # SND_MIPS |
| 34 | 37 | ||
diff --git a/sound/mips/au1x00.c b/sound/mips/au1x00.c index 446cf9748664..7567ebd71913 100644 --- a/sound/mips/au1x00.c +++ b/sound/mips/au1x00.c | |||
| @@ -465,13 +465,13 @@ snd_au1000_pcm_new(struct snd_au1000 *au1000) | |||
| 465 | 465 | ||
| 466 | flags = claim_dma_lock(); | 466 | flags = claim_dma_lock(); |
| 467 | if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX, | 467 | if ((au1000->stream[PLAYBACK]->dma = request_au1000_dma(DMA_ID_AC97C_TX, |
| 468 | "AC97 TX", au1000_dma_interrupt, IRQF_DISABLED, | 468 | "AC97 TX", au1000_dma_interrupt, 0, |
| 469 | au1000->stream[PLAYBACK])) < 0) { | 469 | au1000->stream[PLAYBACK])) < 0) { |
| 470 | release_dma_lock(flags); | 470 | release_dma_lock(flags); |
| 471 | return -EBUSY; | 471 | return -EBUSY; |
| 472 | } | 472 | } |
| 473 | if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX, | 473 | if ((au1000->stream[CAPTURE]->dma = request_au1000_dma(DMA_ID_AC97C_RX, |
| 474 | "AC97 RX", au1000_dma_interrupt, IRQF_DISABLED, | 474 | "AC97 RX", au1000_dma_interrupt, 0, |
| 475 | au1000->stream[CAPTURE])) < 0){ | 475 | au1000->stream[CAPTURE])) < 0){ |
| 476 | release_dma_lock(flags); | 476 | release_dma_lock(flags); |
| 477 | return -EBUSY; | 477 | return -EBUSY; |
diff --git a/sound/oss/sound_timer.c b/sound/oss/sound_timer.c index 48cda6c4c257..8021c85f076d 100644 --- a/sound/oss/sound_timer.c +++ b/sound/oss/sound_timer.c | |||
| @@ -320,7 +320,7 @@ void sound_timer_init(struct sound_lowlev_timer *t, char *name) | |||
| 320 | n = sound_alloc_timerdev(); | 320 | n = sound_alloc_timerdev(); |
| 321 | if (n == -1) | 321 | if (n == -1) |
| 322 | n = 0; /* Overwrite the system timer */ | 322 | n = 0; /* Overwrite the system timer */ |
| 323 | strcpy(sound_timer.info.name, name); | 323 | strlcpy(sound_timer.info.name, name, sizeof(sound_timer.info.name)); |
| 324 | sound_timer_devs[n] = &sound_timer; | 324 | sound_timer_devs[n] = &sound_timer; |
| 325 | } | 325 | } |
| 326 | EXPORT_SYMBOL(sound_timer_init); | 326 | EXPORT_SYMBOL(sound_timer_init); |
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index a9c1af33f276..04628696eb08 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c | |||
| @@ -931,8 +931,9 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, | |||
| 931 | 931 | ||
| 932 | if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, | 932 | if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, |
| 933 | iobase + ALS4K_IOB_30_MIDI_DATA, | 933 | iobase + ALS4K_IOB_30_MIDI_DATA, |
| 934 | MPU401_INFO_INTEGRATED, | 934 | MPU401_INFO_INTEGRATED | |
| 935 | pci->irq, 0, &chip->rmidi)) < 0) { | 935 | MPU401_INFO_IRQ_HOOK, |
| 936 | -1, &chip->rmidi)) < 0) { | ||
| 936 | printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", | 937 | printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", |
| 937 | iobase + ALS4K_IOB_30_MIDI_DATA); | 938 | iobase + ALS4K_IOB_30_MIDI_DATA); |
| 938 | goto out_err; | 939 | goto out_err; |
diff --git a/sound/pci/au88x0/au88x0_mpu401.c b/sound/pci/au88x0/au88x0_mpu401.c index 0dc8d259d1ed..e6c6a0febb75 100644 --- a/sound/pci/au88x0/au88x0_mpu401.c +++ b/sound/pci/au88x0/au88x0_mpu401.c | |||
| @@ -84,7 +84,7 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) | |||
| 84 | #ifdef VORTEX_MPU401_LEGACY | 84 | #ifdef VORTEX_MPU401_LEGACY |
| 85 | if ((temp = | 85 | if ((temp = |
| 86 | snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330, | 86 | snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_MPU401, 0x330, |
| 87 | 0, 0, 0, &rmidi)) != 0) { | 87 | MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) { |
| 88 | hwwrite(vortex->mmio, VORTEX_CTRL, | 88 | hwwrite(vortex->mmio, VORTEX_CTRL, |
| 89 | (hwread(vortex->mmio, VORTEX_CTRL) & | 89 | (hwread(vortex->mmio, VORTEX_CTRL) & |
| 90 | ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); | 90 | ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); |
| @@ -94,8 +94,8 @@ static int __devinit snd_vortex_midi(vortex_t * vortex) | |||
| 94 | port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); | 94 | port = (unsigned long)(vortex->mmio + VORTEX_MIDI_DATA); |
| 95 | if ((temp = | 95 | if ((temp = |
| 96 | snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, | 96 | snd_mpu401_uart_new(vortex->card, 0, MPU401_HW_AUREAL, port, |
| 97 | MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO, | 97 | MPU401_INFO_INTEGRATED | MPU401_INFO_MMIO | |
| 98 | 0, 0, &rmidi)) != 0) { | 98 | MPU401_INFO_IRQ_HOOK, -1, &rmidi)) != 0) { |
| 99 | hwwrite(vortex->mmio, VORTEX_CTRL, | 99 | hwwrite(vortex->mmio, VORTEX_CTRL, |
| 100 | (hwread(vortex->mmio, VORTEX_CTRL) & | 100 | (hwread(vortex->mmio, VORTEX_CTRL) & |
| 101 | ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); | 101 | ~CTRL_MIDI_PORT) & ~CTRL_MIDI_EN); |
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 579fc0dce128..d24fe425e87f 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c | |||
| @@ -2652,8 +2652,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
| 2652 | since our hardware ought to be similar, thus use same ID. */ | 2652 | since our hardware ought to be similar, thus use same ID. */ |
| 2653 | err = snd_mpu401_uart_new( | 2653 | err = snd_mpu401_uart_new( |
| 2654 | card, 0, | 2654 | card, 0, |
| 2655 | MPU401_HW_AZT2320, chip->mpu_io, MPU401_INFO_INTEGRATED, | 2655 | MPU401_HW_AZT2320, chip->mpu_io, |
| 2656 | pci->irq, 0, &chip->rmidi | 2656 | MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, |
| 2657 | -1, &chip->rmidi | ||
| 2657 | ); | 2658 | ); |
| 2658 | if (err < 0) { | 2659 | if (err < 0) { |
| 2659 | snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", | 2660 | snd_printk(KERN_ERR "azf3328: no MPU-401 device at 0x%lx?\n", |
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 9cf99fb7eb9c..da9c73211eca 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c | |||
| @@ -3228,8 +3228,9 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc | |||
| 3228 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, | 3228 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, |
| 3229 | iomidi, | 3229 | iomidi, |
| 3230 | (integrated_midi ? | 3230 | (integrated_midi ? |
| 3231 | MPU401_INFO_INTEGRATED : 0), | 3231 | MPU401_INFO_INTEGRATED : 0) | |
| 3232 | cm->irq, 0, &cm->rmidi)) < 0) { | 3232 | MPU401_INFO_IRQ_HOOK, |
| 3233 | -1, &cm->rmidi)) < 0) { | ||
| 3233 | printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); | 3234 | printk(KERN_ERR "cmipci: no UART401 device at 0x%lx\n", iomidi); |
| 3234 | } | 3235 | } |
| 3235 | } | 3236 | } |
diff --git a/sound/pci/ctxfi/ctpcm.c b/sound/pci/ctxfi/ctpcm.c index 457d21189b0d..2c8622617c8c 100644 --- a/sound/pci/ctxfi/ctpcm.c +++ b/sound/pci/ctxfi/ctpcm.c | |||
| @@ -404,7 +404,7 @@ int ct_alsa_pcm_create(struct ct_atc *atc, | |||
| 404 | int err; | 404 | int err; |
| 405 | int playback_count, capture_count; | 405 | int playback_count, capture_count; |
| 406 | 406 | ||
| 407 | playback_count = (IEC958 == device) ? 1 : 8; | 407 | playback_count = (IEC958 == device) ? 1 : 256; |
| 408 | capture_count = (FRONT == device) ? 1 : 0; | 408 | capture_count = (FRONT == device) ? 1 : 0; |
| 409 | err = snd_pcm_new(atc->card, "ctxfi", device, | 409 | err = snd_pcm_new(atc->card, "ctxfi", device, |
| 410 | playback_count, capture_count, &pcm); | 410 | playback_count, capture_count, &pcm); |
diff --git a/sound/pci/ctxfi/ctsrc.c b/sound/pci/ctxfi/ctsrc.c index c749fa720889..e134b3a5780d 100644 --- a/sound/pci/ctxfi/ctsrc.c +++ b/sound/pci/ctxfi/ctsrc.c | |||
| @@ -20,7 +20,7 @@ | |||
| 20 | #include "cthardware.h" | 20 | #include "cthardware.h" |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | 22 | ||
| 23 | #define SRC_RESOURCE_NUM 64 | 23 | #define SRC_RESOURCE_NUM 256 |
| 24 | #define SRCIMP_RESOURCE_NUM 256 | 24 | #define SRCIMP_RESOURCE_NUM 256 |
| 25 | 25 | ||
| 26 | static unsigned int conj_mask; | 26 | static unsigned int conj_mask; |
diff --git a/sound/pci/ctxfi/ctvmem.h b/sound/pci/ctxfi/ctvmem.h index b23adfca4de6..e6da60eb19ce 100644 --- a/sound/pci/ctxfi/ctvmem.h +++ b/sound/pci/ctxfi/ctvmem.h | |||
| @@ -18,7 +18,7 @@ | |||
| 18 | #ifndef CTVMEM_H | 18 | #ifndef CTVMEM_H |
| 19 | #define CTVMEM_H | 19 | #define CTVMEM_H |
| 20 | 20 | ||
| 21 | #define CT_PTP_NUM 1 /* num of device page table pages */ | 21 | #define CT_PTP_NUM 4 /* num of device page table pages */ |
| 22 | 22 | ||
| 23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
| 24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c index 622bace148e3..e22b8e2bbd88 100644 --- a/sound/pci/emu10k1/emupcm.c +++ b/sound/pci/emu10k1/emupcm.c | |||
| @@ -1146,6 +1146,11 @@ static int snd_emu10k1_playback_open(struct snd_pcm_substream *substream) | |||
| 1146 | kfree(epcm); | 1146 | kfree(epcm); |
| 1147 | return err; | 1147 | return err; |
| 1148 | } | 1148 | } |
| 1149 | err = snd_pcm_hw_rule_noresample(runtime, 48000); | ||
| 1150 | if (err < 0) { | ||
| 1151 | kfree(epcm); | ||
| 1152 | return err; | ||
| 1153 | } | ||
| 1149 | mix = &emu->pcm_mixer[substream->number]; | 1154 | mix = &emu->pcm_mixer[substream->number]; |
| 1150 | for (i = 0; i < 4; i++) | 1155 | for (i = 0; i < 4; i++) |
| 1151 | mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i; | 1156 | mix->send_routing[0][i] = mix->send_routing[1][i] = mix->send_routing[2][i] = i; |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 26a5a2f25d4b..718a2643474e 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
| @@ -1854,8 +1854,9 @@ static int __devinit snd_es1938_probe(struct pci_dev *pci, | |||
| 1854 | } | 1854 | } |
| 1855 | } | 1855 | } |
| 1856 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 1856 | if (snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 1857 | chip->mpu_port, MPU401_INFO_INTEGRATED, | 1857 | chip->mpu_port, |
| 1858 | chip->irq, 0, &chip->rmidi) < 0) { | 1858 | MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, |
| 1859 | -1, &chip->rmidi) < 0) { | ||
| 1859 | printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); | 1860 | printk(KERN_ERR "es1938: unable to initialize MPU-401\n"); |
| 1860 | } else { | 1861 | } else { |
| 1861 | // this line is vital for MIDI interrupt handling on ess-solo1 | 1862 | // this line is vital for MIDI interrupt handling on ess-solo1 |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 99ea9320c6b5..407e4abc4356 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
| @@ -2843,8 +2843,9 @@ static int __devinit snd_es1968_probe(struct pci_dev *pci, | |||
| 2843 | if (enable_mpu[dev]) { | 2843 | if (enable_mpu[dev]) { |
| 2844 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, | 2844 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, |
| 2845 | chip->io_port + ESM_MPU401_PORT, | 2845 | chip->io_port + ESM_MPU401_PORT, |
| 2846 | MPU401_INFO_INTEGRATED, | 2846 | MPU401_INFO_INTEGRATED | |
| 2847 | chip->irq, 0, &chip->rmidi)) < 0) { | 2847 | MPU401_INFO_IRQ_HOOK, |
| 2848 | -1, &chip->rmidi)) < 0) { | ||
| 2848 | printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); | 2849 | printk(KERN_WARNING "es1968: skipping MPU-401 MIDI support..\n"); |
| 2849 | } | 2850 | } |
| 2850 | } | 2851 | } |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index 32b02d906703..136f7232bb7c 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
| @@ -729,11 +729,14 @@ static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = { | |||
| 729 | { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" }, | 729 | { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" }, |
| 730 | }; | 730 | }; |
| 731 | 731 | ||
| 732 | #define get_tea575x_gpio(chip) \ | ||
| 733 | (&snd_fm801_tea575x_gpios[((chip)->tea575x_tuner & TUNER_TYPE_MASK) - 1]) | ||
| 734 | |||
| 732 | static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) | 735 | static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) |
| 733 | { | 736 | { |
| 734 | struct fm801 *chip = tea->private_data; | 737 | struct fm801 *chip = tea->private_data; |
| 735 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 738 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
| 736 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; | 739 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
| 737 | 740 | ||
| 738 | reg &= ~(FM801_GPIO_GP(gpio.data) | | 741 | reg &= ~(FM801_GPIO_GP(gpio.data) | |
| 739 | FM801_GPIO_GP(gpio.clk) | | 742 | FM801_GPIO_GP(gpio.clk) | |
| @@ -751,7 +754,7 @@ static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) | |||
| 751 | { | 754 | { |
| 752 | struct fm801 *chip = tea->private_data; | 755 | struct fm801 *chip = tea->private_data; |
| 753 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 756 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
| 754 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; | 757 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
| 755 | 758 | ||
| 756 | return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | | 759 | return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | |
| 757 | (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; | 760 | (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; |
| @@ -761,7 +764,7 @@ static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output | |||
| 761 | { | 764 | { |
| 762 | struct fm801 *chip = tea->private_data; | 765 | struct fm801 *chip = tea->private_data; |
| 763 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); | 766 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
| 764 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; | 767 | struct snd_fm801_tea575x_gpio gpio = *get_tea575x_gpio(chip); |
| 765 | 768 | ||
| 766 | /* use GPIO lines and set write enable bit */ | 769 | /* use GPIO lines and set write enable bit */ |
| 767 | reg |= FM801_GPIO_GS(gpio.data) | | 770 | reg |= FM801_GPIO_GS(gpio.data) | |
| @@ -1246,7 +1249,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
| 1246 | chip->tea575x_tuner = tea575x_tuner; | 1249 | chip->tea575x_tuner = tea575x_tuner; |
| 1247 | if (!snd_tea575x_init(&chip->tea)) { | 1250 | if (!snd_tea575x_init(&chip->tea)) { |
| 1248 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", | 1251 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", |
| 1249 | snd_fm801_tea575x_gpios[tea575x_tuner - 1].name); | 1252 | get_tea575x_gpio(chip)->name); |
| 1250 | break; | 1253 | break; |
| 1251 | } | 1254 | } |
| 1252 | } | 1255 | } |
| @@ -1256,9 +1259,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
| 1256 | } | 1259 | } |
| 1257 | } | 1260 | } |
| 1258 | if (!(chip->tea575x_tuner & TUNER_DISABLED)) { | 1261 | if (!(chip->tea575x_tuner & TUNER_DISABLED)) { |
| 1259 | strlcpy(chip->tea.card, | 1262 | strlcpy(chip->tea.card, get_tea575x_gpio(chip)->name, |
| 1260 | snd_fm801_tea575x_gpios[(tea575x_tuner & | ||
| 1261 | TUNER_TYPE_MASK) - 1].name, | ||
| 1262 | sizeof(chip->tea.card)); | 1263 | sizeof(chip->tea.card)); |
| 1263 | } | 1264 | } |
| 1264 | #endif | 1265 | #endif |
| @@ -1311,8 +1312,9 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci, | |||
| 1311 | } | 1312 | } |
| 1312 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, | 1313 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_FM801, |
| 1313 | FM801_REG(chip, MPU401_DATA), | 1314 | FM801_REG(chip, MPU401_DATA), |
| 1314 | MPU401_INFO_INTEGRATED, | 1315 | MPU401_INFO_INTEGRATED | |
| 1315 | chip->irq, 0, &chip->rmidi)) < 0) { | 1316 | MPU401_INFO_IRQ_HOOK, |
| 1317 | -1, &chip->rmidi)) < 0) { | ||
| 1316 | snd_card_free(card); | 1318 | snd_card_free(card); |
| 1317 | return err; | 1319 | return err; |
| 1318 | } | 1320 | } |
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 87365d5ea2a9..f928d6634723 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile | |||
| @@ -6,6 +6,9 @@ snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o | |||
| 6 | snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o | 6 | snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o |
| 7 | snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o | 7 | snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o |
| 8 | 8 | ||
| 9 | # for trace-points | ||
| 10 | CFLAGS_hda_codec.o := -I$(src) | ||
| 11 | |||
| 9 | snd-hda-codec-realtek-objs := patch_realtek.o | 12 | snd-hda-codec-realtek-objs := patch_realtek.o |
| 10 | snd-hda-codec-cmedia-objs := patch_cmedia.o | 13 | snd-hda-codec-cmedia-objs := patch_cmedia.o |
| 11 | snd-hda-codec-analog-objs := patch_analog.o | 14 | snd-hda-codec-analog-objs := patch_analog.o |
diff --git a/sound/pci/hda/alc260_quirks.c b/sound/pci/hda/alc260_quirks.c index 21ec2cb100b0..3b5170b9700f 100644 --- a/sound/pci/hda/alc260_quirks.c +++ b/sound/pci/hda/alc260_quirks.c | |||
| @@ -7,9 +7,6 @@ | |||
| 7 | enum { | 7 | enum { |
| 8 | ALC260_AUTO, | 8 | ALC260_AUTO, |
| 9 | ALC260_BASIC, | 9 | ALC260_BASIC, |
| 10 | ALC260_HP, | ||
| 11 | ALC260_HP_DC7600, | ||
| 12 | ALC260_HP_3013, | ||
| 13 | ALC260_FUJITSU_S702X, | 10 | ALC260_FUJITSU_S702X, |
| 14 | ALC260_ACER, | 11 | ALC260_ACER, |
| 15 | ALC260_WILL, | 12 | ALC260_WILL, |
| @@ -142,8 +139,6 @@ static const struct hda_channel_mode alc260_modes[1] = { | |||
| 142 | /* Mixer combinations | 139 | /* Mixer combinations |
| 143 | * | 140 | * |
| 144 | * basic: base_output + input + pc_beep + capture | 141 | * basic: base_output + input + pc_beep + capture |
| 145 | * HP: base_output + input + capture_alt | ||
| 146 | * HP_3013: hp_3013 + input + capture | ||
| 147 | * fujitsu: fujitsu + capture | 142 | * fujitsu: fujitsu + capture |
| 148 | * acer: acer + capture | 143 | * acer: acer + capture |
| 149 | */ | 144 | */ |
| @@ -170,145 +165,6 @@ static const struct snd_kcontrol_new alc260_input_mixer[] = { | |||
| 170 | { } /* end */ | 165 | { } /* end */ |
| 171 | }; | 166 | }; |
| 172 | 167 | ||
| 173 | /* update HP, line and mono out pins according to the master switch */ | ||
| 174 | static void alc260_hp_master_update(struct hda_codec *codec) | ||
| 175 | { | ||
| 176 | update_speakers(codec); | ||
| 177 | } | ||
| 178 | |||
| 179 | static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, | ||
| 180 | struct snd_ctl_elem_value *ucontrol) | ||
| 181 | { | ||
| 182 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 183 | struct alc_spec *spec = codec->spec; | ||
| 184 | *ucontrol->value.integer.value = !spec->master_mute; | ||
| 185 | return 0; | ||
| 186 | } | ||
| 187 | |||
| 188 | static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
| 189 | struct snd_ctl_elem_value *ucontrol) | ||
| 190 | { | ||
| 191 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 192 | struct alc_spec *spec = codec->spec; | ||
| 193 | int val = !*ucontrol->value.integer.value; | ||
| 194 | |||
| 195 | if (val == spec->master_mute) | ||
| 196 | return 0; | ||
| 197 | spec->master_mute = val; | ||
| 198 | alc260_hp_master_update(codec); | ||
| 199 | return 1; | ||
| 200 | } | ||
| 201 | |||
| 202 | static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { | ||
| 203 | { | ||
| 204 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 205 | .name = "Master Playback Switch", | ||
| 206 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, | ||
| 207 | .info = snd_ctl_boolean_mono_info, | ||
| 208 | .get = alc260_hp_master_sw_get, | ||
| 209 | .put = alc260_hp_master_sw_put, | ||
| 210 | }, | ||
| 211 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
| 212 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | ||
| 213 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
| 214 | HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT), | ||
| 215 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, | ||
| 216 | HDA_OUTPUT), | ||
| 217 | HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT), | ||
| 218 | { } /* end */ | ||
| 219 | }; | ||
| 220 | |||
| 221 | static const struct hda_verb alc260_hp_unsol_verbs[] = { | ||
| 222 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 223 | {}, | ||
| 224 | }; | ||
| 225 | |||
| 226 | static void alc260_hp_setup(struct hda_codec *codec) | ||
| 227 | { | ||
| 228 | struct alc_spec *spec = codec->spec; | ||
| 229 | |||
| 230 | spec->autocfg.hp_pins[0] = 0x0f; | ||
| 231 | spec->autocfg.speaker_pins[0] = 0x10; | ||
| 232 | spec->autocfg.speaker_pins[1] = 0x11; | ||
| 233 | spec->automute = 1; | ||
| 234 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 235 | } | ||
| 236 | |||
| 237 | static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | ||
| 238 | { | ||
| 239 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 240 | .name = "Master Playback Switch", | ||
| 241 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x11, | ||
| 242 | .info = snd_ctl_boolean_mono_info, | ||
| 243 | .get = alc260_hp_master_sw_get, | ||
| 244 | .put = alc260_hp_master_sw_put, | ||
| 245 | }, | ||
| 246 | HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), | ||
| 247 | HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), | ||
| 248 | HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT), | ||
| 249 | HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT), | ||
| 250 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | ||
| 251 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 252 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | ||
| 253 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT), | ||
| 254 | { } /* end */ | ||
| 255 | }; | ||
| 256 | |||
| 257 | static void alc260_hp_3013_setup(struct hda_codec *codec) | ||
| 258 | { | ||
| 259 | struct alc_spec *spec = codec->spec; | ||
| 260 | |||
| 261 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 262 | spec->autocfg.speaker_pins[0] = 0x10; | ||
| 263 | spec->autocfg.speaker_pins[1] = 0x11; | ||
| 264 | spec->automute = 1; | ||
| 265 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 266 | } | ||
| 267 | |||
| 268 | static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = { | ||
| 269 | .ops = &snd_hda_bind_vol, | ||
| 270 | .values = { | ||
| 271 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), | ||
| 272 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | ||
| 273 | HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), | ||
| 274 | 0 | ||
| 275 | }, | ||
| 276 | }; | ||
| 277 | |||
| 278 | static const struct hda_bind_ctls alc260_dc7600_bind_switch = { | ||
| 279 | .ops = &snd_hda_bind_sw, | ||
| 280 | .values = { | ||
| 281 | HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), | ||
| 282 | HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
| 283 | 0 | ||
| 284 | }, | ||
| 285 | }; | ||
| 286 | |||
| 287 | static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { | ||
| 288 | HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), | ||
| 289 | HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), | ||
| 290 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), | ||
| 291 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), | ||
| 292 | { } /* end */ | ||
| 293 | }; | ||
| 294 | |||
| 295 | static const struct hda_verb alc260_hp_3013_unsol_verbs[] = { | ||
| 296 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 297 | {}, | ||
| 298 | }; | ||
| 299 | |||
| 300 | static void alc260_hp_3012_setup(struct hda_codec *codec) | ||
| 301 | { | ||
| 302 | struct alc_spec *spec = codec->spec; | ||
| 303 | |||
| 304 | spec->autocfg.hp_pins[0] = 0x10; | ||
| 305 | spec->autocfg.speaker_pins[0] = 0x0f; | ||
| 306 | spec->autocfg.speaker_pins[1] = 0x11; | ||
| 307 | spec->autocfg.speaker_pins[2] = 0x15; | ||
| 308 | spec->automute = 1; | ||
| 309 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 310 | } | ||
| 311 | |||
| 312 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, | 168 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, |
| 313 | * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. | 169 | * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. |
| 314 | */ | 170 | */ |
| @@ -480,106 +336,6 @@ static const struct hda_verb alc260_init_verbs[] = { | |||
| 480 | { } | 336 | { } |
| 481 | }; | 337 | }; |
| 482 | 338 | ||
| 483 | #if 0 /* should be identical with alc260_init_verbs? */ | ||
| 484 | static const struct hda_verb alc260_hp_init_verbs[] = { | ||
| 485 | /* Headphone and output */ | ||
| 486 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
| 487 | /* mono output */ | ||
| 488 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
| 489 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
| 490 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 491 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
| 492 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 493 | /* Line In pin widget for input */ | ||
| 494 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 495 | /* Line-2 pin widget for output */ | ||
| 496 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
| 497 | /* CD pin widget for input */ | ||
| 498 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 499 | /* unmute amp left and right */ | ||
| 500 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, | ||
| 501 | /* set connection select to line in (default select for this ADC) */ | ||
| 502 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
| 503 | /* unmute Line-Out mixer amp left and right (volume = 0) */ | ||
| 504 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
| 505 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
| 506 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
| 507 | /* unmute HP mixer amp left and right (volume = 0) */ | ||
| 508 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
| 509 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
| 510 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
| 511 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & | ||
| 512 | * Line In 2 = 0x03 | ||
| 513 | */ | ||
| 514 | /* mute analog inputs */ | ||
| 515 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 516 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 517 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 518 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 519 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
| 520 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | ||
| 521 | /* Unmute Front out path */ | ||
| 522 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 523 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 524 | /* Unmute Headphone out path */ | ||
| 525 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 526 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 527 | /* Unmute Mono out path */ | ||
| 528 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 529 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 530 | { } | ||
| 531 | }; | ||
| 532 | #endif | ||
| 533 | |||
| 534 | static const struct hda_verb alc260_hp_3013_init_verbs[] = { | ||
| 535 | /* Line out and output */ | ||
| 536 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
| 537 | /* mono output */ | ||
| 538 | {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
| 539 | /* Mic1 (rear panel) pin widget for input and vref at 80% */ | ||
| 540 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 541 | /* Mic2 (front panel) pin widget for input and vref at 80% */ | ||
| 542 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 543 | /* Line In pin widget for input */ | ||
| 544 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 545 | /* Headphone pin widget for output */ | ||
| 546 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
| 547 | /* CD pin widget for input */ | ||
| 548 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 549 | /* unmute amp left and right */ | ||
| 550 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000}, | ||
| 551 | /* set connection select to line in (default select for this ADC) */ | ||
| 552 | {0x04, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
| 553 | /* unmute Line-Out mixer amp left and right (volume = 0) */ | ||
| 554 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
| 555 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
| 556 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
| 557 | /* unmute HP mixer amp left and right (volume = 0) */ | ||
| 558 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | ||
| 559 | /* mute pin widget amp left and right (no gain on this amp) */ | ||
| 560 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | ||
| 561 | /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & | ||
| 562 | * Line In 2 = 0x03 | ||
| 563 | */ | ||
| 564 | /* mute analog inputs */ | ||
| 565 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 566 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 567 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 568 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 569 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
| 570 | /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */ | ||
| 571 | /* Unmute Front out path */ | ||
| 572 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 573 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 574 | /* Unmute Headphone out path */ | ||
| 575 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 576 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 577 | /* Unmute Mono out path */ | ||
| 578 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 579 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 580 | { } | ||
| 581 | }; | ||
| 582 | |||
| 583 | /* Initialisation sequence for ALC260 as configured in Fujitsu S702x | 339 | /* Initialisation sequence for ALC260 as configured in Fujitsu S702x |
| 584 | * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD | 340 | * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD |
| 585 | * audio = 0x16, internal speaker = 0x10. | 341 | * audio = 0x16, internal speaker = 0x10. |
| @@ -1093,9 +849,6 @@ static const struct hda_verb alc260_test_init_verbs[] = { | |||
| 1093 | */ | 849 | */ |
| 1094 | static const char * const alc260_models[ALC260_MODEL_LAST] = { | 850 | static const char * const alc260_models[ALC260_MODEL_LAST] = { |
| 1095 | [ALC260_BASIC] = "basic", | 851 | [ALC260_BASIC] = "basic", |
| 1096 | [ALC260_HP] = "hp", | ||
| 1097 | [ALC260_HP_3013] = "hp-3013", | ||
| 1098 | [ALC260_HP_DC7600] = "hp-dc7600", | ||
| 1099 | [ALC260_FUJITSU_S702X] = "fujitsu", | 852 | [ALC260_FUJITSU_S702X] = "fujitsu", |
| 1100 | [ALC260_ACER] = "acer", | 853 | [ALC260_ACER] = "acer", |
| 1101 | [ALC260_WILL] = "will", | 854 | [ALC260_WILL] = "will", |
| @@ -1112,15 +865,6 @@ static const struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
| 1112 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), | 865 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), |
| 1113 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | 866 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), |
| 1114 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), | 867 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100), |
| 1115 | SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), | ||
| 1116 | SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */ | ||
| 1117 | SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), | ||
| 1118 | SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), | ||
| 1119 | SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), | ||
| 1120 | SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), | ||
| 1121 | SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), | ||
| 1122 | SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), | ||
| 1123 | SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP), | ||
| 1124 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), | 868 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC), |
| 1125 | SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), | 869 | SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC), |
| 1126 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), | 870 | SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), |
| @@ -1144,54 +888,6 @@ static const struct alc_config_preset alc260_presets[] = { | |||
| 1144 | .channel_mode = alc260_modes, | 888 | .channel_mode = alc260_modes, |
| 1145 | .input_mux = &alc260_capture_source, | 889 | .input_mux = &alc260_capture_source, |
| 1146 | }, | 890 | }, |
| 1147 | [ALC260_HP] = { | ||
| 1148 | .mixers = { alc260_hp_output_mixer, | ||
| 1149 | alc260_input_mixer }, | ||
| 1150 | .init_verbs = { alc260_init_verbs, | ||
| 1151 | alc260_hp_unsol_verbs }, | ||
| 1152 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
| 1153 | .dac_nids = alc260_dac_nids, | ||
| 1154 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), | ||
| 1155 | .adc_nids = alc260_adc_nids_alt, | ||
| 1156 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
| 1157 | .channel_mode = alc260_modes, | ||
| 1158 | .input_mux = &alc260_capture_source, | ||
| 1159 | .unsol_event = alc_sku_unsol_event, | ||
| 1160 | .setup = alc260_hp_setup, | ||
| 1161 | .init_hook = alc_inithook, | ||
| 1162 | }, | ||
| 1163 | [ALC260_HP_DC7600] = { | ||
| 1164 | .mixers = { alc260_hp_dc7600_mixer, | ||
| 1165 | alc260_input_mixer }, | ||
| 1166 | .init_verbs = { alc260_init_verbs, | ||
| 1167 | alc260_hp_dc7600_verbs }, | ||
| 1168 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
| 1169 | .dac_nids = alc260_dac_nids, | ||
| 1170 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), | ||
| 1171 | .adc_nids = alc260_adc_nids_alt, | ||
| 1172 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
| 1173 | .channel_mode = alc260_modes, | ||
| 1174 | .input_mux = &alc260_capture_source, | ||
| 1175 | .unsol_event = alc_sku_unsol_event, | ||
| 1176 | .setup = alc260_hp_3012_setup, | ||
| 1177 | .init_hook = alc_inithook, | ||
| 1178 | }, | ||
| 1179 | [ALC260_HP_3013] = { | ||
| 1180 | .mixers = { alc260_hp_3013_mixer, | ||
| 1181 | alc260_input_mixer }, | ||
| 1182 | .init_verbs = { alc260_hp_3013_init_verbs, | ||
| 1183 | alc260_hp_3013_unsol_verbs }, | ||
| 1184 | .num_dacs = ARRAY_SIZE(alc260_dac_nids), | ||
| 1185 | .dac_nids = alc260_dac_nids, | ||
| 1186 | .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt), | ||
| 1187 | .adc_nids = alc260_adc_nids_alt, | ||
| 1188 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | ||
| 1189 | .channel_mode = alc260_modes, | ||
| 1190 | .input_mux = &alc260_capture_source, | ||
| 1191 | .unsol_event = alc_sku_unsol_event, | ||
| 1192 | .setup = alc260_hp_3013_setup, | ||
| 1193 | .init_hook = alc_inithook, | ||
| 1194 | }, | ||
| 1195 | [ALC260_FUJITSU_S702X] = { | 891 | [ALC260_FUJITSU_S702X] = { |
| 1196 | .mixers = { alc260_fujitsu_mixer }, | 892 | .mixers = { alc260_fujitsu_mixer }, |
| 1197 | .init_verbs = { alc260_fujitsu_init_verbs }, | 893 | .init_verbs = { alc260_fujitsu_init_verbs }, |
diff --git a/sound/pci/hda/alc262_quirks.c b/sound/pci/hda/alc262_quirks.c index 8d2097d77642..7894b2b5aacf 100644 --- a/sound/pci/hda/alc262_quirks.c +++ b/sound/pci/hda/alc262_quirks.c | |||
| @@ -10,13 +10,7 @@ enum { | |||
| 10 | ALC262_HIPPO, | 10 | ALC262_HIPPO, |
| 11 | ALC262_HIPPO_1, | 11 | ALC262_HIPPO_1, |
| 12 | ALC262_FUJITSU, | 12 | ALC262_FUJITSU, |
| 13 | ALC262_HP_BPC, | ||
| 14 | ALC262_HP_BPC_D7000_WL, | ||
| 15 | ALC262_HP_BPC_D7000_WF, | ||
| 16 | ALC262_HP_TC_T5735, | ||
| 17 | ALC262_HP_RP5700, | ||
| 18 | ALC262_BENQ_ED8, | 13 | ALC262_BENQ_ED8, |
| 19 | ALC262_SONY_ASSAMD, | ||
| 20 | ALC262_BENQ_T31, | 14 | ALC262_BENQ_T31, |
| 21 | ALC262_ULTRA, | 15 | ALC262_ULTRA, |
| 22 | ALC262_LENOVO_3000, | 16 | ALC262_LENOVO_3000, |
| @@ -66,164 +60,31 @@ static const struct snd_kcontrol_new alc262_base_mixer[] = { | |||
| 66 | { } /* end */ | 60 | { } /* end */ |
| 67 | }; | 61 | }; |
| 68 | 62 | ||
| 69 | /* update HP, line and mono-out pins according to the master switch */ | 63 | /* bind hp and internal speaker mute (with plug check) as master switch */ |
| 70 | #define alc262_hp_master_update alc260_hp_master_update | ||
| 71 | 64 | ||
| 72 | static void alc262_hp_bpc_setup(struct hda_codec *codec) | 65 | static int alc262_hippo_master_sw_get(struct snd_kcontrol *kcontrol, |
| 66 | struct snd_ctl_elem_value *ucontrol) | ||
| 73 | { | 67 | { |
| 68 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 74 | struct alc_spec *spec = codec->spec; | 69 | struct alc_spec *spec = codec->spec; |
| 75 | 70 | *ucontrol->value.integer.value = !spec->master_mute; | |
| 76 | spec->autocfg.hp_pins[0] = 0x1b; | 71 | return 0; |
| 77 | spec->autocfg.speaker_pins[0] = 0x16; | ||
| 78 | spec->automute = 1; | ||
| 79 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 80 | } | 72 | } |
| 81 | 73 | ||
| 82 | static void alc262_hp_wildwest_setup(struct hda_codec *codec) | 74 | static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, |
| 83 | { | 75 | struct snd_ctl_elem_value *ucontrol) |
| 84 | struct alc_spec *spec = codec->spec; | ||
| 85 | |||
| 86 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 87 | spec->autocfg.speaker_pins[0] = 0x16; | ||
| 88 | spec->automute = 1; | ||
| 89 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 90 | } | ||
| 91 | |||
| 92 | #define alc262_hp_master_sw_get alc260_hp_master_sw_get | ||
| 93 | #define alc262_hp_master_sw_put alc260_hp_master_sw_put | ||
| 94 | |||
| 95 | #define ALC262_HP_MASTER_SWITCH \ | ||
| 96 | { \ | ||
| 97 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
| 98 | .name = "Master Playback Switch", \ | ||
| 99 | .info = snd_ctl_boolean_mono_info, \ | ||
| 100 | .get = alc262_hp_master_sw_get, \ | ||
| 101 | .put = alc262_hp_master_sw_put, \ | ||
| 102 | }, \ | ||
| 103 | { \ | ||
| 104 | .iface = NID_MAPPING, \ | ||
| 105 | .name = "Master Playback Switch", \ | ||
| 106 | .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \ | ||
| 107 | } | ||
| 108 | |||
| 109 | |||
| 110 | static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | ||
| 111 | ALC262_HP_MASTER_SWITCH, | ||
| 112 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
| 113 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 114 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 115 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, | ||
| 116 | HDA_OUTPUT), | ||
| 117 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, | ||
| 118 | HDA_OUTPUT), | ||
| 119 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 120 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 121 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 122 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
| 123 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
| 124 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 125 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 126 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 127 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 128 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 129 | HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), | ||
| 130 | HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), | ||
| 131 | { } /* end */ | ||
| 132 | }; | ||
| 133 | |||
| 134 | static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | ||
| 135 | ALC262_HP_MASTER_SWITCH, | ||
| 136 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
| 137 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 138 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
| 139 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 140 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0, | ||
| 141 | HDA_OUTPUT), | ||
| 142 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0, | ||
| 143 | HDA_OUTPUT), | ||
| 144 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 145 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 146 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT), | ||
| 147 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
| 148 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
| 149 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 150 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 151 | { } /* end */ | ||
| 152 | }; | ||
| 153 | |||
| 154 | static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | ||
| 155 | HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 156 | HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 157 | HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 158 | { } /* end */ | ||
| 159 | }; | ||
| 160 | |||
| 161 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
| 162 | static void alc262_hp_t5735_setup(struct hda_codec *codec) | ||
| 163 | { | 76 | { |
| 77 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 164 | struct alc_spec *spec = codec->spec; | 78 | struct alc_spec *spec = codec->spec; |
| 79 | int val = !*ucontrol->value.integer.value; | ||
| 165 | 80 | ||
| 166 | spec->autocfg.hp_pins[0] = 0x15; | 81 | if (val == spec->master_mute) |
| 167 | spec->autocfg.speaker_pins[0] = 0x14; | 82 | return 0; |
| 168 | spec->automute = 1; | 83 | spec->master_mute = val; |
| 169 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 84 | update_outputs(codec); |
| 85 | return 1; | ||
| 170 | } | 86 | } |
| 171 | 87 | ||
| 172 | static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | ||
| 173 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
| 174 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 175 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | ||
| 176 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 177 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 178 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 179 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 180 | { } /* end */ | ||
| 181 | }; | ||
| 182 | |||
| 183 | static const struct hda_verb alc262_hp_t5735_verbs[] = { | ||
| 184 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 185 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 186 | |||
| 187 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 188 | { } | ||
| 189 | }; | ||
| 190 | |||
| 191 | static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { | ||
| 192 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
| 193 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 194 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | ||
| 195 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
| 196 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
| 197 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
| 198 | { } /* end */ | ||
| 199 | }; | ||
| 200 | |||
| 201 | static const struct hda_verb alc262_hp_rp5700_verbs[] = { | ||
| 202 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 203 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 204 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 205 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 206 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 207 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 208 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 209 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 210 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, | ||
| 211 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))}, | ||
| 212 | {} | ||
| 213 | }; | ||
| 214 | |||
| 215 | static const struct hda_input_mux alc262_hp_rp5700_capture_source = { | ||
| 216 | .num_items = 1, | ||
| 217 | .items = { | ||
| 218 | { "Line", 0x1 }, | ||
| 219 | }, | ||
| 220 | }; | ||
| 221 | |||
| 222 | /* bind hp and internal speaker mute (with plug check) as master switch */ | ||
| 223 | #define alc262_hippo_master_update alc262_hp_master_update | ||
| 224 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get | ||
| 225 | #define alc262_hippo_master_sw_put alc262_hp_master_sw_put | ||
| 226 | |||
| 227 | #define ALC262_HIPPO_MASTER_SWITCH \ | 88 | #define ALC262_HIPPO_MASTER_SWITCH \ |
| 228 | { \ | 89 | { \ |
| 229 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 90 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
| @@ -239,6 +100,9 @@ static const struct hda_input_mux alc262_hp_rp5700_capture_source = { | |||
| 239 | (SUBDEV_SPEAKER(0) << 16), \ | 100 | (SUBDEV_SPEAKER(0) << 16), \ |
| 240 | } | 101 | } |
| 241 | 102 | ||
| 103 | #define alc262_hp_master_sw_get alc262_hippo_master_sw_get | ||
| 104 | #define alc262_hp_master_sw_put alc262_hippo_master_sw_put | ||
| 105 | |||
| 242 | static const struct snd_kcontrol_new alc262_hippo_mixer[] = { | 106 | static const struct snd_kcontrol_new alc262_hippo_mixer[] = { |
| 243 | ALC262_HIPPO_MASTER_SWITCH, | 107 | ALC262_HIPPO_MASTER_SWITCH, |
| 244 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 108 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
| @@ -279,8 +143,7 @@ static void alc262_hippo_setup(struct hda_codec *codec) | |||
| 279 | 143 | ||
| 280 | spec->autocfg.hp_pins[0] = 0x15; | 144 | spec->autocfg.hp_pins[0] = 0x15; |
| 281 | spec->autocfg.speaker_pins[0] = 0x14; | 145 | spec->autocfg.speaker_pins[0] = 0x14; |
| 282 | spec->automute = 1; | 146 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 283 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 284 | } | 147 | } |
| 285 | 148 | ||
| 286 | static void alc262_hippo1_setup(struct hda_codec *codec) | 149 | static void alc262_hippo1_setup(struct hda_codec *codec) |
| @@ -289,8 +152,7 @@ static void alc262_hippo1_setup(struct hda_codec *codec) | |||
| 289 | 152 | ||
| 290 | spec->autocfg.hp_pins[0] = 0x1b; | 153 | spec->autocfg.hp_pins[0] = 0x1b; |
| 291 | spec->autocfg.speaker_pins[0] = 0x14; | 154 | spec->autocfg.speaker_pins[0] = 0x14; |
| 292 | spec->automute = 1; | 155 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 293 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 294 | } | 156 | } |
| 295 | 157 | ||
| 296 | 158 | ||
| @@ -353,8 +215,7 @@ static void alc262_tyan_setup(struct hda_codec *codec) | |||
| 353 | 215 | ||
| 354 | spec->autocfg.hp_pins[0] = 0x1b; | 216 | spec->autocfg.hp_pins[0] = 0x1b; |
| 355 | spec->autocfg.speaker_pins[0] = 0x15; | 217 | spec->autocfg.speaker_pins[0] = 0x15; |
| 356 | spec->automute = 1; | 218 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 357 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 358 | } | 219 | } |
| 359 | 220 | ||
| 360 | 221 | ||
| @@ -496,8 +357,7 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec) | |||
| 496 | spec->ext_mic_pin = 0x18; | 357 | spec->ext_mic_pin = 0x18; |
| 497 | spec->int_mic_pin = 0x12; | 358 | spec->int_mic_pin = 0x12; |
| 498 | spec->auto_mic = 1; | 359 | spec->auto_mic = 1; |
| 499 | spec->automute = 1; | 360 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_PIN); |
| 500 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 501 | } | 361 | } |
| 502 | 362 | ||
| 503 | /* | 363 | /* |
| @@ -571,27 +431,6 @@ static const struct hda_input_mux alc262_fujitsu_capture_source = { | |||
| 571 | }, | 431 | }, |
| 572 | }; | 432 | }; |
| 573 | 433 | ||
| 574 | static const struct hda_input_mux alc262_HP_capture_source = { | ||
| 575 | .num_items = 5, | ||
| 576 | .items = { | ||
| 577 | { "Mic", 0x0 }, | ||
| 578 | { "Front Mic", 0x1 }, | ||
| 579 | { "Line", 0x2 }, | ||
| 580 | { "CD", 0x4 }, | ||
| 581 | { "AUX IN", 0x6 }, | ||
| 582 | }, | ||
| 583 | }; | ||
| 584 | |||
| 585 | static const struct hda_input_mux alc262_HP_D7000_capture_source = { | ||
| 586 | .num_items = 4, | ||
| 587 | .items = { | ||
| 588 | { "Mic", 0x0 }, | ||
| 589 | { "Front Mic", 0x2 }, | ||
| 590 | { "Line", 0x1 }, | ||
| 591 | { "CD", 0x4 }, | ||
| 592 | }, | ||
| 593 | }; | ||
| 594 | |||
| 595 | static void alc262_fujitsu_setup(struct hda_codec *codec) | 434 | static void alc262_fujitsu_setup(struct hda_codec *codec) |
| 596 | { | 435 | { |
| 597 | struct alc_spec *spec = codec->spec; | 436 | struct alc_spec *spec = codec->spec; |
| @@ -599,8 +438,7 @@ static void alc262_fujitsu_setup(struct hda_codec *codec) | |||
| 599 | spec->autocfg.hp_pins[0] = 0x14; | 438 | spec->autocfg.hp_pins[0] = 0x14; |
| 600 | spec->autocfg.hp_pins[1] = 0x1b; | 439 | spec->autocfg.hp_pins[1] = 0x1b; |
| 601 | spec->autocfg.speaker_pins[0] = 0x15; | 440 | spec->autocfg.speaker_pins[0] = 0x15; |
| 602 | spec->automute = 1; | 441 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 603 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 604 | } | 442 | } |
| 605 | 443 | ||
| 606 | /* bind volumes of both NID 0x0c and 0x0d */ | 444 | /* bind volumes of both NID 0x0c and 0x0d */ |
| @@ -646,8 +484,7 @@ static void alc262_lenovo_3000_setup(struct hda_codec *codec) | |||
| 646 | spec->autocfg.hp_pins[0] = 0x1b; | 484 | spec->autocfg.hp_pins[0] = 0x1b; |
| 647 | spec->autocfg.speaker_pins[0] = 0x14; | 485 | spec->autocfg.speaker_pins[0] = 0x14; |
| 648 | spec->autocfg.speaker_pins[1] = 0x16; | 486 | spec->autocfg.speaker_pins[1] = 0x16; |
| 649 | spec->automute = 1; | 487 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 650 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 651 | } | 488 | } |
| 652 | 489 | ||
| 653 | static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { | 490 | static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { |
| @@ -752,8 +589,8 @@ static void alc262_ultra_automute(struct hda_codec *codec) | |||
| 752 | mute = 0; | 589 | mute = 0; |
| 753 | /* auto-mute only when HP is used as HP */ | 590 | /* auto-mute only when HP is used as HP */ |
| 754 | if (!spec->cur_mux[0]) { | 591 | if (!spec->cur_mux[0]) { |
| 755 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); | 592 | spec->hp_jack_present = snd_hda_jack_detect(codec, 0x15); |
| 756 | if (spec->jack_present) | 593 | if (spec->hp_jack_present) |
| 757 | mute = HDA_AMP_MUTE; | 594 | mute = HDA_AMP_MUTE; |
| 758 | } | 595 | } |
| 759 | /* mute/unmute internal speaker */ | 596 | /* mute/unmute internal speaker */ |
| @@ -817,206 +654,6 @@ static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { | |||
| 817 | { } /* end */ | 654 | { } /* end */ |
| 818 | }; | 655 | }; |
| 819 | 656 | ||
| 820 | static const struct hda_verb alc262_HP_BPC_init_verbs[] = { | ||
| 821 | /* | ||
| 822 | * Unmute ADC0-2 and set the default input to mic-in | ||
| 823 | */ | ||
| 824 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 825 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 826 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 827 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 828 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 829 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 830 | |||
| 831 | /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
| 832 | * mixer widget | ||
| 833 | * Note: PASD motherboards uses the Line In 2 as the input for | ||
| 834 | * front panel mic (mic 2) | ||
| 835 | */ | ||
| 836 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
| 837 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 838 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 839 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 840 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 841 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
| 842 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
| 843 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
| 844 | |||
| 845 | /* | ||
| 846 | * Set up output mixers (0x0c - 0x0e) | ||
| 847 | */ | ||
| 848 | /* set vol=0 to output mixers */ | ||
| 849 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 850 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 851 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 852 | |||
| 853 | /* set up input amps for analog loopback */ | ||
| 854 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
| 855 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 856 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 857 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 858 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 859 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 860 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 861 | |||
| 862 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 863 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 864 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 865 | |||
| 866 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
| 867 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
| 868 | |||
| 869 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 870 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 871 | |||
| 872 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 873 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 874 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 875 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 876 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 877 | |||
| 878 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 879 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 880 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 881 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 882 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 883 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 884 | |||
| 885 | |||
| 886 | /* FIXME: use matrix-type input source selection */ | ||
| 887 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */ | ||
| 888 | /* Input mixer1: only unmute Mic */ | ||
| 889 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 890 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, | ||
| 891 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, | ||
| 892 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, | ||
| 893 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | ||
| 894 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, | ||
| 895 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, | ||
| 896 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, | ||
| 897 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, | ||
| 898 | /* Input mixer2 */ | ||
| 899 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 900 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, | ||
| 901 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, | ||
| 902 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, | ||
| 903 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | ||
| 904 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, | ||
| 905 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, | ||
| 906 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, | ||
| 907 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, | ||
| 908 | /* Input mixer3 */ | ||
| 909 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 910 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))}, | ||
| 911 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, | ||
| 912 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, | ||
| 913 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, | ||
| 914 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))}, | ||
| 915 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))}, | ||
| 916 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))}, | ||
| 917 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))}, | ||
| 918 | |||
| 919 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 920 | |||
| 921 | { } | ||
| 922 | }; | ||
| 923 | |||
| 924 | static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { | ||
| 925 | /* | ||
| 926 | * Unmute ADC0-2 and set the default input to mic-in | ||
| 927 | */ | ||
| 928 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 929 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 930 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 931 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 932 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 933 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 934 | |||
| 935 | /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
| 936 | * mixer widget | ||
| 937 | * Note: PASD motherboards uses the Line In 2 as the input for front | ||
| 938 | * panel mic (mic 2) | ||
| 939 | */ | ||
| 940 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
| 941 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 942 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 943 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 944 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 945 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
| 946 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
| 947 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, | ||
| 948 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, | ||
| 949 | /* | ||
| 950 | * Set up output mixers (0x0c - 0x0e) | ||
| 951 | */ | ||
| 952 | /* set vol=0 to output mixers */ | ||
| 953 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 954 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 955 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 956 | |||
| 957 | /* set up input amps for analog loopback */ | ||
| 958 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
| 959 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 960 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 961 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 962 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 963 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 964 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 965 | |||
| 966 | |||
| 967 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */ | ||
| 968 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */ | ||
| 969 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */ | ||
| 970 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */ | ||
| 971 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ | ||
| 972 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */ | ||
| 973 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */ | ||
| 974 | |||
| 975 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
| 976 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
| 977 | |||
| 978 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 979 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 980 | |||
| 981 | /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */ | ||
| 982 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 983 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 984 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, | ||
| 985 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 986 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 }, | ||
| 987 | |||
| 988 | /* FIXME: use matrix-type input source selection */ | ||
| 989 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
| 990 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
| 991 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/ | ||
| 992 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/ | ||
| 993 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/ | ||
| 994 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/ | ||
| 995 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/ | ||
| 996 | /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ | ||
| 997 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/ | ||
| 998 | /* Input mixer2 */ | ||
| 999 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 1000 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 1001 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
| 1002 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
| 1003 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
| 1004 | /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ | ||
| 1005 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, | ||
| 1006 | /* Input mixer3 */ | ||
| 1007 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, | ||
| 1008 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, | ||
| 1009 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, | ||
| 1010 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, | ||
| 1011 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, | ||
| 1012 | /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */ | ||
| 1013 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, | ||
| 1014 | |||
| 1015 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 1016 | |||
| 1017 | { } | ||
| 1018 | }; | ||
| 1019 | |||
| 1020 | static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { | 657 | static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { |
| 1021 | 658 | ||
| 1022 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ | 659 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ |
| @@ -1042,13 +679,8 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = { | |||
| 1042 | [ALC262_HIPPO] = "hippo", | 679 | [ALC262_HIPPO] = "hippo", |
| 1043 | [ALC262_HIPPO_1] = "hippo_1", | 680 | [ALC262_HIPPO_1] = "hippo_1", |
| 1044 | [ALC262_FUJITSU] = "fujitsu", | 681 | [ALC262_FUJITSU] = "fujitsu", |
| 1045 | [ALC262_HP_BPC] = "hp-bpc", | ||
| 1046 | [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", | ||
| 1047 | [ALC262_HP_TC_T5735] = "hp-tc-t5735", | ||
| 1048 | [ALC262_HP_RP5700] = "hp-rp5700", | ||
| 1049 | [ALC262_BENQ_ED8] = "benq", | 682 | [ALC262_BENQ_ED8] = "benq", |
| 1050 | [ALC262_BENQ_T31] = "benq-t31", | 683 | [ALC262_BENQ_T31] = "benq-t31", |
| 1051 | [ALC262_SONY_ASSAMD] = "sony-assamd", | ||
| 1052 | [ALC262_TOSHIBA_S06] = "toshiba-s06", | 684 | [ALC262_TOSHIBA_S06] = "toshiba-s06", |
| 1053 | [ALC262_TOSHIBA_RX1] = "toshiba-rx1", | 685 | [ALC262_TOSHIBA_RX1] = "toshiba-rx1", |
| 1054 | [ALC262_ULTRA] = "ultra", | 686 | [ALC262_ULTRA] = "ultra", |
| @@ -1061,41 +693,6 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = { | |||
| 1061 | static const struct snd_pci_quirk alc262_cfg_tbl[] = { | 693 | static const struct snd_pci_quirk alc262_cfg_tbl[] = { |
| 1062 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), | 694 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), |
| 1063 | SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), | 695 | SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), |
| 1064 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", | ||
| 1065 | ALC262_HP_BPC), | ||
| 1066 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", | ||
| 1067 | ALC262_HP_BPC), | ||
| 1068 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", | ||
| 1069 | ALC262_HP_BPC), | ||
| 1070 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", | ||
| 1071 | ALC262_AUTO), | ||
| 1072 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", | ||
| 1073 | ALC262_HP_BPC), | ||
| 1074 | SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), | ||
| 1075 | SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
| 1076 | SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), | ||
| 1077 | SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
| 1078 | SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL), | ||
| 1079 | SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
| 1080 | SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL), | ||
| 1081 | SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF), | ||
| 1082 | SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC), | ||
| 1083 | SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC), | ||
| 1084 | SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), | ||
| 1085 | SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", | ||
| 1086 | ALC262_HP_TC_T5735), | ||
| 1087 | SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700), | ||
| 1088 | SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), | ||
| 1089 | SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), | ||
| 1090 | SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), | ||
| 1091 | SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */ | ||
| 1092 | SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06), | ||
| 1093 | SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO), | ||
| 1094 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO), | ||
| 1095 | #if 0 /* disable the quirk since model=auto works better in recent versions */ | ||
| 1096 | SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO", | ||
| 1097 | ALC262_SONY_ASSAMD), | ||
| 1098 | #endif | ||
| 1099 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", | 696 | SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", |
| 1100 | ALC262_TOSHIBA_RX1), | 697 | ALC262_TOSHIBA_RX1), |
| 1101 | SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), | 698 | SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), |
| @@ -1166,68 +763,6 @@ static const struct alc_config_preset alc262_presets[] = { | |||
| 1166 | .setup = alc262_fujitsu_setup, | 763 | .setup = alc262_fujitsu_setup, |
| 1167 | .init_hook = alc_inithook, | 764 | .init_hook = alc_inithook, |
| 1168 | }, | 765 | }, |
| 1169 | [ALC262_HP_BPC] = { | ||
| 1170 | .mixers = { alc262_HP_BPC_mixer }, | ||
| 1171 | .init_verbs = { alc262_HP_BPC_init_verbs }, | ||
| 1172 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
| 1173 | .dac_nids = alc262_dac_nids, | ||
| 1174 | .hp_nid = 0x03, | ||
| 1175 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
| 1176 | .channel_mode = alc262_modes, | ||
| 1177 | .input_mux = &alc262_HP_capture_source, | ||
| 1178 | .unsol_event = alc_sku_unsol_event, | ||
| 1179 | .setup = alc262_hp_bpc_setup, | ||
| 1180 | .init_hook = alc_inithook, | ||
| 1181 | }, | ||
| 1182 | [ALC262_HP_BPC_D7000_WF] = { | ||
| 1183 | .mixers = { alc262_HP_BPC_WildWest_mixer }, | ||
| 1184 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, | ||
| 1185 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
| 1186 | .dac_nids = alc262_dac_nids, | ||
| 1187 | .hp_nid = 0x03, | ||
| 1188 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
| 1189 | .channel_mode = alc262_modes, | ||
| 1190 | .input_mux = &alc262_HP_D7000_capture_source, | ||
| 1191 | .unsol_event = alc_sku_unsol_event, | ||
| 1192 | .setup = alc262_hp_wildwest_setup, | ||
| 1193 | .init_hook = alc_inithook, | ||
| 1194 | }, | ||
| 1195 | [ALC262_HP_BPC_D7000_WL] = { | ||
| 1196 | .mixers = { alc262_HP_BPC_WildWest_mixer, | ||
| 1197 | alc262_HP_BPC_WildWest_option_mixer }, | ||
| 1198 | .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, | ||
| 1199 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
| 1200 | .dac_nids = alc262_dac_nids, | ||
| 1201 | .hp_nid = 0x03, | ||
| 1202 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
| 1203 | .channel_mode = alc262_modes, | ||
| 1204 | .input_mux = &alc262_HP_D7000_capture_source, | ||
| 1205 | .unsol_event = alc_sku_unsol_event, | ||
| 1206 | .setup = alc262_hp_wildwest_setup, | ||
| 1207 | .init_hook = alc_inithook, | ||
| 1208 | }, | ||
| 1209 | [ALC262_HP_TC_T5735] = { | ||
| 1210 | .mixers = { alc262_hp_t5735_mixer }, | ||
| 1211 | .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs }, | ||
| 1212 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
| 1213 | .dac_nids = alc262_dac_nids, | ||
| 1214 | .hp_nid = 0x03, | ||
| 1215 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
| 1216 | .channel_mode = alc262_modes, | ||
| 1217 | .input_mux = &alc262_capture_source, | ||
| 1218 | .unsol_event = alc_sku_unsol_event, | ||
| 1219 | .setup = alc262_hp_t5735_setup, | ||
| 1220 | .init_hook = alc_inithook, | ||
| 1221 | }, | ||
| 1222 | [ALC262_HP_RP5700] = { | ||
| 1223 | .mixers = { alc262_hp_rp5700_mixer }, | ||
| 1224 | .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs }, | ||
| 1225 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
| 1226 | .dac_nids = alc262_dac_nids, | ||
| 1227 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
| 1228 | .channel_mode = alc262_modes, | ||
| 1229 | .input_mux = &alc262_hp_rp5700_capture_source, | ||
| 1230 | }, | ||
| 1231 | [ALC262_BENQ_ED8] = { | 766 | [ALC262_BENQ_ED8] = { |
| 1232 | .mixers = { alc262_base_mixer }, | 767 | .mixers = { alc262_base_mixer }, |
| 1233 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, | 768 | .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, |
| @@ -1238,19 +773,6 @@ static const struct alc_config_preset alc262_presets[] = { | |||
| 1238 | .channel_mode = alc262_modes, | 773 | .channel_mode = alc262_modes, |
| 1239 | .input_mux = &alc262_capture_source, | 774 | .input_mux = &alc262_capture_source, |
| 1240 | }, | 775 | }, |
| 1241 | [ALC262_SONY_ASSAMD] = { | ||
| 1242 | .mixers = { alc262_sony_mixer }, | ||
| 1243 | .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs}, | ||
| 1244 | .num_dacs = ARRAY_SIZE(alc262_dac_nids), | ||
| 1245 | .dac_nids = alc262_dac_nids, | ||
| 1246 | .hp_nid = 0x02, | ||
| 1247 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | ||
| 1248 | .channel_mode = alc262_modes, | ||
| 1249 | .input_mux = &alc262_capture_source, | ||
| 1250 | .unsol_event = alc_sku_unsol_event, | ||
| 1251 | .setup = alc262_hippo_setup, | ||
| 1252 | .init_hook = alc_inithook, | ||
| 1253 | }, | ||
| 1254 | [ALC262_BENQ_T31] = { | 776 | [ALC262_BENQ_T31] = { |
| 1255 | .mixers = { alc262_benq_t31_mixer }, | 777 | .mixers = { alc262_benq_t31_mixer }, |
| 1256 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, | 778 | .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs, |
diff --git a/sound/pci/hda/alc268_quirks.c b/sound/pci/hda/alc268_quirks.c deleted file mode 100644 index 2e5876ce71fe..000000000000 --- a/sound/pci/hda/alc268_quirks.c +++ /dev/null | |||
| @@ -1,636 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ALC267/ALC268 quirk models | ||
| 3 | * included by patch_realtek.c | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* ALC268 models */ | ||
| 7 | enum { | ||
| 8 | ALC268_AUTO, | ||
| 9 | ALC267_QUANTA_IL1, | ||
| 10 | ALC268_3ST, | ||
| 11 | ALC268_TOSHIBA, | ||
| 12 | ALC268_ACER, | ||
| 13 | ALC268_ACER_DMIC, | ||
| 14 | ALC268_ACER_ASPIRE_ONE, | ||
| 15 | ALC268_DELL, | ||
| 16 | ALC268_ZEPTO, | ||
| 17 | #ifdef CONFIG_SND_DEBUG | ||
| 18 | ALC268_TEST, | ||
| 19 | #endif | ||
| 20 | ALC268_MODEL_LAST /* last tag */ | ||
| 21 | }; | ||
| 22 | |||
| 23 | /* | ||
| 24 | * ALC268 channel source setting (2 channel) | ||
| 25 | */ | ||
| 26 | #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID | ||
| 27 | #define alc268_modes alc260_modes | ||
| 28 | |||
| 29 | static const hda_nid_t alc268_dac_nids[2] = { | ||
| 30 | /* front, hp */ | ||
| 31 | 0x02, 0x03 | ||
| 32 | }; | ||
| 33 | |||
| 34 | static const hda_nid_t alc268_adc_nids[2] = { | ||
| 35 | /* ADC0-1 */ | ||
| 36 | 0x08, 0x07 | ||
| 37 | }; | ||
| 38 | |||
| 39 | static const hda_nid_t alc268_adc_nids_alt[1] = { | ||
| 40 | /* ADC0 */ | ||
| 41 | 0x08 | ||
| 42 | }; | ||
| 43 | |||
| 44 | static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; | ||
| 45 | |||
| 46 | static const struct snd_kcontrol_new alc268_base_mixer[] = { | ||
| 47 | /* output mixer control */ | ||
| 48 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
| 49 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 50 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
| 51 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 52 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 53 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 54 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), | ||
| 55 | { } | ||
| 56 | }; | ||
| 57 | |||
| 58 | static const struct snd_kcontrol_new alc268_toshiba_mixer[] = { | ||
| 59 | /* output mixer control */ | ||
| 60 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
| 61 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
| 62 | ALC262_HIPPO_MASTER_SWITCH, | ||
| 63 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 64 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 65 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), | ||
| 66 | { } | ||
| 67 | }; | ||
| 68 | |||
| 69 | static const struct hda_verb alc268_eapd_verbs[] = { | ||
| 70 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 71 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 72 | { } | ||
| 73 | }; | ||
| 74 | |||
| 75 | /* Toshiba specific */ | ||
| 76 | static const struct hda_verb alc268_toshiba_verbs[] = { | ||
| 77 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 78 | { } /* end */ | ||
| 79 | }; | ||
| 80 | |||
| 81 | /* Acer specific */ | ||
| 82 | /* bind volumes of both NID 0x02 and 0x03 */ | ||
| 83 | static const struct hda_bind_ctls alc268_acer_bind_master_vol = { | ||
| 84 | .ops = &snd_hda_bind_vol, | ||
| 85 | .values = { | ||
| 86 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
| 87 | HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), | ||
| 88 | 0 | ||
| 89 | }, | ||
| 90 | }; | ||
| 91 | |||
| 92 | static void alc268_acer_setup(struct hda_codec *codec) | ||
| 93 | { | ||
| 94 | struct alc_spec *spec = codec->spec; | ||
| 95 | |||
| 96 | spec->autocfg.hp_pins[0] = 0x14; | ||
| 97 | spec->autocfg.speaker_pins[0] = 0x15; | ||
| 98 | spec->automute = 1; | ||
| 99 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 100 | } | ||
| 101 | |||
| 102 | #define alc268_acer_master_sw_get alc262_hp_master_sw_get | ||
| 103 | #define alc268_acer_master_sw_put alc262_hp_master_sw_put | ||
| 104 | |||
| 105 | static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { | ||
| 106 | /* output mixer control */ | ||
| 107 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
| 108 | { | ||
| 109 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 110 | .name = "Master Playback Switch", | ||
| 111 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x15, | ||
| 112 | .info = snd_ctl_boolean_mono_info, | ||
| 113 | .get = alc268_acer_master_sw_get, | ||
| 114 | .put = alc268_acer_master_sw_put, | ||
| 115 | }, | ||
| 116 | HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), | ||
| 117 | { } | ||
| 118 | }; | ||
| 119 | |||
| 120 | static const struct snd_kcontrol_new alc268_acer_mixer[] = { | ||
| 121 | /* output mixer control */ | ||
| 122 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
| 123 | { | ||
| 124 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 125 | .name = "Master Playback Switch", | ||
| 126 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, | ||
| 127 | .info = snd_ctl_boolean_mono_info, | ||
| 128 | .get = alc268_acer_master_sw_get, | ||
| 129 | .put = alc268_acer_master_sw_put, | ||
| 130 | }, | ||
| 131 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 132 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 133 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), | ||
| 134 | { } | ||
| 135 | }; | ||
| 136 | |||
| 137 | static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { | ||
| 138 | /* output mixer control */ | ||
| 139 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
| 140 | { | ||
| 141 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 142 | .name = "Master Playback Switch", | ||
| 143 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, | ||
| 144 | .info = snd_ctl_boolean_mono_info, | ||
| 145 | .get = alc268_acer_master_sw_get, | ||
| 146 | .put = alc268_acer_master_sw_put, | ||
| 147 | }, | ||
| 148 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 149 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), | ||
| 150 | { } | ||
| 151 | }; | ||
| 152 | |||
| 153 | static const struct hda_verb alc268_acer_aspire_one_verbs[] = { | ||
| 154 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 155 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 156 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 157 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 158 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, | ||
| 159 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, | ||
| 160 | { } | ||
| 161 | }; | ||
| 162 | |||
| 163 | static const struct hda_verb alc268_acer_verbs[] = { | ||
| 164 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ | ||
| 165 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 166 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 167 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 168 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 169 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 170 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 171 | { } | ||
| 172 | }; | ||
| 173 | |||
| 174 | /* unsolicited event for HP jack sensing */ | ||
| 175 | #define alc268_toshiba_setup alc262_hippo_setup | ||
| 176 | |||
| 177 | static void alc268_acer_lc_setup(struct hda_codec *codec) | ||
| 178 | { | ||
| 179 | struct alc_spec *spec = codec->spec; | ||
| 180 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 181 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 182 | spec->automute = 1; | ||
| 183 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 184 | spec->ext_mic_pin = 0x18; | ||
| 185 | spec->int_mic_pin = 0x12; | ||
| 186 | spec->auto_mic = 1; | ||
| 187 | } | ||
| 188 | |||
| 189 | static const struct snd_kcontrol_new alc268_dell_mixer[] = { | ||
| 190 | /* output mixer control */ | ||
| 191 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 192 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 193 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 194 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 195 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 196 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 197 | { } | ||
| 198 | }; | ||
| 199 | |||
| 200 | static const struct hda_verb alc268_dell_verbs[] = { | ||
| 201 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 202 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 203 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 204 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, | ||
| 205 | { } | ||
| 206 | }; | ||
| 207 | |||
| 208 | /* mute/unmute internal speaker according to the hp jack and mute state */ | ||
| 209 | static void alc268_dell_setup(struct hda_codec *codec) | ||
| 210 | { | ||
| 211 | struct alc_spec *spec = codec->spec; | ||
| 212 | |||
| 213 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 214 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 215 | spec->ext_mic_pin = 0x18; | ||
| 216 | spec->int_mic_pin = 0x19; | ||
| 217 | spec->auto_mic = 1; | ||
| 218 | spec->automute = 1; | ||
| 219 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 220 | } | ||
| 221 | |||
| 222 | static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { | ||
| 223 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
| 224 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 225 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
| 226 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 227 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
| 228 | HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), | ||
| 229 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 230 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 231 | { } | ||
| 232 | }; | ||
| 233 | |||
| 234 | static const struct hda_verb alc267_quanta_il1_verbs[] = { | ||
| 235 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 236 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, | ||
| 237 | { } | ||
| 238 | }; | ||
| 239 | |||
| 240 | static void alc267_quanta_il1_setup(struct hda_codec *codec) | ||
| 241 | { | ||
| 242 | struct alc_spec *spec = codec->spec; | ||
| 243 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 244 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 245 | spec->ext_mic_pin = 0x18; | ||
| 246 | spec->int_mic_pin = 0x19; | ||
| 247 | spec->auto_mic = 1; | ||
| 248 | spec->automute = 1; | ||
| 249 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 250 | } | ||
| 251 | |||
| 252 | /* | ||
| 253 | * generic initialization of ADC, input mixers and output mixers | ||
| 254 | */ | ||
| 255 | static const struct hda_verb alc268_base_init_verbs[] = { | ||
| 256 | /* Unmute DAC0-1 and set vol = 0 */ | ||
| 257 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 258 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 259 | |||
| 260 | /* | ||
| 261 | * Set up output mixers (0x0c - 0x0e) | ||
| 262 | */ | ||
| 263 | /* set vol=0 to output mixers */ | ||
| 264 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 265 | {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 266 | |||
| 267 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 268 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 269 | |||
| 270 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
| 271 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | ||
| 272 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | ||
| 273 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 274 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 275 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 276 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 277 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 278 | |||
| 279 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 280 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 281 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 282 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 283 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 284 | |||
| 285 | /* set PCBEEP vol = 0, mute connections */ | ||
| 286 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 287 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 288 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 289 | |||
| 290 | /* Unmute Selector 23h,24h and set the default input to mic-in */ | ||
| 291 | |||
| 292 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 293 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 294 | {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 295 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 296 | |||
| 297 | { } | ||
| 298 | }; | ||
| 299 | |||
| 300 | /* only for model=test */ | ||
| 301 | #ifdef CONFIG_SND_DEBUG | ||
| 302 | /* | ||
| 303 | * generic initialization of ADC, input mixers and output mixers | ||
| 304 | */ | ||
| 305 | static const struct hda_verb alc268_volume_init_verbs[] = { | ||
| 306 | /* set output DAC */ | ||
| 307 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 308 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 309 | |||
| 310 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 311 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | ||
| 312 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 313 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 314 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, | ||
| 315 | |||
| 316 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 317 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 318 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 319 | |||
| 320 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 321 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 322 | { } | ||
| 323 | }; | ||
| 324 | #endif /* CONFIG_SND_DEBUG */ | ||
| 325 | |||
| 326 | static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { | ||
| 327 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
| 328 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | ||
| 329 | { } /* end */ | ||
| 330 | }; | ||
| 331 | |||
| 332 | static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = { | ||
| 333 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
| 334 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | ||
| 335 | _DEFINE_CAPSRC(1), | ||
| 336 | { } /* end */ | ||
| 337 | }; | ||
| 338 | |||
| 339 | static const struct snd_kcontrol_new alc268_capture_mixer[] = { | ||
| 340 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
| 341 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | ||
| 342 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), | ||
| 343 | HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT), | ||
| 344 | _DEFINE_CAPSRC(2), | ||
| 345 | { } /* end */ | ||
| 346 | }; | ||
| 347 | |||
| 348 | static const struct hda_input_mux alc268_capture_source = { | ||
| 349 | .num_items = 4, | ||
| 350 | .items = { | ||
| 351 | { "Mic", 0x0 }, | ||
| 352 | { "Front Mic", 0x1 }, | ||
| 353 | { "Line", 0x2 }, | ||
| 354 | { "CD", 0x3 }, | ||
| 355 | }, | ||
| 356 | }; | ||
| 357 | |||
| 358 | static const struct hda_input_mux alc268_acer_capture_source = { | ||
| 359 | .num_items = 3, | ||
| 360 | .items = { | ||
| 361 | { "Mic", 0x0 }, | ||
| 362 | { "Internal Mic", 0x1 }, | ||
| 363 | { "Line", 0x2 }, | ||
| 364 | }, | ||
| 365 | }; | ||
| 366 | |||
| 367 | static const struct hda_input_mux alc268_acer_dmic_capture_source = { | ||
| 368 | .num_items = 3, | ||
| 369 | .items = { | ||
| 370 | { "Mic", 0x0 }, | ||
| 371 | { "Internal Mic", 0x6 }, | ||
| 372 | { "Line", 0x2 }, | ||
| 373 | }, | ||
| 374 | }; | ||
| 375 | |||
| 376 | #ifdef CONFIG_SND_DEBUG | ||
| 377 | static const struct snd_kcontrol_new alc268_test_mixer[] = { | ||
| 378 | /* Volume widgets */ | ||
| 379 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 380 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 381 | HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
| 382 | HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT), | ||
| 383 | HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT), | ||
| 384 | HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT), | ||
| 385 | HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT), | ||
| 386 | HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT), | ||
| 387 | HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT), | ||
| 388 | HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT), | ||
| 389 | HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT), | ||
| 390 | HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT), | ||
| 391 | HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT), | ||
| 392 | /* The below appears problematic on some hardwares */ | ||
| 393 | /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/ | ||
| 394 | HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT), | ||
| 395 | HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT), | ||
| 396 | HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT), | ||
| 397 | HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT), | ||
| 398 | |||
| 399 | /* Modes for retasking pin widgets */ | ||
| 400 | ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT), | ||
| 401 | ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT), | ||
| 402 | ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT), | ||
| 403 | ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT), | ||
| 404 | |||
| 405 | /* Controls for GPIO pins, assuming they are configured as outputs */ | ||
| 406 | ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), | ||
| 407 | ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), | ||
| 408 | ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), | ||
| 409 | ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), | ||
| 410 | |||
| 411 | /* Switches to allow the digital SPDIF output pin to be enabled. | ||
| 412 | * The ALC268 does not have an SPDIF input. | ||
| 413 | */ | ||
| 414 | ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01), | ||
| 415 | |||
| 416 | /* A switch allowing EAPD to be enabled. Some laptops seem to use | ||
| 417 | * this output to turn on an external amplifier. | ||
| 418 | */ | ||
| 419 | ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02), | ||
| 420 | ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02), | ||
| 421 | |||
| 422 | { } /* end */ | ||
| 423 | }; | ||
| 424 | #endif | ||
| 425 | |||
| 426 | /* | ||
| 427 | * configuration and preset | ||
| 428 | */ | ||
| 429 | static const char * const alc268_models[ALC268_MODEL_LAST] = { | ||
| 430 | [ALC267_QUANTA_IL1] = "quanta-il1", | ||
| 431 | [ALC268_3ST] = "3stack", | ||
| 432 | [ALC268_TOSHIBA] = "toshiba", | ||
| 433 | [ALC268_ACER] = "acer", | ||
| 434 | [ALC268_ACER_DMIC] = "acer-dmic", | ||
| 435 | [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", | ||
| 436 | [ALC268_DELL] = "dell", | ||
| 437 | [ALC268_ZEPTO] = "zepto", | ||
| 438 | #ifdef CONFIG_SND_DEBUG | ||
| 439 | [ALC268_TEST] = "test", | ||
| 440 | #endif | ||
| 441 | [ALC268_AUTO] = "auto", | ||
| 442 | }; | ||
| 443 | |||
| 444 | static const struct snd_pci_quirk alc268_cfg_tbl[] = { | ||
| 445 | SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), | ||
| 446 | SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), | ||
| 447 | SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), | ||
| 448 | SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), | ||
| 449 | SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), | ||
| 450 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", | ||
| 451 | ALC268_ACER_ASPIRE_ONE), | ||
| 452 | SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), | ||
| 453 | SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO), | ||
| 454 | SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, | ||
| 455 | "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), | ||
| 456 | /* almost compatible with toshiba but with optional digital outs; | ||
| 457 | * auto-probing seems working fine | ||
| 458 | */ | ||
| 459 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series", | ||
| 460 | ALC268_AUTO), | ||
| 461 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), | ||
| 462 | SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO), | ||
| 463 | SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), | ||
| 464 | SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), | ||
| 465 | {} | ||
| 466 | }; | ||
| 467 | |||
| 468 | /* Toshiba laptops have no unique PCI SSID but only codec SSID */ | ||
| 469 | static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { | ||
| 470 | SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), | ||
| 471 | SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), | ||
| 472 | SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", | ||
| 473 | ALC268_TOSHIBA), | ||
| 474 | {} | ||
| 475 | }; | ||
| 476 | |||
| 477 | static const struct alc_config_preset alc268_presets[] = { | ||
| 478 | [ALC267_QUANTA_IL1] = { | ||
| 479 | .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer }, | ||
| 480 | .cap_mixer = alc268_capture_nosrc_mixer, | ||
| 481 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 482 | alc267_quanta_il1_verbs }, | ||
| 483 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 484 | .dac_nids = alc268_dac_nids, | ||
| 485 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 486 | .adc_nids = alc268_adc_nids_alt, | ||
| 487 | .hp_nid = 0x03, | ||
| 488 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 489 | .channel_mode = alc268_modes, | ||
| 490 | .unsol_event = alc_sku_unsol_event, | ||
| 491 | .setup = alc267_quanta_il1_setup, | ||
| 492 | .init_hook = alc_inithook, | ||
| 493 | }, | ||
| 494 | [ALC268_3ST] = { | ||
| 495 | .mixers = { alc268_base_mixer, alc268_beep_mixer }, | ||
| 496 | .cap_mixer = alc268_capture_alt_mixer, | ||
| 497 | .init_verbs = { alc268_base_init_verbs }, | ||
| 498 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 499 | .dac_nids = alc268_dac_nids, | ||
| 500 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 501 | .adc_nids = alc268_adc_nids_alt, | ||
| 502 | .capsrc_nids = alc268_capsrc_nids, | ||
| 503 | .hp_nid = 0x03, | ||
| 504 | .dig_out_nid = ALC268_DIGOUT_NID, | ||
| 505 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 506 | .channel_mode = alc268_modes, | ||
| 507 | .input_mux = &alc268_capture_source, | ||
| 508 | }, | ||
| 509 | [ALC268_TOSHIBA] = { | ||
| 510 | .mixers = { alc268_toshiba_mixer, alc268_beep_mixer }, | ||
| 511 | .cap_mixer = alc268_capture_alt_mixer, | ||
| 512 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 513 | alc268_toshiba_verbs }, | ||
| 514 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 515 | .dac_nids = alc268_dac_nids, | ||
| 516 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 517 | .adc_nids = alc268_adc_nids_alt, | ||
| 518 | .capsrc_nids = alc268_capsrc_nids, | ||
| 519 | .hp_nid = 0x03, | ||
| 520 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 521 | .channel_mode = alc268_modes, | ||
| 522 | .input_mux = &alc268_capture_source, | ||
| 523 | .unsol_event = alc_sku_unsol_event, | ||
| 524 | .setup = alc268_toshiba_setup, | ||
| 525 | .init_hook = alc_inithook, | ||
| 526 | }, | ||
| 527 | [ALC268_ACER] = { | ||
| 528 | .mixers = { alc268_acer_mixer, alc268_beep_mixer }, | ||
| 529 | .cap_mixer = alc268_capture_alt_mixer, | ||
| 530 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 531 | alc268_acer_verbs }, | ||
| 532 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 533 | .dac_nids = alc268_dac_nids, | ||
| 534 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 535 | .adc_nids = alc268_adc_nids_alt, | ||
| 536 | .capsrc_nids = alc268_capsrc_nids, | ||
| 537 | .hp_nid = 0x02, | ||
| 538 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 539 | .channel_mode = alc268_modes, | ||
| 540 | .input_mux = &alc268_acer_capture_source, | ||
| 541 | .unsol_event = alc_sku_unsol_event, | ||
| 542 | .setup = alc268_acer_setup, | ||
| 543 | .init_hook = alc_inithook, | ||
| 544 | }, | ||
| 545 | [ALC268_ACER_DMIC] = { | ||
| 546 | .mixers = { alc268_acer_dmic_mixer, alc268_beep_mixer }, | ||
| 547 | .cap_mixer = alc268_capture_alt_mixer, | ||
| 548 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 549 | alc268_acer_verbs }, | ||
| 550 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 551 | .dac_nids = alc268_dac_nids, | ||
| 552 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 553 | .adc_nids = alc268_adc_nids_alt, | ||
| 554 | .capsrc_nids = alc268_capsrc_nids, | ||
| 555 | .hp_nid = 0x02, | ||
| 556 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 557 | .channel_mode = alc268_modes, | ||
| 558 | .input_mux = &alc268_acer_dmic_capture_source, | ||
| 559 | .unsol_event = alc_sku_unsol_event, | ||
| 560 | .setup = alc268_acer_setup, | ||
| 561 | .init_hook = alc_inithook, | ||
| 562 | }, | ||
| 563 | [ALC268_ACER_ASPIRE_ONE] = { | ||
| 564 | .mixers = { alc268_acer_aspire_one_mixer, alc268_beep_mixer}, | ||
| 565 | .cap_mixer = alc268_capture_nosrc_mixer, | ||
| 566 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 567 | alc268_acer_aspire_one_verbs }, | ||
| 568 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 569 | .dac_nids = alc268_dac_nids, | ||
| 570 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 571 | .adc_nids = alc268_adc_nids_alt, | ||
| 572 | .capsrc_nids = alc268_capsrc_nids, | ||
| 573 | .hp_nid = 0x03, | ||
| 574 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 575 | .channel_mode = alc268_modes, | ||
| 576 | .unsol_event = alc_sku_unsol_event, | ||
| 577 | .setup = alc268_acer_lc_setup, | ||
| 578 | .init_hook = alc_inithook, | ||
| 579 | }, | ||
| 580 | [ALC268_DELL] = { | ||
| 581 | .mixers = { alc268_dell_mixer, alc268_beep_mixer}, | ||
| 582 | .cap_mixer = alc268_capture_nosrc_mixer, | ||
| 583 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 584 | alc268_dell_verbs }, | ||
| 585 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 586 | .dac_nids = alc268_dac_nids, | ||
| 587 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 588 | .adc_nids = alc268_adc_nids_alt, | ||
| 589 | .capsrc_nids = alc268_capsrc_nids, | ||
| 590 | .hp_nid = 0x02, | ||
| 591 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 592 | .channel_mode = alc268_modes, | ||
| 593 | .unsol_event = alc_sku_unsol_event, | ||
| 594 | .setup = alc268_dell_setup, | ||
| 595 | .init_hook = alc_inithook, | ||
| 596 | }, | ||
| 597 | [ALC268_ZEPTO] = { | ||
| 598 | .mixers = { alc268_base_mixer, alc268_beep_mixer }, | ||
| 599 | .cap_mixer = alc268_capture_alt_mixer, | ||
| 600 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 601 | alc268_toshiba_verbs }, | ||
| 602 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 603 | .dac_nids = alc268_dac_nids, | ||
| 604 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 605 | .adc_nids = alc268_adc_nids_alt, | ||
| 606 | .capsrc_nids = alc268_capsrc_nids, | ||
| 607 | .hp_nid = 0x03, | ||
| 608 | .dig_out_nid = ALC268_DIGOUT_NID, | ||
| 609 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 610 | .channel_mode = alc268_modes, | ||
| 611 | .input_mux = &alc268_capture_source, | ||
| 612 | .unsol_event = alc_sku_unsol_event, | ||
| 613 | .setup = alc268_toshiba_setup, | ||
| 614 | .init_hook = alc_inithook, | ||
| 615 | }, | ||
| 616 | #ifdef CONFIG_SND_DEBUG | ||
| 617 | [ALC268_TEST] = { | ||
| 618 | .mixers = { alc268_test_mixer }, | ||
| 619 | .cap_mixer = alc268_capture_mixer, | ||
| 620 | .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, | ||
| 621 | alc268_volume_init_verbs, | ||
| 622 | alc268_beep_init_verbs }, | ||
| 623 | .num_dacs = ARRAY_SIZE(alc268_dac_nids), | ||
| 624 | .dac_nids = alc268_dac_nids, | ||
| 625 | .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), | ||
| 626 | .adc_nids = alc268_adc_nids_alt, | ||
| 627 | .capsrc_nids = alc268_capsrc_nids, | ||
| 628 | .hp_nid = 0x03, | ||
| 629 | .dig_out_nid = ALC268_DIGOUT_NID, | ||
| 630 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | ||
| 631 | .channel_mode = alc268_modes, | ||
| 632 | .input_mux = &alc268_capture_source, | ||
| 633 | }, | ||
| 634 | #endif | ||
| 635 | }; | ||
| 636 | |||
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c deleted file mode 100644 index 5ac0e2162a46..000000000000 --- a/sound/pci/hda/alc269_quirks.c +++ /dev/null | |||
| @@ -1,674 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ALC269/ALC270/ALC275/ALC276 quirk models | ||
| 3 | * included by patch_realtek.c | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* ALC269 models */ | ||
| 7 | enum { | ||
| 8 | ALC269_AUTO, | ||
| 9 | ALC269_BASIC, | ||
| 10 | ALC269_QUANTA_FL1, | ||
| 11 | ALC269_AMIC, | ||
| 12 | ALC269_DMIC, | ||
| 13 | ALC269VB_AMIC, | ||
| 14 | ALC269VB_DMIC, | ||
| 15 | ALC269_FUJITSU, | ||
| 16 | ALC269_LIFEBOOK, | ||
| 17 | ALC271_ACER, | ||
| 18 | ALC269_MODEL_LAST /* last tag */ | ||
| 19 | }; | ||
| 20 | |||
| 21 | /* | ||
| 22 | * ALC269 channel source setting (2 channel) | ||
| 23 | */ | ||
| 24 | #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID | ||
| 25 | |||
| 26 | #define alc269_dac_nids alc260_dac_nids | ||
| 27 | |||
| 28 | static const hda_nid_t alc269_adc_nids[1] = { | ||
| 29 | /* ADC1 */ | ||
| 30 | 0x08, | ||
| 31 | }; | ||
| 32 | |||
| 33 | static const hda_nid_t alc269_capsrc_nids[1] = { | ||
| 34 | 0x23, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static const hda_nid_t alc269vb_adc_nids[1] = { | ||
| 38 | /* ADC1 */ | ||
| 39 | 0x09, | ||
| 40 | }; | ||
| 41 | |||
| 42 | static const hda_nid_t alc269vb_capsrc_nids[1] = { | ||
| 43 | 0x22, | ||
| 44 | }; | ||
| 45 | |||
| 46 | #define alc269_modes alc260_modes | ||
| 47 | #define alc269_capture_source alc880_lg_lw_capture_source | ||
| 48 | |||
| 49 | static const struct snd_kcontrol_new alc269_base_mixer[] = { | ||
| 50 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 51 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 52 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 53 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 54 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 55 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 56 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 57 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
| 58 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
| 59 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 60 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 61 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
| 62 | { } /* end */ | ||
| 63 | }; | ||
| 64 | |||
| 65 | static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { | ||
| 66 | /* output mixer control */ | ||
| 67 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
| 68 | { | ||
| 69 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 70 | .name = "Master Playback Switch", | ||
| 71 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
| 72 | .info = snd_hda_mixer_amp_switch_info, | ||
| 73 | .get = snd_hda_mixer_amp_switch_get, | ||
| 74 | .put = alc268_acer_master_sw_put, | ||
| 75 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 76 | }, | ||
| 77 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 78 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 79 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 80 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
| 81 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
| 82 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 83 | { } | ||
| 84 | }; | ||
| 85 | |||
| 86 | static const struct snd_kcontrol_new alc269_lifebook_mixer[] = { | ||
| 87 | /* output mixer control */ | ||
| 88 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
| 89 | { | ||
| 90 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 91 | .name = "Master Playback Switch", | ||
| 92 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
| 93 | .info = snd_hda_mixer_amp_switch_info, | ||
| 94 | .get = snd_hda_mixer_amp_switch_get, | ||
| 95 | .put = alc268_acer_master_sw_put, | ||
| 96 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 97 | }, | ||
| 98 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 99 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 100 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 101 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
| 102 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
| 103 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 104 | HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), | ||
| 105 | HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), | ||
| 106 | HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT), | ||
| 107 | { } | ||
| 108 | }; | ||
| 109 | |||
| 110 | static const struct snd_kcontrol_new alc269_laptop_mixer[] = { | ||
| 111 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 112 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 113 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 114 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 115 | { } /* end */ | ||
| 116 | }; | ||
| 117 | |||
| 118 | static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = { | ||
| 119 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 120 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 121 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 122 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 123 | { } /* end */ | ||
| 124 | }; | ||
| 125 | |||
| 126 | static const struct snd_kcontrol_new alc269_asus_mixer[] = { | ||
| 127 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 128 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), | ||
| 129 | { } /* end */ | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* capture mixer elements */ | ||
| 133 | static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { | ||
| 134 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
| 135 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
| 136 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 137 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 138 | { } /* end */ | ||
| 139 | }; | ||
| 140 | |||
| 141 | static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { | ||
| 142 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
| 143 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
| 144 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 145 | { } /* end */ | ||
| 146 | }; | ||
| 147 | |||
| 148 | static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { | ||
| 149 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
| 150 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
| 151 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 152 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 153 | { } /* end */ | ||
| 154 | }; | ||
| 155 | |||
| 156 | static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { | ||
| 157 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
| 158 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
| 159 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 160 | { } /* end */ | ||
| 161 | }; | ||
| 162 | |||
| 163 | /* FSC amilo */ | ||
| 164 | #define alc269_fujitsu_mixer alc269_laptop_mixer | ||
| 165 | |||
| 166 | static const struct hda_verb alc269_quanta_fl1_verbs[] = { | ||
| 167 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 168 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 169 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 170 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 171 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 172 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 173 | { } | ||
| 174 | }; | ||
| 175 | |||
| 176 | static const struct hda_verb alc269_lifebook_verbs[] = { | ||
| 177 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 178 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 179 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 180 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 181 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 182 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 183 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 184 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 185 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 186 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 187 | { } | ||
| 188 | }; | ||
| 189 | |||
| 190 | /* toggle speaker-output according to the hp-jack state */ | ||
| 191 | static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | ||
| 192 | { | ||
| 193 | alc_hp_automute(codec); | ||
| 194 | |||
| 195 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 196 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
| 197 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 198 | AC_VERB_SET_PROC_COEF, 0x680); | ||
| 199 | |||
| 200 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 201 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
| 202 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 203 | AC_VERB_SET_PROC_COEF, 0x480); | ||
| 204 | } | ||
| 205 | |||
| 206 | #define alc269_lifebook_speaker_automute \ | ||
| 207 | alc269_quanta_fl1_speaker_automute | ||
| 208 | |||
| 209 | static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) | ||
| 210 | { | ||
| 211 | unsigned int present_laptop; | ||
| 212 | unsigned int present_dock; | ||
| 213 | |||
| 214 | present_laptop = snd_hda_jack_detect(codec, 0x18); | ||
| 215 | present_dock = snd_hda_jack_detect(codec, 0x1b); | ||
| 216 | |||
| 217 | /* Laptop mic port overrides dock mic port, design decision */ | ||
| 218 | if (present_dock) | ||
| 219 | snd_hda_codec_write(codec, 0x23, 0, | ||
| 220 | AC_VERB_SET_CONNECT_SEL, 0x3); | ||
| 221 | if (present_laptop) | ||
| 222 | snd_hda_codec_write(codec, 0x23, 0, | ||
| 223 | AC_VERB_SET_CONNECT_SEL, 0x0); | ||
| 224 | if (!present_dock && !present_laptop) | ||
| 225 | snd_hda_codec_write(codec, 0x23, 0, | ||
| 226 | AC_VERB_SET_CONNECT_SEL, 0x1); | ||
| 227 | } | ||
| 228 | |||
| 229 | static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, | ||
| 230 | unsigned int res) | ||
| 231 | { | ||
| 232 | switch (res >> 26) { | ||
| 233 | case ALC_HP_EVENT: | ||
| 234 | alc269_quanta_fl1_speaker_automute(codec); | ||
| 235 | break; | ||
| 236 | case ALC_MIC_EVENT: | ||
| 237 | alc_mic_automute(codec); | ||
| 238 | break; | ||
| 239 | } | ||
| 240 | } | ||
| 241 | |||
| 242 | static void alc269_lifebook_unsol_event(struct hda_codec *codec, | ||
| 243 | unsigned int res) | ||
| 244 | { | ||
| 245 | if ((res >> 26) == ALC_HP_EVENT) | ||
| 246 | alc269_lifebook_speaker_automute(codec); | ||
| 247 | if ((res >> 26) == ALC_MIC_EVENT) | ||
| 248 | alc269_lifebook_mic_autoswitch(codec); | ||
| 249 | } | ||
| 250 | |||
| 251 | static void alc269_quanta_fl1_setup(struct hda_codec *codec) | ||
| 252 | { | ||
| 253 | struct alc_spec *spec = codec->spec; | ||
| 254 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 255 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 256 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 257 | spec->automute = 1; | ||
| 258 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 259 | spec->ext_mic_pin = 0x18; | ||
| 260 | spec->int_mic_pin = 0x19; | ||
| 261 | spec->auto_mic = 1; | ||
| 262 | } | ||
| 263 | |||
| 264 | static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) | ||
| 265 | { | ||
| 266 | alc269_quanta_fl1_speaker_automute(codec); | ||
| 267 | alc_mic_automute(codec); | ||
| 268 | } | ||
| 269 | |||
| 270 | static void alc269_lifebook_setup(struct hda_codec *codec) | ||
| 271 | { | ||
| 272 | struct alc_spec *spec = codec->spec; | ||
| 273 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 274 | spec->autocfg.hp_pins[1] = 0x1a; | ||
| 275 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 276 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 277 | spec->automute = 1; | ||
| 278 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 279 | } | ||
| 280 | |||
| 281 | static void alc269_lifebook_init_hook(struct hda_codec *codec) | ||
| 282 | { | ||
| 283 | alc269_lifebook_speaker_automute(codec); | ||
| 284 | alc269_lifebook_mic_autoswitch(codec); | ||
| 285 | } | ||
| 286 | |||
| 287 | static const struct hda_verb alc269_laptop_dmic_init_verbs[] = { | ||
| 288 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 289 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, | ||
| 290 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
| 291 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
| 292 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 293 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 294 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 295 | {} | ||
| 296 | }; | ||
| 297 | |||
| 298 | static const struct hda_verb alc269_laptop_amic_init_verbs[] = { | ||
| 299 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 300 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 301 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
| 302 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, | ||
| 303 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 304 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 305 | {} | ||
| 306 | }; | ||
| 307 | |||
| 308 | static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { | ||
| 309 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 310 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, | ||
| 311 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
| 312 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
| 313 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 314 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 315 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 316 | {} | ||
| 317 | }; | ||
| 318 | |||
| 319 | static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = { | ||
| 320 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 321 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 322 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
| 323 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
| 324 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 325 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 326 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 327 | {} | ||
| 328 | }; | ||
| 329 | |||
| 330 | static const struct hda_verb alc271_acer_dmic_verbs[] = { | ||
| 331 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | ||
| 332 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | ||
| 333 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 334 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 335 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 336 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 337 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 338 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 339 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 340 | {0x22, AC_VERB_SET_CONNECT_SEL, 6}, | ||
| 341 | { } | ||
| 342 | }; | ||
| 343 | |||
| 344 | static void alc269_laptop_amic_setup(struct hda_codec *codec) | ||
| 345 | { | ||
| 346 | struct alc_spec *spec = codec->spec; | ||
| 347 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 348 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 349 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 350 | spec->automute = 1; | ||
| 351 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 352 | spec->ext_mic_pin = 0x18; | ||
| 353 | spec->int_mic_pin = 0x19; | ||
| 354 | spec->auto_mic = 1; | ||
| 355 | } | ||
| 356 | |||
| 357 | static void alc269_laptop_dmic_setup(struct hda_codec *codec) | ||
| 358 | { | ||
| 359 | struct alc_spec *spec = codec->spec; | ||
| 360 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 361 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 362 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 363 | spec->automute = 1; | ||
| 364 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 365 | spec->ext_mic_pin = 0x18; | ||
| 366 | spec->int_mic_pin = 0x12; | ||
| 367 | spec->auto_mic = 1; | ||
| 368 | } | ||
| 369 | |||
| 370 | static void alc269vb_laptop_amic_setup(struct hda_codec *codec) | ||
| 371 | { | ||
| 372 | struct alc_spec *spec = codec->spec; | ||
| 373 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 374 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 375 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 376 | spec->automute = 1; | ||
| 377 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 378 | spec->ext_mic_pin = 0x18; | ||
| 379 | spec->int_mic_pin = 0x19; | ||
| 380 | spec->auto_mic = 1; | ||
| 381 | } | ||
| 382 | |||
| 383 | static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | ||
| 384 | { | ||
| 385 | struct alc_spec *spec = codec->spec; | ||
| 386 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 387 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 388 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 389 | spec->automute = 1; | ||
| 390 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 391 | spec->ext_mic_pin = 0x18; | ||
| 392 | spec->int_mic_pin = 0x12; | ||
| 393 | spec->auto_mic = 1; | ||
| 394 | } | ||
| 395 | |||
| 396 | /* | ||
| 397 | * generic initialization of ADC, input mixers and output mixers | ||
| 398 | */ | ||
| 399 | static const struct hda_verb alc269_init_verbs[] = { | ||
| 400 | /* | ||
| 401 | * Unmute ADC0 and set the default input to mic-in | ||
| 402 | */ | ||
| 403 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 404 | |||
| 405 | /* | ||
| 406 | * Set up output mixers (0x02 - 0x03) | ||
| 407 | */ | ||
| 408 | /* set vol=0 to output mixers */ | ||
| 409 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 410 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 411 | |||
| 412 | /* set up input amps for analog loopback */ | ||
| 413 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
| 414 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 415 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 416 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 417 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 418 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 419 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 420 | |||
| 421 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 422 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 423 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 424 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 425 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 426 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 427 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 428 | |||
| 429 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 430 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 431 | |||
| 432 | /* FIXME: use Mux-type input source selection */ | ||
| 433 | /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ | ||
| 434 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
| 435 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 436 | |||
| 437 | /* set EAPD */ | ||
| 438 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 439 | { } | ||
| 440 | }; | ||
| 441 | |||
| 442 | static const struct hda_verb alc269vb_init_verbs[] = { | ||
| 443 | /* | ||
| 444 | * Unmute ADC0 and set the default input to mic-in | ||
| 445 | */ | ||
| 446 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 447 | |||
| 448 | /* | ||
| 449 | * Set up output mixers (0x02 - 0x03) | ||
| 450 | */ | ||
| 451 | /* set vol=0 to output mixers */ | ||
| 452 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 453 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 454 | |||
| 455 | /* set up input amps for analog loopback */ | ||
| 456 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
| 457 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 458 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 459 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 460 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 461 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 462 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 463 | |||
| 464 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 465 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 466 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 467 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 468 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 469 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 470 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 471 | |||
| 472 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 473 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 474 | |||
| 475 | /* FIXME: use Mux-type input source selection */ | ||
| 476 | /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ | ||
| 477 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
| 478 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 479 | |||
| 480 | /* set EAPD */ | ||
| 481 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 482 | { } | ||
| 483 | }; | ||
| 484 | |||
| 485 | /* | ||
| 486 | * configuration and preset | ||
| 487 | */ | ||
| 488 | static const char * const alc269_models[ALC269_MODEL_LAST] = { | ||
| 489 | [ALC269_BASIC] = "basic", | ||
| 490 | [ALC269_QUANTA_FL1] = "quanta", | ||
| 491 | [ALC269_AMIC] = "laptop-amic", | ||
| 492 | [ALC269_DMIC] = "laptop-dmic", | ||
| 493 | [ALC269_FUJITSU] = "fujitsu", | ||
| 494 | [ALC269_LIFEBOOK] = "lifebook", | ||
| 495 | [ALC269_AUTO] = "auto", | ||
| 496 | }; | ||
| 497 | |||
| 498 | static const struct snd_pci_quirk alc269_cfg_tbl[] = { | ||
| 499 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), | ||
| 500 | SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), | ||
| 501 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | ||
| 502 | ALC269_AMIC), | ||
| 503 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), | ||
| 504 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), | ||
| 505 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), | ||
| 506 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), | ||
| 507 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), | ||
| 508 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), | ||
| 509 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), | ||
| 510 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), | ||
| 511 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), | ||
| 512 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), | ||
| 513 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), | ||
| 514 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), | ||
| 515 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), | ||
| 516 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), | ||
| 517 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), | ||
| 518 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), | ||
| 519 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), | ||
| 520 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), | ||
| 521 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), | ||
| 522 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), | ||
| 523 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), | ||
| 524 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), | ||
| 525 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), | ||
| 526 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), | ||
| 527 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), | ||
| 528 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), | ||
| 529 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), | ||
| 530 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), | ||
| 531 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), | ||
| 532 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), | ||
| 533 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), | ||
| 534 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), | ||
| 535 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), | ||
| 536 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), | ||
| 537 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), | ||
| 538 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), | ||
| 539 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | ||
| 540 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), | ||
| 541 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | ||
| 542 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), | ||
| 543 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), | ||
| 544 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), | ||
| 545 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), | ||
| 546 | {} | ||
| 547 | }; | ||
| 548 | |||
| 549 | static const struct alc_config_preset alc269_presets[] = { | ||
| 550 | [ALC269_BASIC] = { | ||
| 551 | .mixers = { alc269_base_mixer }, | ||
| 552 | .init_verbs = { alc269_init_verbs }, | ||
| 553 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 554 | .dac_nids = alc269_dac_nids, | ||
| 555 | .hp_nid = 0x03, | ||
| 556 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 557 | .channel_mode = alc269_modes, | ||
| 558 | .input_mux = &alc269_capture_source, | ||
| 559 | }, | ||
| 560 | [ALC269_QUANTA_FL1] = { | ||
| 561 | .mixers = { alc269_quanta_fl1_mixer }, | ||
| 562 | .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, | ||
| 563 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 564 | .dac_nids = alc269_dac_nids, | ||
| 565 | .hp_nid = 0x03, | ||
| 566 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 567 | .channel_mode = alc269_modes, | ||
| 568 | .input_mux = &alc269_capture_source, | ||
| 569 | .unsol_event = alc269_quanta_fl1_unsol_event, | ||
| 570 | .setup = alc269_quanta_fl1_setup, | ||
| 571 | .init_hook = alc269_quanta_fl1_init_hook, | ||
| 572 | }, | ||
| 573 | [ALC269_AMIC] = { | ||
| 574 | .mixers = { alc269_laptop_mixer }, | ||
| 575 | .cap_mixer = alc269_laptop_analog_capture_mixer, | ||
| 576 | .init_verbs = { alc269_init_verbs, | ||
| 577 | alc269_laptop_amic_init_verbs }, | ||
| 578 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 579 | .dac_nids = alc269_dac_nids, | ||
| 580 | .hp_nid = 0x03, | ||
| 581 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 582 | .channel_mode = alc269_modes, | ||
| 583 | .unsol_event = alc_sku_unsol_event, | ||
| 584 | .setup = alc269_laptop_amic_setup, | ||
| 585 | .init_hook = alc_inithook, | ||
| 586 | }, | ||
| 587 | [ALC269_DMIC] = { | ||
| 588 | .mixers = { alc269_laptop_mixer }, | ||
| 589 | .cap_mixer = alc269_laptop_digital_capture_mixer, | ||
| 590 | .init_verbs = { alc269_init_verbs, | ||
| 591 | alc269_laptop_dmic_init_verbs }, | ||
| 592 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 593 | .dac_nids = alc269_dac_nids, | ||
| 594 | .hp_nid = 0x03, | ||
| 595 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 596 | .channel_mode = alc269_modes, | ||
| 597 | .unsol_event = alc_sku_unsol_event, | ||
| 598 | .setup = alc269_laptop_dmic_setup, | ||
| 599 | .init_hook = alc_inithook, | ||
| 600 | }, | ||
| 601 | [ALC269VB_AMIC] = { | ||
| 602 | .mixers = { alc269vb_laptop_mixer }, | ||
| 603 | .cap_mixer = alc269vb_laptop_analog_capture_mixer, | ||
| 604 | .init_verbs = { alc269vb_init_verbs, | ||
| 605 | alc269vb_laptop_amic_init_verbs }, | ||
| 606 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 607 | .dac_nids = alc269_dac_nids, | ||
| 608 | .hp_nid = 0x03, | ||
| 609 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 610 | .channel_mode = alc269_modes, | ||
| 611 | .unsol_event = alc_sku_unsol_event, | ||
| 612 | .setup = alc269vb_laptop_amic_setup, | ||
| 613 | .init_hook = alc_inithook, | ||
| 614 | }, | ||
| 615 | [ALC269VB_DMIC] = { | ||
| 616 | .mixers = { alc269vb_laptop_mixer }, | ||
| 617 | .cap_mixer = alc269vb_laptop_digital_capture_mixer, | ||
| 618 | .init_verbs = { alc269vb_init_verbs, | ||
| 619 | alc269vb_laptop_dmic_init_verbs }, | ||
| 620 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 621 | .dac_nids = alc269_dac_nids, | ||
| 622 | .hp_nid = 0x03, | ||
| 623 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 624 | .channel_mode = alc269_modes, | ||
| 625 | .unsol_event = alc_sku_unsol_event, | ||
| 626 | .setup = alc269vb_laptop_dmic_setup, | ||
| 627 | .init_hook = alc_inithook, | ||
| 628 | }, | ||
| 629 | [ALC269_FUJITSU] = { | ||
| 630 | .mixers = { alc269_fujitsu_mixer }, | ||
| 631 | .cap_mixer = alc269_laptop_digital_capture_mixer, | ||
| 632 | .init_verbs = { alc269_init_verbs, | ||
| 633 | alc269_laptop_dmic_init_verbs }, | ||
| 634 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 635 | .dac_nids = alc269_dac_nids, | ||
| 636 | .hp_nid = 0x03, | ||
| 637 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 638 | .channel_mode = alc269_modes, | ||
| 639 | .unsol_event = alc_sku_unsol_event, | ||
| 640 | .setup = alc269_laptop_dmic_setup, | ||
| 641 | .init_hook = alc_inithook, | ||
| 642 | }, | ||
| 643 | [ALC269_LIFEBOOK] = { | ||
| 644 | .mixers = { alc269_lifebook_mixer }, | ||
| 645 | .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, | ||
| 646 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 647 | .dac_nids = alc269_dac_nids, | ||
| 648 | .hp_nid = 0x03, | ||
| 649 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 650 | .channel_mode = alc269_modes, | ||
| 651 | .input_mux = &alc269_capture_source, | ||
| 652 | .unsol_event = alc269_lifebook_unsol_event, | ||
| 653 | .setup = alc269_lifebook_setup, | ||
| 654 | .init_hook = alc269_lifebook_init_hook, | ||
| 655 | }, | ||
| 656 | [ALC271_ACER] = { | ||
| 657 | .mixers = { alc269_asus_mixer }, | ||
| 658 | .cap_mixer = alc269vb_laptop_digital_capture_mixer, | ||
| 659 | .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, | ||
| 660 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
| 661 | .dac_nids = alc269_dac_nids, | ||
| 662 | .adc_nids = alc262_dmic_adc_nids, | ||
| 663 | .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), | ||
| 664 | .capsrc_nids = alc262_dmic_capsrc_nids, | ||
| 665 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
| 666 | .channel_mode = alc269_modes, | ||
| 667 | .input_mux = &alc269_capture_source, | ||
| 668 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
| 669 | .unsol_event = alc_sku_unsol_event, | ||
| 670 | .setup = alc269vb_laptop_dmic_setup, | ||
| 671 | .init_hook = alc_inithook, | ||
| 672 | }, | ||
| 673 | }; | ||
| 674 | |||
diff --git a/sound/pci/hda/alc662_quirks.c b/sound/pci/hda/alc662_quirks.c deleted file mode 100644 index e69a6ea3083a..000000000000 --- a/sound/pci/hda/alc662_quirks.c +++ /dev/null | |||
| @@ -1,1408 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ALC662/ALC663/ALC665/ALC670 quirk models | ||
| 3 | * included by patch_realtek.c | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* ALC662 models */ | ||
| 7 | enum { | ||
| 8 | ALC662_AUTO, | ||
| 9 | ALC662_3ST_2ch_DIG, | ||
| 10 | ALC662_3ST_6ch_DIG, | ||
| 11 | ALC662_3ST_6ch, | ||
| 12 | ALC662_5ST_DIG, | ||
| 13 | ALC662_LENOVO_101E, | ||
| 14 | ALC662_ASUS_EEEPC_P701, | ||
| 15 | ALC662_ASUS_EEEPC_EP20, | ||
| 16 | ALC663_ASUS_M51VA, | ||
| 17 | ALC663_ASUS_G71V, | ||
| 18 | ALC663_ASUS_H13, | ||
| 19 | ALC663_ASUS_G50V, | ||
| 20 | ALC662_ECS, | ||
| 21 | ALC663_ASUS_MODE1, | ||
| 22 | ALC662_ASUS_MODE2, | ||
| 23 | ALC663_ASUS_MODE3, | ||
| 24 | ALC663_ASUS_MODE4, | ||
| 25 | ALC663_ASUS_MODE5, | ||
| 26 | ALC663_ASUS_MODE6, | ||
| 27 | ALC663_ASUS_MODE7, | ||
| 28 | ALC663_ASUS_MODE8, | ||
| 29 | ALC272_DELL, | ||
| 30 | ALC272_DELL_ZM1, | ||
| 31 | ALC272_SAMSUNG_NC10, | ||
| 32 | ALC662_MODEL_LAST, | ||
| 33 | }; | ||
| 34 | |||
| 35 | #define ALC662_DIGOUT_NID 0x06 | ||
| 36 | #define ALC662_DIGIN_NID 0x0a | ||
| 37 | |||
| 38 | static const hda_nid_t alc662_dac_nids[3] = { | ||
| 39 | /* front, rear, clfe */ | ||
| 40 | 0x02, 0x03, 0x04 | ||
| 41 | }; | ||
| 42 | |||
| 43 | static const hda_nid_t alc272_dac_nids[2] = { | ||
| 44 | 0x02, 0x03 | ||
| 45 | }; | ||
| 46 | |||
| 47 | static const hda_nid_t alc662_adc_nids[2] = { | ||
| 48 | /* ADC1-2 */ | ||
| 49 | 0x09, 0x08 | ||
| 50 | }; | ||
| 51 | |||
| 52 | static const hda_nid_t alc272_adc_nids[1] = { | ||
| 53 | /* ADC1-2 */ | ||
| 54 | 0x08, | ||
| 55 | }; | ||
| 56 | |||
| 57 | static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; | ||
| 58 | static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; | ||
| 59 | |||
| 60 | |||
| 61 | /* input MUX */ | ||
| 62 | /* FIXME: should be a matrix-type input source selection */ | ||
| 63 | static const struct hda_input_mux alc662_capture_source = { | ||
| 64 | .num_items = 4, | ||
| 65 | .items = { | ||
| 66 | { "Mic", 0x0 }, | ||
| 67 | { "Front Mic", 0x1 }, | ||
| 68 | { "Line", 0x2 }, | ||
| 69 | { "CD", 0x4 }, | ||
| 70 | }, | ||
| 71 | }; | ||
| 72 | |||
| 73 | static const struct hda_input_mux alc662_lenovo_101e_capture_source = { | ||
| 74 | .num_items = 2, | ||
| 75 | .items = { | ||
| 76 | { "Mic", 0x1 }, | ||
| 77 | { "Line", 0x2 }, | ||
| 78 | }, | ||
| 79 | }; | ||
| 80 | |||
| 81 | static const struct hda_input_mux alc663_capture_source = { | ||
| 82 | .num_items = 3, | ||
| 83 | .items = { | ||
| 84 | { "Mic", 0x0 }, | ||
| 85 | { "Front Mic", 0x1 }, | ||
| 86 | { "Line", 0x2 }, | ||
| 87 | }, | ||
| 88 | }; | ||
| 89 | |||
| 90 | #if 0 /* set to 1 for testing other input sources below */ | ||
| 91 | static const struct hda_input_mux alc272_nc10_capture_source = { | ||
| 92 | .num_items = 16, | ||
| 93 | .items = { | ||
| 94 | { "Autoselect Mic", 0x0 }, | ||
| 95 | { "Internal Mic", 0x1 }, | ||
| 96 | { "In-0x02", 0x2 }, | ||
| 97 | { "In-0x03", 0x3 }, | ||
| 98 | { "In-0x04", 0x4 }, | ||
| 99 | { "In-0x05", 0x5 }, | ||
| 100 | { "In-0x06", 0x6 }, | ||
| 101 | { "In-0x07", 0x7 }, | ||
| 102 | { "In-0x08", 0x8 }, | ||
| 103 | { "In-0x09", 0x9 }, | ||
| 104 | { "In-0x0a", 0x0a }, | ||
| 105 | { "In-0x0b", 0x0b }, | ||
| 106 | { "In-0x0c", 0x0c }, | ||
| 107 | { "In-0x0d", 0x0d }, | ||
| 108 | { "In-0x0e", 0x0e }, | ||
| 109 | { "In-0x0f", 0x0f }, | ||
| 110 | }, | ||
| 111 | }; | ||
| 112 | #endif | ||
| 113 | |||
| 114 | /* | ||
| 115 | * 2ch mode | ||
| 116 | */ | ||
| 117 | static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = { | ||
| 118 | { 2, NULL } | ||
| 119 | }; | ||
| 120 | |||
| 121 | /* | ||
| 122 | * 2ch mode | ||
| 123 | */ | ||
| 124 | static const struct hda_verb alc662_3ST_ch2_init[] = { | ||
| 125 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | ||
| 126 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
| 127 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | ||
| 128 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
| 129 | { } /* end */ | ||
| 130 | }; | ||
| 131 | |||
| 132 | /* | ||
| 133 | * 6ch mode | ||
| 134 | */ | ||
| 135 | static const struct hda_verb alc662_3ST_ch6_init[] = { | ||
| 136 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 137 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
| 138 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | ||
| 139 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 140 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | ||
| 141 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
| 142 | { } /* end */ | ||
| 143 | }; | ||
| 144 | |||
| 145 | static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = { | ||
| 146 | { 2, alc662_3ST_ch2_init }, | ||
| 147 | { 6, alc662_3ST_ch6_init }, | ||
| 148 | }; | ||
| 149 | |||
| 150 | /* | ||
| 151 | * 2ch mode | ||
| 152 | */ | ||
| 153 | static const struct hda_verb alc662_sixstack_ch6_init[] = { | ||
| 154 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 155 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 156 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 157 | { } /* end */ | ||
| 158 | }; | ||
| 159 | |||
| 160 | /* | ||
| 161 | * 6ch mode | ||
| 162 | */ | ||
| 163 | static const struct hda_verb alc662_sixstack_ch8_init[] = { | ||
| 164 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 165 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 166 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 167 | { } /* end */ | ||
| 168 | }; | ||
| 169 | |||
| 170 | static const struct hda_channel_mode alc662_5stack_modes[2] = { | ||
| 171 | { 2, alc662_sixstack_ch6_init }, | ||
| 172 | { 6, alc662_sixstack_ch8_init }, | ||
| 173 | }; | ||
| 174 | |||
| 175 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
| 176 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
| 177 | */ | ||
| 178 | |||
| 179 | static const struct snd_kcontrol_new alc662_base_mixer[] = { | ||
| 180 | /* output mixer control */ | ||
| 181 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
| 182 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), | ||
| 183 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), | ||
| 184 | HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), | ||
| 185 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
| 186 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
| 187 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), | ||
| 188 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), | ||
| 189 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 190 | |||
| 191 | /*Input mixer control */ | ||
| 192 | HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), | ||
| 193 | HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), | ||
| 194 | HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), | ||
| 195 | HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), | ||
| 196 | HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), | ||
| 197 | HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), | ||
| 198 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), | ||
| 199 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), | ||
| 200 | { } /* end */ | ||
| 201 | }; | ||
| 202 | |||
| 203 | static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { | ||
| 204 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 205 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), | ||
| 206 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 207 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 208 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 209 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 210 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 211 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 212 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 213 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 214 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 215 | { } /* end */ | ||
| 216 | }; | ||
| 217 | |||
| 218 | static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { | ||
| 219 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 220 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), | ||
| 221 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 222 | HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT), | ||
| 223 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
| 224 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
| 225 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT), | ||
| 226 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT), | ||
| 227 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 228 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 229 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 230 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 231 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 232 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 233 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 234 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 235 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 236 | { } /* end */ | ||
| 237 | }; | ||
| 238 | |||
| 239 | static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | ||
| 240 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 241 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | ||
| 242 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 243 | HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT), | ||
| 244 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 245 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 246 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 247 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 248 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 249 | { } /* end */ | ||
| 250 | }; | ||
| 251 | |||
| 252 | static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | ||
| 253 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 254 | ALC262_HIPPO_MASTER_SWITCH, | ||
| 255 | |||
| 256 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 257 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 258 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 259 | |||
| 260 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 261 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 262 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 263 | { } /* end */ | ||
| 264 | }; | ||
| 265 | |||
| 266 | static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { | ||
| 267 | ALC262_HIPPO_MASTER_SWITCH, | ||
| 268 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 269 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 270 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), | ||
| 271 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), | ||
| 272 | HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT), | ||
| 273 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 274 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 275 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 276 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 277 | { } /* end */ | ||
| 278 | }; | ||
| 279 | |||
| 280 | static const struct hda_bind_ctls alc663_asus_bind_master_vol = { | ||
| 281 | .ops = &snd_hda_bind_vol, | ||
| 282 | .values = { | ||
| 283 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
| 284 | HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), | ||
| 285 | 0 | ||
| 286 | }, | ||
| 287 | }; | ||
| 288 | |||
| 289 | static const struct hda_bind_ctls alc663_asus_one_bind_switch = { | ||
| 290 | .ops = &snd_hda_bind_sw, | ||
| 291 | .values = { | ||
| 292 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 293 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
| 294 | 0 | ||
| 295 | }, | ||
| 296 | }; | ||
| 297 | |||
| 298 | static const struct snd_kcontrol_new alc663_m51va_mixer[] = { | ||
| 299 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | ||
| 300 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), | ||
| 301 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 302 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 303 | { } /* end */ | ||
| 304 | }; | ||
| 305 | |||
| 306 | static const struct hda_bind_ctls alc663_asus_tree_bind_switch = { | ||
| 307 | .ops = &snd_hda_bind_sw, | ||
| 308 | .values = { | ||
| 309 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 310 | HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
| 311 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
| 312 | 0 | ||
| 313 | }, | ||
| 314 | }; | ||
| 315 | |||
| 316 | static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { | ||
| 317 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | ||
| 318 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), | ||
| 319 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 320 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 321 | HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 322 | HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 323 | |||
| 324 | { } /* end */ | ||
| 325 | }; | ||
| 326 | |||
| 327 | static const struct hda_bind_ctls alc663_asus_four_bind_switch = { | ||
| 328 | .ops = &snd_hda_bind_sw, | ||
| 329 | .values = { | ||
| 330 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 331 | HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
| 332 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
| 333 | 0 | ||
| 334 | }, | ||
| 335 | }; | ||
| 336 | |||
| 337 | static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { | ||
| 338 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | ||
| 339 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), | ||
| 340 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 341 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 342 | HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 343 | HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 344 | { } /* end */ | ||
| 345 | }; | ||
| 346 | |||
| 347 | static const struct snd_kcontrol_new alc662_1bjd_mixer[] = { | ||
| 348 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 349 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 350 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 351 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 352 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 353 | HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 354 | HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 355 | { } /* end */ | ||
| 356 | }; | ||
| 357 | |||
| 358 | static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = { | ||
| 359 | .ops = &snd_hda_bind_vol, | ||
| 360 | .values = { | ||
| 361 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | ||
| 362 | HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), | ||
| 363 | 0 | ||
| 364 | }, | ||
| 365 | }; | ||
| 366 | |||
| 367 | static const struct hda_bind_ctls alc663_asus_two_bind_switch = { | ||
| 368 | .ops = &snd_hda_bind_sw, | ||
| 369 | .values = { | ||
| 370 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 371 | HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), | ||
| 372 | 0 | ||
| 373 | }, | ||
| 374 | }; | ||
| 375 | |||
| 376 | static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { | ||
| 377 | HDA_BIND_VOL("Master Playback Volume", | ||
| 378 | &alc663_asus_two_bind_master_vol), | ||
| 379 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), | ||
| 380 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 381 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 382 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 383 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 384 | { } /* end */ | ||
| 385 | }; | ||
| 386 | |||
| 387 | static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { | ||
| 388 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | ||
| 389 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), | ||
| 390 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 391 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 392 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 393 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 394 | { } /* end */ | ||
| 395 | }; | ||
| 396 | |||
| 397 | static const struct snd_kcontrol_new alc663_g71v_mixer[] = { | ||
| 398 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 399 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 400 | HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 401 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 402 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 403 | |||
| 404 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 405 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 406 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 407 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 408 | { } /* end */ | ||
| 409 | }; | ||
| 410 | |||
| 411 | static const struct snd_kcontrol_new alc663_g50v_mixer[] = { | ||
| 412 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 413 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 414 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 415 | |||
| 416 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 417 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 418 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 419 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 420 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 421 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 422 | { } /* end */ | ||
| 423 | }; | ||
| 424 | |||
| 425 | static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { | ||
| 426 | .ops = &snd_hda_bind_sw, | ||
| 427 | .values = { | ||
| 428 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 429 | HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), | ||
| 430 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
| 431 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
| 432 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | ||
| 433 | 0 | ||
| 434 | }, | ||
| 435 | }; | ||
| 436 | |||
| 437 | static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { | ||
| 438 | .ops = &snd_hda_bind_sw, | ||
| 439 | .values = { | ||
| 440 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
| 441 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT), | ||
| 442 | 0 | ||
| 443 | }, | ||
| 444 | }; | ||
| 445 | |||
| 446 | static const struct snd_kcontrol_new alc663_mode7_mixer[] = { | ||
| 447 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), | ||
| 448 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), | ||
| 449 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), | ||
| 450 | HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 451 | HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 452 | HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 453 | HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 454 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 455 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 456 | { } /* end */ | ||
| 457 | }; | ||
| 458 | |||
| 459 | static const struct snd_kcontrol_new alc663_mode8_mixer[] = { | ||
| 460 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), | ||
| 461 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), | ||
| 462 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), | ||
| 463 | HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 464 | HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 465 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 466 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 467 | { } /* end */ | ||
| 468 | }; | ||
| 469 | |||
| 470 | |||
| 471 | static const struct snd_kcontrol_new alc662_chmode_mixer[] = { | ||
| 472 | { | ||
| 473 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 474 | .name = "Channel Mode", | ||
| 475 | .info = alc_ch_mode_info, | ||
| 476 | .get = alc_ch_mode_get, | ||
| 477 | .put = alc_ch_mode_put, | ||
| 478 | }, | ||
| 479 | { } /* end */ | ||
| 480 | }; | ||
| 481 | |||
| 482 | static const struct hda_verb alc662_init_verbs[] = { | ||
| 483 | /* ADC: mute amp left and right */ | ||
| 484 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 485 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 486 | |||
| 487 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 488 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 489 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 490 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 491 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 492 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 493 | |||
| 494 | /* Front Pin: output 0 (0x0c) */ | ||
| 495 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 496 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 497 | |||
| 498 | /* Rear Pin: output 1 (0x0d) */ | ||
| 499 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 500 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 501 | |||
| 502 | /* CLFE Pin: output 2 (0x0e) */ | ||
| 503 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 504 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 505 | |||
| 506 | /* Mic (rear) pin: input vref at 80% */ | ||
| 507 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 508 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 509 | /* Front Mic pin: input vref at 80% */ | ||
| 510 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 511 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 512 | /* Line In pin: input */ | ||
| 513 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 514 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 515 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
| 516 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 517 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 518 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 519 | /* CD pin widget for input */ | ||
| 520 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 521 | |||
| 522 | /* FIXME: use matrix-type input source selection */ | ||
| 523 | /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ | ||
| 524 | /* Input mixer */ | ||
| 525 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 526 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 527 | |||
| 528 | { } | ||
| 529 | }; | ||
| 530 | |||
| 531 | static const struct hda_verb alc662_eapd_init_verbs[] = { | ||
| 532 | /* always trun on EAPD */ | ||
| 533 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 534 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 535 | { } | ||
| 536 | }; | ||
| 537 | |||
| 538 | static const struct hda_verb alc662_sue_init_verbs[] = { | ||
| 539 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT}, | ||
| 540 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT}, | ||
| 541 | {} | ||
| 542 | }; | ||
| 543 | |||
| 544 | static const struct hda_verb alc662_eeepc_sue_init_verbs[] = { | ||
| 545 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 546 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 547 | {} | ||
| 548 | }; | ||
| 549 | |||
| 550 | /* Set Unsolicited Event*/ | ||
| 551 | static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { | ||
| 552 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 553 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 554 | {} | ||
| 555 | }; | ||
| 556 | |||
| 557 | static const struct hda_verb alc663_m51va_init_verbs[] = { | ||
| 558 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 559 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 560 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 561 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 562 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 563 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 564 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
| 565 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 566 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 567 | {} | ||
| 568 | }; | ||
| 569 | |||
| 570 | static const struct hda_verb alc663_21jd_amic_init_verbs[] = { | ||
| 571 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 572 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 573 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 574 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 575 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 576 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 577 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 578 | {} | ||
| 579 | }; | ||
| 580 | |||
| 581 | static const struct hda_verb alc662_1bjd_amic_init_verbs[] = { | ||
| 582 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 583 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 584 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 585 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | ||
| 586 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 587 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 588 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 589 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 590 | {} | ||
| 591 | }; | ||
| 592 | |||
| 593 | static const struct hda_verb alc663_15jd_amic_init_verbs[] = { | ||
| 594 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 595 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 596 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 597 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 598 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 599 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 600 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 601 | {} | ||
| 602 | }; | ||
| 603 | |||
| 604 | static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { | ||
| 605 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 606 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 607 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 608 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ | ||
| 609 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 610 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 611 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ | ||
| 612 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 613 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 614 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 615 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 616 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 617 | {} | ||
| 618 | }; | ||
| 619 | |||
| 620 | static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { | ||
| 621 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 622 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 623 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 624 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 625 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 626 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 627 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 628 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 629 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 630 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 631 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 632 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 633 | {} | ||
| 634 | }; | ||
| 635 | |||
| 636 | static const struct hda_verb alc663_g71v_init_verbs[] = { | ||
| 637 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 638 | /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ | ||
| 639 | /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ | ||
| 640 | |||
| 641 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 642 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 643 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | ||
| 644 | |||
| 645 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_FRONT_EVENT}, | ||
| 646 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_MIC_EVENT}, | ||
| 647 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC_HP_EVENT}, | ||
| 648 | {} | ||
| 649 | }; | ||
| 650 | |||
| 651 | static const struct hda_verb alc663_g50v_init_verbs[] = { | ||
| 652 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 653 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 654 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | ||
| 655 | |||
| 656 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 657 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 658 | {} | ||
| 659 | }; | ||
| 660 | |||
| 661 | static const struct hda_verb alc662_ecs_init_verbs[] = { | ||
| 662 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, | ||
| 663 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 664 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 665 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 666 | {} | ||
| 667 | }; | ||
| 668 | |||
| 669 | static const struct hda_verb alc272_dell_zm1_init_verbs[] = { | ||
| 670 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 671 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 672 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 673 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 674 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 675 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 676 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 677 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 678 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
| 679 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 680 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 681 | {} | ||
| 682 | }; | ||
| 683 | |||
| 684 | static const struct hda_verb alc272_dell_init_verbs[] = { | ||
| 685 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 686 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 687 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 688 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 689 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 690 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 691 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 692 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 693 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
| 694 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 695 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 696 | {} | ||
| 697 | }; | ||
| 698 | |||
| 699 | static const struct hda_verb alc663_mode7_init_verbs[] = { | ||
| 700 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 701 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 702 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 703 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 704 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 705 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 706 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 707 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 708 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 709 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 710 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 711 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
| 712 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 713 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 714 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 715 | {} | ||
| 716 | }; | ||
| 717 | |||
| 718 | static const struct hda_verb alc663_mode8_init_verbs[] = { | ||
| 719 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 720 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 721 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 722 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 723 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 724 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 725 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 726 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 727 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 728 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 729 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | ||
| 730 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 731 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, | ||
| 732 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 733 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 734 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 735 | {} | ||
| 736 | }; | ||
| 737 | |||
| 738 | static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = { | ||
| 739 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
| 740 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
| 741 | { } /* end */ | ||
| 742 | }; | ||
| 743 | |||
| 744 | static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = { | ||
| 745 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
| 746 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
| 747 | { } /* end */ | ||
| 748 | }; | ||
| 749 | |||
| 750 | static void alc662_lenovo_101e_setup(struct hda_codec *codec) | ||
| 751 | { | ||
| 752 | struct alc_spec *spec = codec->spec; | ||
| 753 | |||
| 754 | spec->autocfg.hp_pins[0] = 0x1b; | ||
| 755 | spec->autocfg.line_out_pins[0] = 0x14; | ||
| 756 | spec->autocfg.speaker_pins[0] = 0x15; | ||
| 757 | spec->automute = 1; | ||
| 758 | spec->detect_line = 1; | ||
| 759 | spec->automute_lines = 1; | ||
| 760 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 761 | } | ||
| 762 | |||
| 763 | static void alc662_eeepc_setup(struct hda_codec *codec) | ||
| 764 | { | ||
| 765 | struct alc_spec *spec = codec->spec; | ||
| 766 | |||
| 767 | alc262_hippo1_setup(codec); | ||
| 768 | spec->ext_mic_pin = 0x18; | ||
| 769 | spec->int_mic_pin = 0x19; | ||
| 770 | spec->auto_mic = 1; | ||
| 771 | } | ||
| 772 | |||
| 773 | static void alc662_eeepc_ep20_setup(struct hda_codec *codec) | ||
| 774 | { | ||
| 775 | struct alc_spec *spec = codec->spec; | ||
| 776 | |||
| 777 | spec->autocfg.hp_pins[0] = 0x14; | ||
| 778 | spec->autocfg.speaker_pins[0] = 0x1b; | ||
| 779 | spec->automute = 1; | ||
| 780 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 781 | } | ||
| 782 | |||
| 783 | static void alc663_m51va_setup(struct hda_codec *codec) | ||
| 784 | { | ||
| 785 | struct alc_spec *spec = codec->spec; | ||
| 786 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 787 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 788 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 789 | spec->automute = 1; | ||
| 790 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 791 | spec->ext_mic_pin = 0x18; | ||
| 792 | spec->int_mic_pin = 0x12; | ||
| 793 | spec->auto_mic = 1; | ||
| 794 | } | ||
| 795 | |||
| 796 | /* ***************** Mode1 ******************************/ | ||
| 797 | static void alc663_mode1_setup(struct hda_codec *codec) | ||
| 798 | { | ||
| 799 | struct alc_spec *spec = codec->spec; | ||
| 800 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 801 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 802 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 803 | spec->automute = 1; | ||
| 804 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 805 | spec->ext_mic_pin = 0x18; | ||
| 806 | spec->int_mic_pin = 0x19; | ||
| 807 | spec->auto_mic = 1; | ||
| 808 | } | ||
| 809 | |||
| 810 | /* ***************** Mode2 ******************************/ | ||
| 811 | static void alc662_mode2_setup(struct hda_codec *codec) | ||
| 812 | { | ||
| 813 | struct alc_spec *spec = codec->spec; | ||
| 814 | spec->autocfg.hp_pins[0] = 0x1b; | ||
| 815 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 816 | spec->automute = 1; | ||
| 817 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 818 | spec->ext_mic_pin = 0x18; | ||
| 819 | spec->int_mic_pin = 0x19; | ||
| 820 | spec->auto_mic = 1; | ||
| 821 | } | ||
| 822 | |||
| 823 | /* ***************** Mode3 ******************************/ | ||
| 824 | static void alc663_mode3_setup(struct hda_codec *codec) | ||
| 825 | { | ||
| 826 | struct alc_spec *spec = codec->spec; | ||
| 827 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 828 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 829 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 830 | spec->automute = 1; | ||
| 831 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 832 | spec->ext_mic_pin = 0x18; | ||
| 833 | spec->int_mic_pin = 0x19; | ||
| 834 | spec->auto_mic = 1; | ||
| 835 | } | ||
| 836 | |||
| 837 | /* ***************** Mode4 ******************************/ | ||
| 838 | static void alc663_mode4_setup(struct hda_codec *codec) | ||
| 839 | { | ||
| 840 | struct alc_spec *spec = codec->spec; | ||
| 841 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 842 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 843 | spec->autocfg.speaker_pins[1] = 0x16; | ||
| 844 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 845 | spec->automute_mixer_nid[1] = 0x0e; | ||
| 846 | spec->automute = 1; | ||
| 847 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 848 | spec->ext_mic_pin = 0x18; | ||
| 849 | spec->int_mic_pin = 0x19; | ||
| 850 | spec->auto_mic = 1; | ||
| 851 | } | ||
| 852 | |||
| 853 | /* ***************** Mode5 ******************************/ | ||
| 854 | static void alc663_mode5_setup(struct hda_codec *codec) | ||
| 855 | { | ||
| 856 | struct alc_spec *spec = codec->spec; | ||
| 857 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 858 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 859 | spec->autocfg.speaker_pins[1] = 0x16; | ||
| 860 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 861 | spec->automute_mixer_nid[1] = 0x0e; | ||
| 862 | spec->automute = 1; | ||
| 863 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 864 | spec->ext_mic_pin = 0x18; | ||
| 865 | spec->int_mic_pin = 0x19; | ||
| 866 | spec->auto_mic = 1; | ||
| 867 | } | ||
| 868 | |||
| 869 | /* ***************** Mode6 ******************************/ | ||
| 870 | static void alc663_mode6_setup(struct hda_codec *codec) | ||
| 871 | { | ||
| 872 | struct alc_spec *spec = codec->spec; | ||
| 873 | spec->autocfg.hp_pins[0] = 0x1b; | ||
| 874 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 875 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 876 | spec->automute_mixer_nid[0] = 0x0c; | ||
| 877 | spec->automute = 1; | ||
| 878 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
| 879 | spec->ext_mic_pin = 0x18; | ||
| 880 | spec->int_mic_pin = 0x19; | ||
| 881 | spec->auto_mic = 1; | ||
| 882 | } | ||
| 883 | |||
| 884 | /* ***************** Mode7 ******************************/ | ||
| 885 | static void alc663_mode7_setup(struct hda_codec *codec) | ||
| 886 | { | ||
| 887 | struct alc_spec *spec = codec->spec; | ||
| 888 | spec->autocfg.hp_pins[0] = 0x1b; | ||
| 889 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 890 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 891 | spec->autocfg.speaker_pins[0] = 0x17; | ||
| 892 | spec->automute = 1; | ||
| 893 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 894 | spec->ext_mic_pin = 0x18; | ||
| 895 | spec->int_mic_pin = 0x19; | ||
| 896 | spec->auto_mic = 1; | ||
| 897 | } | ||
| 898 | |||
| 899 | /* ***************** Mode8 ******************************/ | ||
| 900 | static void alc663_mode8_setup(struct hda_codec *codec) | ||
| 901 | { | ||
| 902 | struct alc_spec *spec = codec->spec; | ||
| 903 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 904 | spec->autocfg.hp_pins[1] = 0x15; | ||
| 905 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 906 | spec->autocfg.speaker_pins[0] = 0x17; | ||
| 907 | spec->automute = 1; | ||
| 908 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 909 | spec->ext_mic_pin = 0x18; | ||
| 910 | spec->int_mic_pin = 0x12; | ||
| 911 | spec->auto_mic = 1; | ||
| 912 | } | ||
| 913 | |||
| 914 | static void alc663_g71v_setup(struct hda_codec *codec) | ||
| 915 | { | ||
| 916 | struct alc_spec *spec = codec->spec; | ||
| 917 | spec->autocfg.hp_pins[0] = 0x21; | ||
| 918 | spec->autocfg.line_out_pins[0] = 0x15; | ||
| 919 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 920 | spec->automute = 1; | ||
| 921 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 922 | spec->detect_line = 1; | ||
| 923 | spec->automute_lines = 1; | ||
| 924 | spec->ext_mic_pin = 0x18; | ||
| 925 | spec->int_mic_pin = 0x12; | ||
| 926 | spec->auto_mic = 1; | ||
| 927 | } | ||
| 928 | |||
| 929 | #define alc663_g50v_setup alc663_m51va_setup | ||
| 930 | |||
| 931 | static const struct snd_kcontrol_new alc662_ecs_mixer[] = { | ||
| 932 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 933 | ALC262_HIPPO_MASTER_SWITCH, | ||
| 934 | |||
| 935 | HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 936 | HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 937 | HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 938 | |||
| 939 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 940 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 941 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 942 | { } /* end */ | ||
| 943 | }; | ||
| 944 | |||
| 945 | static const struct snd_kcontrol_new alc272_nc10_mixer[] = { | ||
| 946 | /* Master Playback automatically created from Speaker and Headphone */ | ||
| 947 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 948 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 949 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 950 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
| 951 | |||
| 952 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 953 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 954 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 955 | |||
| 956 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 957 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 958 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 959 | { } /* end */ | ||
| 960 | }; | ||
| 961 | |||
| 962 | |||
| 963 | /* | ||
| 964 | * configuration and preset | ||
| 965 | */ | ||
| 966 | static const char * const alc662_models[ALC662_MODEL_LAST] = { | ||
| 967 | [ALC662_3ST_2ch_DIG] = "3stack-dig", | ||
| 968 | [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", | ||
| 969 | [ALC662_3ST_6ch] = "3stack-6ch", | ||
| 970 | [ALC662_5ST_DIG] = "5stack-dig", | ||
| 971 | [ALC662_LENOVO_101E] = "lenovo-101e", | ||
| 972 | [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", | ||
| 973 | [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", | ||
| 974 | [ALC662_ECS] = "ecs", | ||
| 975 | [ALC663_ASUS_M51VA] = "m51va", | ||
| 976 | [ALC663_ASUS_G71V] = "g71v", | ||
| 977 | [ALC663_ASUS_H13] = "h13", | ||
| 978 | [ALC663_ASUS_G50V] = "g50v", | ||
| 979 | [ALC663_ASUS_MODE1] = "asus-mode1", | ||
| 980 | [ALC662_ASUS_MODE2] = "asus-mode2", | ||
| 981 | [ALC663_ASUS_MODE3] = "asus-mode3", | ||
| 982 | [ALC663_ASUS_MODE4] = "asus-mode4", | ||
| 983 | [ALC663_ASUS_MODE5] = "asus-mode5", | ||
| 984 | [ALC663_ASUS_MODE6] = "asus-mode6", | ||
| 985 | [ALC663_ASUS_MODE7] = "asus-mode7", | ||
| 986 | [ALC663_ASUS_MODE8] = "asus-mode8", | ||
| 987 | [ALC272_DELL] = "dell", | ||
| 988 | [ALC272_DELL_ZM1] = "dell-zm1", | ||
| 989 | [ALC272_SAMSUNG_NC10] = "samsung-nc10", | ||
| 990 | [ALC662_AUTO] = "auto", | ||
| 991 | }; | ||
| 992 | |||
| 993 | static const struct snd_pci_quirk alc662_cfg_tbl[] = { | ||
| 994 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), | ||
| 995 | SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), | ||
| 996 | SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), | ||
| 997 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), | ||
| 998 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), | ||
| 999 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1), | ||
| 1000 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), | ||
| 1001 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), | ||
| 1002 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1003 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), | ||
| 1004 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1), | ||
| 1005 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1), | ||
| 1006 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1007 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7), | ||
| 1008 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7), | ||
| 1009 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8), | ||
| 1010 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3), | ||
| 1011 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1), | ||
| 1012 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1013 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2), | ||
| 1014 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1), | ||
| 1015 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1016 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), | ||
| 1017 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), | ||
| 1018 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1019 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1), | ||
| 1020 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3), | ||
| 1021 | SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA), | ||
| 1022 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2), | ||
| 1023 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1024 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), | ||
| 1025 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), | ||
| 1026 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1027 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1), | ||
| 1028 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1029 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1030 | SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), | ||
| 1031 | /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/ | ||
| 1032 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), | ||
| 1033 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), | ||
| 1034 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1), | ||
| 1035 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1), | ||
| 1036 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1), | ||
| 1037 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1), | ||
| 1038 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), | ||
| 1039 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), | ||
| 1040 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), | ||
| 1041 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1), | ||
| 1042 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), | ||
| 1043 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), | ||
| 1044 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1), | ||
| 1045 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1), | ||
| 1046 | SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V), | ||
| 1047 | /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/ | ||
| 1048 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), | ||
| 1049 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), | ||
| 1050 | SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA), | ||
| 1051 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), | ||
| 1052 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), | ||
| 1053 | SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), | ||
| 1054 | SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), | ||
| 1055 | SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), | ||
| 1056 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), | ||
| 1057 | SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", | ||
| 1058 | ALC662_3ST_6ch_DIG), | ||
| 1059 | SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), | ||
| 1060 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), | ||
| 1061 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | ||
| 1062 | ALC662_3ST_6ch_DIG), | ||
| 1063 | SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), | ||
| 1064 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), | ||
| 1065 | SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), | ||
| 1066 | SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), | ||
| 1067 | SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", | ||
| 1068 | ALC662_3ST_6ch_DIG), | ||
| 1069 | SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x", | ||
| 1070 | ALC663_ASUS_H13), | ||
| 1071 | SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E), | ||
| 1072 | {} | ||
| 1073 | }; | ||
| 1074 | |||
| 1075 | static const struct alc_config_preset alc662_presets[] = { | ||
| 1076 | [ALC662_3ST_2ch_DIG] = { | ||
| 1077 | .mixers = { alc662_3ST_2ch_mixer }, | ||
| 1078 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, | ||
| 1079 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1080 | .dac_nids = alc662_dac_nids, | ||
| 1081 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1082 | .dig_in_nid = ALC662_DIGIN_NID, | ||
| 1083 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1084 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1085 | .input_mux = &alc662_capture_source, | ||
| 1086 | }, | ||
| 1087 | [ALC662_3ST_6ch_DIG] = { | ||
| 1088 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | ||
| 1089 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, | ||
| 1090 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1091 | .dac_nids = alc662_dac_nids, | ||
| 1092 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1093 | .dig_in_nid = ALC662_DIGIN_NID, | ||
| 1094 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
| 1095 | .channel_mode = alc662_3ST_6ch_modes, | ||
| 1096 | .need_dac_fix = 1, | ||
| 1097 | .input_mux = &alc662_capture_source, | ||
| 1098 | }, | ||
| 1099 | [ALC662_3ST_6ch] = { | ||
| 1100 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | ||
| 1101 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, | ||
| 1102 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1103 | .dac_nids = alc662_dac_nids, | ||
| 1104 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
| 1105 | .channel_mode = alc662_3ST_6ch_modes, | ||
| 1106 | .need_dac_fix = 1, | ||
| 1107 | .input_mux = &alc662_capture_source, | ||
| 1108 | }, | ||
| 1109 | [ALC662_5ST_DIG] = { | ||
| 1110 | .mixers = { alc662_base_mixer, alc662_chmode_mixer }, | ||
| 1111 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, | ||
| 1112 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1113 | .dac_nids = alc662_dac_nids, | ||
| 1114 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1115 | .dig_in_nid = ALC662_DIGIN_NID, | ||
| 1116 | .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), | ||
| 1117 | .channel_mode = alc662_5stack_modes, | ||
| 1118 | .input_mux = &alc662_capture_source, | ||
| 1119 | }, | ||
| 1120 | [ALC662_LENOVO_101E] = { | ||
| 1121 | .mixers = { alc662_lenovo_101e_mixer }, | ||
| 1122 | .init_verbs = { alc662_init_verbs, | ||
| 1123 | alc662_eapd_init_verbs, | ||
| 1124 | alc662_sue_init_verbs }, | ||
| 1125 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1126 | .dac_nids = alc662_dac_nids, | ||
| 1127 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1128 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1129 | .input_mux = &alc662_lenovo_101e_capture_source, | ||
| 1130 | .unsol_event = alc_sku_unsol_event, | ||
| 1131 | .setup = alc662_lenovo_101e_setup, | ||
| 1132 | .init_hook = alc_inithook, | ||
| 1133 | }, | ||
| 1134 | [ALC662_ASUS_EEEPC_P701] = { | ||
| 1135 | .mixers = { alc662_eeepc_p701_mixer }, | ||
| 1136 | .init_verbs = { alc662_init_verbs, | ||
| 1137 | alc662_eapd_init_verbs, | ||
| 1138 | alc662_eeepc_sue_init_verbs }, | ||
| 1139 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1140 | .dac_nids = alc662_dac_nids, | ||
| 1141 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1142 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1143 | .unsol_event = alc_sku_unsol_event, | ||
| 1144 | .setup = alc662_eeepc_setup, | ||
| 1145 | .init_hook = alc_inithook, | ||
| 1146 | }, | ||
| 1147 | [ALC662_ASUS_EEEPC_EP20] = { | ||
| 1148 | .mixers = { alc662_eeepc_ep20_mixer, | ||
| 1149 | alc662_chmode_mixer }, | ||
| 1150 | .init_verbs = { alc662_init_verbs, | ||
| 1151 | alc662_eapd_init_verbs, | ||
| 1152 | alc662_eeepc_ep20_sue_init_verbs }, | ||
| 1153 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1154 | .dac_nids = alc662_dac_nids, | ||
| 1155 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
| 1156 | .channel_mode = alc662_3ST_6ch_modes, | ||
| 1157 | .input_mux = &alc662_lenovo_101e_capture_source, | ||
| 1158 | .unsol_event = alc_sku_unsol_event, | ||
| 1159 | .setup = alc662_eeepc_ep20_setup, | ||
| 1160 | .init_hook = alc_inithook, | ||
| 1161 | }, | ||
| 1162 | [ALC662_ECS] = { | ||
| 1163 | .mixers = { alc662_ecs_mixer }, | ||
| 1164 | .init_verbs = { alc662_init_verbs, | ||
| 1165 | alc662_eapd_init_verbs, | ||
| 1166 | alc662_ecs_init_verbs }, | ||
| 1167 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1168 | .dac_nids = alc662_dac_nids, | ||
| 1169 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1170 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1171 | .unsol_event = alc_sku_unsol_event, | ||
| 1172 | .setup = alc662_eeepc_setup, | ||
| 1173 | .init_hook = alc_inithook, | ||
| 1174 | }, | ||
| 1175 | [ALC663_ASUS_M51VA] = { | ||
| 1176 | .mixers = { alc663_m51va_mixer }, | ||
| 1177 | .init_verbs = { alc662_init_verbs, | ||
| 1178 | alc662_eapd_init_verbs, | ||
| 1179 | alc663_m51va_init_verbs }, | ||
| 1180 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1181 | .dac_nids = alc662_dac_nids, | ||
| 1182 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1183 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1184 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1185 | .unsol_event = alc_sku_unsol_event, | ||
| 1186 | .setup = alc663_m51va_setup, | ||
| 1187 | .init_hook = alc_inithook, | ||
| 1188 | }, | ||
| 1189 | [ALC663_ASUS_G71V] = { | ||
| 1190 | .mixers = { alc663_g71v_mixer }, | ||
| 1191 | .init_verbs = { alc662_init_verbs, | ||
| 1192 | alc662_eapd_init_verbs, | ||
| 1193 | alc663_g71v_init_verbs }, | ||
| 1194 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1195 | .dac_nids = alc662_dac_nids, | ||
| 1196 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1197 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1198 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1199 | .unsol_event = alc_sku_unsol_event, | ||
| 1200 | .setup = alc663_g71v_setup, | ||
| 1201 | .init_hook = alc_inithook, | ||
| 1202 | }, | ||
| 1203 | [ALC663_ASUS_H13] = { | ||
| 1204 | .mixers = { alc663_m51va_mixer }, | ||
| 1205 | .init_verbs = { alc662_init_verbs, | ||
| 1206 | alc662_eapd_init_verbs, | ||
| 1207 | alc663_m51va_init_verbs }, | ||
| 1208 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1209 | .dac_nids = alc662_dac_nids, | ||
| 1210 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1211 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1212 | .setup = alc663_m51va_setup, | ||
| 1213 | .unsol_event = alc_sku_unsol_event, | ||
| 1214 | .init_hook = alc_inithook, | ||
| 1215 | }, | ||
| 1216 | [ALC663_ASUS_G50V] = { | ||
| 1217 | .mixers = { alc663_g50v_mixer }, | ||
| 1218 | .init_verbs = { alc662_init_verbs, | ||
| 1219 | alc662_eapd_init_verbs, | ||
| 1220 | alc663_g50v_init_verbs }, | ||
| 1221 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1222 | .dac_nids = alc662_dac_nids, | ||
| 1223 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1224 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | ||
| 1225 | .channel_mode = alc662_3ST_6ch_modes, | ||
| 1226 | .input_mux = &alc663_capture_source, | ||
| 1227 | .unsol_event = alc_sku_unsol_event, | ||
| 1228 | .setup = alc663_g50v_setup, | ||
| 1229 | .init_hook = alc_inithook, | ||
| 1230 | }, | ||
| 1231 | [ALC663_ASUS_MODE1] = { | ||
| 1232 | .mixers = { alc663_m51va_mixer }, | ||
| 1233 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1234 | .init_verbs = { alc662_init_verbs, | ||
| 1235 | alc662_eapd_init_verbs, | ||
| 1236 | alc663_21jd_amic_init_verbs }, | ||
| 1237 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1238 | .hp_nid = 0x03, | ||
| 1239 | .dac_nids = alc662_dac_nids, | ||
| 1240 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1241 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1242 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1243 | .unsol_event = alc_sku_unsol_event, | ||
| 1244 | .setup = alc663_mode1_setup, | ||
| 1245 | .init_hook = alc_inithook, | ||
| 1246 | }, | ||
| 1247 | [ALC662_ASUS_MODE2] = { | ||
| 1248 | .mixers = { alc662_1bjd_mixer }, | ||
| 1249 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1250 | .init_verbs = { alc662_init_verbs, | ||
| 1251 | alc662_eapd_init_verbs, | ||
| 1252 | alc662_1bjd_amic_init_verbs }, | ||
| 1253 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1254 | .dac_nids = alc662_dac_nids, | ||
| 1255 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1256 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1257 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1258 | .unsol_event = alc_sku_unsol_event, | ||
| 1259 | .setup = alc662_mode2_setup, | ||
| 1260 | .init_hook = alc_inithook, | ||
| 1261 | }, | ||
| 1262 | [ALC663_ASUS_MODE3] = { | ||
| 1263 | .mixers = { alc663_two_hp_m1_mixer }, | ||
| 1264 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1265 | .init_verbs = { alc662_init_verbs, | ||
| 1266 | alc662_eapd_init_verbs, | ||
| 1267 | alc663_two_hp_amic_m1_init_verbs }, | ||
| 1268 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1269 | .hp_nid = 0x03, | ||
| 1270 | .dac_nids = alc662_dac_nids, | ||
| 1271 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1272 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1273 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1274 | .unsol_event = alc_sku_unsol_event, | ||
| 1275 | .setup = alc663_mode3_setup, | ||
| 1276 | .init_hook = alc_inithook, | ||
| 1277 | }, | ||
| 1278 | [ALC663_ASUS_MODE4] = { | ||
| 1279 | .mixers = { alc663_asus_21jd_clfe_mixer }, | ||
| 1280 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1281 | .init_verbs = { alc662_init_verbs, | ||
| 1282 | alc662_eapd_init_verbs, | ||
| 1283 | alc663_21jd_amic_init_verbs}, | ||
| 1284 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1285 | .hp_nid = 0x03, | ||
| 1286 | .dac_nids = alc662_dac_nids, | ||
| 1287 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1288 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1289 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1290 | .unsol_event = alc_sku_unsol_event, | ||
| 1291 | .setup = alc663_mode4_setup, | ||
| 1292 | .init_hook = alc_inithook, | ||
| 1293 | }, | ||
| 1294 | [ALC663_ASUS_MODE5] = { | ||
| 1295 | .mixers = { alc663_asus_15jd_clfe_mixer }, | ||
| 1296 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1297 | .init_verbs = { alc662_init_verbs, | ||
| 1298 | alc662_eapd_init_verbs, | ||
| 1299 | alc663_15jd_amic_init_verbs }, | ||
| 1300 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1301 | .hp_nid = 0x03, | ||
| 1302 | .dac_nids = alc662_dac_nids, | ||
| 1303 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1304 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1305 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1306 | .unsol_event = alc_sku_unsol_event, | ||
| 1307 | .setup = alc663_mode5_setup, | ||
| 1308 | .init_hook = alc_inithook, | ||
| 1309 | }, | ||
| 1310 | [ALC663_ASUS_MODE6] = { | ||
| 1311 | .mixers = { alc663_two_hp_m2_mixer }, | ||
| 1312 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1313 | .init_verbs = { alc662_init_verbs, | ||
| 1314 | alc662_eapd_init_verbs, | ||
| 1315 | alc663_two_hp_amic_m2_init_verbs }, | ||
| 1316 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1317 | .hp_nid = 0x03, | ||
| 1318 | .dac_nids = alc662_dac_nids, | ||
| 1319 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1320 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1321 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1322 | .unsol_event = alc_sku_unsol_event, | ||
| 1323 | .setup = alc663_mode6_setup, | ||
| 1324 | .init_hook = alc_inithook, | ||
| 1325 | }, | ||
| 1326 | [ALC663_ASUS_MODE7] = { | ||
| 1327 | .mixers = { alc663_mode7_mixer }, | ||
| 1328 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1329 | .init_verbs = { alc662_init_verbs, | ||
| 1330 | alc662_eapd_init_verbs, | ||
| 1331 | alc663_mode7_init_verbs }, | ||
| 1332 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1333 | .hp_nid = 0x03, | ||
| 1334 | .dac_nids = alc662_dac_nids, | ||
| 1335 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1336 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1337 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1338 | .unsol_event = alc_sku_unsol_event, | ||
| 1339 | .setup = alc663_mode7_setup, | ||
| 1340 | .init_hook = alc_inithook, | ||
| 1341 | }, | ||
| 1342 | [ALC663_ASUS_MODE8] = { | ||
| 1343 | .mixers = { alc663_mode8_mixer }, | ||
| 1344 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1345 | .init_verbs = { alc662_init_verbs, | ||
| 1346 | alc662_eapd_init_verbs, | ||
| 1347 | alc663_mode8_init_verbs }, | ||
| 1348 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | ||
| 1349 | .hp_nid = 0x03, | ||
| 1350 | .dac_nids = alc662_dac_nids, | ||
| 1351 | .dig_out_nid = ALC662_DIGOUT_NID, | ||
| 1352 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1353 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1354 | .unsol_event = alc_sku_unsol_event, | ||
| 1355 | .setup = alc663_mode8_setup, | ||
| 1356 | .init_hook = alc_inithook, | ||
| 1357 | }, | ||
| 1358 | [ALC272_DELL] = { | ||
| 1359 | .mixers = { alc663_m51va_mixer }, | ||
| 1360 | .cap_mixer = alc272_auto_capture_mixer, | ||
| 1361 | .init_verbs = { alc662_init_verbs, | ||
| 1362 | alc662_eapd_init_verbs, | ||
| 1363 | alc272_dell_init_verbs }, | ||
| 1364 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
| 1365 | .dac_nids = alc272_dac_nids, | ||
| 1366 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1367 | .adc_nids = alc272_adc_nids, | ||
| 1368 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), | ||
| 1369 | .capsrc_nids = alc272_capsrc_nids, | ||
| 1370 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1371 | .unsol_event = alc_sku_unsol_event, | ||
| 1372 | .setup = alc663_m51va_setup, | ||
| 1373 | .init_hook = alc_inithook, | ||
| 1374 | }, | ||
| 1375 | [ALC272_DELL_ZM1] = { | ||
| 1376 | .mixers = { alc663_m51va_mixer }, | ||
| 1377 | .cap_mixer = alc662_auto_capture_mixer, | ||
| 1378 | .init_verbs = { alc662_init_verbs, | ||
| 1379 | alc662_eapd_init_verbs, | ||
| 1380 | alc272_dell_zm1_init_verbs }, | ||
| 1381 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
| 1382 | .dac_nids = alc272_dac_nids, | ||
| 1383 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1384 | .adc_nids = alc662_adc_nids, | ||
| 1385 | .num_adc_nids = 1, | ||
| 1386 | .capsrc_nids = alc662_capsrc_nids, | ||
| 1387 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1388 | .unsol_event = alc_sku_unsol_event, | ||
| 1389 | .setup = alc663_m51va_setup, | ||
| 1390 | .init_hook = alc_inithook, | ||
| 1391 | }, | ||
| 1392 | [ALC272_SAMSUNG_NC10] = { | ||
| 1393 | .mixers = { alc272_nc10_mixer }, | ||
| 1394 | .init_verbs = { alc662_init_verbs, | ||
| 1395 | alc662_eapd_init_verbs, | ||
| 1396 | alc663_21jd_amic_init_verbs }, | ||
| 1397 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | ||
| 1398 | .dac_nids = alc272_dac_nids, | ||
| 1399 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | ||
| 1400 | .channel_mode = alc662_3ST_2ch_modes, | ||
| 1401 | /*.input_mux = &alc272_nc10_capture_source,*/ | ||
| 1402 | .unsol_event = alc_sku_unsol_event, | ||
| 1403 | .setup = alc663_mode4_setup, | ||
| 1404 | .init_hook = alc_inithook, | ||
| 1405 | }, | ||
| 1406 | }; | ||
| 1407 | |||
| 1408 | |||
diff --git a/sound/pci/hda/alc680_quirks.c b/sound/pci/hda/alc680_quirks.c deleted file mode 100644 index 0eeb227c7bc2..000000000000 --- a/sound/pci/hda/alc680_quirks.c +++ /dev/null | |||
| @@ -1,222 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ALC680 quirk models | ||
| 3 | * included by patch_realtek.c | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* ALC680 models */ | ||
| 7 | enum { | ||
| 8 | ALC680_AUTO, | ||
| 9 | ALC680_BASE, | ||
| 10 | ALC680_MODEL_LAST, | ||
| 11 | }; | ||
| 12 | |||
| 13 | #define ALC680_DIGIN_NID ALC880_DIGIN_NID | ||
| 14 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID | ||
| 15 | #define alc680_modes alc260_modes | ||
| 16 | |||
| 17 | static const hda_nid_t alc680_dac_nids[3] = { | ||
| 18 | /* Lout1, Lout2, hp */ | ||
| 19 | 0x02, 0x03, 0x04 | ||
| 20 | }; | ||
| 21 | |||
| 22 | static const hda_nid_t alc680_adc_nids[3] = { | ||
| 23 | /* ADC0-2 */ | ||
| 24 | /* DMIC, MIC, Line-in*/ | ||
| 25 | 0x07, 0x08, 0x09 | ||
| 26 | }; | ||
| 27 | |||
| 28 | /* | ||
| 29 | * Analog capture ADC cgange | ||
| 30 | */ | ||
| 31 | static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec) | ||
| 32 | { | ||
| 33 | static hda_nid_t pins[] = {0x18, 0x19}; | ||
| 34 | static hda_nid_t adcs[] = {0x08, 0x09}; | ||
| 35 | int i; | ||
| 36 | |||
| 37 | for (i = 0; i < ARRAY_SIZE(pins); i++) { | ||
| 38 | if (!is_jack_detectable(codec, pins[i])) | ||
| 39 | continue; | ||
| 40 | if (snd_hda_jack_detect(codec, pins[i])) | ||
| 41 | return adcs[i]; | ||
| 42 | } | ||
| 43 | return 0x07; | ||
| 44 | } | ||
| 45 | |||
| 46 | static void alc680_rec_autoswitch(struct hda_codec *codec) | ||
| 47 | { | ||
| 48 | struct alc_spec *spec = codec->spec; | ||
| 49 | hda_nid_t nid = alc680_get_cur_adc(codec); | ||
| 50 | if (spec->cur_adc && nid != spec->cur_adc) { | ||
| 51 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
| 52 | spec->cur_adc = nid; | ||
| 53 | snd_hda_codec_setup_stream(codec, nid, | ||
| 54 | spec->cur_adc_stream_tag, 0, | ||
| 55 | spec->cur_adc_format); | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
| 60 | struct hda_codec *codec, | ||
| 61 | unsigned int stream_tag, | ||
| 62 | unsigned int format, | ||
| 63 | struct snd_pcm_substream *substream) | ||
| 64 | { | ||
| 65 | struct alc_spec *spec = codec->spec; | ||
| 66 | hda_nid_t nid = alc680_get_cur_adc(codec); | ||
| 67 | |||
| 68 | spec->cur_adc = nid; | ||
| 69 | spec->cur_adc_stream_tag = stream_tag; | ||
| 70 | spec->cur_adc_format = format; | ||
| 71 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | ||
| 72 | return 0; | ||
| 73 | } | ||
| 74 | |||
| 75 | static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
| 76 | struct hda_codec *codec, | ||
| 77 | struct snd_pcm_substream *substream) | ||
| 78 | { | ||
| 79 | struct alc_spec *spec = codec->spec; | ||
| 80 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
| 81 | spec->cur_adc = 0; | ||
| 82 | return 0; | ||
| 83 | } | ||
| 84 | |||
| 85 | static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = { | ||
| 86 | .substreams = 1, /* can be overridden */ | ||
| 87 | .channels_min = 2, | ||
| 88 | .channels_max = 2, | ||
| 89 | /* NID is set in alc_build_pcms */ | ||
| 90 | .ops = { | ||
| 91 | .prepare = alc680_capture_pcm_prepare, | ||
| 92 | .cleanup = alc680_capture_pcm_cleanup | ||
| 93 | }, | ||
| 94 | }; | ||
| 95 | |||
| 96 | static const struct snd_kcontrol_new alc680_base_mixer[] = { | ||
| 97 | /* output mixer control */ | ||
| 98 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | ||
| 99 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 100 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), | ||
| 101 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), | ||
| 102 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT), | ||
| 103 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 104 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 105 | { } | ||
| 106 | }; | ||
| 107 | |||
| 108 | static const struct hda_bind_ctls alc680_bind_cap_vol = { | ||
| 109 | .ops = &snd_hda_bind_vol, | ||
| 110 | .values = { | ||
| 111 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | ||
| 112 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | ||
| 113 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
| 114 | 0 | ||
| 115 | }, | ||
| 116 | }; | ||
| 117 | |||
| 118 | static const struct hda_bind_ctls alc680_bind_cap_switch = { | ||
| 119 | .ops = &snd_hda_bind_sw, | ||
| 120 | .values = { | ||
| 121 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | ||
| 122 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | ||
| 123 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | ||
| 124 | 0 | ||
| 125 | }, | ||
| 126 | }; | ||
| 127 | |||
| 128 | static const struct snd_kcontrol_new alc680_master_capture_mixer[] = { | ||
| 129 | HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), | ||
| 130 | HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), | ||
| 131 | { } /* end */ | ||
| 132 | }; | ||
| 133 | |||
| 134 | /* | ||
| 135 | * generic initialization of ADC, input mixers and output mixers | ||
| 136 | */ | ||
| 137 | static const struct hda_verb alc680_init_verbs[] = { | ||
| 138 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 139 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 140 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 141 | |||
| 142 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 143 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 144 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 145 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 146 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 147 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 148 | |||
| 149 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 150 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 151 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 152 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 153 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 154 | |||
| 155 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
| 156 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, | ||
| 157 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_MIC_EVENT | AC_USRSP_EN}, | ||
| 158 | |||
| 159 | { } | ||
| 160 | }; | ||
| 161 | |||
| 162 | /* toggle speaker-output according to the hp-jack state */ | ||
| 163 | static void alc680_base_setup(struct hda_codec *codec) | ||
| 164 | { | ||
| 165 | struct alc_spec *spec = codec->spec; | ||
| 166 | |||
| 167 | spec->autocfg.hp_pins[0] = 0x16; | ||
| 168 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 169 | spec->autocfg.speaker_pins[1] = 0x15; | ||
| 170 | spec->autocfg.num_inputs = 2; | ||
| 171 | spec->autocfg.inputs[0].pin = 0x18; | ||
| 172 | spec->autocfg.inputs[0].type = AUTO_PIN_MIC; | ||
| 173 | spec->autocfg.inputs[1].pin = 0x19; | ||
| 174 | spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; | ||
| 175 | spec->automute = 1; | ||
| 176 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 177 | } | ||
| 178 | |||
| 179 | static void alc680_unsol_event(struct hda_codec *codec, | ||
| 180 | unsigned int res) | ||
| 181 | { | ||
| 182 | if ((res >> 26) == ALC_HP_EVENT) | ||
| 183 | alc_hp_automute(codec); | ||
| 184 | if ((res >> 26) == ALC_MIC_EVENT) | ||
| 185 | alc680_rec_autoswitch(codec); | ||
| 186 | } | ||
| 187 | |||
| 188 | static void alc680_inithook(struct hda_codec *codec) | ||
| 189 | { | ||
| 190 | alc_hp_automute(codec); | ||
| 191 | alc680_rec_autoswitch(codec); | ||
| 192 | } | ||
| 193 | |||
| 194 | /* | ||
| 195 | * configuration and preset | ||
| 196 | */ | ||
| 197 | static const char * const alc680_models[ALC680_MODEL_LAST] = { | ||
| 198 | [ALC680_BASE] = "base", | ||
| 199 | [ALC680_AUTO] = "auto", | ||
| 200 | }; | ||
| 201 | |||
| 202 | static const struct snd_pci_quirk alc680_cfg_tbl[] = { | ||
| 203 | SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), | ||
| 204 | {} | ||
| 205 | }; | ||
| 206 | |||
| 207 | static const struct alc_config_preset alc680_presets[] = { | ||
| 208 | [ALC680_BASE] = { | ||
| 209 | .mixers = { alc680_base_mixer }, | ||
| 210 | .cap_mixer = alc680_master_capture_mixer, | ||
| 211 | .init_verbs = { alc680_init_verbs }, | ||
| 212 | .num_dacs = ARRAY_SIZE(alc680_dac_nids), | ||
| 213 | .dac_nids = alc680_dac_nids, | ||
| 214 | .dig_out_nid = ALC680_DIGOUT_NID, | ||
| 215 | .num_channel_mode = ARRAY_SIZE(alc680_modes), | ||
| 216 | .channel_mode = alc680_modes, | ||
| 217 | .unsol_event = alc680_unsol_event, | ||
| 218 | .setup = alc680_base_setup, | ||
| 219 | .init_hook = alc680_inithook, | ||
| 220 | |||
| 221 | }, | ||
| 222 | }; | ||
diff --git a/sound/pci/hda/alc861_quirks.c b/sound/pci/hda/alc861_quirks.c deleted file mode 100644 index d719ec6350eb..000000000000 --- a/sound/pci/hda/alc861_quirks.c +++ /dev/null | |||
| @@ -1,725 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ALC660/ALC861 quirk models | ||
| 3 | * included by patch_realtek.c | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* ALC861 models */ | ||
| 7 | enum { | ||
| 8 | ALC861_AUTO, | ||
| 9 | ALC861_3ST, | ||
| 10 | ALC660_3ST, | ||
| 11 | ALC861_3ST_DIG, | ||
| 12 | ALC861_6ST_DIG, | ||
| 13 | ALC861_UNIWILL_M31, | ||
| 14 | ALC861_TOSHIBA, | ||
| 15 | ALC861_ASUS, | ||
| 16 | ALC861_ASUS_LAPTOP, | ||
| 17 | ALC861_MODEL_LAST, | ||
| 18 | }; | ||
| 19 | |||
| 20 | /* | ||
| 21 | * ALC861 channel source setting (2/6 channel selection for 3-stack) | ||
| 22 | */ | ||
| 23 | |||
| 24 | /* | ||
| 25 | * set the path ways for 2 channel output | ||
| 26 | * need to set the codec line out and mic 1 pin widgets to inputs | ||
| 27 | */ | ||
| 28 | static const struct hda_verb alc861_threestack_ch2_init[] = { | ||
| 29 | /* set pin widget 1Ah (line in) for input */ | ||
| 30 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 31 | /* set pin widget 18h (mic1/2) for input, for mic also enable | ||
| 32 | * the vref | ||
| 33 | */ | ||
| 34 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 35 | |||
| 36 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | ||
| 37 | #if 0 | ||
| 38 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ | ||
| 39 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ | ||
| 40 | #endif | ||
| 41 | { } /* end */ | ||
| 42 | }; | ||
| 43 | /* | ||
| 44 | * 6ch mode | ||
| 45 | * need to set the codec line out and mic 1 pin widgets to outputs | ||
| 46 | */ | ||
| 47 | static const struct hda_verb alc861_threestack_ch6_init[] = { | ||
| 48 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ | ||
| 49 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 50 | /* set pin widget 18h (mic1) for output (CLFE)*/ | ||
| 51 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 52 | |||
| 53 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 54 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 55 | |||
| 56 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | ||
| 57 | #if 0 | ||
| 58 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ | ||
| 59 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ | ||
| 60 | #endif | ||
| 61 | { } /* end */ | ||
| 62 | }; | ||
| 63 | |||
| 64 | static const struct hda_channel_mode alc861_threestack_modes[2] = { | ||
| 65 | { 2, alc861_threestack_ch2_init }, | ||
| 66 | { 6, alc861_threestack_ch6_init }, | ||
| 67 | }; | ||
| 68 | /* Set mic1 as input and unmute the mixer */ | ||
| 69 | static const struct hda_verb alc861_uniwill_m31_ch2_init[] = { | ||
| 70 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 71 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ | ||
| 72 | { } /* end */ | ||
| 73 | }; | ||
| 74 | /* Set mic1 as output and mute mixer */ | ||
| 75 | static const struct hda_verb alc861_uniwill_m31_ch4_init[] = { | ||
| 76 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 77 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ | ||
| 78 | { } /* end */ | ||
| 79 | }; | ||
| 80 | |||
| 81 | static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = { | ||
| 82 | { 2, alc861_uniwill_m31_ch2_init }, | ||
| 83 | { 4, alc861_uniwill_m31_ch4_init }, | ||
| 84 | }; | ||
| 85 | |||
| 86 | /* Set mic1 and line-in as input and unmute the mixer */ | ||
| 87 | static const struct hda_verb alc861_asus_ch2_init[] = { | ||
| 88 | /* set pin widget 1Ah (line in) for input */ | ||
| 89 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 90 | /* set pin widget 18h (mic1/2) for input, for mic also enable | ||
| 91 | * the vref | ||
| 92 | */ | ||
| 93 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 94 | |||
| 95 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, | ||
| 96 | #if 0 | ||
| 97 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ | ||
| 98 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/ | ||
| 99 | #endif | ||
| 100 | { } /* end */ | ||
| 101 | }; | ||
| 102 | /* Set mic1 nad line-in as output and mute mixer */ | ||
| 103 | static const struct hda_verb alc861_asus_ch6_init[] = { | ||
| 104 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ | ||
| 105 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 106 | /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ | ||
| 107 | /* set pin widget 18h (mic1) for output (CLFE)*/ | ||
| 108 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 109 | /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ | ||
| 110 | { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 111 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 112 | |||
| 113 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, | ||
| 114 | #if 0 | ||
| 115 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ | ||
| 116 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/ | ||
| 117 | #endif | ||
| 118 | { } /* end */ | ||
| 119 | }; | ||
| 120 | |||
| 121 | static const struct hda_channel_mode alc861_asus_modes[2] = { | ||
| 122 | { 2, alc861_asus_ch2_init }, | ||
| 123 | { 6, alc861_asus_ch6_init }, | ||
| 124 | }; | ||
| 125 | |||
| 126 | /* patch-ALC861 */ | ||
| 127 | |||
| 128 | static const struct snd_kcontrol_new alc861_base_mixer[] = { | ||
| 129 | /* output mixer control */ | ||
| 130 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
| 131 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
| 132 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), | ||
| 133 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), | ||
| 134 | HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), | ||
| 135 | |||
| 136 | /*Input mixer control */ | ||
| 137 | /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
| 138 | HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ | ||
| 139 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
| 140 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
| 141 | HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), | ||
| 142 | HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), | ||
| 143 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
| 144 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
| 145 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | ||
| 146 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | ||
| 147 | |||
| 148 | { } /* end */ | ||
| 149 | }; | ||
| 150 | |||
| 151 | static const struct snd_kcontrol_new alc861_3ST_mixer[] = { | ||
| 152 | /* output mixer control */ | ||
| 153 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
| 154 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
| 155 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), | ||
| 156 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), | ||
| 157 | /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ | ||
| 158 | |||
| 159 | /* Input mixer control */ | ||
| 160 | /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
| 161 | HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ | ||
| 162 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
| 163 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
| 164 | HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), | ||
| 165 | HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), | ||
| 166 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
| 167 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
| 168 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | ||
| 169 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | ||
| 170 | |||
| 171 | { | ||
| 172 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 173 | .name = "Channel Mode", | ||
| 174 | .info = alc_ch_mode_info, | ||
| 175 | .get = alc_ch_mode_get, | ||
| 176 | .put = alc_ch_mode_put, | ||
| 177 | .private_value = ARRAY_SIZE(alc861_threestack_modes), | ||
| 178 | }, | ||
| 179 | { } /* end */ | ||
| 180 | }; | ||
| 181 | |||
| 182 | static const struct snd_kcontrol_new alc861_toshiba_mixer[] = { | ||
| 183 | /* output mixer control */ | ||
| 184 | HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
| 185 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
| 186 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
| 187 | |||
| 188 | { } /* end */ | ||
| 189 | }; | ||
| 190 | |||
| 191 | static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | ||
| 192 | /* output mixer control */ | ||
| 193 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
| 194 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
| 195 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), | ||
| 196 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), | ||
| 197 | /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */ | ||
| 198 | |||
| 199 | /* Input mixer control */ | ||
| 200 | /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
| 201 | HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */ | ||
| 202 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
| 203 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
| 204 | HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), | ||
| 205 | HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), | ||
| 206 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
| 207 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
| 208 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | ||
| 209 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), | ||
| 210 | |||
| 211 | { | ||
| 212 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 213 | .name = "Channel Mode", | ||
| 214 | .info = alc_ch_mode_info, | ||
| 215 | .get = alc_ch_mode_get, | ||
| 216 | .put = alc_ch_mode_put, | ||
| 217 | .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), | ||
| 218 | }, | ||
| 219 | { } /* end */ | ||
| 220 | }; | ||
| 221 | |||
| 222 | static const struct snd_kcontrol_new alc861_asus_mixer[] = { | ||
| 223 | /* output mixer control */ | ||
| 224 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | ||
| 225 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | ||
| 226 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT), | ||
| 227 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT), | ||
| 228 | HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), | ||
| 229 | |||
| 230 | /* Input mixer control */ | ||
| 231 | HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT), | ||
| 232 | HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
| 233 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
| 234 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
| 235 | HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT), | ||
| 236 | HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT), | ||
| 237 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | ||
| 238 | HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), | ||
| 239 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), | ||
| 240 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), | ||
| 241 | |||
| 242 | { | ||
| 243 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 244 | .name = "Channel Mode", | ||
| 245 | .info = alc_ch_mode_info, | ||
| 246 | .get = alc_ch_mode_get, | ||
| 247 | .put = alc_ch_mode_put, | ||
| 248 | .private_value = ARRAY_SIZE(alc861_asus_modes), | ||
| 249 | }, | ||
| 250 | { } | ||
| 251 | }; | ||
| 252 | |||
| 253 | /* additional mixer */ | ||
| 254 | static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { | ||
| 255 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | ||
| 256 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | ||
| 257 | { } | ||
| 258 | }; | ||
| 259 | |||
| 260 | /* | ||
| 261 | * generic initialization of ADC, input mixers and output mixers | ||
| 262 | */ | ||
| 263 | static const struct hda_verb alc861_base_init_verbs[] = { | ||
| 264 | /* | ||
| 265 | * Unmute ADC0 and set the default input to mic-in | ||
| 266 | */ | ||
| 267 | /* port-A for surround (rear panel) */ | ||
| 268 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 269 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 270 | /* port-B for mic-in (rear panel) with vref */ | ||
| 271 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 272 | /* port-C for line-in (rear panel) */ | ||
| 273 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 274 | /* port-D for Front */ | ||
| 275 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 276 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 277 | /* port-E for HP out (front panel) */ | ||
| 278 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | ||
| 279 | /* route front PCM to HP */ | ||
| 280 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 281 | /* port-F for mic-in (front panel) with vref */ | ||
| 282 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 283 | /* port-G for CLFE (rear panel) */ | ||
| 284 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 285 | { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 286 | /* port-H for side (rear panel) */ | ||
| 287 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 288 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 289 | /* CD-in */ | ||
| 290 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 291 | /* route front mic to ADC1*/ | ||
| 292 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 293 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 294 | |||
| 295 | /* Unmute DAC0~3 & spdif out*/ | ||
| 296 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 297 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 298 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 299 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 300 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 301 | |||
| 302 | /* Unmute Mixer 14 (mic) 1c (Line in)*/ | ||
| 303 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 304 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 305 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 306 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 307 | |||
| 308 | /* Unmute Stereo Mixer 15 */ | ||
| 309 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 310 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 311 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 312 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ | ||
| 313 | |||
| 314 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 315 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 316 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 317 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 318 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 319 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 320 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 321 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 322 | /* hp used DAC 3 (Front) */ | ||
| 323 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
| 324 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 325 | |||
| 326 | { } | ||
| 327 | }; | ||
| 328 | |||
| 329 | static const struct hda_verb alc861_threestack_init_verbs[] = { | ||
| 330 | /* | ||
| 331 | * Unmute ADC0 and set the default input to mic-in | ||
| 332 | */ | ||
| 333 | /* port-A for surround (rear panel) */ | ||
| 334 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 335 | /* port-B for mic-in (rear panel) with vref */ | ||
| 336 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 337 | /* port-C for line-in (rear panel) */ | ||
| 338 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 339 | /* port-D for Front */ | ||
| 340 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 341 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 342 | /* port-E for HP out (front panel) */ | ||
| 343 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, | ||
| 344 | /* route front PCM to HP */ | ||
| 345 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 346 | /* port-F for mic-in (front panel) with vref */ | ||
| 347 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 348 | /* port-G for CLFE (rear panel) */ | ||
| 349 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 350 | /* port-H for side (rear panel) */ | ||
| 351 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 352 | /* CD-in */ | ||
| 353 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 354 | /* route front mic to ADC1*/ | ||
| 355 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 356 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 357 | /* Unmute DAC0~3 & spdif out*/ | ||
| 358 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 359 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 360 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 361 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 362 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 363 | |||
| 364 | /* Unmute Mixer 14 (mic) 1c (Line in)*/ | ||
| 365 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 366 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 367 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 368 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 369 | |||
| 370 | /* Unmute Stereo Mixer 15 */ | ||
| 371 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 372 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 373 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 374 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ | ||
| 375 | |||
| 376 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 377 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 378 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 379 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 380 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 381 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 382 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 383 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 384 | /* hp used DAC 3 (Front) */ | ||
| 385 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
| 386 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 387 | { } | ||
| 388 | }; | ||
| 389 | |||
| 390 | static const struct hda_verb alc861_uniwill_m31_init_verbs[] = { | ||
| 391 | /* | ||
| 392 | * Unmute ADC0 and set the default input to mic-in | ||
| 393 | */ | ||
| 394 | /* port-A for surround (rear panel) */ | ||
| 395 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 396 | /* port-B for mic-in (rear panel) with vref */ | ||
| 397 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 398 | /* port-C for line-in (rear panel) */ | ||
| 399 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 400 | /* port-D for Front */ | ||
| 401 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 402 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 403 | /* port-E for HP out (front panel) */ | ||
| 404 | /* this has to be set to VREF80 */ | ||
| 405 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 406 | /* route front PCM to HP */ | ||
| 407 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 408 | /* port-F for mic-in (front panel) with vref */ | ||
| 409 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 410 | /* port-G for CLFE (rear panel) */ | ||
| 411 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 412 | /* port-H for side (rear panel) */ | ||
| 413 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 414 | /* CD-in */ | ||
| 415 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 416 | /* route front mic to ADC1*/ | ||
| 417 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 418 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 419 | /* Unmute DAC0~3 & spdif out*/ | ||
| 420 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 421 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 422 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 423 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 424 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 425 | |||
| 426 | /* Unmute Mixer 14 (mic) 1c (Line in)*/ | ||
| 427 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 428 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 429 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 430 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 431 | |||
| 432 | /* Unmute Stereo Mixer 15 */ | ||
| 433 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 434 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 435 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 436 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ | ||
| 437 | |||
| 438 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 439 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 440 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 441 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 442 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 443 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 444 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 445 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 446 | /* hp used DAC 3 (Front) */ | ||
| 447 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
| 448 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 449 | { } | ||
| 450 | }; | ||
| 451 | |||
| 452 | static const struct hda_verb alc861_asus_init_verbs[] = { | ||
| 453 | /* | ||
| 454 | * Unmute ADC0 and set the default input to mic-in | ||
| 455 | */ | ||
| 456 | /* port-A for surround (rear panel) | ||
| 457 | * according to codec#0 this is the HP jack | ||
| 458 | */ | ||
| 459 | { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ | ||
| 460 | /* route front PCM to HP */ | ||
| 461 | { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, | ||
| 462 | /* port-B for mic-in (rear panel) with vref */ | ||
| 463 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 464 | /* port-C for line-in (rear panel) */ | ||
| 465 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 466 | /* port-D for Front */ | ||
| 467 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 468 | { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 469 | /* port-E for HP out (front panel) */ | ||
| 470 | /* this has to be set to VREF80 */ | ||
| 471 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 472 | /* route front PCM to HP */ | ||
| 473 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, | ||
| 474 | /* port-F for mic-in (front panel) with vref */ | ||
| 475 | { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | ||
| 476 | /* port-G for CLFE (rear panel) */ | ||
| 477 | { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 478 | /* port-H for side (rear panel) */ | ||
| 479 | { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | ||
| 480 | /* CD-in */ | ||
| 481 | { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | ||
| 482 | /* route front mic to ADC1*/ | ||
| 483 | {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 484 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 485 | /* Unmute DAC0~3 & spdif out*/ | ||
| 486 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 487 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 488 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 489 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 490 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 491 | /* Unmute Mixer 14 (mic) 1c (Line in)*/ | ||
| 492 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 493 | {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 494 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 495 | {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 496 | |||
| 497 | /* Unmute Stereo Mixer 15 */ | ||
| 498 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 499 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 500 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 501 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ | ||
| 502 | |||
| 503 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 504 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 505 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 506 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 507 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 508 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 509 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 510 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 511 | /* hp used DAC 3 (Front) */ | ||
| 512 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | ||
| 513 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 514 | { } | ||
| 515 | }; | ||
| 516 | |||
| 517 | /* additional init verbs for ASUS laptops */ | ||
| 518 | static const struct hda_verb alc861_asus_laptop_init_verbs[] = { | ||
| 519 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ | ||
| 520 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ | ||
| 521 | { } | ||
| 522 | }; | ||
| 523 | |||
| 524 | static const struct hda_verb alc861_toshiba_init_verbs[] = { | ||
| 525 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 526 | |||
| 527 | { } | ||
| 528 | }; | ||
| 529 | |||
| 530 | /* toggle speaker-output according to the hp-jack state */ | ||
| 531 | static void alc861_toshiba_automute(struct hda_codec *codec) | ||
| 532 | { | ||
| 533 | unsigned int present = snd_hda_jack_detect(codec, 0x0f); | ||
| 534 | |||
| 535 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0, | ||
| 536 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
| 537 | snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3, | ||
| 538 | HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE); | ||
| 539 | } | ||
| 540 | |||
| 541 | static void alc861_toshiba_unsol_event(struct hda_codec *codec, | ||
| 542 | unsigned int res) | ||
| 543 | { | ||
| 544 | if ((res >> 26) == ALC_HP_EVENT) | ||
| 545 | alc861_toshiba_automute(codec); | ||
| 546 | } | ||
| 547 | |||
| 548 | #define ALC861_DIGOUT_NID 0x07 | ||
| 549 | |||
| 550 | static const struct hda_channel_mode alc861_8ch_modes[1] = { | ||
| 551 | { 8, NULL } | ||
| 552 | }; | ||
| 553 | |||
| 554 | static const hda_nid_t alc861_dac_nids[4] = { | ||
| 555 | /* front, surround, clfe, side */ | ||
| 556 | 0x03, 0x06, 0x05, 0x04 | ||
| 557 | }; | ||
| 558 | |||
| 559 | static const hda_nid_t alc660_dac_nids[3] = { | ||
| 560 | /* front, clfe, surround */ | ||
| 561 | 0x03, 0x05, 0x06 | ||
| 562 | }; | ||
| 563 | |||
| 564 | static const hda_nid_t alc861_adc_nids[1] = { | ||
| 565 | /* ADC0-2 */ | ||
| 566 | 0x08, | ||
| 567 | }; | ||
| 568 | |||
| 569 | static const struct hda_input_mux alc861_capture_source = { | ||
| 570 | .num_items = 5, | ||
| 571 | .items = { | ||
| 572 | { "Mic", 0x0 }, | ||
| 573 | { "Front Mic", 0x3 }, | ||
| 574 | { "Line", 0x1 }, | ||
| 575 | { "CD", 0x4 }, | ||
| 576 | { "Mixer", 0x5 }, | ||
| 577 | }, | ||
| 578 | }; | ||
| 579 | |||
| 580 | /* | ||
| 581 | * configuration and preset | ||
| 582 | */ | ||
| 583 | static const char * const alc861_models[ALC861_MODEL_LAST] = { | ||
| 584 | [ALC861_3ST] = "3stack", | ||
| 585 | [ALC660_3ST] = "3stack-660", | ||
| 586 | [ALC861_3ST_DIG] = "3stack-dig", | ||
| 587 | [ALC861_6ST_DIG] = "6stack-dig", | ||
| 588 | [ALC861_UNIWILL_M31] = "uniwill-m31", | ||
| 589 | [ALC861_TOSHIBA] = "toshiba", | ||
| 590 | [ALC861_ASUS] = "asus", | ||
| 591 | [ALC861_ASUS_LAPTOP] = "asus-laptop", | ||
| 592 | [ALC861_AUTO] = "auto", | ||
| 593 | }; | ||
| 594 | |||
| 595 | static const struct snd_pci_quirk alc861_cfg_tbl[] = { | ||
| 596 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), | ||
| 597 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), | ||
| 598 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), | ||
| 599 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), | ||
| 600 | SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), | ||
| 601 | SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG), | ||
| 602 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), | ||
| 603 | /* FIXME: the entry below breaks Toshiba A100 (model=auto works!) | ||
| 604 | * Any other models that need this preset? | ||
| 605 | */ | ||
| 606 | /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */ | ||
| 607 | SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST), | ||
| 608 | SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST), | ||
| 609 | SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), | ||
| 610 | SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), | ||
| 611 | SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP), | ||
| 612 | /* FIXME: the below seems conflict */ | ||
| 613 | /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */ | ||
| 614 | SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), | ||
| 615 | SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), | ||
| 616 | {} | ||
| 617 | }; | ||
| 618 | |||
| 619 | static const struct alc_config_preset alc861_presets[] = { | ||
| 620 | [ALC861_3ST] = { | ||
| 621 | .mixers = { alc861_3ST_mixer }, | ||
| 622 | .init_verbs = { alc861_threestack_init_verbs }, | ||
| 623 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 624 | .dac_nids = alc861_dac_nids, | ||
| 625 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | ||
| 626 | .channel_mode = alc861_threestack_modes, | ||
| 627 | .need_dac_fix = 1, | ||
| 628 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 629 | .adc_nids = alc861_adc_nids, | ||
| 630 | .input_mux = &alc861_capture_source, | ||
| 631 | }, | ||
| 632 | [ALC861_3ST_DIG] = { | ||
| 633 | .mixers = { alc861_base_mixer }, | ||
| 634 | .init_verbs = { alc861_threestack_init_verbs }, | ||
| 635 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 636 | .dac_nids = alc861_dac_nids, | ||
| 637 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
| 638 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | ||
| 639 | .channel_mode = alc861_threestack_modes, | ||
| 640 | .need_dac_fix = 1, | ||
| 641 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 642 | .adc_nids = alc861_adc_nids, | ||
| 643 | .input_mux = &alc861_capture_source, | ||
| 644 | }, | ||
| 645 | [ALC861_6ST_DIG] = { | ||
| 646 | .mixers = { alc861_base_mixer }, | ||
| 647 | .init_verbs = { alc861_base_init_verbs }, | ||
| 648 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 649 | .dac_nids = alc861_dac_nids, | ||
| 650 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
| 651 | .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes), | ||
| 652 | .channel_mode = alc861_8ch_modes, | ||
| 653 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 654 | .adc_nids = alc861_adc_nids, | ||
| 655 | .input_mux = &alc861_capture_source, | ||
| 656 | }, | ||
| 657 | [ALC660_3ST] = { | ||
| 658 | .mixers = { alc861_3ST_mixer }, | ||
| 659 | .init_verbs = { alc861_threestack_init_verbs }, | ||
| 660 | .num_dacs = ARRAY_SIZE(alc660_dac_nids), | ||
| 661 | .dac_nids = alc660_dac_nids, | ||
| 662 | .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes), | ||
| 663 | .channel_mode = alc861_threestack_modes, | ||
| 664 | .need_dac_fix = 1, | ||
| 665 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 666 | .adc_nids = alc861_adc_nids, | ||
| 667 | .input_mux = &alc861_capture_source, | ||
| 668 | }, | ||
| 669 | [ALC861_UNIWILL_M31] = { | ||
| 670 | .mixers = { alc861_uniwill_m31_mixer }, | ||
| 671 | .init_verbs = { alc861_uniwill_m31_init_verbs }, | ||
| 672 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 673 | .dac_nids = alc861_dac_nids, | ||
| 674 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
| 675 | .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes), | ||
| 676 | .channel_mode = alc861_uniwill_m31_modes, | ||
| 677 | .need_dac_fix = 1, | ||
| 678 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 679 | .adc_nids = alc861_adc_nids, | ||
| 680 | .input_mux = &alc861_capture_source, | ||
| 681 | }, | ||
| 682 | [ALC861_TOSHIBA] = { | ||
| 683 | .mixers = { alc861_toshiba_mixer }, | ||
| 684 | .init_verbs = { alc861_base_init_verbs, | ||
| 685 | alc861_toshiba_init_verbs }, | ||
| 686 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 687 | .dac_nids = alc861_dac_nids, | ||
| 688 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
| 689 | .channel_mode = alc883_3ST_2ch_modes, | ||
| 690 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 691 | .adc_nids = alc861_adc_nids, | ||
| 692 | .input_mux = &alc861_capture_source, | ||
| 693 | .unsol_event = alc861_toshiba_unsol_event, | ||
| 694 | .init_hook = alc861_toshiba_automute, | ||
| 695 | }, | ||
| 696 | [ALC861_ASUS] = { | ||
| 697 | .mixers = { alc861_asus_mixer }, | ||
| 698 | .init_verbs = { alc861_asus_init_verbs }, | ||
| 699 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 700 | .dac_nids = alc861_dac_nids, | ||
| 701 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
| 702 | .num_channel_mode = ARRAY_SIZE(alc861_asus_modes), | ||
| 703 | .channel_mode = alc861_asus_modes, | ||
| 704 | .need_dac_fix = 1, | ||
| 705 | .hp_nid = 0x06, | ||
| 706 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 707 | .adc_nids = alc861_adc_nids, | ||
| 708 | .input_mux = &alc861_capture_source, | ||
| 709 | }, | ||
| 710 | [ALC861_ASUS_LAPTOP] = { | ||
| 711 | .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer }, | ||
| 712 | .init_verbs = { alc861_asus_init_verbs, | ||
| 713 | alc861_asus_laptop_init_verbs }, | ||
| 714 | .num_dacs = ARRAY_SIZE(alc861_dac_nids), | ||
| 715 | .dac_nids = alc861_dac_nids, | ||
| 716 | .dig_out_nid = ALC861_DIGOUT_NID, | ||
| 717 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
| 718 | .channel_mode = alc883_3ST_2ch_modes, | ||
| 719 | .need_dac_fix = 1, | ||
| 720 | .num_adc_nids = ARRAY_SIZE(alc861_adc_nids), | ||
| 721 | .adc_nids = alc861_adc_nids, | ||
| 722 | .input_mux = &alc861_capture_source, | ||
| 723 | }, | ||
| 724 | }; | ||
| 725 | |||
diff --git a/sound/pci/hda/alc861vd_quirks.c b/sound/pci/hda/alc861vd_quirks.c deleted file mode 100644 index 8f28450f41f8..000000000000 --- a/sound/pci/hda/alc861vd_quirks.c +++ /dev/null | |||
| @@ -1,605 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ALC660-VD/ALC861-VD quirk models | ||
| 3 | * included by patch_realtek.c | ||
| 4 | */ | ||
| 5 | |||
| 6 | /* ALC861-VD models */ | ||
| 7 | enum { | ||
| 8 | ALC861VD_AUTO, | ||
| 9 | ALC660VD_3ST, | ||
| 10 | ALC660VD_3ST_DIG, | ||
| 11 | ALC660VD_ASUS_V1S, | ||
| 12 | ALC861VD_3ST, | ||
| 13 | ALC861VD_3ST_DIG, | ||
| 14 | ALC861VD_6ST_DIG, | ||
| 15 | ALC861VD_LENOVO, | ||
| 16 | ALC861VD_DALLAS, | ||
| 17 | ALC861VD_HP, | ||
| 18 | ALC861VD_MODEL_LAST, | ||
| 19 | }; | ||
| 20 | |||
| 21 | #define ALC861VD_DIGOUT_NID 0x06 | ||
| 22 | |||
| 23 | static const hda_nid_t alc861vd_dac_nids[4] = { | ||
| 24 | /* front, surr, clfe, side surr */ | ||
| 25 | 0x02, 0x03, 0x04, 0x05 | ||
| 26 | }; | ||
| 27 | |||
| 28 | /* dac_nids for ALC660vd are in a different order - according to | ||
| 29 | * Realtek's driver. | ||
| 30 | * This should probably result in a different mixer for 6stack models | ||
| 31 | * of ALC660vd codecs, but for now there is only 3stack mixer | ||
| 32 | * - and it is the same as in 861vd. | ||
| 33 | * adc_nids in ALC660vd are (is) the same as in 861vd | ||
| 34 | */ | ||
| 35 | static const hda_nid_t alc660vd_dac_nids[3] = { | ||
| 36 | /* front, rear, clfe, rear_surr */ | ||
| 37 | 0x02, 0x04, 0x03 | ||
| 38 | }; | ||
| 39 | |||
| 40 | static const hda_nid_t alc861vd_adc_nids[1] = { | ||
| 41 | /* ADC0 */ | ||
| 42 | 0x09, | ||
| 43 | }; | ||
| 44 | |||
| 45 | static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; | ||
| 46 | |||
| 47 | /* input MUX */ | ||
| 48 | /* FIXME: should be a matrix-type input source selection */ | ||
| 49 | static const struct hda_input_mux alc861vd_capture_source = { | ||
| 50 | .num_items = 4, | ||
| 51 | .items = { | ||
| 52 | { "Mic", 0x0 }, | ||
| 53 | { "Front Mic", 0x1 }, | ||
| 54 | { "Line", 0x2 }, | ||
| 55 | { "CD", 0x4 }, | ||
| 56 | }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static const struct hda_input_mux alc861vd_dallas_capture_source = { | ||
| 60 | .num_items = 2, | ||
| 61 | .items = { | ||
| 62 | { "Mic", 0x0 }, | ||
| 63 | { "Internal Mic", 0x1 }, | ||
| 64 | }, | ||
| 65 | }; | ||
| 66 | |||
| 67 | static const struct hda_input_mux alc861vd_hp_capture_source = { | ||
| 68 | .num_items = 2, | ||
| 69 | .items = { | ||
| 70 | { "Front Mic", 0x0 }, | ||
| 71 | { "ATAPI Mic", 0x1 }, | ||
| 72 | }, | ||
| 73 | }; | ||
| 74 | |||
| 75 | /* | ||
| 76 | * 2ch mode | ||
| 77 | */ | ||
| 78 | static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { | ||
| 79 | { 2, NULL } | ||
| 80 | }; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * 6ch mode | ||
| 84 | */ | ||
| 85 | static const struct hda_verb alc861vd_6stack_ch6_init[] = { | ||
| 86 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | ||
| 87 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 88 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 89 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 90 | { } /* end */ | ||
| 91 | }; | ||
| 92 | |||
| 93 | /* | ||
| 94 | * 8ch mode | ||
| 95 | */ | ||
| 96 | static const struct hda_verb alc861vd_6stack_ch8_init[] = { | ||
| 97 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 98 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 99 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 100 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
| 101 | { } /* end */ | ||
| 102 | }; | ||
| 103 | |||
| 104 | static const struct hda_channel_mode alc861vd_6stack_modes[2] = { | ||
| 105 | { 6, alc861vd_6stack_ch6_init }, | ||
| 106 | { 8, alc861vd_6stack_ch8_init }, | ||
| 107 | }; | ||
| 108 | |||
| 109 | static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = { | ||
| 110 | { | ||
| 111 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 112 | .name = "Channel Mode", | ||
| 113 | .info = alc_ch_mode_info, | ||
| 114 | .get = alc_ch_mode_get, | ||
| 115 | .put = alc_ch_mode_put, | ||
| 116 | }, | ||
| 117 | { } /* end */ | ||
| 118 | }; | ||
| 119 | |||
| 120 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | ||
| 121 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | ||
| 122 | */ | ||
| 123 | static const struct snd_kcontrol_new alc861vd_6st_mixer[] = { | ||
| 124 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 125 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
| 126 | |||
| 127 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 128 | HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT), | ||
| 129 | |||
| 130 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, | ||
| 131 | HDA_OUTPUT), | ||
| 132 | HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, | ||
| 133 | HDA_OUTPUT), | ||
| 134 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT), | ||
| 135 | HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), | ||
| 136 | |||
| 137 | HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT), | ||
| 138 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | ||
| 139 | |||
| 140 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 141 | |||
| 142 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 143 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 144 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 145 | |||
| 146 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 147 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 148 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 149 | |||
| 150 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 151 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 152 | |||
| 153 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 154 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 155 | |||
| 156 | { } /* end */ | ||
| 157 | }; | ||
| 158 | |||
| 159 | static const struct snd_kcontrol_new alc861vd_3st_mixer[] = { | ||
| 160 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 161 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
| 162 | |||
| 163 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 164 | |||
| 165 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 166 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 167 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 168 | |||
| 169 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 170 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 171 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 172 | |||
| 173 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
| 174 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
| 175 | |||
| 176 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 177 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 178 | |||
| 179 | { } /* end */ | ||
| 180 | }; | ||
| 181 | |||
| 182 | static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { | ||
| 183 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 184 | /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ | ||
| 185 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
| 186 | |||
| 187 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | ||
| 188 | |||
| 189 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 190 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 191 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 192 | |||
| 193 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 194 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 195 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 196 | |||
| 197 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | ||
| 198 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | ||
| 199 | |||
| 200 | { } /* end */ | ||
| 201 | }; | ||
| 202 | |||
| 203 | /* Pin assignment: Speaker=0x14, HP = 0x15, | ||
| 204 | * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d | ||
| 205 | */ | ||
| 206 | static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = { | ||
| 207 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 208 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), | ||
| 209 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 210 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | ||
| 211 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
| 212 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 213 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 214 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
| 215 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 216 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 217 | { } /* end */ | ||
| 218 | }; | ||
| 219 | |||
| 220 | /* Pin assignment: Speaker=0x14, Line-out = 0x15, | ||
| 221 | * Front Mic=0x18, ATAPI Mic = 0x19, | ||
| 222 | */ | ||
| 223 | static const struct snd_kcontrol_new alc861vd_hp_mixer[] = { | ||
| 224 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
| 225 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
| 226 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 227 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), | ||
| 228 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
| 229 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
| 230 | HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | ||
| 231 | HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), | ||
| 232 | |||
| 233 | { } /* end */ | ||
| 234 | }; | ||
| 235 | |||
| 236 | /* | ||
| 237 | * generic initialization of ADC, input mixers and output mixers | ||
| 238 | */ | ||
| 239 | static const struct hda_verb alc861vd_volume_init_verbs[] = { | ||
| 240 | /* | ||
| 241 | * Unmute ADC0 and set the default input to mic-in | ||
| 242 | */ | ||
| 243 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 244 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 245 | |||
| 246 | /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of | ||
| 247 | * the analog-loopback mixer widget | ||
| 248 | */ | ||
| 249 | /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ | ||
| 250 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 251 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 252 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 253 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 254 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
| 255 | |||
| 256 | /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ | ||
| 257 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 258 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 259 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | ||
| 260 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, | ||
| 261 | |||
| 262 | /* | ||
| 263 | * Set up output mixers (0x02 - 0x05) | ||
| 264 | */ | ||
| 265 | /* set vol=0 to output mixers */ | ||
| 266 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 267 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 268 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 269 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 270 | |||
| 271 | /* set up input amps for analog loopback */ | ||
| 272 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
| 273 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 274 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 275 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 276 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 277 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 278 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 279 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 280 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 281 | |||
| 282 | { } | ||
| 283 | }; | ||
| 284 | |||
| 285 | /* | ||
| 286 | * 3-stack pin configuration: | ||
| 287 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b | ||
| 288 | */ | ||
| 289 | static const struct hda_verb alc861vd_3stack_init_verbs[] = { | ||
| 290 | /* | ||
| 291 | * Set pin mode and muting | ||
| 292 | */ | ||
| 293 | /* set front pin widgets 0x14 for output */ | ||
| 294 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 295 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 296 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 297 | |||
| 298 | /* Mic (rear) pin: input vref at 80% */ | ||
| 299 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 300 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 301 | /* Front Mic pin: input vref at 80% */ | ||
| 302 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 303 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 304 | /* Line In pin: input */ | ||
| 305 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 306 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 307 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
| 308 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 309 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 310 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 311 | /* CD pin widget for input */ | ||
| 312 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 313 | |||
| 314 | { } | ||
| 315 | }; | ||
| 316 | |||
| 317 | /* | ||
| 318 | * 6-stack pin configuration: | ||
| 319 | */ | ||
| 320 | static const struct hda_verb alc861vd_6stack_init_verbs[] = { | ||
| 321 | /* | ||
| 322 | * Set pin mode and muting | ||
| 323 | */ | ||
| 324 | /* set front pin widgets 0x14 for output */ | ||
| 325 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 326 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 327 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 328 | |||
| 329 | /* Rear Pin: output 1 (0x0d) */ | ||
| 330 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 331 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 332 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
| 333 | /* CLFE Pin: output 2 (0x0e) */ | ||
| 334 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 335 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 336 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
| 337 | /* Side Pin: output 3 (0x0f) */ | ||
| 338 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 339 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 340 | {0x17, AC_VERB_SET_CONNECT_SEL, 0x03}, | ||
| 341 | |||
| 342 | /* Mic (rear) pin: input vref at 80% */ | ||
| 343 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 344 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 345 | /* Front Mic pin: input vref at 80% */ | ||
| 346 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 347 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 348 | /* Line In pin: input */ | ||
| 349 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 350 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 351 | /* Line-2 In: Headphone output (output 0 - 0x0c) */ | ||
| 352 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 353 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 354 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 355 | /* CD pin widget for input */ | ||
| 356 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 357 | |||
| 358 | { } | ||
| 359 | }; | ||
| 360 | |||
| 361 | static const struct hda_verb alc861vd_eapd_verbs[] = { | ||
| 362 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
| 363 | { } | ||
| 364 | }; | ||
| 365 | |||
| 366 | static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | ||
| 367 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 368 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 369 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | ||
| 370 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 371 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
| 372 | {} | ||
| 373 | }; | ||
| 374 | |||
| 375 | static void alc861vd_lenovo_setup(struct hda_codec *codec) | ||
| 376 | { | ||
| 377 | struct alc_spec *spec = codec->spec; | ||
| 378 | spec->autocfg.hp_pins[0] = 0x1b; | ||
| 379 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 380 | spec->automute = 1; | ||
| 381 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 382 | } | ||
| 383 | |||
| 384 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) | ||
| 385 | { | ||
| 386 | alc_hp_automute(codec); | ||
| 387 | alc88x_simple_mic_automute(codec); | ||
| 388 | } | ||
| 389 | |||
| 390 | static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | ||
| 391 | unsigned int res) | ||
| 392 | { | ||
| 393 | switch (res >> 26) { | ||
| 394 | case ALC_MIC_EVENT: | ||
| 395 | alc88x_simple_mic_automute(codec); | ||
| 396 | break; | ||
| 397 | default: | ||
| 398 | alc_sku_unsol_event(codec, res); | ||
| 399 | break; | ||
| 400 | } | ||
| 401 | } | ||
| 402 | |||
| 403 | static const struct hda_verb alc861vd_dallas_verbs[] = { | ||
| 404 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 405 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 406 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 407 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
| 408 | |||
| 409 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 410 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
| 411 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 412 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 413 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 414 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 415 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 416 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
| 417 | |||
| 418 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 419 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 420 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 421 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 422 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 423 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 424 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 425 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 426 | |||
| 427 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
| 428 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 429 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | ||
| 430 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | ||
| 431 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 432 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 433 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 434 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 435 | |||
| 436 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
| 437 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
| 438 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
| 439 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
| 440 | |||
| 441 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
| 442 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 443 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
| 444 | |||
| 445 | { } /* end */ | ||
| 446 | }; | ||
| 447 | |||
| 448 | /* toggle speaker-output according to the hp-jack state */ | ||
| 449 | static void alc861vd_dallas_setup(struct hda_codec *codec) | ||
| 450 | { | ||
| 451 | struct alc_spec *spec = codec->spec; | ||
| 452 | |||
| 453 | spec->autocfg.hp_pins[0] = 0x15; | ||
| 454 | spec->autocfg.speaker_pins[0] = 0x14; | ||
| 455 | spec->automute = 1; | ||
| 456 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 457 | } | ||
| 458 | |||
| 459 | /* | ||
| 460 | * configuration and preset | ||
| 461 | */ | ||
| 462 | static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { | ||
| 463 | [ALC660VD_3ST] = "3stack-660", | ||
| 464 | [ALC660VD_3ST_DIG] = "3stack-660-digout", | ||
| 465 | [ALC660VD_ASUS_V1S] = "asus-v1s", | ||
| 466 | [ALC861VD_3ST] = "3stack", | ||
| 467 | [ALC861VD_3ST_DIG] = "3stack-digout", | ||
| 468 | [ALC861VD_6ST_DIG] = "6stack-digout", | ||
| 469 | [ALC861VD_LENOVO] = "lenovo", | ||
| 470 | [ALC861VD_DALLAS] = "dallas", | ||
| 471 | [ALC861VD_HP] = "hp", | ||
| 472 | [ALC861VD_AUTO] = "auto", | ||
| 473 | }; | ||
| 474 | |||
| 475 | static const struct snd_pci_quirk alc861vd_cfg_tbl[] = { | ||
| 476 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), | ||
| 477 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), | ||
| 478 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), | ||
| 479 | /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */ | ||
| 480 | SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S), | ||
| 481 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), | ||
| 482 | SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), | ||
| 483 | SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), | ||
| 484 | /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/ | ||
| 485 | SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO), | ||
| 486 | SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), | ||
| 487 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), | ||
| 488 | SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), | ||
| 489 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO), | ||
| 490 | SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), | ||
| 491 | {} | ||
| 492 | }; | ||
| 493 | |||
| 494 | static const struct alc_config_preset alc861vd_presets[] = { | ||
| 495 | [ALC660VD_3ST] = { | ||
| 496 | .mixers = { alc861vd_3st_mixer }, | ||
| 497 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 498 | alc861vd_3stack_init_verbs }, | ||
| 499 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
| 500 | .dac_nids = alc660vd_dac_nids, | ||
| 501 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 502 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 503 | .input_mux = &alc861vd_capture_source, | ||
| 504 | }, | ||
| 505 | [ALC660VD_3ST_DIG] = { | ||
| 506 | .mixers = { alc861vd_3st_mixer }, | ||
| 507 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 508 | alc861vd_3stack_init_verbs }, | ||
| 509 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
| 510 | .dac_nids = alc660vd_dac_nids, | ||
| 511 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
| 512 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 513 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 514 | .input_mux = &alc861vd_capture_source, | ||
| 515 | }, | ||
| 516 | [ALC861VD_3ST] = { | ||
| 517 | .mixers = { alc861vd_3st_mixer }, | ||
| 518 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 519 | alc861vd_3stack_init_verbs }, | ||
| 520 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
| 521 | .dac_nids = alc861vd_dac_nids, | ||
| 522 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 523 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 524 | .input_mux = &alc861vd_capture_source, | ||
| 525 | }, | ||
| 526 | [ALC861VD_3ST_DIG] = { | ||
| 527 | .mixers = { alc861vd_3st_mixer }, | ||
| 528 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 529 | alc861vd_3stack_init_verbs }, | ||
| 530 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
| 531 | .dac_nids = alc861vd_dac_nids, | ||
| 532 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
| 533 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 534 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 535 | .input_mux = &alc861vd_capture_source, | ||
| 536 | }, | ||
| 537 | [ALC861VD_6ST_DIG] = { | ||
| 538 | .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer }, | ||
| 539 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 540 | alc861vd_6stack_init_verbs }, | ||
| 541 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
| 542 | .dac_nids = alc861vd_dac_nids, | ||
| 543 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
| 544 | .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes), | ||
| 545 | .channel_mode = alc861vd_6stack_modes, | ||
| 546 | .input_mux = &alc861vd_capture_source, | ||
| 547 | }, | ||
| 548 | [ALC861VD_LENOVO] = { | ||
| 549 | .mixers = { alc861vd_lenovo_mixer }, | ||
| 550 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 551 | alc861vd_3stack_init_verbs, | ||
| 552 | alc861vd_eapd_verbs, | ||
| 553 | alc861vd_lenovo_unsol_verbs }, | ||
| 554 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
| 555 | .dac_nids = alc660vd_dac_nids, | ||
| 556 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 557 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 558 | .input_mux = &alc861vd_capture_source, | ||
| 559 | .unsol_event = alc861vd_lenovo_unsol_event, | ||
| 560 | .setup = alc861vd_lenovo_setup, | ||
| 561 | .init_hook = alc861vd_lenovo_init_hook, | ||
| 562 | }, | ||
| 563 | [ALC861VD_DALLAS] = { | ||
| 564 | .mixers = { alc861vd_dallas_mixer }, | ||
| 565 | .init_verbs = { alc861vd_dallas_verbs }, | ||
| 566 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
| 567 | .dac_nids = alc861vd_dac_nids, | ||
| 568 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 569 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 570 | .input_mux = &alc861vd_dallas_capture_source, | ||
| 571 | .unsol_event = alc_sku_unsol_event, | ||
| 572 | .setup = alc861vd_dallas_setup, | ||
| 573 | .init_hook = alc_hp_automute, | ||
| 574 | }, | ||
| 575 | [ALC861VD_HP] = { | ||
| 576 | .mixers = { alc861vd_hp_mixer }, | ||
| 577 | .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs }, | ||
| 578 | .num_dacs = ARRAY_SIZE(alc861vd_dac_nids), | ||
| 579 | .dac_nids = alc861vd_dac_nids, | ||
| 580 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
| 581 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 582 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 583 | .input_mux = &alc861vd_hp_capture_source, | ||
| 584 | .unsol_event = alc_sku_unsol_event, | ||
| 585 | .setup = alc861vd_dallas_setup, | ||
| 586 | .init_hook = alc_hp_automute, | ||
| 587 | }, | ||
| 588 | [ALC660VD_ASUS_V1S] = { | ||
| 589 | .mixers = { alc861vd_lenovo_mixer }, | ||
| 590 | .init_verbs = { alc861vd_volume_init_verbs, | ||
| 591 | alc861vd_3stack_init_verbs, | ||
| 592 | alc861vd_eapd_verbs, | ||
| 593 | alc861vd_lenovo_unsol_verbs }, | ||
| 594 | .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), | ||
| 595 | .dac_nids = alc660vd_dac_nids, | ||
| 596 | .dig_out_nid = ALC861VD_DIGOUT_NID, | ||
| 597 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | ||
| 598 | .channel_mode = alc861vd_3stack_2ch_modes, | ||
| 599 | .input_mux = &alc861vd_capture_source, | ||
| 600 | .unsol_event = alc861vd_lenovo_unsol_event, | ||
| 601 | .setup = alc861vd_lenovo_setup, | ||
| 602 | .init_hook = alc861vd_lenovo_init_hook, | ||
| 603 | }, | ||
| 604 | }; | ||
| 605 | |||
diff --git a/sound/pci/hda/alc880_quirks.c b/sound/pci/hda/alc880_quirks.c index c844d2b59988..bea22edcfd8c 100644 --- a/sound/pci/hda/alc880_quirks.c +++ b/sound/pci/hda/alc880_quirks.c | |||
| @@ -749,8 +749,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec) | |||
| 749 | spec->autocfg.hp_pins[0] = 0x14; | 749 | spec->autocfg.hp_pins[0] = 0x14; |
| 750 | spec->autocfg.speaker_pins[0] = 0x15; | 750 | spec->autocfg.speaker_pins[0] = 0x15; |
| 751 | spec->autocfg.speaker_pins[0] = 0x16; | 751 | spec->autocfg.speaker_pins[0] = 0x16; |
| 752 | spec->automute = 1; | 752 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 753 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 754 | } | 753 | } |
| 755 | 754 | ||
| 756 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | 755 | static void alc880_uniwill_init_hook(struct hda_codec *codec) |
| @@ -781,8 +780,7 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec) | |||
| 781 | 780 | ||
| 782 | spec->autocfg.hp_pins[0] = 0x14; | 781 | spec->autocfg.hp_pins[0] = 0x14; |
| 783 | spec->autocfg.speaker_pins[0] = 0x15; | 782 | spec->autocfg.speaker_pins[0] = 0x15; |
| 784 | spec->automute = 1; | 783 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 785 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 786 | } | 784 | } |
| 787 | 785 | ||
| 788 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 786 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
| @@ -1051,8 +1049,7 @@ static void alc880_lg_setup(struct hda_codec *codec) | |||
| 1051 | 1049 | ||
| 1052 | spec->autocfg.hp_pins[0] = 0x1b; | 1050 | spec->autocfg.hp_pins[0] = 0x1b; |
| 1053 | spec->autocfg.speaker_pins[0] = 0x17; | 1051 | spec->autocfg.speaker_pins[0] = 0x17; |
| 1054 | spec->automute = 1; | 1052 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1055 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1056 | } | 1053 | } |
| 1057 | 1054 | ||
| 1058 | /* | 1055 | /* |
| @@ -1137,8 +1134,7 @@ static void alc880_lg_lw_setup(struct hda_codec *codec) | |||
| 1137 | 1134 | ||
| 1138 | spec->autocfg.hp_pins[0] = 0x1b; | 1135 | spec->autocfg.hp_pins[0] = 0x1b; |
| 1139 | spec->autocfg.speaker_pins[0] = 0x14; | 1136 | spec->autocfg.speaker_pins[0] = 0x14; |
| 1140 | spec->automute = 1; | 1137 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1141 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1142 | } | 1138 | } |
| 1143 | 1139 | ||
| 1144 | static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | 1140 | static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { |
| @@ -1188,7 +1184,7 @@ static void alc880_medion_rim_automute(struct hda_codec *codec) | |||
| 1188 | struct alc_spec *spec = codec->spec; | 1184 | struct alc_spec *spec = codec->spec; |
| 1189 | alc_hp_automute(codec); | 1185 | alc_hp_automute(codec); |
| 1190 | /* toggle EAPD */ | 1186 | /* toggle EAPD */ |
| 1191 | if (spec->jack_present) | 1187 | if (spec->hp_jack_present) |
| 1192 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | 1188 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); |
| 1193 | else | 1189 | else |
| 1194 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); | 1190 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2); |
| @@ -1210,8 +1206,7 @@ static void alc880_medion_rim_setup(struct hda_codec *codec) | |||
| 1210 | 1206 | ||
| 1211 | spec->autocfg.hp_pins[0] = 0x14; | 1207 | spec->autocfg.hp_pins[0] = 0x14; |
| 1212 | spec->autocfg.speaker_pins[0] = 0x1b; | 1208 | spec->autocfg.speaker_pins[0] = 0x1b; |
| 1213 | spec->automute = 1; | 1209 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1214 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1215 | } | 1210 | } |
| 1216 | 1211 | ||
| 1217 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1212 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
diff --git a/sound/pci/hda/alc882_quirks.c b/sound/pci/hda/alc882_quirks.c index 617d04723b82..e251514a26a4 100644 --- a/sound/pci/hda/alc882_quirks.c +++ b/sound/pci/hda/alc882_quirks.c | |||
| @@ -173,8 +173,7 @@ static void alc889_automute_setup(struct hda_codec *codec) | |||
| 173 | spec->autocfg.speaker_pins[2] = 0x17; | 173 | spec->autocfg.speaker_pins[2] = 0x17; |
| 174 | spec->autocfg.speaker_pins[3] = 0x19; | 174 | spec->autocfg.speaker_pins[3] = 0x19; |
| 175 | spec->autocfg.speaker_pins[4] = 0x1a; | 175 | spec->autocfg.speaker_pins[4] = 0x1a; |
| 176 | spec->automute = 1; | 176 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 177 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 178 | } | 177 | } |
| 179 | 178 | ||
| 180 | static void alc889_intel_init_hook(struct hda_codec *codec) | 179 | static void alc889_intel_init_hook(struct hda_codec *codec) |
| @@ -191,8 +190,7 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) | |||
| 191 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ | 190 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ |
| 192 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ | 191 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ |
| 193 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ | 192 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ |
| 194 | spec->automute = 1; | 193 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 195 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 196 | } | 194 | } |
| 197 | 195 | ||
| 198 | /* | 196 | /* |
| @@ -475,8 +473,7 @@ static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) | |||
| 475 | spec->autocfg.speaker_pins[0] = 0x14; | 473 | spec->autocfg.speaker_pins[0] = 0x14; |
| 476 | spec->autocfg.speaker_pins[1] = 0x16; | 474 | spec->autocfg.speaker_pins[1] = 0x16; |
| 477 | spec->autocfg.speaker_pins[2] = 0x17; | 475 | spec->autocfg.speaker_pins[2] = 0x17; |
| 478 | spec->automute = 1; | 476 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 479 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 480 | } | 477 | } |
| 481 | 478 | ||
| 482 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) | 479 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) |
| @@ -487,8 +484,7 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) | |||
| 487 | spec->autocfg.speaker_pins[0] = 0x14; | 484 | spec->autocfg.speaker_pins[0] = 0x14; |
| 488 | spec->autocfg.speaker_pins[1] = 0x16; | 485 | spec->autocfg.speaker_pins[1] = 0x16; |
| 489 | spec->autocfg.speaker_pins[2] = 0x17; | 486 | spec->autocfg.speaker_pins[2] = 0x17; |
| 490 | spec->automute = 1; | 487 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 491 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 492 | } | 488 | } |
| 493 | 489 | ||
| 494 | static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) | 490 | static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) |
| @@ -499,8 +495,7 @@ static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) | |||
| 499 | spec->autocfg.speaker_pins[0] = 0x14; | 495 | spec->autocfg.speaker_pins[0] = 0x14; |
| 500 | spec->autocfg.speaker_pins[1] = 0x16; | 496 | spec->autocfg.speaker_pins[1] = 0x16; |
| 501 | spec->autocfg.speaker_pins[2] = 0x17; | 497 | spec->autocfg.speaker_pins[2] = 0x17; |
| 502 | spec->automute = 1; | 498 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 503 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 504 | } | 499 | } |
| 505 | 500 | ||
| 506 | static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | 501 | static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) |
| @@ -511,8 +506,7 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | |||
| 511 | spec->autocfg.speaker_pins[0] = 0x14; | 506 | spec->autocfg.speaker_pins[0] = 0x14; |
| 512 | spec->autocfg.speaker_pins[1] = 0x16; | 507 | spec->autocfg.speaker_pins[1] = 0x16; |
| 513 | spec->autocfg.speaker_pins[2] = 0x1b; | 508 | spec->autocfg.speaker_pins[2] = 0x1b; |
| 514 | spec->automute = 1; | 509 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 515 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 516 | } | 510 | } |
| 517 | 511 | ||
| 518 | #define ALC882_DIGOUT_NID 0x06 | 512 | #define ALC882_DIGOUT_NID 0x06 |
| @@ -1711,8 +1705,7 @@ static void alc885_imac24_setup(struct hda_codec *codec) | |||
| 1711 | spec->autocfg.hp_pins[0] = 0x14; | 1705 | spec->autocfg.hp_pins[0] = 0x14; |
| 1712 | spec->autocfg.speaker_pins[0] = 0x18; | 1706 | spec->autocfg.speaker_pins[0] = 0x18; |
| 1713 | spec->autocfg.speaker_pins[1] = 0x1a; | 1707 | spec->autocfg.speaker_pins[1] = 0x1a; |
| 1714 | spec->automute = 1; | 1708 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1715 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1716 | } | 1709 | } |
| 1717 | 1710 | ||
| 1718 | #define alc885_mb5_setup alc885_imac24_setup | 1711 | #define alc885_mb5_setup alc885_imac24_setup |
| @@ -1721,12 +1714,11 @@ static void alc885_imac24_setup(struct hda_codec *codec) | |||
| 1721 | /* Macbook Air 2,1 */ | 1714 | /* Macbook Air 2,1 */ |
| 1722 | static void alc885_mba21_setup(struct hda_codec *codec) | 1715 | static void alc885_mba21_setup(struct hda_codec *codec) |
| 1723 | { | 1716 | { |
| 1724 | struct alc_spec *spec = codec->spec; | 1717 | struct alc_spec *spec = codec->spec; |
| 1725 | 1718 | ||
| 1726 | spec->autocfg.hp_pins[0] = 0x14; | 1719 | spec->autocfg.hp_pins[0] = 0x14; |
| 1727 | spec->autocfg.speaker_pins[0] = 0x18; | 1720 | spec->autocfg.speaker_pins[0] = 0x18; |
| 1728 | spec->automute = 1; | 1721 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1729 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1730 | } | 1722 | } |
| 1731 | 1723 | ||
| 1732 | 1724 | ||
| @@ -1737,8 +1729,7 @@ static void alc885_mbp3_setup(struct hda_codec *codec) | |||
| 1737 | 1729 | ||
| 1738 | spec->autocfg.hp_pins[0] = 0x15; | 1730 | spec->autocfg.hp_pins[0] = 0x15; |
| 1739 | spec->autocfg.speaker_pins[0] = 0x14; | 1731 | spec->autocfg.speaker_pins[0] = 0x14; |
| 1740 | spec->automute = 1; | 1732 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1741 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1742 | } | 1733 | } |
| 1743 | 1734 | ||
| 1744 | static void alc885_imac91_setup(struct hda_codec *codec) | 1735 | static void alc885_imac91_setup(struct hda_codec *codec) |
| @@ -1748,8 +1739,7 @@ static void alc885_imac91_setup(struct hda_codec *codec) | |||
| 1748 | spec->autocfg.hp_pins[0] = 0x14; | 1739 | spec->autocfg.hp_pins[0] = 0x14; |
| 1749 | spec->autocfg.speaker_pins[0] = 0x18; | 1740 | spec->autocfg.speaker_pins[0] = 0x18; |
| 1750 | spec->autocfg.speaker_pins[1] = 0x1a; | 1741 | spec->autocfg.speaker_pins[1] = 0x1a; |
| 1751 | spec->automute = 1; | 1742 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1752 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1753 | } | 1743 | } |
| 1754 | 1744 | ||
| 1755 | static const struct hda_verb alc882_targa_verbs[] = { | 1745 | static const struct hda_verb alc882_targa_verbs[] = { |
| @@ -1773,7 +1763,7 @@ static void alc882_targa_automute(struct hda_codec *codec) | |||
| 1773 | struct alc_spec *spec = codec->spec; | 1763 | struct alc_spec *spec = codec->spec; |
| 1774 | alc_hp_automute(codec); | 1764 | alc_hp_automute(codec); |
| 1775 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, | 1765 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
| 1776 | spec->jack_present ? 1 : 3); | 1766 | spec->hp_jack_present ? 1 : 3); |
| 1777 | } | 1767 | } |
| 1778 | 1768 | ||
| 1779 | static void alc882_targa_setup(struct hda_codec *codec) | 1769 | static void alc882_targa_setup(struct hda_codec *codec) |
| @@ -1782,8 +1772,7 @@ static void alc882_targa_setup(struct hda_codec *codec) | |||
| 1782 | 1772 | ||
| 1783 | spec->autocfg.hp_pins[0] = 0x14; | 1773 | spec->autocfg.hp_pins[0] = 0x14; |
| 1784 | spec->autocfg.speaker_pins[0] = 0x1b; | 1774 | spec->autocfg.speaker_pins[0] = 0x1b; |
| 1785 | spec->automute = 1; | 1775 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 1786 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 1787 | } | 1776 | } |
| 1788 | 1777 | ||
| 1789 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | 1778 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) |
| @@ -2187,8 +2176,7 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec) | |||
| 2187 | 2176 | ||
| 2188 | spec->autocfg.hp_pins[0] = 0x1a; | 2177 | spec->autocfg.hp_pins[0] = 0x1a; |
| 2189 | spec->autocfg.speaker_pins[0] = 0x15; | 2178 | spec->autocfg.speaker_pins[0] = 0x15; |
| 2190 | spec->automute = 1; | 2179 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2191 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2192 | } | 2180 | } |
| 2193 | 2181 | ||
| 2194 | static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | 2182 | static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { |
| @@ -2341,8 +2329,7 @@ static void alc883_mitac_setup(struct hda_codec *codec) | |||
| 2341 | spec->autocfg.hp_pins[0] = 0x15; | 2329 | spec->autocfg.hp_pins[0] = 0x15; |
| 2342 | spec->autocfg.speaker_pins[0] = 0x14; | 2330 | spec->autocfg.speaker_pins[0] = 0x14; |
| 2343 | spec->autocfg.speaker_pins[1] = 0x17; | 2331 | spec->autocfg.speaker_pins[1] = 0x17; |
| 2344 | spec->automute = 1; | 2332 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2345 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2346 | } | 2333 | } |
| 2347 | 2334 | ||
| 2348 | static const struct hda_verb alc883_mitac_verbs[] = { | 2335 | static const struct hda_verb alc883_mitac_verbs[] = { |
| @@ -2507,8 +2494,7 @@ static void alc888_3st_hp_setup(struct hda_codec *codec) | |||
| 2507 | spec->autocfg.speaker_pins[0] = 0x14; | 2494 | spec->autocfg.speaker_pins[0] = 0x14; |
| 2508 | spec->autocfg.speaker_pins[1] = 0x16; | 2495 | spec->autocfg.speaker_pins[1] = 0x16; |
| 2509 | spec->autocfg.speaker_pins[2] = 0x18; | 2496 | spec->autocfg.speaker_pins[2] = 0x18; |
| 2510 | spec->automute = 1; | 2497 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2511 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2512 | } | 2498 | } |
| 2513 | 2499 | ||
| 2514 | static const struct hda_verb alc888_3st_hp_verbs[] = { | 2500 | static const struct hda_verb alc888_3st_hp_verbs[] = { |
| @@ -2568,8 +2554,7 @@ static void alc888_lenovo_ms7195_setup(struct hda_codec *codec) | |||
| 2568 | spec->autocfg.hp_pins[0] = 0x1b; | 2554 | spec->autocfg.hp_pins[0] = 0x1b; |
| 2569 | spec->autocfg.line_out_pins[0] = 0x14; | 2555 | spec->autocfg.line_out_pins[0] = 0x14; |
| 2570 | spec->autocfg.speaker_pins[0] = 0x15; | 2556 | spec->autocfg.speaker_pins[0] = 0x15; |
| 2571 | spec->automute = 1; | 2557 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2572 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2573 | } | 2558 | } |
| 2574 | 2559 | ||
| 2575 | /* toggle speaker-output according to the hp-jack state */ | 2560 | /* toggle speaker-output according to the hp-jack state */ |
| @@ -2579,8 +2564,7 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) | |||
| 2579 | 2564 | ||
| 2580 | spec->autocfg.hp_pins[0] = 0x14; | 2565 | spec->autocfg.hp_pins[0] = 0x14; |
| 2581 | spec->autocfg.speaker_pins[0] = 0x15; | 2566 | spec->autocfg.speaker_pins[0] = 0x15; |
| 2582 | spec->automute = 1; | 2567 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2583 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2584 | } | 2568 | } |
| 2585 | 2569 | ||
| 2586 | /* toggle speaker-output according to the hp-jack state */ | 2570 | /* toggle speaker-output according to the hp-jack state */ |
| @@ -2593,8 +2577,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec) | |||
| 2593 | 2577 | ||
| 2594 | spec->autocfg.hp_pins[0] = 0x15; | 2578 | spec->autocfg.hp_pins[0] = 0x15; |
| 2595 | spec->autocfg.speaker_pins[0] = 0x14; | 2579 | spec->autocfg.speaker_pins[0] = 0x14; |
| 2596 | spec->automute = 1; | 2580 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2597 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2598 | } | 2581 | } |
| 2599 | 2582 | ||
| 2600 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) | 2583 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) |
| @@ -2623,8 +2606,7 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) | |||
| 2623 | 2606 | ||
| 2624 | spec->autocfg.hp_pins[0] = 0x14; | 2607 | spec->autocfg.hp_pins[0] = 0x14; |
| 2625 | spec->autocfg.speaker_pins[0] = 0x15; | 2608 | spec->autocfg.speaker_pins[0] = 0x15; |
| 2626 | spec->automute = 1; | 2609 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2627 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2628 | } | 2610 | } |
| 2629 | 2611 | ||
| 2630 | static void alc883_haier_w66_setup(struct hda_codec *codec) | 2612 | static void alc883_haier_w66_setup(struct hda_codec *codec) |
| @@ -2633,8 +2615,7 @@ static void alc883_haier_w66_setup(struct hda_codec *codec) | |||
| 2633 | 2615 | ||
| 2634 | spec->autocfg.hp_pins[0] = 0x1b; | 2616 | spec->autocfg.hp_pins[0] = 0x1b; |
| 2635 | spec->autocfg.speaker_pins[0] = 0x14; | 2617 | spec->autocfg.speaker_pins[0] = 0x14; |
| 2636 | spec->automute = 1; | 2618 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2637 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2638 | } | 2619 | } |
| 2639 | 2620 | ||
| 2640 | static void alc883_lenovo_101e_setup(struct hda_codec *codec) | 2621 | static void alc883_lenovo_101e_setup(struct hda_codec *codec) |
| @@ -2644,10 +2625,7 @@ static void alc883_lenovo_101e_setup(struct hda_codec *codec) | |||
| 2644 | spec->autocfg.hp_pins[0] = 0x1b; | 2625 | spec->autocfg.hp_pins[0] = 0x1b; |
| 2645 | spec->autocfg.line_out_pins[0] = 0x14; | 2626 | spec->autocfg.line_out_pins[0] = 0x14; |
| 2646 | spec->autocfg.speaker_pins[0] = 0x15; | 2627 | spec->autocfg.speaker_pins[0] = 0x15; |
| 2647 | spec->automute = 1; | 2628 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2648 | spec->detect_line = 1; | ||
| 2649 | spec->automute_lines = 1; | ||
| 2650 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2651 | } | 2629 | } |
| 2652 | 2630 | ||
| 2653 | /* toggle speaker-output according to the hp-jack state */ | 2631 | /* toggle speaker-output according to the hp-jack state */ |
| @@ -2658,8 +2636,7 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec) | |||
| 2658 | spec->autocfg.hp_pins[0] = 0x14; | 2636 | spec->autocfg.hp_pins[0] = 0x14; |
| 2659 | spec->autocfg.speaker_pins[0] = 0x15; | 2637 | spec->autocfg.speaker_pins[0] = 0x15; |
| 2660 | spec->autocfg.speaker_pins[1] = 0x16; | 2638 | spec->autocfg.speaker_pins[1] = 0x16; |
| 2661 | spec->automute = 1; | 2639 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2662 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2663 | } | 2640 | } |
| 2664 | 2641 | ||
| 2665 | static const struct hda_verb alc883_acer_eapd_verbs[] = { | 2642 | static const struct hda_verb alc883_acer_eapd_verbs[] = { |
| @@ -2689,8 +2666,7 @@ static void alc888_6st_dell_setup(struct hda_codec *codec) | |||
| 2689 | spec->autocfg.speaker_pins[1] = 0x15; | 2666 | spec->autocfg.speaker_pins[1] = 0x15; |
| 2690 | spec->autocfg.speaker_pins[2] = 0x16; | 2667 | spec->autocfg.speaker_pins[2] = 0x16; |
| 2691 | spec->autocfg.speaker_pins[3] = 0x17; | 2668 | spec->autocfg.speaker_pins[3] = 0x17; |
| 2692 | spec->automute = 1; | 2669 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2693 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2694 | } | 2670 | } |
| 2695 | 2671 | ||
| 2696 | static void alc888_lenovo_sky_setup(struct hda_codec *codec) | 2672 | static void alc888_lenovo_sky_setup(struct hda_codec *codec) |
| @@ -2703,8 +2679,7 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec) | |||
| 2703 | spec->autocfg.speaker_pins[2] = 0x16; | 2679 | spec->autocfg.speaker_pins[2] = 0x16; |
| 2704 | spec->autocfg.speaker_pins[3] = 0x17; | 2680 | spec->autocfg.speaker_pins[3] = 0x17; |
| 2705 | spec->autocfg.speaker_pins[4] = 0x1a; | 2681 | spec->autocfg.speaker_pins[4] = 0x1a; |
| 2706 | spec->automute = 1; | 2682 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2707 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2708 | } | 2683 | } |
| 2709 | 2684 | ||
| 2710 | static void alc883_vaiott_setup(struct hda_codec *codec) | 2685 | static void alc883_vaiott_setup(struct hda_codec *codec) |
| @@ -2714,8 +2689,7 @@ static void alc883_vaiott_setup(struct hda_codec *codec) | |||
| 2714 | spec->autocfg.hp_pins[0] = 0x15; | 2689 | spec->autocfg.hp_pins[0] = 0x15; |
| 2715 | spec->autocfg.speaker_pins[0] = 0x14; | 2690 | spec->autocfg.speaker_pins[0] = 0x14; |
| 2716 | spec->autocfg.speaker_pins[1] = 0x17; | 2691 | spec->autocfg.speaker_pins[1] = 0x17; |
| 2717 | spec->automute = 1; | 2692 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2718 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2719 | } | 2693 | } |
| 2720 | 2694 | ||
| 2721 | static const struct hda_verb alc888_asus_m90v_verbs[] = { | 2695 | static const struct hda_verb alc888_asus_m90v_verbs[] = { |
| @@ -2739,8 +2713,7 @@ static void alc883_mode2_setup(struct hda_codec *codec) | |||
| 2739 | spec->ext_mic_pin = 0x18; | 2713 | spec->ext_mic_pin = 0x18; |
| 2740 | spec->int_mic_pin = 0x19; | 2714 | spec->int_mic_pin = 0x19; |
| 2741 | spec->auto_mic = 1; | 2715 | spec->auto_mic = 1; |
| 2742 | spec->automute = 1; | 2716 | alc_simple_setup_automute(spec, ALC_AUTOMUTE_AMP); |
| 2743 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
| 2744 | } | 2717 | } |
| 2745 | 2718 | ||
| 2746 | static const struct hda_verb alc888_asus_eee1601_verbs[] = { | 2719 | static const struct hda_verb alc888_asus_eee1601_verbs[] = { |
diff --git a/sound/pci/hda/alc_quirks.c b/sound/pci/hda/alc_quirks.c index 2be1129cf458..a18952ed4311 100644 --- a/sound/pci/hda/alc_quirks.c +++ b/sound/pci/hda/alc_quirks.c | |||
| @@ -453,6 +453,19 @@ static void setup_preset(struct hda_codec *codec, | |||
| 453 | alc_fixup_autocfg_pin_nums(codec); | 453 | alc_fixup_autocfg_pin_nums(codec); |
| 454 | } | 454 | } |
| 455 | 455 | ||
| 456 | static void alc_simple_setup_automute(struct alc_spec *spec, int mode) | ||
| 457 | { | ||
| 458 | int lo_pin = spec->autocfg.line_out_pins[0]; | ||
| 459 | |||
| 460 | if (lo_pin == spec->autocfg.speaker_pins[0] || | ||
| 461 | lo_pin == spec->autocfg.hp_pins[0]) | ||
| 462 | lo_pin = 0; | ||
| 463 | spec->automute_mode = mode; | ||
| 464 | spec->detect_hp = !!spec->autocfg.hp_pins[0]; | ||
| 465 | spec->detect_lo = !!lo_pin; | ||
| 466 | spec->automute_lo = spec->automute_lo_possible = !!lo_pin; | ||
| 467 | spec->automute_speaker = spec->automute_speaker_possible = !!spec->autocfg.speaker_pins[0]; | ||
| 468 | } | ||
| 456 | 469 | ||
| 457 | /* auto-toggle front mic */ | 470 | /* auto-toggle front mic */ |
| 458 | static void alc88x_simple_mic_automute(struct hda_codec *codec) | 471 | static void alc88x_simple_mic_automute(struct hda_codec *codec) |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index f3aefef37216..1715e8b24ff0 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
| @@ -34,6 +34,9 @@ | |||
| 34 | #include "hda_beep.h" | 34 | #include "hda_beep.h" |
| 35 | #include <sound/hda_hwdep.h> | 35 | #include <sound/hda_hwdep.h> |
| 36 | 36 | ||
| 37 | #define CREATE_TRACE_POINTS | ||
| 38 | #include "hda_trace.h" | ||
| 39 | |||
| 37 | /* | 40 | /* |
| 38 | * vendor / preset table | 41 | * vendor / preset table |
| 39 | */ | 42 | */ |
| @@ -208,15 +211,19 @@ static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd, | |||
| 208 | again: | 211 | again: |
| 209 | snd_hda_power_up(codec); | 212 | snd_hda_power_up(codec); |
| 210 | mutex_lock(&bus->cmd_mutex); | 213 | mutex_lock(&bus->cmd_mutex); |
| 214 | trace_hda_send_cmd(codec, cmd); | ||
| 211 | err = bus->ops.command(bus, cmd); | 215 | err = bus->ops.command(bus, cmd); |
| 212 | if (!err && res) | 216 | if (!err && res) { |
| 213 | *res = bus->ops.get_response(bus, codec->addr); | 217 | *res = bus->ops.get_response(bus, codec->addr); |
| 218 | trace_hda_get_response(codec, *res); | ||
| 219 | } | ||
| 214 | mutex_unlock(&bus->cmd_mutex); | 220 | mutex_unlock(&bus->cmd_mutex); |
| 215 | snd_hda_power_down(codec); | 221 | snd_hda_power_down(codec); |
| 216 | if (res && *res == -1 && bus->rirb_error) { | 222 | if (res && *res == -1 && bus->rirb_error) { |
| 217 | if (bus->response_reset) { | 223 | if (bus->response_reset) { |
| 218 | snd_printd("hda_codec: resetting BUS due to " | 224 | snd_printd("hda_codec: resetting BUS due to " |
| 219 | "fatal communication error\n"); | 225 | "fatal communication error\n"); |
| 226 | trace_hda_bus_reset(bus); | ||
| 220 | bus->ops.bus_reset(bus); | 227 | bus->ops.bus_reset(bus); |
| 221 | } | 228 | } |
| 222 | goto again; | 229 | goto again; |
| @@ -607,6 +614,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) | |||
| 607 | struct hda_bus_unsolicited *unsol; | 614 | struct hda_bus_unsolicited *unsol; |
| 608 | unsigned int wp; | 615 | unsigned int wp; |
| 609 | 616 | ||
| 617 | trace_hda_unsol_event(bus, res, res_ex); | ||
| 610 | unsol = bus->unsol; | 618 | unsol = bus->unsol; |
| 611 | if (!unsol) | 619 | if (!unsol) |
| 612 | return 0; | 620 | return 0; |
| @@ -1483,8 +1491,11 @@ static void really_cleanup_stream(struct hda_codec *codec, | |||
| 1483 | struct hda_cvt_setup *q) | 1491 | struct hda_cvt_setup *q) |
| 1484 | { | 1492 | { |
| 1485 | hda_nid_t nid = q->nid; | 1493 | hda_nid_t nid = q->nid; |
| 1486 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | 1494 | if (q->stream_tag || q->channel_id) |
| 1487 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); | 1495 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); |
| 1496 | if (q->format_id) | ||
| 1497 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0 | ||
| 1498 | ); | ||
| 1488 | memset(q, 0, sizeof(*q)); | 1499 | memset(q, 0, sizeof(*q)); |
| 1489 | q->nid = nid; | 1500 | q->nid = nid; |
| 1490 | } | 1501 | } |
| @@ -1689,6 +1700,29 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid) | |||
| 1689 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); | 1700 | EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps); |
| 1690 | 1701 | ||
| 1691 | /** | 1702 | /** |
| 1703 | * snd_hda_override_pin_caps - Override the pin capabilities | ||
| 1704 | * @codec: the CODEC | ||
| 1705 | * @nid: the NID to override | ||
| 1706 | * @caps: the capability bits to set | ||
| 1707 | * | ||
| 1708 | * Override the cached PIN capabilitiy bits value by the given one. | ||
| 1709 | * | ||
| 1710 | * Returns zero if successful or a negative error code. | ||
| 1711 | */ | ||
| 1712 | int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, | ||
| 1713 | unsigned int caps) | ||
| 1714 | { | ||
| 1715 | struct hda_amp_info *info; | ||
| 1716 | info = get_alloc_amp_hash(codec, HDA_HASH_PINCAP_KEY(nid)); | ||
| 1717 | if (!info) | ||
| 1718 | return -ENOMEM; | ||
| 1719 | info->amp_caps = caps; | ||
| 1720 | info->head.val |= INFO_AMP_CAPS; | ||
| 1721 | return 0; | ||
| 1722 | } | ||
| 1723 | EXPORT_SYMBOL_HDA(snd_hda_override_pin_caps); | ||
| 1724 | |||
| 1725 | /** | ||
| 1692 | * snd_hda_pin_sense - execute pin sense measurement | 1726 | * snd_hda_pin_sense - execute pin sense measurement |
| 1693 | * @codec: the CODEC to sense | 1727 | * @codec: the CODEC to sense |
| 1694 | * @nid: the pin NID to sense | 1728 | * @nid: the pin NID to sense |
| @@ -4087,6 +4121,7 @@ static void hda_power_work(struct work_struct *work) | |||
| 4087 | return; | 4121 | return; |
| 4088 | } | 4122 | } |
| 4089 | 4123 | ||
| 4124 | trace_hda_power_down(codec); | ||
| 4090 | hda_call_codec_suspend(codec); | 4125 | hda_call_codec_suspend(codec); |
| 4091 | if (bus->ops.pm_notify) | 4126 | if (bus->ops.pm_notify) |
| 4092 | bus->ops.pm_notify(bus); | 4127 | bus->ops.pm_notify(bus); |
| @@ -4125,6 +4160,7 @@ void snd_hda_power_up(struct hda_codec *codec) | |||
| 4125 | if (codec->power_on || codec->power_transition) | 4160 | if (codec->power_on || codec->power_transition) |
| 4126 | return; | 4161 | return; |
| 4127 | 4162 | ||
| 4163 | trace_hda_power_up(codec); | ||
| 4128 | snd_hda_update_power_acct(codec); | 4164 | snd_hda_update_power_acct(codec); |
| 4129 | codec->power_on = 1; | 4165 | codec->power_on = 1; |
| 4130 | codec->power_jiffies = jiffies; | 4166 | codec->power_jiffies = jiffies; |
| @@ -4537,6 +4573,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, | |||
| 4537 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, | 4573 | snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, |
| 4538 | 0, format); | 4574 | 0, format); |
| 4539 | /* extra outputs copied from front */ | 4575 | /* extra outputs copied from front */ |
| 4576 | for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++) | ||
| 4577 | if (!mout->no_share_stream && mout->hp_out_nid[i]) | ||
| 4578 | snd_hda_codec_setup_stream(codec, | ||
| 4579 | mout->hp_out_nid[i], | ||
| 4580 | stream_tag, 0, format); | ||
| 4540 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) | 4581 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) |
| 4541 | if (!mout->no_share_stream && mout->extra_out_nid[i]) | 4582 | if (!mout->no_share_stream && mout->extra_out_nid[i]) |
| 4542 | snd_hda_codec_setup_stream(codec, | 4583 | snd_hda_codec_setup_stream(codec, |
| @@ -4569,6 +4610,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | |||
| 4569 | snd_hda_codec_cleanup_stream(codec, nids[i]); | 4610 | snd_hda_codec_cleanup_stream(codec, nids[i]); |
| 4570 | if (mout->hp_nid) | 4611 | if (mout->hp_nid) |
| 4571 | snd_hda_codec_cleanup_stream(codec, mout->hp_nid); | 4612 | snd_hda_codec_cleanup_stream(codec, mout->hp_nid); |
| 4613 | for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++) | ||
| 4614 | if (mout->hp_out_nid[i]) | ||
| 4615 | snd_hda_codec_cleanup_stream(codec, | ||
| 4616 | mout->hp_out_nid[i]); | ||
| 4572 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) | 4617 | for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) |
| 4573 | if (mout->extra_out_nid[i]) | 4618 | if (mout->extra_out_nid[i]) |
| 4574 | snd_hda_codec_cleanup_stream(codec, | 4619 | snd_hda_codec_cleanup_stream(codec, |
| @@ -4649,6 +4694,27 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | |||
| 4649 | } | 4694 | } |
| 4650 | } | 4695 | } |
| 4651 | 4696 | ||
| 4697 | /* Reorder the surround channels | ||
| 4698 | * ALSA sequence is front/surr/clfe/side | ||
| 4699 | * HDA sequence is: | ||
| 4700 | * 4-ch: front/surr => OK as it is | ||
| 4701 | * 6-ch: front/clfe/surr | ||
| 4702 | * 8-ch: front/clfe/rear/side|fc | ||
| 4703 | */ | ||
| 4704 | static void reorder_outputs(unsigned int nums, hda_nid_t *pins) | ||
| 4705 | { | ||
| 4706 | hda_nid_t nid; | ||
| 4707 | |||
| 4708 | switch (nums) { | ||
| 4709 | case 3: | ||
| 4710 | case 4: | ||
| 4711 | nid = pins[1]; | ||
| 4712 | pins[1] = pins[2]; | ||
| 4713 | pins[2] = nid; | ||
| 4714 | break; | ||
| 4715 | } | ||
| 4716 | } | ||
| 4717 | |||
| 4652 | /* | 4718 | /* |
| 4653 | * Parse all pin widgets and store the useful pin nids to cfg | 4719 | * Parse all pin widgets and store the useful pin nids to cfg |
| 4654 | * | 4720 | * |
| @@ -4666,12 +4732,13 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | |||
| 4666 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, | 4732 | * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, |
| 4667 | * respectively. | 4733 | * respectively. |
| 4668 | */ | 4734 | */ |
| 4669 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, | 4735 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, |
| 4670 | struct auto_pin_cfg *cfg, | 4736 | struct auto_pin_cfg *cfg, |
| 4671 | const hda_nid_t *ignore_nids) | 4737 | const hda_nid_t *ignore_nids, |
| 4738 | unsigned int cond_flags) | ||
| 4672 | { | 4739 | { |
| 4673 | hda_nid_t nid, end_nid; | 4740 | hda_nid_t nid, end_nid; |
| 4674 | short seq, assoc_line_out, assoc_speaker; | 4741 | short seq, assoc_line_out; |
| 4675 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; | 4742 | short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; |
| 4676 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; | 4743 | short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; |
| 4677 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; | 4744 | short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; |
| @@ -4682,7 +4749,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
| 4682 | memset(sequences_line_out, 0, sizeof(sequences_line_out)); | 4749 | memset(sequences_line_out, 0, sizeof(sequences_line_out)); |
| 4683 | memset(sequences_speaker, 0, sizeof(sequences_speaker)); | 4750 | memset(sequences_speaker, 0, sizeof(sequences_speaker)); |
| 4684 | memset(sequences_hp, 0, sizeof(sequences_hp)); | 4751 | memset(sequences_hp, 0, sizeof(sequences_hp)); |
| 4685 | assoc_line_out = assoc_speaker = 0; | 4752 | assoc_line_out = 0; |
| 4686 | 4753 | ||
| 4687 | end_nid = codec->start_nid + codec->num_nodes; | 4754 | end_nid = codec->start_nid + codec->num_nodes; |
| 4688 | for (nid = codec->start_nid; nid < end_nid; nid++) { | 4755 | for (nid = codec->start_nid; nid < end_nid; nid++) { |
| @@ -4734,16 +4801,10 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
| 4734 | case AC_JACK_SPEAKER: | 4801 | case AC_JACK_SPEAKER: |
| 4735 | seq = get_defcfg_sequence(def_conf); | 4802 | seq = get_defcfg_sequence(def_conf); |
| 4736 | assoc = get_defcfg_association(def_conf); | 4803 | assoc = get_defcfg_association(def_conf); |
| 4737 | if (!assoc) | ||
| 4738 | continue; | ||
| 4739 | if (!assoc_speaker) | ||
| 4740 | assoc_speaker = assoc; | ||
| 4741 | else if (assoc_speaker != assoc) | ||
| 4742 | continue; | ||
| 4743 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) | 4804 | if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) |
| 4744 | continue; | 4805 | continue; |
| 4745 | cfg->speaker_pins[cfg->speaker_outs] = nid; | 4806 | cfg->speaker_pins[cfg->speaker_outs] = nid; |
| 4746 | sequences_speaker[cfg->speaker_outs] = seq; | 4807 | sequences_speaker[cfg->speaker_outs] = (assoc << 4) | seq; |
| 4747 | cfg->speaker_outs++; | 4808 | cfg->speaker_outs++; |
| 4748 | break; | 4809 | break; |
| 4749 | case AC_JACK_HP_OUT: | 4810 | case AC_JACK_HP_OUT: |
| @@ -4792,7 +4853,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
| 4792 | * If no line-out is defined but multiple HPs are found, | 4853 | * If no line-out is defined but multiple HPs are found, |
| 4793 | * some of them might be the real line-outs. | 4854 | * some of them might be the real line-outs. |
| 4794 | */ | 4855 | */ |
| 4795 | if (!cfg->line_outs && cfg->hp_outs > 1) { | 4856 | if (!cfg->line_outs && cfg->hp_outs > 1 && |
| 4857 | !(cond_flags & HDA_PINCFG_NO_HP_FIXUP)) { | ||
| 4796 | int i = 0; | 4858 | int i = 0; |
| 4797 | while (i < cfg->hp_outs) { | 4859 | while (i < cfg->hp_outs) { |
| 4798 | /* The real HPs should have the sequence 0x0f */ | 4860 | /* The real HPs should have the sequence 0x0f */ |
| @@ -4829,7 +4891,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
| 4829 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin | 4891 | * FIX-UP: if no line-outs are detected, try to use speaker or HP pin |
| 4830 | * as a primary output | 4892 | * as a primary output |
| 4831 | */ | 4893 | */ |
| 4832 | if (!cfg->line_outs) { | 4894 | if (!cfg->line_outs && |
| 4895 | !(cond_flags & HDA_PINCFG_NO_LO_FIXUP)) { | ||
| 4833 | if (cfg->speaker_outs) { | 4896 | if (cfg->speaker_outs) { |
| 4834 | cfg->line_outs = cfg->speaker_outs; | 4897 | cfg->line_outs = cfg->speaker_outs; |
| 4835 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | 4898 | memcpy(cfg->line_out_pins, cfg->speaker_pins, |
| @@ -4847,21 +4910,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
| 4847 | } | 4910 | } |
| 4848 | } | 4911 | } |
| 4849 | 4912 | ||
| 4850 | /* Reorder the surround channels | 4913 | reorder_outputs(cfg->line_outs, cfg->line_out_pins); |
| 4851 | * ALSA sequence is front/surr/clfe/side | 4914 | reorder_outputs(cfg->hp_outs, cfg->hp_pins); |
| 4852 | * HDA sequence is: | 4915 | reorder_outputs(cfg->speaker_outs, cfg->speaker_pins); |
| 4853 | * 4-ch: front/surr => OK as it is | ||
| 4854 | * 6-ch: front/clfe/surr | ||
| 4855 | * 8-ch: front/clfe/rear/side|fc | ||
| 4856 | */ | ||
| 4857 | switch (cfg->line_outs) { | ||
| 4858 | case 3: | ||
| 4859 | case 4: | ||
| 4860 | nid = cfg->line_out_pins[1]; | ||
| 4861 | cfg->line_out_pins[1] = cfg->line_out_pins[2]; | ||
| 4862 | cfg->line_out_pins[2] = nid; | ||
| 4863 | break; | ||
| 4864 | } | ||
| 4865 | 4916 | ||
| 4866 | sort_autocfg_input_pins(cfg); | 4917 | sort_autocfg_input_pins(cfg); |
| 4867 | 4918 | ||
| @@ -4899,7 +4950,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
| 4899 | 4950 | ||
| 4900 | return 0; | 4951 | return 0; |
| 4901 | } | 4952 | } |
| 4902 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config); | 4953 | EXPORT_SYMBOL_HDA(snd_hda_parse_pin_defcfg); |
| 4903 | 4954 | ||
| 4904 | int snd_hda_get_input_pin_attr(unsigned int def_conf) | 4955 | int snd_hda_get_input_pin_attr(unsigned int def_conf) |
| 4905 | { | 4956 | { |
| @@ -5158,30 +5209,6 @@ void snd_array_free(struct snd_array *array) | |||
| 5158 | EXPORT_SYMBOL_HDA(snd_array_free); | 5209 | EXPORT_SYMBOL_HDA(snd_array_free); |
| 5159 | 5210 | ||
| 5160 | /** | 5211 | /** |
| 5161 | * snd_print_pcm_rates - Print the supported PCM rates to the string buffer | ||
| 5162 | * @pcm: PCM caps bits | ||
| 5163 | * @buf: the string buffer to write | ||
| 5164 | * @buflen: the max buffer length | ||
| 5165 | * | ||
| 5166 | * used by hda_proc.c and hda_eld.c | ||
| 5167 | */ | ||
| 5168 | void snd_print_pcm_rates(int pcm, char *buf, int buflen) | ||
| 5169 | { | ||
| 5170 | static unsigned int rates[] = { | ||
| 5171 | 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, | ||
| 5172 | 96000, 176400, 192000, 384000 | ||
| 5173 | }; | ||
| 5174 | int i, j; | ||
| 5175 | |||
| 5176 | for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++) | ||
| 5177 | if (pcm & (1 << i)) | ||
| 5178 | j += snprintf(buf + j, buflen - j, " %d", rates[i]); | ||
| 5179 | |||
| 5180 | buf[j] = '\0'; /* necessary when j == 0 */ | ||
| 5181 | } | ||
| 5182 | EXPORT_SYMBOL_HDA(snd_print_pcm_rates); | ||
| 5183 | |||
| 5184 | /** | ||
| 5185 | * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer | 5212 | * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer |
| 5186 | * @pcm: PCM caps bits | 5213 | * @pcm: PCM caps bits |
| 5187 | * @buf: the string buffer to write | 5214 | * @buf: the string buffer to write |
| @@ -5222,6 +5249,8 @@ static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, | |||
| 5222 | return "Mic"; | 5249 | return "Mic"; |
| 5223 | case SND_JACK_LINEOUT: | 5250 | case SND_JACK_LINEOUT: |
| 5224 | return "Line-out"; | 5251 | return "Line-out"; |
| 5252 | case SND_JACK_LINEIN: | ||
| 5253 | return "Line-in"; | ||
| 5225 | case SND_JACK_HEADSET: | 5254 | case SND_JACK_HEADSET: |
| 5226 | return "Headset"; | 5255 | return "Headset"; |
| 5227 | case SND_JACK_VIDEOOUT: | 5256 | case SND_JACK_VIDEOOUT: |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index c34f730f4815..1c8ddf547a2d 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
| @@ -318,6 +318,11 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
| 318 | int size; | 318 | int size; |
| 319 | unsigned char *buf; | 319 | unsigned char *buf; |
| 320 | 320 | ||
| 321 | /* | ||
| 322 | * ELD size is initialized to zero in caller function. If no errors and | ||
| 323 | * ELD is valid, actual eld_size is assigned in hdmi_update_eld() | ||
| 324 | */ | ||
| 325 | |||
| 321 | if (!eld->eld_valid) | 326 | if (!eld->eld_valid) |
| 322 | return -ENOENT; | 327 | return -ENOENT; |
| 323 | 328 | ||
| @@ -327,14 +332,13 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
| 327 | snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n"); | 332 | snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n"); |
| 328 | size = 128; | 333 | size = 128; |
| 329 | } | 334 | } |
| 330 | if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { | 335 | if (size < ELD_FIXED_BYTES || size > ELD_MAX_SIZE) { |
| 331 | snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size); | 336 | snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size); |
| 332 | return -ERANGE; | 337 | return -ERANGE; |
| 333 | } | 338 | } |
| 334 | 339 | ||
| 335 | buf = kmalloc(size, GFP_KERNEL); | 340 | /* set ELD buffer */ |
| 336 | if (!buf) | 341 | buf = eld->eld_buffer; |
| 337 | return -ENOMEM; | ||
| 338 | 342 | ||
| 339 | for (i = 0; i < size; i++) { | 343 | for (i = 0; i < size; i++) { |
| 340 | unsigned int val = hdmi_get_eld_data(codec, nid, i); | 344 | unsigned int val = hdmi_get_eld_data(codec, nid, i); |
| @@ -356,10 +360,31 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
| 356 | ret = hdmi_update_eld(eld, buf, size); | 360 | ret = hdmi_update_eld(eld, buf, size); |
| 357 | 361 | ||
| 358 | error: | 362 | error: |
| 359 | kfree(buf); | ||
| 360 | return ret; | 363 | return ret; |
| 361 | } | 364 | } |
| 362 | 365 | ||
| 366 | /** | ||
| 367 | * SNDRV_PCM_RATE_* and AC_PAR_PCM values don't match, print correct rates with | ||
| 368 | * hdmi-specific routine. | ||
| 369 | */ | ||
| 370 | static void hdmi_print_pcm_rates(int pcm, char *buf, int buflen) | ||
| 371 | { | ||
| 372 | static unsigned int alsa_rates[] = { | ||
| 373 | 5512, 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, | ||
| 374 | 96000, 176400, 192000, 384000 | ||
| 375 | }; | ||
| 376 | int i, j; | ||
| 377 | |||
| 378 | for (i = 0, j = 0; i < ARRAY_SIZE(alsa_rates); i++) | ||
| 379 | if (pcm & (1 << i)) | ||
| 380 | j += snprintf(buf + j, buflen - j, " %d", | ||
| 381 | alsa_rates[i]); | ||
| 382 | |||
| 383 | buf[j] = '\0'; /* necessary when j == 0 */ | ||
| 384 | } | ||
| 385 | |||
| 386 | #define SND_PRINT_RATES_ADVISED_BUFSIZE 80 | ||
| 387 | |||
| 363 | static void hdmi_show_short_audio_desc(struct cea_sad *a) | 388 | static void hdmi_show_short_audio_desc(struct cea_sad *a) |
| 364 | { | 389 | { |
| 365 | char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; | 390 | char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; |
| @@ -368,7 +393,7 @@ static void hdmi_show_short_audio_desc(struct cea_sad *a) | |||
| 368 | if (!a->format) | 393 | if (!a->format) |
| 369 | return; | 394 | return; |
| 370 | 395 | ||
| 371 | snd_print_pcm_rates(a->rates, buf, sizeof(buf)); | 396 | hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); |
| 372 | 397 | ||
| 373 | if (a->format == AUDIO_CODING_TYPE_LPCM) | 398 | if (a->format == AUDIO_CODING_TYPE_LPCM) |
| 374 | snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); | 399 | snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2) - 8); |
| @@ -427,7 +452,7 @@ static void hdmi_print_sad_info(int i, struct cea_sad *a, | |||
| 427 | i, a->format, cea_audio_coding_type_names[a->format]); | 452 | i, a->format, cea_audio_coding_type_names[a->format]); |
| 428 | snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); | 453 | snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); |
| 429 | 454 | ||
| 430 | snd_print_pcm_rates(a->rates, buf, sizeof(buf)); | 455 | hdmi_print_pcm_rates(a->rates, buf, sizeof(buf)); |
| 431 | snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); | 456 | snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); |
| 432 | 457 | ||
| 433 | if (a->format == AUDIO_CODING_TYPE_LPCM) { | 458 | if (a->format == AUDIO_CODING_TYPE_LPCM) { |
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c index bf3ced51e0f8..72e5885007cc 100644 --- a/sound/pci/hda/hda_hwdep.c +++ b/sound/pci/hda/hda_hwdep.c | |||
| @@ -643,14 +643,14 @@ static inline int strmatch(const char *a, const char *b) | |||
| 643 | static void parse_codec_mode(char *buf, struct hda_bus *bus, | 643 | static void parse_codec_mode(char *buf, struct hda_bus *bus, |
| 644 | struct hda_codec **codecp) | 644 | struct hda_codec **codecp) |
| 645 | { | 645 | { |
| 646 | unsigned int vendorid, subid, caddr; | 646 | int vendorid, subid, caddr; |
| 647 | struct hda_codec *codec; | 647 | struct hda_codec *codec; |
| 648 | 648 | ||
| 649 | *codecp = NULL; | 649 | *codecp = NULL; |
| 650 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { | 650 | if (sscanf(buf, "%i %i %i", &vendorid, &subid, &caddr) == 3) { |
| 651 | list_for_each_entry(codec, &bus->codec_list, list) { | 651 | list_for_each_entry(codec, &bus->codec_list, list) { |
| 652 | if (codec->vendor_id == vendorid && | 652 | if ((vendorid <= 0 || codec->vendor_id == vendorid) && |
| 653 | codec->subsystem_id == subid && | 653 | (subid <= 0 || codec->subsystem_id == subid) && |
| 654 | codec->addr == caddr) { | 654 | codec->addr == caddr) { |
| 655 | *codecp = codec; | 655 | *codecp = codec; |
| 656 | break; | 656 | break; |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 191284a1c0ae..bd7fc99af187 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
| @@ -34,7 +34,6 @@ | |||
| 34 | * | 34 | * |
| 35 | */ | 35 | */ |
| 36 | 36 | ||
| 37 | #include <asm/io.h> | ||
| 38 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
| 39 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
| 40 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
| @@ -46,6 +45,12 @@ | |||
| 46 | #include <linux/pci.h> | 45 | #include <linux/pci.h> |
| 47 | #include <linux/mutex.h> | 46 | #include <linux/mutex.h> |
| 48 | #include <linux/reboot.h> | 47 | #include <linux/reboot.h> |
| 48 | #include <linux/io.h> | ||
| 49 | #ifdef CONFIG_X86 | ||
| 50 | /* for snoop control */ | ||
| 51 | #include <asm/pgtable.h> | ||
| 52 | #include <asm/cacheflush.h> | ||
| 53 | #endif | ||
| 49 | #include <sound/core.h> | 54 | #include <sound/core.h> |
| 50 | #include <sound/initval.h> | 55 | #include <sound/initval.h> |
| 51 | #include "hda_codec.h" | 56 | #include "hda_codec.h" |
| @@ -116,6 +121,22 @@ module_param(power_save_controller, bool, 0644); | |||
| 116 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 121 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
| 117 | #endif | 122 | #endif |
| 118 | 123 | ||
| 124 | static int align_buffer_size = 1; | ||
| 125 | module_param(align_buffer_size, bool, 0644); | ||
| 126 | MODULE_PARM_DESC(align_buffer_size, | ||
| 127 | "Force buffer and period sizes to be multiple of 128 bytes."); | ||
| 128 | |||
| 129 | #ifdef CONFIG_X86 | ||
| 130 | static bool hda_snoop = true; | ||
| 131 | module_param_named(snoop, hda_snoop, bool, 0444); | ||
| 132 | MODULE_PARM_DESC(snoop, "Enable/disable snooping"); | ||
| 133 | #define azx_snoop(chip) (chip)->snoop | ||
| 134 | #else | ||
| 135 | #define hda_snoop true | ||
| 136 | #define azx_snoop(chip) true | ||
| 137 | #endif | ||
| 138 | |||
| 139 | |||
| 119 | MODULE_LICENSE("GPL"); | 140 | MODULE_LICENSE("GPL"); |
| 120 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 141 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
| 121 | "{Intel, ICH6M}," | 142 | "{Intel, ICH6M}," |
| @@ -360,7 +381,7 @@ struct azx_dev { | |||
| 360 | */ | 381 | */ |
| 361 | unsigned char stream_tag; /* assigned stream */ | 382 | unsigned char stream_tag; /* assigned stream */ |
| 362 | unsigned char index; /* stream index */ | 383 | unsigned char index; /* stream index */ |
| 363 | int device; /* last device number assigned to */ | 384 | int assigned_key; /* last device# key assigned to */ |
| 364 | 385 | ||
| 365 | unsigned int opened :1; | 386 | unsigned int opened :1; |
| 366 | unsigned int running :1; | 387 | unsigned int running :1; |
| @@ -371,6 +392,7 @@ struct azx_dev { | |||
| 371 | * when link position is not greater than FIFO size | 392 | * when link position is not greater than FIFO size |
| 372 | */ | 393 | */ |
| 373 | unsigned int insufficient :1; | 394 | unsigned int insufficient :1; |
| 395 | unsigned int wc_marked:1; | ||
| 374 | }; | 396 | }; |
| 375 | 397 | ||
| 376 | /* CORB/RIRB */ | 398 | /* CORB/RIRB */ |
| @@ -438,6 +460,7 @@ struct azx { | |||
| 438 | unsigned int msi :1; | 460 | unsigned int msi :1; |
| 439 | unsigned int irq_pending_warned :1; | 461 | unsigned int irq_pending_warned :1; |
| 440 | unsigned int probing :1; /* codec probing phase */ | 462 | unsigned int probing :1; /* codec probing phase */ |
| 463 | unsigned int snoop:1; | ||
| 441 | 464 | ||
| 442 | /* for debugging */ | 465 | /* for debugging */ |
| 443 | unsigned int last_cmd[AZX_MAX_CODECS]; | 466 | unsigned int last_cmd[AZX_MAX_CODECS]; |
| @@ -481,6 +504,7 @@ enum { | |||
| 481 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ | 504 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ |
| 482 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | 505 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
| 483 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | 506 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ |
| 507 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | ||
| 484 | 508 | ||
| 485 | /* quirks for ATI SB / AMD Hudson */ | 509 | /* quirks for ATI SB / AMD Hudson */ |
| 486 | #define AZX_DCAPS_PRESET_ATI_SB \ | 510 | #define AZX_DCAPS_PRESET_ATI_SB \ |
| @@ -542,6 +566,45 @@ static char *driver_short_names[] __devinitdata = { | |||
| 542 | /* for pcm support */ | 566 | /* for pcm support */ |
| 543 | #define get_azx_dev(substream) (substream->runtime->private_data) | 567 | #define get_azx_dev(substream) (substream->runtime->private_data) |
| 544 | 568 | ||
| 569 | #ifdef CONFIG_X86 | ||
| 570 | static void __mark_pages_wc(struct azx *chip, void *addr, size_t size, bool on) | ||
| 571 | { | ||
| 572 | if (azx_snoop(chip)) | ||
| 573 | return; | ||
| 574 | if (addr && size) { | ||
| 575 | int pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
| 576 | if (on) | ||
| 577 | set_memory_wc((unsigned long)addr, pages); | ||
| 578 | else | ||
| 579 | set_memory_wb((unsigned long)addr, pages); | ||
| 580 | } | ||
| 581 | } | ||
| 582 | |||
| 583 | static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, | ||
| 584 | bool on) | ||
| 585 | { | ||
| 586 | __mark_pages_wc(chip, buf->area, buf->bytes, on); | ||
| 587 | } | ||
| 588 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, | ||
| 589 | struct snd_pcm_runtime *runtime, bool on) | ||
| 590 | { | ||
| 591 | if (azx_dev->wc_marked != on) { | ||
| 592 | __mark_pages_wc(chip, runtime->dma_area, runtime->dma_bytes, on); | ||
| 593 | azx_dev->wc_marked = on; | ||
| 594 | } | ||
| 595 | } | ||
| 596 | #else | ||
| 597 | /* NOP for other archs */ | ||
| 598 | static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf, | ||
| 599 | bool on) | ||
| 600 | { | ||
| 601 | } | ||
| 602 | static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev, | ||
| 603 | struct snd_pcm_runtime *runtime, bool on) | ||
| 604 | { | ||
| 605 | } | ||
| 606 | #endif | ||
| 607 | |||
| 545 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); | 608 | static int azx_acquire_irq(struct azx *chip, int do_disconnect); |
| 546 | static int azx_send_cmd(struct hda_bus *bus, unsigned int val); | 609 | static int azx_send_cmd(struct hda_bus *bus, unsigned int val); |
| 547 | /* | 610 | /* |
| @@ -563,6 +626,7 @@ static int azx_alloc_cmd_io(struct azx *chip) | |||
| 563 | snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); | 626 | snd_printk(KERN_ERR SFX "cannot allocate CORB/RIRB\n"); |
| 564 | return err; | 627 | return err; |
| 565 | } | 628 | } |
| 629 | mark_pages_wc(chip, &chip->rb, true); | ||
| 566 | return 0; | 630 | return 0; |
| 567 | } | 631 | } |
| 568 | 632 | ||
| @@ -1079,7 +1143,15 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, | |||
| 1079 | 1143 | ||
| 1080 | static void azx_init_pci(struct azx *chip) | 1144 | static void azx_init_pci(struct azx *chip) |
| 1081 | { | 1145 | { |
| 1082 | unsigned short snoop; | 1146 | /* force to non-snoop mode for a new VIA controller when BIOS is set */ |
| 1147 | if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) { | ||
| 1148 | u8 snoop; | ||
| 1149 | pci_read_config_byte(chip->pci, 0x42, &snoop); | ||
| 1150 | if (!(snoop & 0x80) && chip->pci->revision == 0x30) { | ||
| 1151 | chip->snoop = 0; | ||
| 1152 | snd_printdd(SFX "Force to non-snoop mode\n"); | ||
| 1153 | } | ||
| 1154 | } | ||
| 1083 | 1155 | ||
| 1084 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 1156 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
| 1085 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 1157 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
| @@ -1096,15 +1168,15 @@ static void azx_init_pci(struct azx *chip) | |||
| 1096 | * we need to enable snoop. | 1168 | * we need to enable snoop. |
| 1097 | */ | 1169 | */ |
| 1098 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { | 1170 | if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { |
| 1099 | snd_printdd(SFX "Enabling ATI snoop\n"); | 1171 | snd_printdd(SFX "Setting ATI snoop: %d\n", azx_snoop(chip)); |
| 1100 | update_pci_byte(chip->pci, | 1172 | update_pci_byte(chip->pci, |
| 1101 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 1173 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07, |
| 1102 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); | 1174 | azx_snoop(chip) ? ATI_SB450_HDAUDIO_ENABLE_SNOOP : 0); |
| 1103 | } | 1175 | } |
| 1104 | 1176 | ||
| 1105 | /* For NVIDIA HDA, enable snoop */ | 1177 | /* For NVIDIA HDA, enable snoop */ |
| 1106 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { | 1178 | if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { |
| 1107 | snd_printdd(SFX "Enabling Nvidia snoop\n"); | 1179 | snd_printdd(SFX "Setting Nvidia snoop: %d\n", azx_snoop(chip)); |
| 1108 | update_pci_byte(chip->pci, | 1180 | update_pci_byte(chip->pci, |
| 1109 | NVIDIA_HDA_TRANSREG_ADDR, | 1181 | NVIDIA_HDA_TRANSREG_ADDR, |
| 1110 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); | 1182 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); |
| @@ -1118,16 +1190,20 @@ static void azx_init_pci(struct azx *chip) | |||
| 1118 | 1190 | ||
| 1119 | /* Enable SCH/PCH snoop if needed */ | 1191 | /* Enable SCH/PCH snoop if needed */ |
| 1120 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { | 1192 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { |
| 1193 | unsigned short snoop; | ||
| 1121 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 1194 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
| 1122 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 1195 | if ((!azx_snoop(chip) && !(snoop & INTEL_SCH_HDA_DEVC_NOSNOOP)) || |
| 1123 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, | 1196 | (azx_snoop(chip) && (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP))) { |
| 1124 | snoop & (~INTEL_SCH_HDA_DEVC_NOSNOOP)); | 1197 | snoop &= ~INTEL_SCH_HDA_DEVC_NOSNOOP; |
| 1198 | if (!azx_snoop(chip)) | ||
| 1199 | snoop |= INTEL_SCH_HDA_DEVC_NOSNOOP; | ||
| 1200 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, snoop); | ||
| 1125 | pci_read_config_word(chip->pci, | 1201 | pci_read_config_word(chip->pci, |
| 1126 | INTEL_SCH_HDA_DEVC, &snoop); | 1202 | INTEL_SCH_HDA_DEVC, &snoop); |
| 1127 | snd_printdd(SFX "HDA snoop disabled, enabling ... %s\n", | ||
| 1128 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | ||
| 1129 | ? "Failed" : "OK"); | ||
| 1130 | } | 1203 | } |
| 1204 | snd_printdd(SFX "SCH snoop: %s\n", | ||
| 1205 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | ||
| 1206 | ? "Disabled" : "Enabled"); | ||
| 1131 | } | 1207 | } |
| 1132 | } | 1208 | } |
| 1133 | 1209 | ||
| @@ -1334,12 +1410,16 @@ static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) | |||
| 1334 | */ | 1410 | */ |
| 1335 | static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) | 1411 | static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) |
| 1336 | { | 1412 | { |
| 1413 | unsigned int val; | ||
| 1337 | /* make sure the run bit is zero for SD */ | 1414 | /* make sure the run bit is zero for SD */ |
| 1338 | azx_stream_clear(chip, azx_dev); | 1415 | azx_stream_clear(chip, azx_dev); |
| 1339 | /* program the stream_tag */ | 1416 | /* program the stream_tag */ |
| 1340 | azx_sd_writel(azx_dev, SD_CTL, | 1417 | val = azx_sd_readl(azx_dev, SD_CTL); |
| 1341 | (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)| | 1418 | val = (val & ~SD_CTL_STREAM_TAG_MASK) | |
| 1342 | (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT)); | 1419 | (azx_dev->stream_tag << SD_CTL_STREAM_TAG_SHIFT); |
| 1420 | if (!azx_snoop(chip)) | ||
| 1421 | val |= SD_CTL_TRAFFIC_PRIO; | ||
| 1422 | azx_sd_writel(azx_dev, SD_CTL, val); | ||
| 1343 | 1423 | ||
| 1344 | /* program the length of samples in cyclic buffer */ | 1424 | /* program the length of samples in cyclic buffer */ |
| 1345 | azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); | 1425 | azx_sd_writel(azx_dev, SD_CBL, azx_dev->bufsize); |
| @@ -1533,6 +1613,9 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) | |||
| 1533 | { | 1613 | { |
| 1534 | int dev, i, nums; | 1614 | int dev, i, nums; |
| 1535 | struct azx_dev *res = NULL; | 1615 | struct azx_dev *res = NULL; |
| 1616 | /* make a non-zero unique key for the substream */ | ||
| 1617 | int key = (substream->pcm->device << 16) | (substream->number << 2) | | ||
| 1618 | (substream->stream + 1); | ||
| 1536 | 1619 | ||
| 1537 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 1620 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 1538 | dev = chip->playback_index_offset; | 1621 | dev = chip->playback_index_offset; |
| @@ -1544,12 +1627,12 @@ azx_assign_device(struct azx *chip, struct snd_pcm_substream *substream) | |||
| 1544 | for (i = 0; i < nums; i++, dev++) | 1627 | for (i = 0; i < nums; i++, dev++) |
| 1545 | if (!chip->azx_dev[dev].opened) { | 1628 | if (!chip->azx_dev[dev].opened) { |
| 1546 | res = &chip->azx_dev[dev]; | 1629 | res = &chip->azx_dev[dev]; |
| 1547 | if (res->device == substream->pcm->device) | 1630 | if (res->assigned_key == key) |
| 1548 | break; | 1631 | break; |
| 1549 | } | 1632 | } |
| 1550 | if (res) { | 1633 | if (res) { |
| 1551 | res->opened = 1; | 1634 | res->opened = 1; |
| 1552 | res->device = substream->pcm->device; | 1635 | res->assigned_key = key; |
| 1553 | } | 1636 | } |
| 1554 | return res; | 1637 | return res; |
| 1555 | } | 1638 | } |
| @@ -1599,6 +1682,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
| 1599 | struct snd_pcm_runtime *runtime = substream->runtime; | 1682 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1600 | unsigned long flags; | 1683 | unsigned long flags; |
| 1601 | int err; | 1684 | int err; |
| 1685 | int buff_step; | ||
| 1602 | 1686 | ||
| 1603 | mutex_lock(&chip->open_mutex); | 1687 | mutex_lock(&chip->open_mutex); |
| 1604 | azx_dev = azx_assign_device(chip, substream); | 1688 | azx_dev = azx_assign_device(chip, substream); |
| @@ -1613,10 +1697,25 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |||
| 1613 | runtime->hw.rates = hinfo->rates; | 1697 | runtime->hw.rates = hinfo->rates; |
| 1614 | snd_pcm_limit_hw_rates(runtime); | 1698 | snd_pcm_limit_hw_rates(runtime); |
| 1615 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | 1699 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); |
| 1700 | if (align_buffer_size) | ||
| 1701 | /* constrain buffer sizes to be multiple of 128 | ||
| 1702 | bytes. This is more efficient in terms of memory | ||
| 1703 | access but isn't required by the HDA spec and | ||
| 1704 | prevents users from specifying exact period/buffer | ||
| 1705 | sizes. For example for 44.1kHz, a period size set | ||
| 1706 | to 20ms will be rounded to 19.59ms. */ | ||
| 1707 | buff_step = 128; | ||
| 1708 | else | ||
| 1709 | /* Don't enforce steps on buffer sizes, still need to | ||
| 1710 | be multiple of 4 bytes (HDA spec). Tested on Intel | ||
| 1711 | HDA controllers, may not work on all devices where | ||
| 1712 | option needs to be disabled */ | ||
| 1713 | buff_step = 4; | ||
| 1714 | |||
| 1616 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, | 1715 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, |
| 1617 | 128); | 1716 | buff_step); |
| 1618 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, | 1717 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, |
| 1619 | 128); | 1718 | buff_step); |
| 1620 | snd_hda_power_up(apcm->codec); | 1719 | snd_hda_power_up(apcm->codec); |
| 1621 | err = hinfo->ops.open(hinfo, apcm->codec, substream); | 1720 | err = hinfo->ops.open(hinfo, apcm->codec, substream); |
| 1622 | if (err < 0) { | 1721 | if (err < 0) { |
| @@ -1671,19 +1770,30 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) | |||
| 1671 | static int azx_pcm_hw_params(struct snd_pcm_substream *substream, | 1770 | static int azx_pcm_hw_params(struct snd_pcm_substream *substream, |
| 1672 | struct snd_pcm_hw_params *hw_params) | 1771 | struct snd_pcm_hw_params *hw_params) |
| 1673 | { | 1772 | { |
| 1773 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
| 1774 | struct azx *chip = apcm->chip; | ||
| 1775 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 1674 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1776 | struct azx_dev *azx_dev = get_azx_dev(substream); |
| 1777 | int ret; | ||
| 1675 | 1778 | ||
| 1779 | mark_runtime_wc(chip, azx_dev, runtime, false); | ||
| 1676 | azx_dev->bufsize = 0; | 1780 | azx_dev->bufsize = 0; |
| 1677 | azx_dev->period_bytes = 0; | 1781 | azx_dev->period_bytes = 0; |
| 1678 | azx_dev->format_val = 0; | 1782 | azx_dev->format_val = 0; |
| 1679 | return snd_pcm_lib_malloc_pages(substream, | 1783 | ret = snd_pcm_lib_malloc_pages(substream, |
| 1680 | params_buffer_bytes(hw_params)); | 1784 | params_buffer_bytes(hw_params)); |
| 1785 | if (ret < 0) | ||
| 1786 | return ret; | ||
| 1787 | mark_runtime_wc(chip, azx_dev, runtime, true); | ||
| 1788 | return ret; | ||
| 1681 | } | 1789 | } |
| 1682 | 1790 | ||
| 1683 | static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | 1791 | static int azx_pcm_hw_free(struct snd_pcm_substream *substream) |
| 1684 | { | 1792 | { |
| 1685 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 1793 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
| 1686 | struct azx_dev *azx_dev = get_azx_dev(substream); | 1794 | struct azx_dev *azx_dev = get_azx_dev(substream); |
| 1795 | struct azx *chip = apcm->chip; | ||
| 1796 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 1687 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; | 1797 | struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; |
| 1688 | 1798 | ||
| 1689 | /* reset BDL address */ | 1799 | /* reset BDL address */ |
| @@ -1696,6 +1806,7 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) | |||
| 1696 | 1806 | ||
| 1697 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); | 1807 | snd_hda_codec_cleanup(apcm->codec, hinfo, substream); |
| 1698 | 1808 | ||
| 1809 | mark_runtime_wc(chip, azx_dev, runtime, false); | ||
| 1699 | return snd_pcm_lib_free_pages(substream); | 1810 | return snd_pcm_lib_free_pages(substream); |
| 1700 | } | 1811 | } |
| 1701 | 1812 | ||
| @@ -2055,6 +2166,20 @@ static void azx_clear_irq_pending(struct azx *chip) | |||
| 2055 | spin_unlock_irq(&chip->reg_lock); | 2166 | spin_unlock_irq(&chip->reg_lock); |
| 2056 | } | 2167 | } |
| 2057 | 2168 | ||
| 2169 | #ifdef CONFIG_X86 | ||
| 2170 | static int azx_pcm_mmap(struct snd_pcm_substream *substream, | ||
| 2171 | struct vm_area_struct *area) | ||
| 2172 | { | ||
| 2173 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | ||
| 2174 | struct azx *chip = apcm->chip; | ||
| 2175 | if (!azx_snoop(chip)) | ||
| 2176 | area->vm_page_prot = pgprot_writecombine(area->vm_page_prot); | ||
| 2177 | return snd_pcm_lib_default_mmap(substream, area); | ||
| 2178 | } | ||
| 2179 | #else | ||
| 2180 | #define azx_pcm_mmap NULL | ||
| 2181 | #endif | ||
| 2182 | |||
| 2058 | static struct snd_pcm_ops azx_pcm_ops = { | 2183 | static struct snd_pcm_ops azx_pcm_ops = { |
| 2059 | .open = azx_pcm_open, | 2184 | .open = azx_pcm_open, |
| 2060 | .close = azx_pcm_close, | 2185 | .close = azx_pcm_close, |
| @@ -2064,6 +2189,7 @@ static struct snd_pcm_ops azx_pcm_ops = { | |||
| 2064 | .prepare = azx_pcm_prepare, | 2189 | .prepare = azx_pcm_prepare, |
| 2065 | .trigger = azx_pcm_trigger, | 2190 | .trigger = azx_pcm_trigger, |
| 2066 | .pointer = azx_pcm_pointer, | 2191 | .pointer = azx_pcm_pointer, |
| 2192 | .mmap = azx_pcm_mmap, | ||
| 2067 | .page = snd_pcm_sgbuf_ops_page, | 2193 | .page = snd_pcm_sgbuf_ops_page, |
| 2068 | }; | 2194 | }; |
| 2069 | 2195 | ||
| @@ -2344,13 +2470,19 @@ static int azx_free(struct azx *chip) | |||
| 2344 | 2470 | ||
| 2345 | if (chip->azx_dev) { | 2471 | if (chip->azx_dev) { |
| 2346 | for (i = 0; i < chip->num_streams; i++) | 2472 | for (i = 0; i < chip->num_streams; i++) |
| 2347 | if (chip->azx_dev[i].bdl.area) | 2473 | if (chip->azx_dev[i].bdl.area) { |
| 2474 | mark_pages_wc(chip, &chip->azx_dev[i].bdl, false); | ||
| 2348 | snd_dma_free_pages(&chip->azx_dev[i].bdl); | 2475 | snd_dma_free_pages(&chip->azx_dev[i].bdl); |
| 2476 | } | ||
| 2349 | } | 2477 | } |
| 2350 | if (chip->rb.area) | 2478 | if (chip->rb.area) { |
| 2479 | mark_pages_wc(chip, &chip->rb, false); | ||
| 2351 | snd_dma_free_pages(&chip->rb); | 2480 | snd_dma_free_pages(&chip->rb); |
| 2352 | if (chip->posbuf.area) | 2481 | } |
| 2482 | if (chip->posbuf.area) { | ||
| 2483 | mark_pages_wc(chip, &chip->posbuf, false); | ||
| 2353 | snd_dma_free_pages(&chip->posbuf); | 2484 | snd_dma_free_pages(&chip->posbuf); |
| 2485 | } | ||
| 2354 | pci_release_regions(chip->pci); | 2486 | pci_release_regions(chip->pci); |
| 2355 | pci_disable_device(chip->pci); | 2487 | pci_disable_device(chip->pci); |
| 2356 | kfree(chip->azx_dev); | 2488 | kfree(chip->azx_dev); |
| @@ -2546,6 +2678,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 2546 | check_probe_mask(chip, dev); | 2678 | check_probe_mask(chip, dev); |
| 2547 | 2679 | ||
| 2548 | chip->single_cmd = single_cmd; | 2680 | chip->single_cmd = single_cmd; |
| 2681 | chip->snoop = hda_snoop; | ||
| 2549 | 2682 | ||
| 2550 | if (bdl_pos_adj[dev] < 0) { | 2683 | if (bdl_pos_adj[dev] < 0) { |
| 2551 | switch (chip->driver_type) { | 2684 | switch (chip->driver_type) { |
| @@ -2618,6 +2751,10 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 2618 | gcap &= ~ICH6_GCAP_64OK; | 2751 | gcap &= ~ICH6_GCAP_64OK; |
| 2619 | } | 2752 | } |
| 2620 | 2753 | ||
| 2754 | /* disable buffer size rounding to 128-byte multiples if supported */ | ||
| 2755 | if (chip->driver_caps & AZX_DCAPS_BUFSIZE) | ||
| 2756 | align_buffer_size = 0; | ||
| 2757 | |||
| 2621 | /* allow 64bit DMA address if supported by H/W */ | 2758 | /* allow 64bit DMA address if supported by H/W */ |
| 2622 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2759 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
| 2623 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); | 2760 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |
| @@ -2669,6 +2806,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 2669 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); | 2806 | snd_printk(KERN_ERR SFX "cannot allocate BDL\n"); |
| 2670 | goto errout; | 2807 | goto errout; |
| 2671 | } | 2808 | } |
| 2809 | mark_pages_wc(chip, &chip->azx_dev[i].bdl, true); | ||
| 2672 | } | 2810 | } |
| 2673 | /* allocate memory for the position buffer */ | 2811 | /* allocate memory for the position buffer */ |
| 2674 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | 2812 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, |
| @@ -2678,6 +2816,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
| 2678 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); | 2816 | snd_printk(KERN_ERR SFX "cannot allocate posbuf\n"); |
| 2679 | goto errout; | 2817 | goto errout; |
| 2680 | } | 2818 | } |
| 2819 | mark_pages_wc(chip, &chip->posbuf, true); | ||
| 2681 | /* allocate CORB/RIRB */ | 2820 | /* allocate CORB/RIRB */ |
| 2682 | err = azx_alloc_cmd_io(chip); | 2821 | err = azx_alloc_cmd_io(chip); |
| 2683 | if (err < 0) | 2822 | if (err < 0) |
| @@ -2819,37 +2958,49 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
| 2819 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | 2958 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { |
| 2820 | /* CPT */ | 2959 | /* CPT */ |
| 2821 | { PCI_DEVICE(0x8086, 0x1c20), | 2960 | { PCI_DEVICE(0x8086, 0x1c20), |
| 2822 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | 2961 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| 2962 | AZX_DCAPS_BUFSIZE }, | ||
| 2823 | /* PBG */ | 2963 | /* PBG */ |
| 2824 | { PCI_DEVICE(0x8086, 0x1d20), | 2964 | { PCI_DEVICE(0x8086, 0x1d20), |
| 2825 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | 2965 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| 2966 | AZX_DCAPS_BUFSIZE}, | ||
| 2826 | /* Panther Point */ | 2967 | /* Panther Point */ |
| 2827 | { PCI_DEVICE(0x8086, 0x1e20), | 2968 | { PCI_DEVICE(0x8086, 0x1e20), |
| 2828 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | 2969 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
| 2970 | AZX_DCAPS_BUFSIZE}, | ||
| 2829 | /* SCH */ | 2971 | /* SCH */ |
| 2830 | { PCI_DEVICE(0x8086, 0x811b), | 2972 | { PCI_DEVICE(0x8086, 0x811b), |
| 2831 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, | 2973 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
| 2974 | AZX_DCAPS_BUFSIZE}, | ||
| 2832 | { PCI_DEVICE(0x8086, 0x2668), | 2975 | { PCI_DEVICE(0x8086, 0x2668), |
| 2833 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */ | 2976 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2977 | AZX_DCAPS_BUFSIZE }, /* ICH6 */ | ||
| 2834 | { PCI_DEVICE(0x8086, 0x27d8), | 2978 | { PCI_DEVICE(0x8086, 0x27d8), |
| 2835 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */ | 2979 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2980 | AZX_DCAPS_BUFSIZE }, /* ICH7 */ | ||
| 2836 | { PCI_DEVICE(0x8086, 0x269a), | 2981 | { PCI_DEVICE(0x8086, 0x269a), |
| 2837 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */ | 2982 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2983 | AZX_DCAPS_BUFSIZE }, /* ESB2 */ | ||
| 2838 | { PCI_DEVICE(0x8086, 0x284b), | 2984 | { PCI_DEVICE(0x8086, 0x284b), |
| 2839 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */ | 2985 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2986 | AZX_DCAPS_BUFSIZE }, /* ICH8 */ | ||
| 2840 | { PCI_DEVICE(0x8086, 0x293e), | 2987 | { PCI_DEVICE(0x8086, 0x293e), |
| 2841 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ | 2988 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2989 | AZX_DCAPS_BUFSIZE }, /* ICH9 */ | ||
| 2842 | { PCI_DEVICE(0x8086, 0x293f), | 2990 | { PCI_DEVICE(0x8086, 0x293f), |
| 2843 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ | 2991 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2992 | AZX_DCAPS_BUFSIZE }, /* ICH9 */ | ||
| 2844 | { PCI_DEVICE(0x8086, 0x3a3e), | 2993 | { PCI_DEVICE(0x8086, 0x3a3e), |
| 2845 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ | 2994 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2995 | AZX_DCAPS_BUFSIZE }, /* ICH10 */ | ||
| 2846 | { PCI_DEVICE(0x8086, 0x3a6e), | 2996 | { PCI_DEVICE(0x8086, 0x3a6e), |
| 2847 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ | 2997 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
| 2998 | AZX_DCAPS_BUFSIZE }, /* ICH10 */ | ||
| 2848 | /* Generic Intel */ | 2999 | /* Generic Intel */ |
| 2849 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), | 3000 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), |
| 2850 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 3001 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
| 2851 | .class_mask = 0xffffff, | 3002 | .class_mask = 0xffffff, |
| 2852 | .driver_data = AZX_DRIVER_ICH }, | 3003 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_BUFSIZE }, |
| 2853 | /* ATI SB 450/600/700/800/900 */ | 3004 | /* ATI SB 450/600/700/800/900 */ |
| 2854 | { PCI_DEVICE(0x1002, 0x437b), | 3005 | { PCI_DEVICE(0x1002, 0x437b), |
| 2855 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, | 3006 | .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 2e7ac31afa8d..81e12c0ed0a2 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
| @@ -267,11 +267,14 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, | |||
| 267 | enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */ | 267 | enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */ |
| 268 | enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */ | 268 | enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */ |
| 269 | 269 | ||
| 270 | #define HDA_MAX_OUTS 5 | ||
| 271 | |||
| 270 | struct hda_multi_out { | 272 | struct hda_multi_out { |
| 271 | int num_dacs; /* # of DACs, must be more than 1 */ | 273 | int num_dacs; /* # of DACs, must be more than 1 */ |
| 272 | const hda_nid_t *dac_nids; /* DAC list */ | 274 | const hda_nid_t *dac_nids; /* DAC list */ |
| 273 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ | 275 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ |
| 274 | hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ | 276 | hda_nid_t hp_out_nid[HDA_MAX_OUTS]; /* DACs for multiple HPs */ |
| 277 | hda_nid_t extra_out_nid[HDA_MAX_OUTS]; /* other (e.g. speaker) DACs */ | ||
| 275 | hda_nid_t dig_out_nid; /* digital out audio widget */ | 278 | hda_nid_t dig_out_nid; /* digital out audio widget */ |
| 276 | const hda_nid_t *slave_dig_outs; | 279 | const hda_nid_t *slave_dig_outs; |
| 277 | int max_channels; /* currently supported analog channels */ | 280 | int max_channels; /* currently supported analog channels */ |
| @@ -333,9 +336,6 @@ int snd_hda_codec_proc_new(struct hda_codec *codec); | |||
| 333 | static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } | 336 | static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } |
| 334 | #endif | 337 | #endif |
| 335 | 338 | ||
| 336 | #define SND_PRINT_RATES_ADVISED_BUFSIZE 80 | ||
| 337 | void snd_print_pcm_rates(int pcm, char *buf, int buflen); | ||
| 338 | |||
| 339 | #define SND_PRINT_BITS_ADVISED_BUFSIZE 16 | 339 | #define SND_PRINT_BITS_ADVISED_BUFSIZE 16 |
| 340 | void snd_print_pcm_bits(int pcm, char *buf, int buflen); | 340 | void snd_print_pcm_bits(int pcm, char *buf, int buflen); |
| 341 | 341 | ||
| @@ -385,7 +385,7 @@ enum { | |||
| 385 | AUTO_PIN_HP_OUT | 385 | AUTO_PIN_HP_OUT |
| 386 | }; | 386 | }; |
| 387 | 387 | ||
| 388 | #define AUTO_CFG_MAX_OUTS 5 | 388 | #define AUTO_CFG_MAX_OUTS HDA_MAX_OUTS |
| 389 | #define AUTO_CFG_MAX_INS 8 | 389 | #define AUTO_CFG_MAX_INS 8 |
| 390 | 390 | ||
| 391 | struct auto_pin_cfg_item { | 391 | struct auto_pin_cfg_item { |
| @@ -443,9 +443,18 @@ struct auto_pin_cfg { | |||
| 443 | #define get_defcfg_device(cfg) \ | 443 | #define get_defcfg_device(cfg) \ |
| 444 | ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | 444 | ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) |
| 445 | 445 | ||
| 446 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, | 446 | /* bit-flags for snd_hda_parse_pin_def_config() behavior */ |
| 447 | struct auto_pin_cfg *cfg, | 447 | #define HDA_PINCFG_NO_HP_FIXUP (1 << 0) /* no HP-split */ |
| 448 | const hda_nid_t *ignore_nids); | 448 | #define HDA_PINCFG_NO_LO_FIXUP (1 << 1) /* don't take other outs as LO */ |
| 449 | |||
| 450 | int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | ||
| 451 | struct auto_pin_cfg *cfg, | ||
| 452 | const hda_nid_t *ignore_nids, | ||
| 453 | unsigned int cond_flags); | ||
| 454 | |||
| 455 | /* older function */ | ||
| 456 | #define snd_hda_parse_pin_def_config(codec, cfg, ignore) \ | ||
| 457 | snd_hda_parse_pin_defcfg(codec, cfg, ignore, 0) | ||
| 449 | 458 | ||
| 450 | /* amp values */ | 459 | /* amp values */ |
| 451 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) | 460 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) |
| @@ -492,6 +501,8 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction); | |||
| 492 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 501 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, |
| 493 | unsigned int caps); | 502 | unsigned int caps); |
| 494 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); | 503 | u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); |
| 504 | int snd_hda_override_pin_caps(struct hda_codec *codec, hda_nid_t nid, | ||
| 505 | unsigned int caps); | ||
| 495 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); | 506 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); |
| 496 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | 507 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); |
| 497 | 508 | ||
| @@ -589,7 +600,8 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
| 589 | #define get_amp_nid_(pv) ((pv) & 0xffff) | 600 | #define get_amp_nid_(pv) ((pv) & 0xffff) |
| 590 | #define get_amp_nid(kc) get_amp_nid_((kc)->private_value) | 601 | #define get_amp_nid(kc) get_amp_nid_((kc)->private_value) |
| 591 | #define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) | 602 | #define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) |
| 592 | #define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) | 603 | #define get_amp_direction_(pv) (((pv) >> 18) & 0x1) |
| 604 | #define get_amp_direction(kc) get_amp_direction_((kc)->private_value) | ||
| 593 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) | 605 | #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) |
| 594 | #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) | 606 | #define get_amp_offset(kc) (((kc)->private_value >> 23) & 0x3f) |
| 595 | #define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) | 607 | #define get_amp_min_mute(kc) (((kc)->private_value >> 29) & 0x1) |
| @@ -607,6 +619,7 @@ struct cea_sad { | |||
| 607 | }; | 619 | }; |
| 608 | 620 | ||
| 609 | #define ELD_FIXED_BYTES 20 | 621 | #define ELD_FIXED_BYTES 20 |
| 622 | #define ELD_MAX_SIZE 256 | ||
| 610 | #define ELD_MAX_MNL 16 | 623 | #define ELD_MAX_MNL 16 |
| 611 | #define ELD_MAX_SAD 16 | 624 | #define ELD_MAX_SAD 16 |
| 612 | 625 | ||
| @@ -631,6 +644,7 @@ struct hdmi_eld { | |||
| 631 | int spk_alloc; | 644 | int spk_alloc; |
| 632 | int sad_count; | 645 | int sad_count; |
| 633 | struct cea_sad sad[ELD_MAX_SAD]; | 646 | struct cea_sad sad[ELD_MAX_SAD]; |
| 647 | char eld_buffer[ELD_MAX_SIZE]; | ||
| 634 | #ifdef CONFIG_PROC_FS | 648 | #ifdef CONFIG_PROC_FS |
| 635 | struct snd_info_entry *proc_entry; | 649 | struct snd_info_entry *proc_entry; |
| 636 | #endif | 650 | #endif |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 2be57b051aa2..2c981b55940b 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
| @@ -152,12 +152,18 @@ static void print_amp_vals(struct snd_info_buffer *buffer, | |||
| 152 | 152 | ||
| 153 | static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) | 153 | static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) |
| 154 | { | 154 | { |
| 155 | char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; | 155 | static unsigned int rates[] = { |
| 156 | 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200, | ||
| 157 | 96000, 176400, 192000, 384000 | ||
| 158 | }; | ||
| 159 | int i; | ||
| 156 | 160 | ||
| 157 | pcm &= AC_SUPPCM_RATES; | 161 | pcm &= AC_SUPPCM_RATES; |
| 158 | snd_iprintf(buffer, " rates [0x%x]:", pcm); | 162 | snd_iprintf(buffer, " rates [0x%x]:", pcm); |
| 159 | snd_print_pcm_rates(pcm, buf, sizeof(buf)); | 163 | for (i = 0; i < ARRAY_SIZE(rates); i++) |
| 160 | snd_iprintf(buffer, "%s\n", buf); | 164 | if (pcm & (1 << i)) |
| 165 | snd_iprintf(buffer, " %d", rates[i]); | ||
| 166 | snd_iprintf(buffer, "\n"); | ||
| 161 | } | 167 | } |
| 162 | 168 | ||
| 163 | static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) | 169 | static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) |
diff --git a/sound/pci/hda/hda_trace.h b/sound/pci/hda/hda_trace.h new file mode 100644 index 000000000000..9884871ddb00 --- /dev/null +++ b/sound/pci/hda/hda_trace.h | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | #undef TRACE_SYSTEM | ||
| 2 | #define TRACE_SYSTEM hda | ||
| 3 | #define TRACE_INCLUDE_FILE hda_trace | ||
| 4 | |||
| 5 | #if !defined(_TRACE_HDA_H) || defined(TRACE_HEADER_MULTI_READ) | ||
| 6 | #define _TRACE_HDA_H | ||
| 7 | |||
| 8 | #include <linux/tracepoint.h> | ||
| 9 | |||
| 10 | struct hda_bus; | ||
| 11 | struct hda_codec; | ||
| 12 | |||
| 13 | DECLARE_EVENT_CLASS(hda_cmd, | ||
| 14 | |||
| 15 | TP_PROTO(struct hda_codec *codec, unsigned int val), | ||
| 16 | |||
| 17 | TP_ARGS(codec, val), | ||
| 18 | |||
| 19 | TP_STRUCT__entry( | ||
| 20 | __field( unsigned int, card ) | ||
| 21 | __field( unsigned int, addr ) | ||
| 22 | __field( unsigned int, val ) | ||
| 23 | ), | ||
| 24 | |||
| 25 | TP_fast_assign( | ||
| 26 | __entry->card = (codec)->bus->card->number; | ||
| 27 | __entry->addr = (codec)->addr; | ||
| 28 | __entry->val = (val); | ||
| 29 | ), | ||
| 30 | |||
| 31 | TP_printk("[%d:%d] val=%x", __entry->card, __entry->addr, __entry->val) | ||
| 32 | ); | ||
| 33 | |||
| 34 | DEFINE_EVENT(hda_cmd, hda_send_cmd, | ||
| 35 | TP_PROTO(struct hda_codec *codec, unsigned int val), | ||
| 36 | TP_ARGS(codec, val) | ||
| 37 | ); | ||
| 38 | |||
| 39 | DEFINE_EVENT(hda_cmd, hda_get_response, | ||
| 40 | TP_PROTO(struct hda_codec *codec, unsigned int val), | ||
| 41 | TP_ARGS(codec, val) | ||
| 42 | ); | ||
| 43 | |||
| 44 | TRACE_EVENT(hda_bus_reset, | ||
| 45 | |||
| 46 | TP_PROTO(struct hda_bus *bus), | ||
| 47 | |||
| 48 | TP_ARGS(bus), | ||
| 49 | |||
| 50 | TP_STRUCT__entry( | ||
| 51 | __field( unsigned int, card ) | ||
| 52 | ), | ||
| 53 | |||
| 54 | TP_fast_assign( | ||
| 55 | __entry->card = (bus)->card->number; | ||
| 56 | ), | ||
| 57 | |||
| 58 | TP_printk("[%d]", __entry->card) | ||
| 59 | ); | ||
| 60 | |||
| 61 | DECLARE_EVENT_CLASS(hda_power, | ||
| 62 | |||
| 63 | TP_PROTO(struct hda_codec *codec), | ||
| 64 | |||
| 65 | TP_ARGS(codec), | ||
| 66 | |||
| 67 | TP_STRUCT__entry( | ||
| 68 | __field( unsigned int, card ) | ||
| 69 | __field( unsigned int, addr ) | ||
| 70 | ), | ||
| 71 | |||
| 72 | TP_fast_assign( | ||
| 73 | __entry->card = (codec)->bus->card->number; | ||
| 74 | __entry->addr = (codec)->addr; | ||
| 75 | ), | ||
| 76 | |||
| 77 | TP_printk("[%d:%d]", __entry->card, __entry->addr) | ||
| 78 | ); | ||
| 79 | |||
| 80 | DEFINE_EVENT(hda_power, hda_power_down, | ||
| 81 | TP_PROTO(struct hda_codec *codec), | ||
| 82 | TP_ARGS(codec) | ||
| 83 | ); | ||
| 84 | |||
| 85 | DEFINE_EVENT(hda_power, hda_power_up, | ||
| 86 | TP_PROTO(struct hda_codec *codec), | ||
| 87 | TP_ARGS(codec) | ||
| 88 | ); | ||
| 89 | |||
| 90 | TRACE_EVENT(hda_unsol_event, | ||
| 91 | |||
| 92 | TP_PROTO(struct hda_bus *bus, u32 res, u32 res_ex), | ||
| 93 | |||
| 94 | TP_ARGS(bus, res, res_ex), | ||
| 95 | |||
| 96 | TP_STRUCT__entry( | ||
| 97 | __field( unsigned int, card ) | ||
| 98 | __field( u32, res ) | ||
| 99 | __field( u32, res_ex ) | ||
| 100 | ), | ||
| 101 | |||
| 102 | TP_fast_assign( | ||
| 103 | __entry->card = (bus)->card->number; | ||
| 104 | __entry->res = res; | ||
| 105 | __entry->res_ex = res_ex; | ||
| 106 | ), | ||
| 107 | |||
| 108 | TP_printk("[%d] res=%x, res_ex=%x", __entry->card, | ||
| 109 | __entry->res, __entry->res_ex) | ||
| 110 | ); | ||
| 111 | |||
| 112 | #endif /* _TRACE_HDA_H */ | ||
| 113 | |||
| 114 | /* This part must be outside protection */ | ||
| 115 | #undef TRACE_INCLUDE_PATH | ||
| 116 | #define TRACE_INCLUDE_PATH . | ||
| 117 | #include <trace/define_trace.h> | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 8648917acffb..d8aac588f23b 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
| @@ -48,6 +48,8 @@ struct ad198x_spec { | |||
| 48 | 48 | ||
| 49 | const hda_nid_t *alt_dac_nid; | 49 | const hda_nid_t *alt_dac_nid; |
| 50 | const struct hda_pcm_stream *stream_analog_alt_playback; | 50 | const struct hda_pcm_stream *stream_analog_alt_playback; |
| 51 | int independent_hp; | ||
| 52 | int num_active_streams; | ||
| 51 | 53 | ||
| 52 | /* capture */ | 54 | /* capture */ |
| 53 | unsigned int num_adc_nids; | 55 | unsigned int num_adc_nids; |
| @@ -302,6 +304,72 @@ static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid) | |||
| 302 | } | 304 | } |
| 303 | #endif | 305 | #endif |
| 304 | 306 | ||
| 307 | static void activate_ctl(struct hda_codec *codec, const char *name, int active) | ||
| 308 | { | ||
| 309 | struct snd_kcontrol *ctl = snd_hda_find_mixer_ctl(codec, name); | ||
| 310 | if (ctl) { | ||
| 311 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
| 312 | ctl->vd[0].access |= active ? 0 : | ||
| 313 | SNDRV_CTL_ELEM_ACCESS_INACTIVE; | ||
| 314 | ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_WRITE; | ||
| 315 | ctl->vd[0].access |= active ? | ||
| 316 | SNDRV_CTL_ELEM_ACCESS_WRITE : 0; | ||
| 317 | snd_ctl_notify(codec->bus->card, | ||
| 318 | SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | static void set_stream_active(struct hda_codec *codec, bool active) | ||
| 323 | { | ||
| 324 | struct ad198x_spec *spec = codec->spec; | ||
| 325 | if (active) | ||
| 326 | spec->num_active_streams++; | ||
| 327 | else | ||
| 328 | spec->num_active_streams--; | ||
| 329 | activate_ctl(codec, "Independent HP", spec->num_active_streams == 0); | ||
| 330 | } | ||
| 331 | |||
| 332 | static int ad1988_independent_hp_info(struct snd_kcontrol *kcontrol, | ||
| 333 | struct snd_ctl_elem_info *uinfo) | ||
| 334 | { | ||
| 335 | static const char * const texts[] = { "OFF", "ON", NULL}; | ||
| 336 | int index; | ||
| 337 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
| 338 | uinfo->count = 1; | ||
| 339 | uinfo->value.enumerated.items = 2; | ||
| 340 | index = uinfo->value.enumerated.item; | ||
| 341 | if (index >= 2) | ||
| 342 | index = 1; | ||
| 343 | strcpy(uinfo->value.enumerated.name, texts[index]); | ||
| 344 | return 0; | ||
| 345 | } | ||
| 346 | |||
| 347 | static int ad1988_independent_hp_get(struct snd_kcontrol *kcontrol, | ||
| 348 | struct snd_ctl_elem_value *ucontrol) | ||
| 349 | { | ||
| 350 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 351 | struct ad198x_spec *spec = codec->spec; | ||
| 352 | ucontrol->value.enumerated.item[0] = spec->independent_hp; | ||
| 353 | return 0; | ||
| 354 | } | ||
| 355 | |||
| 356 | static int ad1988_independent_hp_put(struct snd_kcontrol *kcontrol, | ||
| 357 | struct snd_ctl_elem_value *ucontrol) | ||
| 358 | { | ||
| 359 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 360 | struct ad198x_spec *spec = codec->spec; | ||
| 361 | unsigned int select = ucontrol->value.enumerated.item[0]; | ||
| 362 | if (spec->independent_hp != select) { | ||
| 363 | spec->independent_hp = select; | ||
| 364 | if (spec->independent_hp) | ||
| 365 | spec->multiout.hp_nid = 0; | ||
| 366 | else | ||
| 367 | spec->multiout.hp_nid = spec->alt_dac_nid[0]; | ||
| 368 | return 1; | ||
| 369 | } | ||
| 370 | return 0; | ||
| 371 | } | ||
| 372 | |||
| 305 | /* | 373 | /* |
| 306 | * Analog playback callbacks | 374 | * Analog playback callbacks |
| 307 | */ | 375 | */ |
| @@ -310,8 +378,15 @@ static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
| 310 | struct snd_pcm_substream *substream) | 378 | struct snd_pcm_substream *substream) |
| 311 | { | 379 | { |
| 312 | struct ad198x_spec *spec = codec->spec; | 380 | struct ad198x_spec *spec = codec->spec; |
| 313 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | 381 | int err; |
| 382 | set_stream_active(codec, true); | ||
| 383 | err = snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | ||
| 314 | hinfo); | 384 | hinfo); |
| 385 | if (err < 0) { | ||
| 386 | set_stream_active(codec, false); | ||
| 387 | return err; | ||
| 388 | } | ||
| 389 | return 0; | ||
| 315 | } | 390 | } |
| 316 | 391 | ||
| 317 | static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 392 | static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
| @@ -333,11 +408,41 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
| 333 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 408 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
| 334 | } | 409 | } |
| 335 | 410 | ||
| 411 | static int ad198x_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
| 412 | struct hda_codec *codec, | ||
| 413 | struct snd_pcm_substream *substream) | ||
| 414 | { | ||
| 415 | set_stream_active(codec, false); | ||
| 416 | return 0; | ||
| 417 | } | ||
| 418 | |||
| 419 | static int ad1988_alt_playback_pcm_open(struct hda_pcm_stream *hinfo, | ||
| 420 | struct hda_codec *codec, | ||
| 421 | struct snd_pcm_substream *substream) | ||
| 422 | { | ||
| 423 | struct ad198x_spec *spec = codec->spec; | ||
| 424 | if (!spec->independent_hp) | ||
| 425 | return -EBUSY; | ||
| 426 | set_stream_active(codec, true); | ||
| 427 | return 0; | ||
| 428 | } | ||
| 429 | |||
| 430 | static int ad1988_alt_playback_pcm_close(struct hda_pcm_stream *hinfo, | ||
| 431 | struct hda_codec *codec, | ||
| 432 | struct snd_pcm_substream *substream) | ||
| 433 | { | ||
| 434 | set_stream_active(codec, false); | ||
| 435 | return 0; | ||
| 436 | } | ||
| 437 | |||
| 336 | static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { | 438 | static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { |
| 337 | .substreams = 1, | 439 | .substreams = 1, |
| 338 | .channels_min = 2, | 440 | .channels_min = 2, |
| 339 | .channels_max = 2, | 441 | .channels_max = 2, |
| 340 | /* NID is set in ad198x_build_pcms */ | 442 | .ops = { |
| 443 | .open = ad1988_alt_playback_pcm_open, | ||
| 444 | .close = ad1988_alt_playback_pcm_close | ||
| 445 | }, | ||
| 341 | }; | 446 | }; |
| 342 | 447 | ||
| 343 | /* | 448 | /* |
| @@ -402,7 +507,6 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
| 402 | return 0; | 507 | return 0; |
| 403 | } | 508 | } |
| 404 | 509 | ||
| 405 | |||
| 406 | /* | 510 | /* |
| 407 | */ | 511 | */ |
| 408 | static const struct hda_pcm_stream ad198x_pcm_analog_playback = { | 512 | static const struct hda_pcm_stream ad198x_pcm_analog_playback = { |
| @@ -413,7 +517,8 @@ static const struct hda_pcm_stream ad198x_pcm_analog_playback = { | |||
| 413 | .ops = { | 517 | .ops = { |
| 414 | .open = ad198x_playback_pcm_open, | 518 | .open = ad198x_playback_pcm_open, |
| 415 | .prepare = ad198x_playback_pcm_prepare, | 519 | .prepare = ad198x_playback_pcm_prepare, |
| 416 | .cleanup = ad198x_playback_pcm_cleanup | 520 | .cleanup = ad198x_playback_pcm_cleanup, |
| 521 | .close = ad198x_playback_pcm_close | ||
| 417 | }, | 522 | }, |
| 418 | }; | 523 | }; |
| 419 | 524 | ||
| @@ -2058,7 +2163,6 @@ static int patch_ad1981(struct hda_codec *codec) | |||
| 2058 | enum { | 2163 | enum { |
| 2059 | AD1988_6STACK, | 2164 | AD1988_6STACK, |
| 2060 | AD1988_6STACK_DIG, | 2165 | AD1988_6STACK_DIG, |
| 2061 | AD1988_6STACK_DIG_FP, | ||
| 2062 | AD1988_3STACK, | 2166 | AD1988_3STACK, |
| 2063 | AD1988_3STACK_DIG, | 2167 | AD1988_3STACK_DIG, |
| 2064 | AD1988_LAPTOP, | 2168 | AD1988_LAPTOP, |
| @@ -2168,6 +2272,17 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
| 2168 | return err; | 2272 | return err; |
| 2169 | } | 2273 | } |
| 2170 | 2274 | ||
| 2275 | static const struct snd_kcontrol_new ad1988_hp_mixers[] = { | ||
| 2276 | { | ||
| 2277 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 2278 | .name = "Independent HP", | ||
| 2279 | .info = ad1988_independent_hp_info, | ||
| 2280 | .get = ad1988_independent_hp_get, | ||
| 2281 | .put = ad1988_independent_hp_put, | ||
| 2282 | }, | ||
| 2283 | { } /* end */ | ||
| 2284 | }; | ||
| 2285 | |||
| 2171 | /* 6-stack mode */ | 2286 | /* 6-stack mode */ |
| 2172 | static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { | 2287 | static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { |
| 2173 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2288 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
| @@ -2188,6 +2303,7 @@ static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { | |||
| 2188 | }; | 2303 | }; |
| 2189 | 2304 | ||
| 2190 | static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { | 2305 | static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { |
| 2306 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 2191 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | 2307 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), |
| 2192 | HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), | 2308 | HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), |
| 2193 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), | 2309 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), |
| @@ -2210,13 +2326,6 @@ static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { | |||
| 2210 | 2326 | ||
| 2211 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), | 2327 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), |
| 2212 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), | 2328 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), |
| 2213 | |||
| 2214 | { } /* end */ | ||
| 2215 | }; | ||
| 2216 | |||
| 2217 | static const struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { | ||
| 2218 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 2219 | |||
| 2220 | { } /* end */ | 2329 | { } /* end */ |
| 2221 | }; | 2330 | }; |
| 2222 | 2331 | ||
| @@ -2238,6 +2347,7 @@ static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { | |||
| 2238 | }; | 2347 | }; |
| 2239 | 2348 | ||
| 2240 | static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { | 2349 | static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { |
| 2350 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 2241 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | 2351 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), |
| 2242 | HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), | 2352 | HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), |
| 2243 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), | 2353 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), |
| @@ -2272,6 +2382,7 @@ static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { | |||
| 2272 | 2382 | ||
| 2273 | /* laptop mode */ | 2383 | /* laptop mode */ |
| 2274 | static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { | 2384 | static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { |
| 2385 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
| 2275 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2386 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
| 2276 | HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), | 2387 | HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), |
| 2277 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), | 2388 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), |
| @@ -2446,7 +2557,7 @@ static const struct hda_verb ad1988_6stack_init_verbs[] = { | |||
| 2446 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2557 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2447 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2558 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2448 | /* Port-A front headphon path */ | 2559 | /* Port-A front headphon path */ |
| 2449 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ | 2560 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ |
| 2450 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 2561 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 2451 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2562 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
| 2452 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2563 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| @@ -2594,7 +2705,7 @@ static const struct hda_verb ad1988_3stack_init_verbs[] = { | |||
| 2594 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2705 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2595 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2706 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2596 | /* Port-A front headphon path */ | 2707 | /* Port-A front headphon path */ |
| 2597 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ | 2708 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ |
| 2598 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 2709 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 2599 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2710 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
| 2600 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2711 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| @@ -2669,7 +2780,7 @@ static const struct hda_verb ad1988_laptop_init_verbs[] = { | |||
| 2669 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2780 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2670 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2781 | {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| 2671 | /* Port-A front headphon path */ | 2782 | /* Port-A front headphon path */ |
| 2672 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x01}, /* DAC1:04h */ | 2783 | {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ |
| 2673 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 2784 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
| 2674 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2785 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
| 2675 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2786 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
| @@ -2782,11 +2893,11 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) | |||
| 2782 | { | 2893 | { |
| 2783 | static const hda_nid_t idx_to_dac[8] = { | 2894 | static const hda_nid_t idx_to_dac[8] = { |
| 2784 | /* A B C D E F G H */ | 2895 | /* A B C D E F G H */ |
| 2785 | 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a | 2896 | 0x03, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a |
| 2786 | }; | 2897 | }; |
| 2787 | static const hda_nid_t idx_to_dac_rev2[8] = { | 2898 | static const hda_nid_t idx_to_dac_rev2[8] = { |
| 2788 | /* A B C D E F G H */ | 2899 | /* A B C D E F G H */ |
| 2789 | 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 | 2900 | 0x03, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 |
| 2790 | }; | 2901 | }; |
| 2791 | if (is_rev2(codec)) | 2902 | if (is_rev2(codec)) |
| 2792 | return idx_to_dac_rev2[idx]; | 2903 | return idx_to_dac_rev2[idx]; |
| @@ -3023,8 +3134,8 @@ static void ad1988_auto_set_output_and_unmute(struct hda_codec *codec, | |||
| 3023 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 3134 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); |
| 3024 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); | 3135 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); |
| 3025 | switch (nid) { | 3136 | switch (nid) { |
| 3026 | case 0x11: /* port-A - DAC 04 */ | 3137 | case 0x11: /* port-A - DAC 03 */ |
| 3027 | snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x01); | 3138 | snd_hda_codec_write(codec, 0x37, 0, AC_VERB_SET_CONNECT_SEL, 0x00); |
| 3028 | break; | 3139 | break; |
| 3029 | case 0x14: /* port-B - DAC 06 */ | 3140 | case 0x14: /* port-B - DAC 06 */ |
| 3030 | snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02); | 3141 | snd_hda_codec_write(codec, 0x30, 0, AC_VERB_SET_CONNECT_SEL, 0x02); |
| @@ -3150,7 +3261,6 @@ static int ad1988_auto_init(struct hda_codec *codec) | |||
| 3150 | static const char * const ad1988_models[AD1988_MODEL_LAST] = { | 3261 | static const char * const ad1988_models[AD1988_MODEL_LAST] = { |
| 3151 | [AD1988_6STACK] = "6stack", | 3262 | [AD1988_6STACK] = "6stack", |
| 3152 | [AD1988_6STACK_DIG] = "6stack-dig", | 3263 | [AD1988_6STACK_DIG] = "6stack-dig", |
| 3153 | [AD1988_6STACK_DIG_FP] = "6stack-dig-fp", | ||
| 3154 | [AD1988_3STACK] = "3stack", | 3264 | [AD1988_3STACK] = "3stack", |
| 3155 | [AD1988_3STACK_DIG] = "3stack-dig", | 3265 | [AD1988_3STACK_DIG] = "3stack-dig", |
| 3156 | [AD1988_LAPTOP] = "laptop", | 3266 | [AD1988_LAPTOP] = "laptop", |
| @@ -3208,10 +3318,11 @@ static int patch_ad1988(struct hda_codec *codec) | |||
| 3208 | } | 3318 | } |
| 3209 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 3319 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
| 3210 | 3320 | ||
| 3321 | if (!spec->multiout.hp_nid) | ||
| 3322 | spec->multiout.hp_nid = ad1988_alt_dac_nid[0]; | ||
| 3211 | switch (board_config) { | 3323 | switch (board_config) { |
| 3212 | case AD1988_6STACK: | 3324 | case AD1988_6STACK: |
| 3213 | case AD1988_6STACK_DIG: | 3325 | case AD1988_6STACK_DIG: |
| 3214 | case AD1988_6STACK_DIG_FP: | ||
| 3215 | spec->multiout.max_channels = 8; | 3326 | spec->multiout.max_channels = 8; |
| 3216 | spec->multiout.num_dacs = 4; | 3327 | spec->multiout.num_dacs = 4; |
| 3217 | if (is_rev2(codec)) | 3328 | if (is_rev2(codec)) |
| @@ -3227,19 +3338,7 @@ static int patch_ad1988(struct hda_codec *codec) | |||
| 3227 | spec->mixers[1] = ad1988_6stack_mixers2; | 3338 | spec->mixers[1] = ad1988_6stack_mixers2; |
| 3228 | spec->num_init_verbs = 1; | 3339 | spec->num_init_verbs = 1; |
| 3229 | spec->init_verbs[0] = ad1988_6stack_init_verbs; | 3340 | spec->init_verbs[0] = ad1988_6stack_init_verbs; |
| 3230 | if (board_config == AD1988_6STACK_DIG_FP) { | 3341 | if (board_config == AD1988_6STACK_DIG) { |
| 3231 | spec->num_mixers++; | ||
| 3232 | spec->mixers[2] = ad1988_6stack_fp_mixers; | ||
| 3233 | spec->num_init_verbs++; | ||
| 3234 | spec->init_verbs[1] = ad1988_6stack_fp_init_verbs; | ||
| 3235 | spec->slave_vols = ad1988_6stack_fp_slave_vols; | ||
| 3236 | spec->slave_sws = ad1988_6stack_fp_slave_sws; | ||
| 3237 | spec->alt_dac_nid = ad1988_alt_dac_nid; | ||
| 3238 | spec->stream_analog_alt_playback = | ||
| 3239 | &ad198x_pcm_analog_alt_playback; | ||
| 3240 | } | ||
| 3241 | if ((board_config == AD1988_6STACK_DIG) || | ||
| 3242 | (board_config == AD1988_6STACK_DIG_FP)) { | ||
| 3243 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; | 3342 | spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; |
| 3244 | spec->dig_in_nid = AD1988_SPDIF_IN; | 3343 | spec->dig_in_nid = AD1988_SPDIF_IN; |
| 3245 | } | 3344 | } |
| @@ -3282,6 +3381,15 @@ static int patch_ad1988(struct hda_codec *codec) | |||
| 3282 | break; | 3381 | break; |
| 3283 | } | 3382 | } |
| 3284 | 3383 | ||
| 3384 | if (spec->autocfg.hp_pins[0]) { | ||
| 3385 | spec->mixers[spec->num_mixers++] = ad1988_hp_mixers; | ||
| 3386 | spec->slave_vols = ad1988_6stack_fp_slave_vols; | ||
| 3387 | spec->slave_sws = ad1988_6stack_fp_slave_sws; | ||
| 3388 | spec->alt_dac_nid = ad1988_alt_dac_nid; | ||
| 3389 | spec->stream_analog_alt_playback = | ||
| 3390 | &ad198x_pcm_analog_alt_playback; | ||
| 3391 | } | ||
| 3392 | |||
| 3285 | spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); | 3393 | spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); |
| 3286 | spec->adc_nids = ad1988_adc_nids; | 3394 | spec->adc_nids = ad1988_adc_nids; |
| 3287 | spec->capsrc_nids = ad1988_capsrc_nids; | 3395 | spec->capsrc_nids = ad1988_capsrc_nids; |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 76752d8ea733..0c8b5a1993ed 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
| @@ -136,6 +136,8 @@ struct conexant_spec { | |||
| 136 | unsigned int thinkpad:1; | 136 | unsigned int thinkpad:1; |
| 137 | unsigned int hp_laptop:1; | 137 | unsigned int hp_laptop:1; |
| 138 | unsigned int asus:1; | 138 | unsigned int asus:1; |
| 139 | unsigned int pin_eapd_ctrls:1; | ||
| 140 | unsigned int single_adc_amp:1; | ||
| 139 | 141 | ||
| 140 | unsigned int adc_switching:1; | 142 | unsigned int adc_switching:1; |
| 141 | 143 | ||
| @@ -1867,39 +1869,6 @@ static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { | |||
| 1867 | { } /* end */ | 1869 | { } /* end */ |
| 1868 | }; | 1870 | }; |
| 1869 | 1871 | ||
| 1870 | static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { | ||
| 1871 | /* Line in, Mic */ | ||
| 1872 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | ||
| 1873 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 1874 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | ||
| 1875 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
| 1876 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
| 1877 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | ||
| 1878 | /* SPK */ | ||
| 1879 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
| 1880 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 1881 | /* HP, Amp */ | ||
| 1882 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 1883 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 1884 | /* Docking HP */ | ||
| 1885 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
| 1886 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
| 1887 | /* DAC1 */ | ||
| 1888 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
| 1889 | /* Record selector: Internal mic */ | ||
| 1890 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, | ||
| 1891 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, | ||
| 1892 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, | ||
| 1893 | /* SPDIF route: PCM */ | ||
| 1894 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* needed for W500 Advanced Mini Dock 250410 */ | ||
| 1895 | {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
| 1896 | /* EAPD */ | ||
| 1897 | {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ | ||
| 1898 | {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, | ||
| 1899 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, | ||
| 1900 | { } /* end */ | ||
| 1901 | }; | ||
| 1902 | |||
| 1903 | static const struct hda_verb cxt5051_f700_init_verbs[] = { | 1872 | static const struct hda_verb cxt5051_f700_init_verbs[] = { |
| 1904 | /* Line in, Mic */ | 1873 | /* Line in, Mic */ |
| 1905 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | 1874 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, |
| @@ -1968,7 +1937,6 @@ enum { | |||
| 1968 | CXT5051_LAPTOP, /* Laptops w/ EAPD support */ | 1937 | CXT5051_LAPTOP, /* Laptops w/ EAPD support */ |
| 1969 | CXT5051_HP, /* no docking */ | 1938 | CXT5051_HP, /* no docking */ |
| 1970 | CXT5051_HP_DV6736, /* HP without mic switch */ | 1939 | CXT5051_HP_DV6736, /* HP without mic switch */ |
| 1971 | CXT5051_LENOVO_X200, /* Lenovo X200 laptop, also used for Advanced Mini Dock 250410 */ | ||
| 1972 | CXT5051_F700, /* HP Compaq Presario F700 */ | 1940 | CXT5051_F700, /* HP Compaq Presario F700 */ |
| 1973 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ | 1941 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ |
| 1974 | CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ | 1942 | CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ |
| @@ -1980,7 +1948,6 @@ static const char *const cxt5051_models[CXT5051_MODELS] = { | |||
| 1980 | [CXT5051_LAPTOP] = "laptop", | 1948 | [CXT5051_LAPTOP] = "laptop", |
| 1981 | [CXT5051_HP] = "hp", | 1949 | [CXT5051_HP] = "hp", |
| 1982 | [CXT5051_HP_DV6736] = "hp-dv6736", | 1950 | [CXT5051_HP_DV6736] = "hp-dv6736", |
| 1983 | [CXT5051_LENOVO_X200] = "lenovo-x200", | ||
| 1984 | [CXT5051_F700] = "hp-700", | 1951 | [CXT5051_F700] = "hp-700", |
| 1985 | [CXT5051_TOSHIBA] = "toshiba", | 1952 | [CXT5051_TOSHIBA] = "toshiba", |
| 1986 | [CXT5051_IDEAPAD] = "ideapad", | 1953 | [CXT5051_IDEAPAD] = "ideapad", |
| @@ -1995,7 +1962,6 @@ static const struct snd_pci_quirk cxt5051_cfg_tbl[] = { | |||
| 1995 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", | 1962 | SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", |
| 1996 | CXT5051_LAPTOP), | 1963 | CXT5051_LAPTOP), |
| 1997 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), | 1964 | SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), |
| 1998 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), | ||
| 1999 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), | 1965 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo IdeaPad", CXT5051_IDEAPAD), |
| 2000 | {} | 1966 | {} |
| 2001 | }; | 1967 | }; |
| @@ -2053,13 +2019,6 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
| 2053 | spec->mixers[0] = cxt5051_hp_dv6736_mixers; | 2019 | spec->mixers[0] = cxt5051_hp_dv6736_mixers; |
| 2054 | spec->auto_mic = 0; | 2020 | spec->auto_mic = 0; |
| 2055 | break; | 2021 | break; |
| 2056 | case CXT5051_LENOVO_X200: | ||
| 2057 | spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; | ||
| 2058 | /* Thinkpad X301 does not have S/PDIF wired and no ability | ||
| 2059 | to use a docking station. */ | ||
| 2060 | if (codec->subsystem_id == 0x17aa211f) | ||
| 2061 | spec->multiout.dig_out_nid = 0; | ||
| 2062 | break; | ||
| 2063 | case CXT5051_F700: | 2022 | case CXT5051_F700: |
| 2064 | spec->init_verbs[0] = cxt5051_f700_init_verbs; | 2023 | spec->init_verbs[0] = cxt5051_f700_init_verbs; |
| 2065 | spec->mixers[0] = cxt5051_f700_mixers; | 2024 | spec->mixers[0] = cxt5051_f700_mixers; |
| @@ -3473,12 +3432,14 @@ static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | |||
| 3473 | static void do_automute(struct hda_codec *codec, int num_pins, | 3432 | static void do_automute(struct hda_codec *codec, int num_pins, |
| 3474 | hda_nid_t *pins, bool on) | 3433 | hda_nid_t *pins, bool on) |
| 3475 | { | 3434 | { |
| 3435 | struct conexant_spec *spec = codec->spec; | ||
| 3476 | int i; | 3436 | int i; |
| 3477 | for (i = 0; i < num_pins; i++) | 3437 | for (i = 0; i < num_pins; i++) |
| 3478 | snd_hda_codec_write(codec, pins[i], 0, | 3438 | snd_hda_codec_write(codec, pins[i], 0, |
| 3479 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 3439 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
| 3480 | on ? PIN_OUT : 0); | 3440 | on ? PIN_OUT : 0); |
| 3481 | cx_auto_turn_eapd(codec, num_pins, pins, on); | 3441 | if (spec->pin_eapd_ctrls) |
| 3442 | cx_auto_turn_eapd(codec, num_pins, pins, on); | ||
| 3482 | } | 3443 | } |
| 3483 | 3444 | ||
| 3484 | static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | 3445 | static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) |
| @@ -3503,9 +3464,12 @@ static void cx_auto_update_speakers(struct hda_codec *codec) | |||
| 3503 | int on = 1; | 3464 | int on = 1; |
| 3504 | 3465 | ||
| 3505 | /* turn on HP EAPD when HP jacks are present */ | 3466 | /* turn on HP EAPD when HP jacks are present */ |
| 3506 | if (spec->auto_mute) | 3467 | if (spec->pin_eapd_ctrls) { |
| 3507 | on = spec->hp_present; | 3468 | if (spec->auto_mute) |
| 3508 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); | 3469 | on = spec->hp_present; |
| 3470 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); | ||
| 3471 | } | ||
| 3472 | |||
| 3509 | /* mute speakers in auto-mode if HP or LO jacks are plugged */ | 3473 | /* mute speakers in auto-mode if HP or LO jacks are plugged */ |
| 3510 | if (spec->auto_mute) | 3474 | if (spec->auto_mute) |
| 3511 | on = !(spec->hp_present || | 3475 | on = !(spec->hp_present || |
| @@ -3932,20 +3896,10 @@ static void cx_auto_parse_beep(struct hda_codec *codec) | |||
| 3932 | #define cx_auto_parse_beep(codec) | 3896 | #define cx_auto_parse_beep(codec) |
| 3933 | #endif | 3897 | #endif |
| 3934 | 3898 | ||
| 3935 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 3899 | /* parse EAPDs */ |
| 3936 | { | ||
| 3937 | int i; | ||
| 3938 | for (i = 0; i < nums; i++) | ||
| 3939 | if (list[i] == nid) | ||
| 3940 | return true; | ||
| 3941 | return false; | ||
| 3942 | } | ||
| 3943 | |||
| 3944 | /* parse extra-EAPD that aren't assigned to any pins */ | ||
| 3945 | static void cx_auto_parse_eapd(struct hda_codec *codec) | 3900 | static void cx_auto_parse_eapd(struct hda_codec *codec) |
| 3946 | { | 3901 | { |
| 3947 | struct conexant_spec *spec = codec->spec; | 3902 | struct conexant_spec *spec = codec->spec; |
| 3948 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
| 3949 | hda_nid_t nid, end_nid; | 3903 | hda_nid_t nid, end_nid; |
| 3950 | 3904 | ||
| 3951 | end_nid = codec->start_nid + codec->num_nodes; | 3905 | end_nid = codec->start_nid + codec->num_nodes; |
| @@ -3954,14 +3908,18 @@ static void cx_auto_parse_eapd(struct hda_codec *codec) | |||
| 3954 | continue; | 3908 | continue; |
| 3955 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) | 3909 | if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) |
| 3956 | continue; | 3910 | continue; |
| 3957 | if (found_in_nid_list(nid, cfg->line_out_pins, cfg->line_outs) || | ||
| 3958 | found_in_nid_list(nid, cfg->hp_pins, cfg->hp_outs) || | ||
| 3959 | found_in_nid_list(nid, cfg->speaker_pins, cfg->speaker_outs)) | ||
| 3960 | continue; | ||
| 3961 | spec->eapds[spec->num_eapds++] = nid; | 3911 | spec->eapds[spec->num_eapds++] = nid; |
| 3962 | if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) | 3912 | if (spec->num_eapds >= ARRAY_SIZE(spec->eapds)) |
| 3963 | break; | 3913 | break; |
| 3964 | } | 3914 | } |
| 3915 | |||
| 3916 | /* NOTE: below is a wild guess; if we have more than two EAPDs, | ||
| 3917 | * it's a new chip, where EAPDs are supposed to be associated to | ||
| 3918 | * pins, and we can control EAPD per pin. | ||
| 3919 | * OTOH, if only one or two EAPDs are found, it's an old chip, | ||
| 3920 | * thus it might control over all pins. | ||
| 3921 | */ | ||
| 3922 | spec->pin_eapd_ctrls = spec->num_eapds > 2; | ||
| 3965 | } | 3923 | } |
| 3966 | 3924 | ||
| 3967 | static int cx_auto_parse_auto_config(struct hda_codec *codec) | 3925 | static int cx_auto_parse_auto_config(struct hda_codec *codec) |
| @@ -4067,8 +4025,9 @@ static void cx_auto_init_output(struct hda_codec *codec) | |||
| 4067 | } | 4025 | } |
| 4068 | } | 4026 | } |
| 4069 | cx_auto_update_speakers(codec); | 4027 | cx_auto_update_speakers(codec); |
| 4070 | /* turn on/off extra EAPDs, too */ | 4028 | /* turn on all EAPDs if no individual EAPD control is available */ |
| 4071 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); | 4029 | if (!spec->pin_eapd_ctrls) |
| 4030 | cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); | ||
| 4072 | } | 4031 | } |
| 4073 | 4032 | ||
| 4074 | static void cx_auto_init_input(struct hda_codec *codec) | 4033 | static void cx_auto_init_input(struct hda_codec *codec) |
| @@ -4255,6 +4214,8 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, | |||
| 4255 | int idx = get_input_connection(codec, adc_nid, nid); | 4214 | int idx = get_input_connection(codec, adc_nid, nid); |
| 4256 | if (idx < 0) | 4215 | if (idx < 0) |
| 4257 | continue; | 4216 | continue; |
| 4217 | if (spec->single_adc_amp) | ||
| 4218 | idx = 0; | ||
| 4258 | return cx_auto_add_volume_idx(codec, label, pfx, | 4219 | return cx_auto_add_volume_idx(codec, label, pfx, |
| 4259 | cidx, adc_nid, HDA_INPUT, idx); | 4220 | cidx, adc_nid, HDA_INPUT, idx); |
| 4260 | } | 4221 | } |
| @@ -4295,14 +4256,21 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) | |||
| 4295 | struct hda_input_mux *imux = &spec->private_imux; | 4256 | struct hda_input_mux *imux = &spec->private_imux; |
| 4296 | const char *prev_label; | 4257 | const char *prev_label; |
| 4297 | int input_conn[HDA_MAX_NUM_INPUTS]; | 4258 | int input_conn[HDA_MAX_NUM_INPUTS]; |
| 4298 | int i, err, cidx; | 4259 | int i, j, err, cidx; |
| 4299 | int multi_connection; | 4260 | int multi_connection; |
| 4300 | 4261 | ||
| 4262 | if (!imux->num_items) | ||
| 4263 | return 0; | ||
| 4264 | |||
| 4301 | multi_connection = 0; | 4265 | multi_connection = 0; |
| 4302 | for (i = 0; i < imux->num_items; i++) { | 4266 | for (i = 0; i < imux->num_items; i++) { |
| 4303 | cidx = get_input_connection(codec, spec->imux_info[i].adc, | 4267 | cidx = get_input_connection(codec, spec->imux_info[i].adc, |
| 4304 | spec->imux_info[i].pin); | 4268 | spec->imux_info[i].pin); |
| 4305 | input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; | 4269 | if (cidx < 0) |
| 4270 | continue; | ||
| 4271 | input_conn[i] = spec->imux_info[i].adc; | ||
| 4272 | if (!spec->single_adc_amp) | ||
| 4273 | input_conn[i] |= cidx << 8; | ||
| 4306 | if (i > 0 && input_conn[i] != input_conn[0]) | 4274 | if (i > 0 && input_conn[i] != input_conn[0]) |
| 4307 | multi_connection = 1; | 4275 | multi_connection = 1; |
| 4308 | } | 4276 | } |
| @@ -4331,6 +4299,15 @@ static int cx_auto_build_input_controls(struct hda_codec *codec) | |||
| 4331 | err = cx_auto_add_capture_volume(codec, nid, | 4299 | err = cx_auto_add_capture_volume(codec, nid, |
| 4332 | "Capture", "", cidx); | 4300 | "Capture", "", cidx); |
| 4333 | } else { | 4301 | } else { |
| 4302 | bool dup_found = false; | ||
| 4303 | for (j = 0; j < i; j++) { | ||
| 4304 | if (input_conn[j] == input_conn[i]) { | ||
| 4305 | dup_found = true; | ||
| 4306 | break; | ||
| 4307 | } | ||
| 4308 | } | ||
| 4309 | if (dup_found) | ||
| 4310 | continue; | ||
| 4334 | err = cx_auto_add_capture_volume(codec, nid, | 4311 | err = cx_auto_add_capture_volume(codec, nid, |
| 4335 | label, " Capture", cidx); | 4312 | label, " Capture", cidx); |
| 4336 | } | 4313 | } |
| @@ -4394,6 +4371,53 @@ static const struct hda_codec_ops cx_auto_patch_ops = { | |||
| 4394 | .reboot_notify = snd_hda_shutup_pins, | 4371 | .reboot_notify = snd_hda_shutup_pins, |
| 4395 | }; | 4372 | }; |
| 4396 | 4373 | ||
| 4374 | /* | ||
| 4375 | * pin fix-up | ||
| 4376 | */ | ||
| 4377 | struct cxt_pincfg { | ||
| 4378 | hda_nid_t nid; | ||
| 4379 | u32 val; | ||
| 4380 | }; | ||
| 4381 | |||
| 4382 | static void apply_pincfg(struct hda_codec *codec, const struct cxt_pincfg *cfg) | ||
| 4383 | { | ||
| 4384 | for (; cfg->nid; cfg++) | ||
| 4385 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); | ||
| 4386 | |||
| 4387 | } | ||
| 4388 | |||
| 4389 | static void apply_pin_fixup(struct hda_codec *codec, | ||
| 4390 | const struct snd_pci_quirk *quirk, | ||
| 4391 | const struct cxt_pincfg **table) | ||
| 4392 | { | ||
| 4393 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | ||
| 4394 | if (quirk) { | ||
| 4395 | snd_printdd(KERN_INFO "hda_codec: applying pincfg for %s\n", | ||
| 4396 | quirk->name); | ||
| 4397 | apply_pincfg(codec, table[quirk->value]); | ||
| 4398 | } | ||
| 4399 | } | ||
| 4400 | |||
| 4401 | enum { | ||
| 4402 | CXT_PINCFG_LENOVO_X200, | ||
| 4403 | }; | ||
| 4404 | |||
| 4405 | static const struct cxt_pincfg cxt_pincfg_lenovo_x200[] = { | ||
| 4406 | { 0x16, 0x042140ff }, /* HP (seq# overridden) */ | ||
| 4407 | { 0x17, 0x21a11000 }, /* dock-mic */ | ||
| 4408 | { 0x19, 0x2121103f }, /* dock-HP */ | ||
| 4409 | {} | ||
| 4410 | }; | ||
| 4411 | |||
| 4412 | static const struct cxt_pincfg *cxt_pincfg_tbl[] = { | ||
| 4413 | [CXT_PINCFG_LENOVO_X200] = cxt_pincfg_lenovo_x200, | ||
| 4414 | }; | ||
| 4415 | |||
| 4416 | static const struct snd_pci_quirk cxt_fixups[] = { | ||
| 4417 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT_PINCFG_LENOVO_X200), | ||
| 4418 | {} | ||
| 4419 | }; | ||
| 4420 | |||
| 4397 | static int patch_conexant_auto(struct hda_codec *codec) | 4421 | static int patch_conexant_auto(struct hda_codec *codec) |
| 4398 | { | 4422 | { |
| 4399 | struct conexant_spec *spec; | 4423 | struct conexant_spec *spec; |
| @@ -4407,6 +4431,15 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
| 4407 | return -ENOMEM; | 4431 | return -ENOMEM; |
| 4408 | codec->spec = spec; | 4432 | codec->spec = spec; |
| 4409 | codec->pin_amp_workaround = 1; | 4433 | codec->pin_amp_workaround = 1; |
| 4434 | |||
| 4435 | switch (codec->vendor_id) { | ||
| 4436 | case 0x14f15045: | ||
| 4437 | spec->single_adc_amp = 1; | ||
| 4438 | break; | ||
| 4439 | } | ||
| 4440 | |||
| 4441 | apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl); | ||
| 4442 | |||
| 4410 | err = cx_auto_search_adcs(codec); | 4443 | err = cx_auto_search_adcs(codec); |
| 4411 | if (err < 0) | 4444 | if (err < 0) |
| 4412 | return err; | 4445 | return err; |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 19cb72db9c38..342540128fb8 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
| @@ -324,6 +324,66 @@ static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid) | |||
| 324 | return -EINVAL; | 324 | return -EINVAL; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, | ||
| 328 | struct snd_ctl_elem_info *uinfo) | ||
| 329 | { | ||
| 330 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 331 | struct hdmi_spec *spec; | ||
| 332 | int pin_idx; | ||
| 333 | |||
| 334 | spec = codec->spec; | ||
| 335 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; | ||
| 336 | |||
| 337 | pin_idx = kcontrol->private_value; | ||
| 338 | uinfo->count = spec->pins[pin_idx].sink_eld.eld_size; | ||
| 339 | |||
| 340 | return 0; | ||
| 341 | } | ||
| 342 | |||
| 343 | static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, | ||
| 344 | struct snd_ctl_elem_value *ucontrol) | ||
| 345 | { | ||
| 346 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 347 | struct hdmi_spec *spec; | ||
| 348 | int pin_idx; | ||
| 349 | |||
| 350 | spec = codec->spec; | ||
| 351 | pin_idx = kcontrol->private_value; | ||
| 352 | |||
| 353 | memcpy(ucontrol->value.bytes.data, | ||
| 354 | spec->pins[pin_idx].sink_eld.eld_buffer, ELD_MAX_SIZE); | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | static struct snd_kcontrol_new eld_bytes_ctl = { | ||
| 360 | .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, | ||
| 361 | .iface = SNDRV_CTL_ELEM_IFACE_PCM, | ||
| 362 | .name = "ELD", | ||
| 363 | .info = hdmi_eld_ctl_info, | ||
| 364 | .get = hdmi_eld_ctl_get, | ||
| 365 | }; | ||
| 366 | |||
| 367 | static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx, | ||
| 368 | int device) | ||
| 369 | { | ||
| 370 | struct snd_kcontrol *kctl; | ||
| 371 | struct hdmi_spec *spec = codec->spec; | ||
| 372 | int err; | ||
| 373 | |||
| 374 | kctl = snd_ctl_new1(&eld_bytes_ctl, codec); | ||
| 375 | if (!kctl) | ||
| 376 | return -ENOMEM; | ||
| 377 | kctl->private_value = pin_idx; | ||
| 378 | kctl->id.device = device; | ||
| 379 | |||
| 380 | err = snd_hda_ctl_add(codec, spec->pins[pin_idx].pin_nid, kctl); | ||
| 381 | if (err < 0) | ||
| 382 | return err; | ||
| 383 | |||
| 384 | return 0; | ||
| 385 | } | ||
| 386 | |||
| 327 | #ifdef BE_PARANOID | 387 | #ifdef BE_PARANOID |
| 328 | static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, | 388 | static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, |
| 329 | int *packet_index, int *byte_index) | 389 | int *packet_index, int *byte_index) |
| @@ -967,19 +1027,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
| 967 | 1027 | ||
| 968 | per_pin->pin_nid = pin_nid; | 1028 | per_pin->pin_nid = pin_nid; |
| 969 | 1029 | ||
| 970 | err = snd_hda_input_jack_add(codec, pin_nid, | ||
| 971 | SND_JACK_VIDEOOUT, NULL); | ||
| 972 | if (err < 0) | ||
| 973 | return err; | ||
| 974 | |||
| 975 | err = hdmi_read_pin_conn(codec, pin_idx); | 1030 | err = hdmi_read_pin_conn(codec, pin_idx); |
| 976 | if (err < 0) | 1031 | if (err < 0) |
| 977 | return err; | 1032 | return err; |
| 978 | 1033 | ||
| 979 | spec->num_pins++; | 1034 | spec->num_pins++; |
| 980 | 1035 | ||
| 981 | hdmi_present_sense(codec, pin_nid, eld); | ||
| 982 | |||
| 983 | return 0; | 1036 | return 0; |
| 984 | } | 1037 | } |
| 985 | 1038 | ||
| @@ -1162,6 +1215,25 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
| 1162 | return 0; | 1215 | return 0; |
| 1163 | } | 1216 | } |
| 1164 | 1217 | ||
| 1218 | static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) | ||
| 1219 | { | ||
| 1220 | int err; | ||
| 1221 | char hdmi_str[32]; | ||
| 1222 | struct hdmi_spec *spec = codec->spec; | ||
| 1223 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | ||
| 1224 | int pcmdev = spec->pcm_rec[pin_idx].device; | ||
| 1225 | |||
| 1226 | snprintf(hdmi_str, sizeof(hdmi_str), "HDMI/DP,pcm=%d", pcmdev); | ||
| 1227 | |||
| 1228 | err = snd_hda_input_jack_add(codec, per_pin->pin_nid, | ||
| 1229 | SND_JACK_VIDEOOUT, pcmdev > 0 ? hdmi_str : NULL); | ||
| 1230 | if (err < 0) | ||
| 1231 | return err; | ||
| 1232 | |||
| 1233 | hdmi_present_sense(codec, per_pin->pin_nid, &per_pin->sink_eld); | ||
| 1234 | return 0; | ||
| 1235 | } | ||
| 1236 | |||
| 1165 | static int generic_hdmi_build_controls(struct hda_codec *codec) | 1237 | static int generic_hdmi_build_controls(struct hda_codec *codec) |
| 1166 | { | 1238 | { |
| 1167 | struct hdmi_spec *spec = codec->spec; | 1239 | struct hdmi_spec *spec = codec->spec; |
| @@ -1170,12 +1242,25 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
| 1170 | 1242 | ||
| 1171 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1243 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
| 1172 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1244 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
| 1245 | |||
| 1246 | err = generic_hdmi_build_jack(codec, pin_idx); | ||
| 1247 | if (err < 0) | ||
| 1248 | return err; | ||
| 1249 | |||
| 1173 | err = snd_hda_create_spdif_out_ctls(codec, | 1250 | err = snd_hda_create_spdif_out_ctls(codec, |
| 1174 | per_pin->pin_nid, | 1251 | per_pin->pin_nid, |
| 1175 | per_pin->mux_nids[0]); | 1252 | per_pin->mux_nids[0]); |
| 1176 | if (err < 0) | 1253 | if (err < 0) |
| 1177 | return err; | 1254 | return err; |
| 1178 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | 1255 | snd_hda_spdif_ctls_unassign(codec, pin_idx); |
| 1256 | |||
| 1257 | /* add control for ELD Bytes */ | ||
| 1258 | err = hdmi_create_eld_ctl(codec, | ||
| 1259 | pin_idx, | ||
| 1260 | spec->pcm_rec[pin_idx].device); | ||
| 1261 | |||
| 1262 | if (err < 0) | ||
| 1263 | return err; | ||
| 1179 | } | 1264 | } |
| 1180 | 1265 | ||
| 1181 | return 0; | 1266 | return 0; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7a73621a8909..8f93b97559a5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
| @@ -116,6 +116,8 @@ struct alc_spec { | |||
| 116 | const hda_nid_t *capsrc_nids; | 116 | const hda_nid_t *capsrc_nids; |
| 117 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 117 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
| 118 | hda_nid_t mixer_nid; /* analog-mixer NID */ | 118 | hda_nid_t mixer_nid; /* analog-mixer NID */ |
| 119 | DECLARE_BITMAP(vol_ctls, 0x20 << 1); | ||
| 120 | DECLARE_BITMAP(sw_ctls, 0x20 << 1); | ||
| 119 | 121 | ||
| 120 | /* capture setup for dynamic dual-adc switch */ | 122 | /* capture setup for dynamic dual-adc switch */ |
| 121 | hda_nid_t cur_adc; | 123 | hda_nid_t cur_adc; |
| @@ -159,23 +161,27 @@ struct alc_spec { | |||
| 159 | void (*power_hook)(struct hda_codec *codec); | 161 | void (*power_hook)(struct hda_codec *codec); |
| 160 | #endif | 162 | #endif |
| 161 | void (*shutup)(struct hda_codec *codec); | 163 | void (*shutup)(struct hda_codec *codec); |
| 164 | void (*automute_hook)(struct hda_codec *codec); | ||
| 162 | 165 | ||
| 163 | /* for pin sensing */ | 166 | /* for pin sensing */ |
| 164 | unsigned int jack_present: 1; | 167 | unsigned int hp_jack_present:1; |
| 165 | unsigned int line_jack_present:1; | 168 | unsigned int line_jack_present:1; |
| 166 | unsigned int master_mute:1; | 169 | unsigned int master_mute:1; |
| 167 | unsigned int auto_mic:1; | 170 | unsigned int auto_mic:1; |
| 168 | unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ | 171 | unsigned int auto_mic_valid_imux:1; /* valid imux for auto-mic */ |
| 169 | unsigned int automute:1; /* HP automute enabled */ | 172 | unsigned int automute_speaker:1; /* automute speaker outputs */ |
| 170 | unsigned int detect_line:1; /* Line-out detection enabled */ | 173 | unsigned int automute_lo:1; /* automute LO outputs */ |
| 171 | unsigned int automute_lines:1; /* automute line-out as well; NOP when automute_hp_lo isn't set */ | 174 | unsigned int detect_hp:1; /* Headphone detection enabled */ |
| 172 | unsigned int automute_hp_lo:1; /* both HP and LO available */ | 175 | unsigned int detect_lo:1; /* Line-out detection enabled */ |
| 176 | unsigned int automute_speaker_possible:1; /* there are speakers and either LO or HP */ | ||
| 177 | unsigned int automute_lo_possible:1; /* there are line outs and HP */ | ||
| 173 | 178 | ||
| 174 | /* other flags */ | 179 | /* other flags */ |
| 175 | unsigned int no_analog :1; /* digital I/O only */ | 180 | unsigned int no_analog :1; /* digital I/O only */ |
| 176 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ | 181 | unsigned int dyn_adc_switch:1; /* switch ADCs (for ALC275) */ |
| 177 | unsigned int single_input_src:1; | 182 | unsigned int single_input_src:1; |
| 178 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 183 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
| 184 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ | ||
| 179 | 185 | ||
| 180 | /* auto-mute control */ | 186 | /* auto-mute control */ |
| 181 | int automute_mode; | 187 | int automute_mode; |
| @@ -193,6 +199,7 @@ struct alc_spec { | |||
| 193 | /* for PLL fix */ | 199 | /* for PLL fix */ |
| 194 | hda_nid_t pll_nid; | 200 | hda_nid_t pll_nid; |
| 195 | unsigned int pll_coef_idx, pll_coef_bit; | 201 | unsigned int pll_coef_idx, pll_coef_bit; |
| 202 | unsigned int coef0; | ||
| 196 | 203 | ||
| 197 | /* fix-up list */ | 204 | /* fix-up list */ |
| 198 | int fixup_id; | 205 | int fixup_id; |
| @@ -202,6 +209,9 @@ struct alc_spec { | |||
| 202 | /* multi-io */ | 209 | /* multi-io */ |
| 203 | int multi_ios; | 210 | int multi_ios; |
| 204 | struct alc_multi_io multi_io[4]; | 211 | struct alc_multi_io multi_io[4]; |
| 212 | |||
| 213 | /* bind volumes */ | ||
| 214 | struct snd_array bind_ctls; | ||
| 205 | }; | 215 | }; |
| 206 | 216 | ||
| 207 | #define ALC_MODEL_AUTO 0 /* common for all chips */ | 217 | #define ALC_MODEL_AUTO 0 /* common for all chips */ |
| @@ -525,8 +535,8 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
| 525 | } | 535 | } |
| 526 | } | 536 | } |
| 527 | 537 | ||
| 528 | /* Toggle internal speakers muting */ | 538 | /* Toggle outputs muting */ |
| 529 | static void update_speakers(struct hda_codec *codec) | 539 | static void update_outputs(struct hda_codec *codec) |
| 530 | { | 540 | { |
| 531 | struct alc_spec *spec = codec->spec; | 541 | struct alc_spec *spec = codec->spec; |
| 532 | int on; | 542 | int on; |
| @@ -538,10 +548,10 @@ static void update_speakers(struct hda_codec *codec) | |||
| 538 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | 548 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
| 539 | spec->autocfg.hp_pins, spec->master_mute, true); | 549 | spec->autocfg.hp_pins, spec->master_mute, true); |
| 540 | 550 | ||
| 541 | if (!spec->automute) | 551 | if (!spec->automute_speaker) |
| 542 | on = 0; | 552 | on = 0; |
| 543 | else | 553 | else |
| 544 | on = spec->jack_present | spec->line_jack_present; | 554 | on = spec->hp_jack_present | spec->line_jack_present; |
| 545 | on |= spec->master_mute; | 555 | on |= spec->master_mute; |
| 546 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), | 556 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), |
| 547 | spec->autocfg.speaker_pins, on, false); | 557 | spec->autocfg.speaker_pins, on, false); |
| @@ -551,26 +561,35 @@ static void update_speakers(struct hda_codec *codec) | |||
| 551 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || | 561 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || |
| 552 | spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) | 562 | spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) |
| 553 | return; | 563 | return; |
| 554 | if (!spec->automute || (spec->automute_hp_lo && !spec->automute_lines)) | 564 | if (!spec->automute_lo) |
| 555 | on = 0; | 565 | on = 0; |
| 556 | else | 566 | else |
| 557 | on = spec->jack_present; | 567 | on = spec->hp_jack_present; |
| 558 | on |= spec->master_mute; | 568 | on |= spec->master_mute; |
| 559 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | 569 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), |
| 560 | spec->autocfg.line_out_pins, on, false); | 570 | spec->autocfg.line_out_pins, on, false); |
| 561 | } | 571 | } |
| 562 | 572 | ||
| 573 | static void call_update_outputs(struct hda_codec *codec) | ||
| 574 | { | ||
| 575 | struct alc_spec *spec = codec->spec; | ||
| 576 | if (spec->automute_hook) | ||
| 577 | spec->automute_hook(codec); | ||
| 578 | else | ||
| 579 | update_outputs(codec); | ||
| 580 | } | ||
| 581 | |||
| 563 | /* standard HP-automute helper */ | 582 | /* standard HP-automute helper */ |
| 564 | static void alc_hp_automute(struct hda_codec *codec) | 583 | static void alc_hp_automute(struct hda_codec *codec) |
| 565 | { | 584 | { |
| 566 | struct alc_spec *spec = codec->spec; | 585 | struct alc_spec *spec = codec->spec; |
| 567 | 586 | ||
| 568 | spec->jack_present = | 587 | spec->hp_jack_present = |
| 569 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | 588 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
| 570 | spec->autocfg.hp_pins); | 589 | spec->autocfg.hp_pins); |
| 571 | if (!spec->automute) | 590 | if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo)) |
| 572 | return; | 591 | return; |
| 573 | update_speakers(codec); | 592 | call_update_outputs(codec); |
| 574 | } | 593 | } |
| 575 | 594 | ||
| 576 | /* standard line-out-automute helper */ | 595 | /* standard line-out-automute helper */ |
| @@ -585,9 +604,9 @@ static void alc_line_automute(struct hda_codec *codec) | |||
| 585 | spec->line_jack_present = | 604 | spec->line_jack_present = |
| 586 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | 605 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), |
| 587 | spec->autocfg.line_out_pins); | 606 | spec->autocfg.line_out_pins); |
| 588 | if (!spec->automute || !spec->detect_line) | 607 | if (!spec->automute_speaker || !spec->detect_lo) |
| 589 | return; | 608 | return; |
| 590 | update_speakers(codec); | 609 | call_update_outputs(codec); |
| 591 | } | 610 | } |
| 592 | 611 | ||
| 593 | #define get_connection_index(codec, mux, nid) \ | 612 | #define get_connection_index(codec, mux, nid) \ |
| @@ -785,7 +804,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, | |||
| 785 | 804 | ||
| 786 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 805 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
| 787 | uinfo->count = 1; | 806 | uinfo->count = 1; |
| 788 | if (spec->automute_hp_lo) { | 807 | if (spec->automute_speaker_possible && spec->automute_lo_possible) { |
| 789 | uinfo->value.enumerated.items = 3; | 808 | uinfo->value.enumerated.items = 3; |
| 790 | texts = texts3; | 809 | texts = texts3; |
| 791 | } else { | 810 | } else { |
| @@ -804,13 +823,12 @@ static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, | |||
| 804 | { | 823 | { |
| 805 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 824 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
| 806 | struct alc_spec *spec = codec->spec; | 825 | struct alc_spec *spec = codec->spec; |
| 807 | unsigned int val; | 826 | unsigned int val = 0; |
| 808 | if (!spec->automute) | 827 | if (spec->automute_speaker) |
| 809 | val = 0; | 828 | val++; |
| 810 | else if (!spec->automute_hp_lo || !spec->automute_lines) | 829 | if (spec->automute_lo) |
| 811 | val = 1; | 830 | val++; |
| 812 | else | 831 | |
| 813 | val = 2; | ||
| 814 | ucontrol->value.enumerated.item[0] = val; | 832 | ucontrol->value.enumerated.item[0] = val; |
| 815 | return 0; | 833 | return 0; |
| 816 | } | 834 | } |
| @@ -823,29 +841,36 @@ static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, | |||
| 823 | 841 | ||
| 824 | switch (ucontrol->value.enumerated.item[0]) { | 842 | switch (ucontrol->value.enumerated.item[0]) { |
| 825 | case 0: | 843 | case 0: |
| 826 | if (!spec->automute) | 844 | if (!spec->automute_speaker && !spec->automute_lo) |
| 827 | return 0; | 845 | return 0; |
| 828 | spec->automute = 0; | 846 | spec->automute_speaker = 0; |
| 847 | spec->automute_lo = 0; | ||
| 829 | break; | 848 | break; |
| 830 | case 1: | 849 | case 1: |
| 831 | if (spec->automute && | 850 | if (spec->automute_speaker_possible) { |
| 832 | (!spec->automute_hp_lo || !spec->automute_lines)) | 851 | if (!spec->automute_lo && spec->automute_speaker) |
| 833 | return 0; | 852 | return 0; |
| 834 | spec->automute = 1; | 853 | spec->automute_speaker = 1; |
| 835 | spec->automute_lines = 0; | 854 | spec->automute_lo = 0; |
| 855 | } else if (spec->automute_lo_possible) { | ||
| 856 | if (spec->automute_lo) | ||
| 857 | return 0; | ||
| 858 | spec->automute_lo = 1; | ||
| 859 | } else | ||
| 860 | return -EINVAL; | ||
| 836 | break; | 861 | break; |
| 837 | case 2: | 862 | case 2: |
| 838 | if (!spec->automute_hp_lo) | 863 | if (!spec->automute_lo_possible || !spec->automute_speaker_possible) |
| 839 | return -EINVAL; | 864 | return -EINVAL; |
| 840 | if (spec->automute && spec->automute_lines) | 865 | if (spec->automute_speaker && spec->automute_lo) |
| 841 | return 0; | 866 | return 0; |
| 842 | spec->automute = 1; | 867 | spec->automute_speaker = 1; |
| 843 | spec->automute_lines = 1; | 868 | spec->automute_lo = 1; |
| 844 | break; | 869 | break; |
| 845 | default: | 870 | default: |
| 846 | return -EINVAL; | 871 | return -EINVAL; |
| 847 | } | 872 | } |
| 848 | update_speakers(codec); | 873 | call_update_outputs(codec); |
| 849 | return 1; | 874 | return 1; |
| 850 | } | 875 | } |
| 851 | 876 | ||
| @@ -882,7 +907,7 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec) | |||
| 882 | * Check the availability of HP/line-out auto-mute; | 907 | * Check the availability of HP/line-out auto-mute; |
| 883 | * Set up appropriately if really supported | 908 | * Set up appropriately if really supported |
| 884 | */ | 909 | */ |
| 885 | static void alc_init_auto_hp(struct hda_codec *codec) | 910 | static void alc_init_automute(struct hda_codec *codec) |
| 886 | { | 911 | { |
| 887 | struct alc_spec *spec = codec->spec; | 912 | struct alc_spec *spec = codec->spec; |
| 888 | struct auto_pin_cfg *cfg = &spec->autocfg; | 913 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| @@ -897,8 +922,6 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
| 897 | present++; | 922 | present++; |
| 898 | if (present < 2) /* need two different output types */ | 923 | if (present < 2) /* need two different output types */ |
| 899 | return; | 924 | return; |
| 900 | if (present == 3) | ||
| 901 | spec->automute_hp_lo = 1; /* both HP and LO automute */ | ||
| 902 | 925 | ||
| 903 | if (!cfg->speaker_pins[0] && | 926 | if (!cfg->speaker_pins[0] && |
| 904 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { | 927 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { |
| @@ -914,6 +937,8 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
| 914 | cfg->hp_outs = cfg->line_outs; | 937 | cfg->hp_outs = cfg->line_outs; |
| 915 | } | 938 | } |
| 916 | 939 | ||
| 940 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
| 941 | |||
| 917 | for (i = 0; i < cfg->hp_outs; i++) { | 942 | for (i = 0; i < cfg->hp_outs; i++) { |
| 918 | hda_nid_t nid = cfg->hp_pins[i]; | 943 | hda_nid_t nid = cfg->hp_pins[i]; |
| 919 | if (!is_jack_detectable(codec, nid)) | 944 | if (!is_jack_detectable(codec, nid)) |
| @@ -923,28 +948,32 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
| 923 | snd_hda_codec_write_cache(codec, nid, 0, | 948 | snd_hda_codec_write_cache(codec, nid, 0, |
| 924 | AC_VERB_SET_UNSOLICITED_ENABLE, | 949 | AC_VERB_SET_UNSOLICITED_ENABLE, |
| 925 | AC_USRSP_EN | ALC_HP_EVENT); | 950 | AC_USRSP_EN | ALC_HP_EVENT); |
| 926 | spec->automute = 1; | 951 | spec->detect_hp = 1; |
| 927 | spec->automute_mode = ALC_AUTOMUTE_PIN; | 952 | } |
| 928 | } | 953 | |
| 929 | if (spec->automute && cfg->line_out_pins[0] && | 954 | if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) { |
| 930 | cfg->speaker_pins[0] && | 955 | if (cfg->speaker_outs) |
| 931 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | 956 | for (i = 0; i < cfg->line_outs; i++) { |
| 932 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | 957 | hda_nid_t nid = cfg->line_out_pins[i]; |
| 933 | for (i = 0; i < cfg->line_outs; i++) { | 958 | if (!is_jack_detectable(codec, nid)) |
| 934 | hda_nid_t nid = cfg->line_out_pins[i]; | 959 | continue; |
| 935 | if (!is_jack_detectable(codec, nid)) | 960 | snd_printdd("realtek: Enable Line-Out " |
| 936 | continue; | 961 | "auto-muting on NID 0x%x\n", nid); |
| 937 | snd_printdd("realtek: Enable Line-Out auto-muting " | 962 | snd_hda_codec_write_cache(codec, nid, 0, |
| 938 | "on NID 0x%x\n", nid); | 963 | AC_VERB_SET_UNSOLICITED_ENABLE, |
| 939 | snd_hda_codec_write_cache(codec, nid, 0, | 964 | AC_USRSP_EN | ALC_FRONT_EVENT); |
| 940 | AC_VERB_SET_UNSOLICITED_ENABLE, | 965 | spec->detect_lo = 1; |
| 941 | AC_USRSP_EN | ALC_FRONT_EVENT); | ||
| 942 | spec->detect_line = 1; | ||
| 943 | } | 966 | } |
| 944 | spec->automute_lines = spec->detect_line; | 967 | spec->automute_lo_possible = spec->detect_hp; |
| 945 | } | 968 | } |
| 946 | 969 | ||
| 947 | if (spec->automute) { | 970 | spec->automute_speaker_possible = cfg->speaker_outs && |
| 971 | (spec->detect_hp || spec->detect_lo); | ||
| 972 | |||
| 973 | spec->automute_lo = spec->automute_lo_possible; | ||
| 974 | spec->automute_speaker = spec->automute_speaker_possible; | ||
| 975 | |||
| 976 | if (spec->automute_speaker_possible || spec->automute_lo_possible) { | ||
| 948 | /* create a control for automute mode */ | 977 | /* create a control for automute mode */ |
| 949 | alc_add_automute_mode_enum(codec); | 978 | alc_add_automute_mode_enum(codec); |
| 950 | spec->unsol_event = alc_sku_unsol_event; | 979 | spec->unsol_event = alc_sku_unsol_event; |
| @@ -1145,7 +1174,7 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
| 1145 | /* check the availabilities of auto-mute and auto-mic switches */ | 1174 | /* check the availabilities of auto-mute and auto-mic switches */ |
| 1146 | static void alc_auto_check_switches(struct hda_codec *codec) | 1175 | static void alc_auto_check_switches(struct hda_codec *codec) |
| 1147 | { | 1176 | { |
| 1148 | alc_init_auto_hp(codec); | 1177 | alc_init_automute(codec); |
| 1149 | alc_init_auto_mic(codec); | 1178 | alc_init_auto_mic(codec); |
| 1150 | } | 1179 | } |
| 1151 | 1180 | ||
| @@ -1528,6 +1557,15 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx, | |||
| 1528 | coef_val); | 1557 | coef_val); |
| 1529 | } | 1558 | } |
| 1530 | 1559 | ||
| 1560 | /* a special bypass for COEF 0; read the cached value at the second time */ | ||
| 1561 | static unsigned int alc_get_coef0(struct hda_codec *codec) | ||
| 1562 | { | ||
| 1563 | struct alc_spec *spec = codec->spec; | ||
| 1564 | if (!spec->coef0) | ||
| 1565 | spec->coef0 = alc_read_coef_idx(codec, 0); | ||
| 1566 | return spec->coef0; | ||
| 1567 | } | ||
| 1568 | |||
| 1531 | /* | 1569 | /* |
| 1532 | * Digital I/O handling | 1570 | * Digital I/O handling |
| 1533 | */ | 1571 | */ |
| @@ -2368,6 +2406,18 @@ static void alc_free_kctls(struct hda_codec *codec) | |||
| 2368 | snd_array_free(&spec->kctls); | 2406 | snd_array_free(&spec->kctls); |
| 2369 | } | 2407 | } |
| 2370 | 2408 | ||
| 2409 | static void alc_free_bind_ctls(struct hda_codec *codec) | ||
| 2410 | { | ||
| 2411 | struct alc_spec *spec = codec->spec; | ||
| 2412 | if (spec->bind_ctls.list) { | ||
| 2413 | struct hda_bind_ctls **ctl = spec->bind_ctls.list; | ||
| 2414 | int i; | ||
| 2415 | for (i = 0; i < spec->bind_ctls.used; i++) | ||
| 2416 | kfree(ctl[i]); | ||
| 2417 | } | ||
| 2418 | snd_array_free(&spec->bind_ctls); | ||
| 2419 | } | ||
| 2420 | |||
| 2371 | static void alc_free(struct hda_codec *codec) | 2421 | static void alc_free(struct hda_codec *codec) |
| 2372 | { | 2422 | { |
| 2373 | struct alc_spec *spec = codec->spec; | 2423 | struct alc_spec *spec = codec->spec; |
| @@ -2378,6 +2428,7 @@ static void alc_free(struct hda_codec *codec) | |||
| 2378 | alc_shutup(codec); | 2428 | alc_shutup(codec); |
| 2379 | snd_hda_input_jack_free(codec); | 2429 | snd_hda_input_jack_free(codec); |
| 2380 | alc_free_kctls(codec); | 2430 | alc_free_kctls(codec); |
| 2431 | alc_free_bind_ctls(codec); | ||
| 2381 | kfree(spec); | 2432 | kfree(spec); |
| 2382 | snd_hda_detach_beep_device(codec); | 2433 | snd_hda_detach_beep_device(codec); |
| 2383 | } | 2434 | } |
| @@ -2441,6 +2492,47 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name) | |||
| 2441 | } | 2492 | } |
| 2442 | 2493 | ||
| 2443 | /* | 2494 | /* |
| 2495 | * Rename codecs appropriately from COEF value | ||
| 2496 | */ | ||
| 2497 | struct alc_codec_rename_table { | ||
| 2498 | unsigned int vendor_id; | ||
| 2499 | unsigned short coef_mask; | ||
| 2500 | unsigned short coef_bits; | ||
| 2501 | const char *name; | ||
| 2502 | }; | ||
| 2503 | |||
| 2504 | static struct alc_codec_rename_table rename_tbl[] = { | ||
| 2505 | { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, | ||
| 2506 | { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, | ||
| 2507 | { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, | ||
| 2508 | { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, | ||
| 2509 | { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, | ||
| 2510 | { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, | ||
| 2511 | { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, | ||
| 2512 | { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, | ||
| 2513 | { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, | ||
| 2514 | { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, | ||
| 2515 | { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, | ||
| 2516 | { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, | ||
| 2517 | { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, | ||
| 2518 | { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, | ||
| 2519 | { } /* terminator */ | ||
| 2520 | }; | ||
| 2521 | |||
| 2522 | static int alc_codec_rename_from_preset(struct hda_codec *codec) | ||
| 2523 | { | ||
| 2524 | const struct alc_codec_rename_table *p; | ||
| 2525 | |||
| 2526 | for (p = rename_tbl; p->vendor_id; p++) { | ||
| 2527 | if (p->vendor_id != codec->vendor_id) | ||
| 2528 | continue; | ||
| 2529 | if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) | ||
| 2530 | return alc_codec_rename(codec, p->name); | ||
| 2531 | } | ||
| 2532 | return 0; | ||
| 2533 | } | ||
| 2534 | |||
| 2535 | /* | ||
| 2444 | * Automatic parse of I/O pins from the BIOS configuration | 2536 | * Automatic parse of I/O pins from the BIOS configuration |
| 2445 | */ | 2537 | */ |
| 2446 | 2538 | ||
| @@ -2448,11 +2540,15 @@ enum { | |||
| 2448 | ALC_CTL_WIDGET_VOL, | 2540 | ALC_CTL_WIDGET_VOL, |
| 2449 | ALC_CTL_WIDGET_MUTE, | 2541 | ALC_CTL_WIDGET_MUTE, |
| 2450 | ALC_CTL_BIND_MUTE, | 2542 | ALC_CTL_BIND_MUTE, |
| 2543 | ALC_CTL_BIND_VOL, | ||
| 2544 | ALC_CTL_BIND_SW, | ||
| 2451 | }; | 2545 | }; |
| 2452 | static const struct snd_kcontrol_new alc_control_templates[] = { | 2546 | static const struct snd_kcontrol_new alc_control_templates[] = { |
| 2453 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 2547 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
| 2454 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 2548 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
| 2455 | HDA_BIND_MUTE(NULL, 0, 0, 0), | 2549 | HDA_BIND_MUTE(NULL, 0, 0, 0), |
| 2550 | HDA_BIND_VOL(NULL, 0), | ||
| 2551 | HDA_BIND_SW(NULL, 0), | ||
| 2456 | }; | 2552 | }; |
| 2457 | 2553 | ||
| 2458 | /* add dynamic controls */ | 2554 | /* add dynamic controls */ |
| @@ -2493,13 +2589,14 @@ static int add_control_with_pfx(struct alc_spec *spec, int type, | |||
| 2493 | #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ | 2589 | #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ |
| 2494 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) | 2590 | add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) |
| 2495 | 2591 | ||
| 2592 | static const char * const channel_name[4] = { | ||
| 2593 | "Front", "Surround", "CLFE", "Side" | ||
| 2594 | }; | ||
| 2595 | |||
| 2496 | static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | 2596 | static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, |
| 2497 | bool can_be_master, int *index) | 2597 | bool can_be_master, int *index) |
| 2498 | { | 2598 | { |
| 2499 | struct auto_pin_cfg *cfg = &spec->autocfg; | 2599 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 2500 | static const char * const chname[4] = { | ||
| 2501 | "Front", "Surround", NULL /*CLFE*/, "Side" | ||
| 2502 | }; | ||
| 2503 | 2600 | ||
| 2504 | *index = 0; | 2601 | *index = 0; |
| 2505 | if (cfg->line_outs == 1 && !spec->multi_ios && | 2602 | if (cfg->line_outs == 1 && !spec->multi_ios && |
| @@ -2522,7 +2619,10 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
| 2522 | return "PCM"; | 2619 | return "PCM"; |
| 2523 | break; | 2620 | break; |
| 2524 | } | 2621 | } |
| 2525 | return chname[ch]; | 2622 | if (snd_BUG_ON(ch >= ARRAY_SIZE(channel_name))) |
| 2623 | return "PCM"; | ||
| 2624 | |||
| 2625 | return channel_name[ch]; | ||
| 2526 | } | 2626 | } |
| 2527 | 2627 | ||
| 2528 | /* create input playback/capture controls for the given pin */ | 2628 | /* create input playback/capture controls for the given pin */ |
| @@ -2786,8 +2886,9 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
| 2786 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2886 | if (found_in_nid_list(nid, spec->multiout.dac_nids, |
| 2787 | spec->multiout.num_dacs)) | 2887 | spec->multiout.num_dacs)) |
| 2788 | continue; | 2888 | continue; |
| 2789 | if (spec->multiout.hp_nid == nid) | 2889 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, |
| 2790 | continue; | 2890 | ARRAY_SIZE(spec->multiout.hp_out_nid))) |
| 2891 | continue; | ||
| 2791 | if (found_in_nid_list(nid, spec->multiout.extra_out_nid, | 2892 | if (found_in_nid_list(nid, spec->multiout.extra_out_nid, |
| 2792 | ARRAY_SIZE(spec->multiout.extra_out_nid))) | 2893 | ARRAY_SIZE(spec->multiout.extra_out_nid))) |
| 2793 | continue; | 2894 | continue; |
| @@ -2804,6 +2905,29 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
| 2804 | return 0; | 2905 | return 0; |
| 2805 | } | 2906 | } |
| 2806 | 2907 | ||
| 2908 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | ||
| 2909 | const hda_nid_t *pins, hda_nid_t *dacs) | ||
| 2910 | { | ||
| 2911 | int i; | ||
| 2912 | |||
| 2913 | if (num_outs && !dacs[0]) { | ||
| 2914 | dacs[0] = alc_auto_look_for_dac(codec, pins[0]); | ||
| 2915 | if (!dacs[0]) | ||
| 2916 | return 0; | ||
| 2917 | } | ||
| 2918 | |||
| 2919 | for (i = 1; i < num_outs; i++) | ||
| 2920 | dacs[i] = get_dac_if_single(codec, pins[i]); | ||
| 2921 | for (i = 1; i < num_outs; i++) { | ||
| 2922 | if (!dacs[i]) | ||
| 2923 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | ||
| 2924 | } | ||
| 2925 | return 0; | ||
| 2926 | } | ||
| 2927 | |||
| 2928 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | ||
| 2929 | unsigned int location); | ||
| 2930 | |||
| 2807 | /* fill in the dac_nids table from the parsed pin configuration */ | 2931 | /* fill in the dac_nids table from the parsed pin configuration */ |
| 2808 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 2932 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
| 2809 | { | 2933 | { |
| @@ -2815,7 +2939,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
| 2815 | again: | 2939 | again: |
| 2816 | /* set num_dacs once to full for alc_auto_look_for_dac() */ | 2940 | /* set num_dacs once to full for alc_auto_look_for_dac() */ |
| 2817 | spec->multiout.num_dacs = cfg->line_outs; | 2941 | spec->multiout.num_dacs = cfg->line_outs; |
| 2818 | spec->multiout.hp_nid = 0; | 2942 | spec->multiout.hp_out_nid[0] = 0; |
| 2819 | spec->multiout.extra_out_nid[0] = 0; | 2943 | spec->multiout.extra_out_nid[0] = 0; |
| 2820 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | 2944 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); |
| 2821 | spec->multiout.dac_nids = spec->private_dac_nids; | 2945 | spec->multiout.dac_nids = spec->private_dac_nids; |
| @@ -2826,7 +2950,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
| 2826 | spec->private_dac_nids[i] = | 2950 | spec->private_dac_nids[i] = |
| 2827 | get_dac_if_single(codec, cfg->line_out_pins[i]); | 2951 | get_dac_if_single(codec, cfg->line_out_pins[i]); |
| 2828 | if (cfg->hp_outs) | 2952 | if (cfg->hp_outs) |
| 2829 | spec->multiout.hp_nid = | 2953 | spec->multiout.hp_out_nid[0] = |
| 2830 | get_dac_if_single(codec, cfg->hp_pins[0]); | 2954 | get_dac_if_single(codec, cfg->hp_pins[0]); |
| 2831 | if (cfg->speaker_outs) | 2955 | if (cfg->speaker_outs) |
| 2832 | spec->multiout.extra_out_nid[0] = | 2956 | spec->multiout.extra_out_nid[0] = |
| @@ -2858,24 +2982,58 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
| 2858 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | 2982 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); |
| 2859 | } | 2983 | } |
| 2860 | 2984 | ||
| 2861 | if (cfg->hp_outs && !spec->multiout.hp_nid) | 2985 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
| 2862 | spec->multiout.hp_nid = | 2986 | /* try to fill multi-io first */ |
| 2863 | alc_auto_look_for_dac(codec, cfg->hp_pins[0]); | 2987 | unsigned int location, defcfg; |
| 2864 | if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0]) | 2988 | int num_pins; |
| 2865 | spec->multiout.extra_out_nid[0] = | 2989 | |
| 2866 | alc_auto_look_for_dac(codec, cfg->speaker_pins[0]); | 2990 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); |
| 2991 | location = get_defcfg_location(defcfg); | ||
| 2992 | |||
| 2993 | num_pins = alc_auto_fill_multi_ios(codec, location); | ||
| 2994 | if (num_pins > 0) { | ||
| 2995 | spec->multi_ios = num_pins; | ||
| 2996 | spec->ext_channel_count = 2; | ||
| 2997 | spec->multiout.num_dacs = num_pins + 1; | ||
| 2998 | } | ||
| 2999 | } | ||
| 3000 | |||
| 3001 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | ||
| 3002 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, | ||
| 3003 | spec->multiout.hp_out_nid); | ||
| 3004 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | ||
| 3005 | alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, | ||
| 3006 | spec->multiout.extra_out_nid); | ||
| 2867 | 3007 | ||
| 2868 | return 0; | 3008 | return 0; |
| 2869 | } | 3009 | } |
| 2870 | 3010 | ||
| 3011 | static inline unsigned int get_ctl_pos(unsigned int data) | ||
| 3012 | { | ||
| 3013 | hda_nid_t nid = get_amp_nid_(data); | ||
| 3014 | unsigned int dir = get_amp_direction_(data); | ||
| 3015 | return (nid << 1) | dir; | ||
| 3016 | } | ||
| 3017 | |||
| 3018 | #define is_ctl_used(bits, data) \ | ||
| 3019 | test_bit(get_ctl_pos(data), bits) | ||
| 3020 | #define mark_ctl_usage(bits, data) \ | ||
| 3021 | set_bit(get_ctl_pos(data), bits) | ||
| 3022 | |||
| 2871 | static int alc_auto_add_vol_ctl(struct hda_codec *codec, | 3023 | static int alc_auto_add_vol_ctl(struct hda_codec *codec, |
| 2872 | const char *pfx, int cidx, | 3024 | const char *pfx, int cidx, |
| 2873 | hda_nid_t nid, unsigned int chs) | 3025 | hda_nid_t nid, unsigned int chs) |
| 2874 | { | 3026 | { |
| 3027 | struct alc_spec *spec = codec->spec; | ||
| 3028 | unsigned int val; | ||
| 2875 | if (!nid) | 3029 | if (!nid) |
| 2876 | return 0; | 3030 | return 0; |
| 3031 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT); | ||
| 3032 | if (is_ctl_used(spec->vol_ctls, val) && chs != 2) /* exclude LFE */ | ||
| 3033 | return 0; | ||
| 3034 | mark_ctl_usage(spec->vol_ctls, val); | ||
| 2877 | return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, | 3035 | return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx, |
| 2878 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 3036 | val); |
| 2879 | } | 3037 | } |
| 2880 | 3038 | ||
| 2881 | #define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ | 3039 | #define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ |
| @@ -2888,6 +3046,7 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec, | |||
| 2888 | const char *pfx, int cidx, | 3046 | const char *pfx, int cidx, |
| 2889 | hda_nid_t nid, unsigned int chs) | 3047 | hda_nid_t nid, unsigned int chs) |
| 2890 | { | 3048 | { |
| 3049 | struct alc_spec *spec = codec->spec; | ||
| 2891 | int wid_type; | 3050 | int wid_type; |
| 2892 | int type; | 3051 | int type; |
| 2893 | unsigned long val; | 3052 | unsigned long val; |
| @@ -2904,6 +3063,9 @@ static int alc_auto_add_sw_ctl(struct hda_codec *codec, | |||
| 2904 | type = ALC_CTL_BIND_MUTE; | 3063 | type = ALC_CTL_BIND_MUTE; |
| 2905 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); | 3064 | val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT); |
| 2906 | } | 3065 | } |
| 3066 | if (is_ctl_used(spec->sw_ctls, val) && chs != 2) /* exclude LFE */ | ||
| 3067 | return 0; | ||
| 3068 | mark_ctl_usage(spec->sw_ctls, val); | ||
| 2907 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); | 3069 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); |
| 2908 | } | 3070 | } |
| 2909 | 3071 | ||
| @@ -2964,7 +3126,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
| 2964 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3126 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
| 2965 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3127 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
| 2966 | name = alc_get_line_out_pfx(spec, i, true, &index); | 3128 | name = alc_get_line_out_pfx(spec, i, true, &index); |
| 2967 | if (!name) { | 3129 | if (!name || !strcmp(name, "CLFE")) { |
| 2968 | /* Center/LFE */ | 3130 | /* Center/LFE */ |
| 2969 | err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); | 3131 | err = alc_auto_add_vol_ctl(codec, "Center", 0, vol, 1); |
| 2970 | if (err < 0) | 3132 | if (err < 0) |
| @@ -2990,23 +3152,24 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
| 2990 | return 0; | 3152 | return 0; |
| 2991 | } | 3153 | } |
| 2992 | 3154 | ||
| 2993 | /* add playback controls for speaker and HP outputs */ | ||
| 2994 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | 3155 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
| 2995 | hda_nid_t dac, const char *pfx) | 3156 | hda_nid_t dac, const char *pfx) |
| 2996 | { | 3157 | { |
| 2997 | struct alc_spec *spec = codec->spec; | 3158 | struct alc_spec *spec = codec->spec; |
| 2998 | hda_nid_t sw, vol; | 3159 | hda_nid_t sw, vol; |
| 2999 | int err; | 3160 | int err; |
| 3000 | 3161 | ||
| 3001 | if (!pin) | ||
| 3002 | return 0; | ||
| 3003 | if (!dac) { | 3162 | if (!dac) { |
| 3163 | unsigned int val; | ||
| 3004 | /* the corresponding DAC is already occupied */ | 3164 | /* the corresponding DAC is already occupied */ |
| 3005 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) | 3165 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) |
| 3006 | return 0; /* no way */ | 3166 | return 0; /* no way */ |
| 3007 | /* create a switch only */ | 3167 | /* create a switch only */ |
| 3008 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, | 3168 | val = HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT); |
| 3009 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | 3169 | if (is_ctl_used(spec->sw_ctls, val)) |
| 3170 | return 0; /* already created */ | ||
| 3171 | mark_ctl_usage(spec->sw_ctls, val); | ||
| 3172 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); | ||
| 3010 | } | 3173 | } |
| 3011 | 3174 | ||
| 3012 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3175 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
| @@ -3020,20 +3183,112 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
| 3020 | return 0; | 3183 | return 0; |
| 3021 | } | 3184 | } |
| 3022 | 3185 | ||
| 3186 | static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec, | ||
| 3187 | unsigned int nums, | ||
| 3188 | struct hda_ctl_ops *ops) | ||
| 3189 | { | ||
| 3190 | struct alc_spec *spec = codec->spec; | ||
| 3191 | struct hda_bind_ctls **ctlp, *ctl; | ||
| 3192 | snd_array_init(&spec->bind_ctls, sizeof(ctl), 8); | ||
| 3193 | ctlp = snd_array_new(&spec->bind_ctls); | ||
| 3194 | if (!ctlp) | ||
| 3195 | return NULL; | ||
| 3196 | ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL); | ||
| 3197 | *ctlp = ctl; | ||
| 3198 | if (ctl) | ||
| 3199 | ctl->ops = ops; | ||
| 3200 | return ctl; | ||
| 3201 | } | ||
| 3202 | |||
| 3203 | /* add playback controls for speaker and HP outputs */ | ||
| 3204 | static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | ||
| 3205 | const hda_nid_t *pins, | ||
| 3206 | const hda_nid_t *dacs, | ||
| 3207 | const char *pfx) | ||
| 3208 | { | ||
| 3209 | struct alc_spec *spec = codec->spec; | ||
| 3210 | struct hda_bind_ctls *ctl; | ||
| 3211 | char name[32]; | ||
| 3212 | int i, n, err; | ||
| 3213 | |||
| 3214 | if (!num_pins || !pins[0]) | ||
| 3215 | return 0; | ||
| 3216 | |||
| 3217 | if (num_pins == 1) { | ||
| 3218 | hda_nid_t dac = *dacs; | ||
| 3219 | if (!dac) | ||
| 3220 | dac = spec->multiout.dac_nids[0]; | ||
| 3221 | return alc_auto_create_extra_out(codec, *pins, dac, pfx); | ||
| 3222 | } | ||
| 3223 | |||
| 3224 | if (dacs[num_pins - 1]) { | ||
| 3225 | /* OK, we have a multi-output system with individual volumes */ | ||
| 3226 | for (i = 0; i < num_pins; i++) { | ||
| 3227 | snprintf(name, sizeof(name), "%s %s", | ||
| 3228 | pfx, channel_name[i]); | ||
| 3229 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
| 3230 | name); | ||
| 3231 | if (err < 0) | ||
| 3232 | return err; | ||
| 3233 | } | ||
| 3234 | return 0; | ||
| 3235 | } | ||
| 3236 | |||
| 3237 | /* Let's create a bind-controls */ | ||
| 3238 | ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_sw); | ||
| 3239 | if (!ctl) | ||
| 3240 | return -ENOMEM; | ||
| 3241 | n = 0; | ||
| 3242 | for (i = 0; i < num_pins; i++) { | ||
| 3243 | if (get_wcaps(codec, pins[i]) & AC_WCAP_OUT_AMP) | ||
| 3244 | ctl->values[n++] = | ||
| 3245 | HDA_COMPOSE_AMP_VAL(pins[i], 3, 0, HDA_OUTPUT); | ||
| 3246 | } | ||
| 3247 | if (n) { | ||
| 3248 | snprintf(name, sizeof(name), "%s Playback Switch", pfx); | ||
| 3249 | err = add_control(spec, ALC_CTL_BIND_SW, name, 0, (long)ctl); | ||
| 3250 | if (err < 0) | ||
| 3251 | return err; | ||
| 3252 | } | ||
| 3253 | |||
| 3254 | ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol); | ||
| 3255 | if (!ctl) | ||
| 3256 | return -ENOMEM; | ||
| 3257 | n = 0; | ||
| 3258 | for (i = 0; i < num_pins; i++) { | ||
| 3259 | hda_nid_t vol; | ||
| 3260 | if (!pins[i] || !dacs[i]) | ||
| 3261 | continue; | ||
| 3262 | vol = alc_look_for_out_vol_nid(codec, pins[i], dacs[i]); | ||
| 3263 | if (vol) | ||
| 3264 | ctl->values[n++] = | ||
| 3265 | HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT); | ||
| 3266 | } | ||
| 3267 | if (n) { | ||
| 3268 | snprintf(name, sizeof(name), "%s Playback Volume", pfx); | ||
| 3269 | err = add_control(spec, ALC_CTL_BIND_VOL, name, 0, (long)ctl); | ||
| 3270 | if (err < 0) | ||
| 3271 | return err; | ||
| 3272 | } | ||
| 3273 | return 0; | ||
| 3274 | } | ||
| 3275 | |||
| 3023 | static int alc_auto_create_hp_out(struct hda_codec *codec) | 3276 | static int alc_auto_create_hp_out(struct hda_codec *codec) |
| 3024 | { | 3277 | { |
| 3025 | struct alc_spec *spec = codec->spec; | 3278 | struct alc_spec *spec = codec->spec; |
| 3026 | return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], | 3279 | return alc_auto_create_extra_outs(codec, spec->autocfg.hp_outs, |
| 3027 | spec->multiout.hp_nid, | 3280 | spec->autocfg.hp_pins, |
| 3028 | "Headphone"); | 3281 | spec->multiout.hp_out_nid, |
| 3282 | "Headphone"); | ||
| 3029 | } | 3283 | } |
| 3030 | 3284 | ||
| 3031 | static int alc_auto_create_speaker_out(struct hda_codec *codec) | 3285 | static int alc_auto_create_speaker_out(struct hda_codec *codec) |
| 3032 | { | 3286 | { |
| 3033 | struct alc_spec *spec = codec->spec; | 3287 | struct alc_spec *spec = codec->spec; |
| 3034 | return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0], | 3288 | return alc_auto_create_extra_outs(codec, spec->autocfg.speaker_outs, |
| 3035 | spec->multiout.extra_out_nid[0], | 3289 | spec->autocfg.speaker_pins, |
| 3036 | "Speaker"); | 3290 | spec->multiout.extra_out_nid, |
| 3291 | "Speaker"); | ||
| 3037 | } | 3292 | } |
| 3038 | 3293 | ||
| 3039 | static void alc_auto_set_output_and_unmute(struct hda_codec *codec, | 3294 | static void alc_auto_set_output_and_unmute(struct hda_codec *codec, |
| @@ -3090,20 +3345,37 @@ static void alc_auto_init_multi_out(struct hda_codec *codec) | |||
| 3090 | static void alc_auto_init_extra_out(struct hda_codec *codec) | 3345 | static void alc_auto_init_extra_out(struct hda_codec *codec) |
| 3091 | { | 3346 | { |
| 3092 | struct alc_spec *spec = codec->spec; | 3347 | struct alc_spec *spec = codec->spec; |
| 3348 | int i; | ||
| 3093 | hda_nid_t pin, dac; | 3349 | hda_nid_t pin, dac; |
| 3094 | 3350 | ||
| 3095 | pin = spec->autocfg.hp_pins[0]; | 3351 | for (i = 0; i < spec->autocfg.hp_outs; i++) { |
| 3096 | if (pin) { | 3352 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) |
| 3097 | dac = spec->multiout.hp_nid; | 3353 | break; |
| 3098 | if (!dac) | 3354 | pin = spec->autocfg.hp_pins[i]; |
| 3099 | dac = spec->multiout.dac_nids[0]; | 3355 | if (!pin) |
| 3356 | break; | ||
| 3357 | dac = spec->multiout.hp_out_nid[i]; | ||
| 3358 | if (!dac) { | ||
| 3359 | if (i > 0 && spec->multiout.hp_out_nid[0]) | ||
| 3360 | dac = spec->multiout.hp_out_nid[0]; | ||
| 3361 | else | ||
| 3362 | dac = spec->multiout.dac_nids[0]; | ||
| 3363 | } | ||
| 3100 | alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); | 3364 | alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); |
| 3101 | } | 3365 | } |
| 3102 | pin = spec->autocfg.speaker_pins[0]; | 3366 | for (i = 0; i < spec->autocfg.speaker_outs; i++) { |
| 3103 | if (pin) { | 3367 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) |
| 3104 | dac = spec->multiout.extra_out_nid[0]; | 3368 | break; |
| 3105 | if (!dac) | 3369 | pin = spec->autocfg.speaker_pins[i]; |
| 3106 | dac = spec->multiout.dac_nids[0]; | 3370 | if (!pin) |
| 3371 | break; | ||
| 3372 | dac = spec->multiout.extra_out_nid[i]; | ||
| 3373 | if (!dac) { | ||
| 3374 | if (i > 0 && spec->multiout.extra_out_nid[0]) | ||
| 3375 | dac = spec->multiout.extra_out_nid[0]; | ||
| 3376 | else | ||
| 3377 | dac = spec->multiout.dac_nids[0]; | ||
| 3378 | } | ||
| 3107 | alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); | 3379 | alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); |
| 3108 | } | 3380 | } |
| 3109 | } | 3381 | } |
| @@ -3116,6 +3388,7 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
| 3116 | { | 3388 | { |
| 3117 | struct alc_spec *spec = codec->spec; | 3389 | struct alc_spec *spec = codec->spec; |
| 3118 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3390 | struct auto_pin_cfg *cfg = &spec->autocfg; |
| 3391 | hda_nid_t prime_dac = spec->private_dac_nids[0]; | ||
| 3119 | int type, i, num_pins = 0; | 3392 | int type, i, num_pins = 0; |
| 3120 | 3393 | ||
| 3121 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | 3394 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { |
| @@ -3143,8 +3416,13 @@ static int alc_auto_fill_multi_ios(struct hda_codec *codec, | |||
| 3143 | } | 3416 | } |
| 3144 | } | 3417 | } |
| 3145 | spec->multiout.num_dacs = 1; | 3418 | spec->multiout.num_dacs = 1; |
| 3146 | if (num_pins < 2) | 3419 | if (num_pins < 2) { |
| 3420 | /* clear up again */ | ||
| 3421 | memset(spec->private_dac_nids, 0, | ||
| 3422 | sizeof(spec->private_dac_nids)); | ||
| 3423 | spec->private_dac_nids[0] = prime_dac; | ||
| 3147 | return 0; | 3424 | return 0; |
| 3425 | } | ||
| 3148 | return num_pins; | 3426 | return num_pins; |
| 3149 | } | 3427 | } |
| 3150 | 3428 | ||
| @@ -3230,36 +3508,11 @@ static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { | |||
| 3230 | .put = alc_auto_ch_mode_put, | 3508 | .put = alc_auto_ch_mode_put, |
| 3231 | }; | 3509 | }; |
| 3232 | 3510 | ||
| 3233 | static int alc_auto_add_multi_channel_mode(struct hda_codec *codec, | 3511 | static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) |
| 3234 | int (*fill_dac)(struct hda_codec *)) | ||
| 3235 | { | 3512 | { |
| 3236 | struct alc_spec *spec = codec->spec; | 3513 | struct alc_spec *spec = codec->spec; |
| 3237 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
| 3238 | unsigned int location, defcfg; | ||
| 3239 | int num_pins; | ||
| 3240 | |||
| 3241 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) { | ||
| 3242 | /* use HP as primary out */ | ||
| 3243 | cfg->speaker_outs = cfg->line_outs; | ||
| 3244 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
| 3245 | sizeof(cfg->speaker_pins)); | ||
| 3246 | cfg->line_outs = cfg->hp_outs; | ||
| 3247 | memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins)); | ||
| 3248 | cfg->hp_outs = 0; | ||
| 3249 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
| 3250 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
| 3251 | if (fill_dac) | ||
| 3252 | fill_dac(codec); | ||
| 3253 | } | ||
| 3254 | if (cfg->line_outs != 1 || | ||
| 3255 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
| 3256 | return 0; | ||
| 3257 | 3514 | ||
| 3258 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); | 3515 | if (spec->multi_ios > 0) { |
| 3259 | location = get_defcfg_location(defcfg); | ||
| 3260 | |||
| 3261 | num_pins = alc_auto_fill_multi_ios(codec, location); | ||
| 3262 | if (num_pins > 0) { | ||
| 3263 | struct snd_kcontrol_new *knew; | 3516 | struct snd_kcontrol_new *knew; |
| 3264 | 3517 | ||
| 3265 | knew = alc_kcontrol_new(spec); | 3518 | knew = alc_kcontrol_new(spec); |
| @@ -3269,10 +3522,6 @@ static int alc_auto_add_multi_channel_mode(struct hda_codec *codec, | |||
| 3269 | knew->name = kstrdup("Channel Mode", GFP_KERNEL); | 3522 | knew->name = kstrdup("Channel Mode", GFP_KERNEL); |
| 3270 | if (!knew->name) | 3523 | if (!knew->name) |
| 3271 | return -ENOMEM; | 3524 | return -ENOMEM; |
| 3272 | |||
| 3273 | spec->multi_ios = num_pins; | ||
| 3274 | spec->ext_channel_count = 2; | ||
| 3275 | spec->multiout.num_dacs = num_pins + 1; | ||
| 3276 | } | 3525 | } |
| 3277 | return 0; | 3526 | return 0; |
| 3278 | } | 3527 | } |
| @@ -3555,27 +3804,42 @@ static int alc_parse_auto_config(struct hda_codec *codec, | |||
| 3555 | const hda_nid_t *ssid_nids) | 3804 | const hda_nid_t *ssid_nids) |
| 3556 | { | 3805 | { |
| 3557 | struct alc_spec *spec = codec->spec; | 3806 | struct alc_spec *spec = codec->spec; |
| 3807 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
| 3558 | int err; | 3808 | int err; |
| 3559 | 3809 | ||
| 3560 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 3810 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, |
| 3561 | ignore_nids); | 3811 | spec->parse_flags); |
| 3562 | if (err < 0) | 3812 | if (err < 0) |
| 3563 | return err; | 3813 | return err; |
| 3564 | if (!spec->autocfg.line_outs) { | 3814 | if (!cfg->line_outs) { |
| 3565 | if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) { | 3815 | if (cfg->dig_outs || cfg->dig_in_pin) { |
| 3566 | spec->multiout.max_channels = 2; | 3816 | spec->multiout.max_channels = 2; |
| 3567 | spec->no_analog = 1; | 3817 | spec->no_analog = 1; |
| 3568 | goto dig_only; | 3818 | goto dig_only; |
| 3569 | } | 3819 | } |
| 3570 | return 0; /* can't find valid BIOS pin config */ | 3820 | return 0; /* can't find valid BIOS pin config */ |
| 3571 | } | 3821 | } |
| 3822 | |||
| 3823 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | ||
| 3824 | cfg->line_outs <= cfg->hp_outs) { | ||
| 3825 | /* use HP as primary out */ | ||
| 3826 | cfg->speaker_outs = cfg->line_outs; | ||
| 3827 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | ||
| 3828 | sizeof(cfg->speaker_pins)); | ||
| 3829 | cfg->line_outs = cfg->hp_outs; | ||
| 3830 | memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins)); | ||
| 3831 | cfg->hp_outs = 0; | ||
| 3832 | memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); | ||
| 3833 | cfg->line_out_type = AUTO_PIN_HP_OUT; | ||
| 3834 | } | ||
| 3835 | |||
| 3572 | err = alc_auto_fill_dac_nids(codec); | 3836 | err = alc_auto_fill_dac_nids(codec); |
| 3573 | if (err < 0) | 3837 | if (err < 0) |
| 3574 | return err; | 3838 | return err; |
| 3575 | err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); | 3839 | err = alc_auto_add_multi_channel_mode(codec); |
| 3576 | if (err < 0) | 3840 | if (err < 0) |
| 3577 | return err; | 3841 | return err; |
| 3578 | err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg); | 3842 | err = alc_auto_create_multi_out_ctls(codec, cfg); |
| 3579 | if (err < 0) | 3843 | if (err < 0) |
| 3580 | return err; | 3844 | return err; |
| 3581 | err = alc_auto_create_hp_out(codec); | 3845 | err = alc_auto_create_hp_out(codec); |
| @@ -3678,10 +3942,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
| 3678 | if (board_config == ALC_MODEL_AUTO) { | 3942 | if (board_config == ALC_MODEL_AUTO) { |
| 3679 | /* automatic parse from the BIOS config */ | 3943 | /* automatic parse from the BIOS config */ |
| 3680 | err = alc880_parse_auto_config(codec); | 3944 | err = alc880_parse_auto_config(codec); |
| 3681 | if (err < 0) { | 3945 | if (err < 0) |
| 3682 | alc_free(codec); | 3946 | goto error; |
| 3683 | return err; | ||
| 3684 | } | ||
| 3685 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | 3947 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS |
| 3686 | else if (!err) { | 3948 | else if (!err) { |
| 3687 | printk(KERN_INFO | 3949 | printk(KERN_INFO |
| @@ -3706,10 +3968,8 @@ static int patch_alc880(struct hda_codec *codec) | |||
| 3706 | 3968 | ||
| 3707 | if (!spec->no_analog) { | 3969 | if (!spec->no_analog) { |
| 3708 | err = snd_hda_attach_beep_device(codec, 0x1); | 3970 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 3709 | if (err < 0) { | 3971 | if (err < 0) |
| 3710 | alc_free(codec); | 3972 | goto error; |
| 3711 | return err; | ||
| 3712 | } | ||
| 3713 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 3973 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
| 3714 | } | 3974 | } |
| 3715 | 3975 | ||
| @@ -3724,6 +3984,10 @@ static int patch_alc880(struct hda_codec *codec) | |||
| 3724 | #endif | 3984 | #endif |
| 3725 | 3985 | ||
| 3726 | return 0; | 3986 | return 0; |
| 3987 | |||
| 3988 | error: | ||
| 3989 | alc_free(codec); | ||
| 3990 | return err; | ||
| 3727 | } | 3991 | } |
| 3728 | 3992 | ||
| 3729 | 3993 | ||
| @@ -3805,10 +4069,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
| 3805 | if (board_config == ALC_MODEL_AUTO) { | 4069 | if (board_config == ALC_MODEL_AUTO) { |
| 3806 | /* automatic parse from the BIOS config */ | 4070 | /* automatic parse from the BIOS config */ |
| 3807 | err = alc260_parse_auto_config(codec); | 4071 | err = alc260_parse_auto_config(codec); |
| 3808 | if (err < 0) { | 4072 | if (err < 0) |
| 3809 | alc_free(codec); | 4073 | goto error; |
| 3810 | return err; | ||
| 3811 | } | ||
| 3812 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | 4074 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS |
| 3813 | else if (!err) { | 4075 | else if (!err) { |
| 3814 | printk(KERN_INFO | 4076 | printk(KERN_INFO |
| @@ -3833,10 +4095,8 @@ static int patch_alc260(struct hda_codec *codec) | |||
| 3833 | 4095 | ||
| 3834 | if (!spec->no_analog) { | 4096 | if (!spec->no_analog) { |
| 3835 | err = snd_hda_attach_beep_device(codec, 0x1); | 4097 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 3836 | if (err < 0) { | 4098 | if (err < 0) |
| 3837 | alc_free(codec); | 4099 | goto error; |
| 3838 | return err; | ||
| 3839 | } | ||
| 3840 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 4100 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
| 3841 | } | 4101 | } |
| 3842 | 4102 | ||
| @@ -3854,6 +4114,10 @@ static int patch_alc260(struct hda_codec *codec) | |||
| 3854 | #endif | 4114 | #endif |
| 3855 | 4115 | ||
| 3856 | return 0; | 4116 | return 0; |
| 4117 | |||
| 4118 | error: | ||
| 4119 | alc_free(codec); | ||
| 4120 | return err; | ||
| 3857 | } | 4121 | } |
| 3858 | 4122 | ||
| 3859 | 4123 | ||
| @@ -3880,6 +4144,7 @@ enum { | |||
| 3880 | PINFIX_LENOVO_Y530, | 4144 | PINFIX_LENOVO_Y530, |
| 3881 | PINFIX_PB_M5210, | 4145 | PINFIX_PB_M5210, |
| 3882 | PINFIX_ACER_ASPIRE_7736, | 4146 | PINFIX_ACER_ASPIRE_7736, |
| 4147 | PINFIX_ASUS_W90V, | ||
| 3883 | }; | 4148 | }; |
| 3884 | 4149 | ||
| 3885 | static const struct alc_fixup alc882_fixups[] = { | 4150 | static const struct alc_fixup alc882_fixups[] = { |
| @@ -3911,10 +4176,18 @@ static const struct alc_fixup alc882_fixups[] = { | |||
| 3911 | .type = ALC_FIXUP_SKU, | 4176 | .type = ALC_FIXUP_SKU, |
| 3912 | .v.sku = ALC_FIXUP_SKU_IGNORE, | 4177 | .v.sku = ALC_FIXUP_SKU_IGNORE, |
| 3913 | }, | 4178 | }, |
| 4179 | [PINFIX_ASUS_W90V] = { | ||
| 4180 | .type = ALC_FIXUP_PINS, | ||
| 4181 | .v.pins = (const struct alc_pincfg[]) { | ||
| 4182 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ | ||
| 4183 | { } | ||
| 4184 | } | ||
| 4185 | }, | ||
| 3914 | }; | 4186 | }; |
| 3915 | 4187 | ||
| 3916 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 4188 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
| 3917 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | 4189 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), |
| 4190 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", PINFIX_ASUS_W90V), | ||
| 3918 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), | 4191 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), |
| 3919 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 4192 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), |
| 3920 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), | 4193 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), |
| @@ -3961,6 +4234,10 @@ static int patch_alc882(struct hda_codec *codec) | |||
| 3961 | break; | 4234 | break; |
| 3962 | } | 4235 | } |
| 3963 | 4236 | ||
| 4237 | err = alc_codec_rename_from_preset(codec); | ||
| 4238 | if (err < 0) | ||
| 4239 | goto error; | ||
| 4240 | |||
| 3964 | board_config = alc_board_config(codec, ALC882_MODEL_LAST, | 4241 | board_config = alc_board_config(codec, ALC882_MODEL_LAST, |
| 3965 | alc882_models, alc882_cfg_tbl); | 4242 | alc882_models, alc882_cfg_tbl); |
| 3966 | 4243 | ||
| @@ -3984,10 +4261,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
| 3984 | if (board_config == ALC_MODEL_AUTO) { | 4261 | if (board_config == ALC_MODEL_AUTO) { |
| 3985 | /* automatic parse from the BIOS config */ | 4262 | /* automatic parse from the BIOS config */ |
| 3986 | err = alc882_parse_auto_config(codec); | 4263 | err = alc882_parse_auto_config(codec); |
| 3987 | if (err < 0) { | 4264 | if (err < 0) |
| 3988 | alc_free(codec); | 4265 | goto error; |
| 3989 | return err; | ||
| 3990 | } | ||
| 3991 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | 4266 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS |
| 3992 | else if (!err) { | 4267 | else if (!err) { |
| 3993 | printk(KERN_INFO | 4268 | printk(KERN_INFO |
| @@ -4012,10 +4287,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
| 4012 | 4287 | ||
| 4013 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 4288 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
| 4014 | err = snd_hda_attach_beep_device(codec, 0x1); | 4289 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 4015 | if (err < 0) { | 4290 | if (err < 0) |
| 4016 | alc_free(codec); | 4291 | goto error; |
| 4017 | return err; | ||
| 4018 | } | ||
| 4019 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4292 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
| 4020 | } | 4293 | } |
| 4021 | 4294 | ||
| @@ -4034,6 +4307,10 @@ static int patch_alc882(struct hda_codec *codec) | |||
| 4034 | #endif | 4307 | #endif |
| 4035 | 4308 | ||
| 4036 | return 0; | 4309 | return 0; |
| 4310 | |||
| 4311 | error: | ||
| 4312 | alc_free(codec); | ||
| 4313 | return err; | ||
| 4037 | } | 4314 | } |
| 4038 | 4315 | ||
| 4039 | 4316 | ||
| @@ -4138,10 +4415,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
| 4138 | if (board_config == ALC_MODEL_AUTO) { | 4415 | if (board_config == ALC_MODEL_AUTO) { |
| 4139 | /* automatic parse from the BIOS config */ | 4416 | /* automatic parse from the BIOS config */ |
| 4140 | err = alc262_parse_auto_config(codec); | 4417 | err = alc262_parse_auto_config(codec); |
| 4141 | if (err < 0) { | 4418 | if (err < 0) |
| 4142 | alc_free(codec); | 4419 | goto error; |
| 4143 | return err; | ||
| 4144 | } | ||
| 4145 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | 4420 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS |
| 4146 | else if (!err) { | 4421 | else if (!err) { |
| 4147 | printk(KERN_INFO | 4422 | printk(KERN_INFO |
| @@ -4166,10 +4441,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
| 4166 | 4441 | ||
| 4167 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 4442 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
| 4168 | err = snd_hda_attach_beep_device(codec, 0x1); | 4443 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 4169 | if (err < 0) { | 4444 | if (err < 0) |
| 4170 | alc_free(codec); | 4445 | goto error; |
| 4171 | return err; | ||
| 4172 | } | ||
| 4173 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 4446 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
| 4174 | } | 4447 | } |
| 4175 | 4448 | ||
| @@ -4189,6 +4462,10 @@ static int patch_alc262(struct hda_codec *codec) | |||
| 4189 | #endif | 4462 | #endif |
| 4190 | 4463 | ||
| 4191 | return 0; | 4464 | return 0; |
| 4465 | |||
| 4466 | error: | ||
| 4467 | alc_free(codec); | ||
| 4468 | return err; | ||
| 4192 | } | 4469 | } |
| 4193 | 4470 | ||
| 4194 | /* | 4471 | /* |
| @@ -4237,14 +4514,9 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
| 4237 | 4514 | ||
| 4238 | /* | 4515 | /* |
| 4239 | */ | 4516 | */ |
| 4240 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4241 | #include "alc268_quirks.c" | ||
| 4242 | #endif | ||
| 4243 | |||
| 4244 | static int patch_alc268(struct hda_codec *codec) | 4517 | static int patch_alc268(struct hda_codec *codec) |
| 4245 | { | 4518 | { |
| 4246 | struct alc_spec *spec; | 4519 | struct alc_spec *spec; |
| 4247 | int board_config; | ||
| 4248 | int i, has_beep, err; | 4520 | int i, has_beep, err; |
| 4249 | 4521 | ||
| 4250 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4522 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| @@ -4255,38 +4527,10 @@ static int patch_alc268(struct hda_codec *codec) | |||
| 4255 | 4527 | ||
| 4256 | /* ALC268 has no aa-loopback mixer */ | 4528 | /* ALC268 has no aa-loopback mixer */ |
| 4257 | 4529 | ||
| 4258 | board_config = alc_board_config(codec, ALC268_MODEL_LAST, | 4530 | /* automatic parse from the BIOS config */ |
| 4259 | alc268_models, alc268_cfg_tbl); | 4531 | err = alc268_parse_auto_config(codec); |
| 4260 | 4532 | if (err < 0) | |
| 4261 | if (board_config < 0) | 4533 | goto error; |
| 4262 | board_config = alc_board_codec_sid_config(codec, | ||
| 4263 | ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); | ||
| 4264 | |||
| 4265 | if (board_config < 0) { | ||
| 4266 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
| 4267 | codec->chip_name); | ||
| 4268 | board_config = ALC_MODEL_AUTO; | ||
| 4269 | } | ||
| 4270 | |||
| 4271 | if (board_config == ALC_MODEL_AUTO) { | ||
| 4272 | /* automatic parse from the BIOS config */ | ||
| 4273 | err = alc268_parse_auto_config(codec); | ||
| 4274 | if (err < 0) { | ||
| 4275 | alc_free(codec); | ||
| 4276 | return err; | ||
| 4277 | } | ||
| 4278 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4279 | else if (!err) { | ||
| 4280 | printk(KERN_INFO | ||
| 4281 | "hda_codec: Cannot set up configuration " | ||
| 4282 | "from BIOS. Using base mode...\n"); | ||
| 4283 | board_config = ALC268_3ST; | ||
| 4284 | } | ||
| 4285 | #endif | ||
| 4286 | } | ||
| 4287 | |||
| 4288 | if (board_config != ALC_MODEL_AUTO) | ||
| 4289 | setup_preset(codec, &alc268_presets[board_config]); | ||
| 4290 | 4534 | ||
| 4291 | has_beep = 0; | 4535 | has_beep = 0; |
| 4292 | for (i = 0; i < spec->num_mixers; i++) { | 4536 | for (i = 0; i < spec->num_mixers; i++) { |
| @@ -4298,10 +4542,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
| 4298 | 4542 | ||
| 4299 | if (has_beep) { | 4543 | if (has_beep) { |
| 4300 | err = snd_hda_attach_beep_device(codec, 0x1); | 4544 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 4301 | if (err < 0) { | 4545 | if (err < 0) |
| 4302 | alc_free(codec); | 4546 | goto error; |
| 4303 | return err; | ||
| 4304 | } | ||
| 4305 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 4547 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) |
| 4306 | /* override the amp caps for beep generator */ | 4548 | /* override the amp caps for beep generator */ |
| 4307 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | 4549 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, |
| @@ -4323,13 +4565,16 @@ static int patch_alc268(struct hda_codec *codec) | |||
| 4323 | spec->vmaster_nid = 0x02; | 4565 | spec->vmaster_nid = 0x02; |
| 4324 | 4566 | ||
| 4325 | codec->patch_ops = alc_patch_ops; | 4567 | codec->patch_ops = alc_patch_ops; |
| 4326 | if (board_config == ALC_MODEL_AUTO) | 4568 | spec->init_hook = alc_auto_init_std; |
| 4327 | spec->init_hook = alc_auto_init_std; | ||
| 4328 | spec->shutup = alc_eapd_shutup; | 4569 | spec->shutup = alc_eapd_shutup; |
| 4329 | 4570 | ||
| 4330 | alc_init_jacks(codec); | 4571 | alc_init_jacks(codec); |
| 4331 | 4572 | ||
| 4332 | return 0; | 4573 | return 0; |
| 4574 | |||
| 4575 | error: | ||
| 4576 | alc_free(codec); | ||
| 4577 | return err; | ||
| 4333 | } | 4578 | } |
| 4334 | 4579 | ||
| 4335 | /* | 4580 | /* |
| @@ -4423,9 +4668,9 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | |||
| 4423 | 4668 | ||
| 4424 | static void alc269_shutup(struct hda_codec *codec) | 4669 | static void alc269_shutup(struct hda_codec *codec) |
| 4425 | { | 4670 | { |
| 4426 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) | 4671 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) |
| 4427 | alc269_toggle_power_output(codec, 0); | 4672 | alc269_toggle_power_output(codec, 0); |
| 4428 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 4673 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
| 4429 | alc269_toggle_power_output(codec, 0); | 4674 | alc269_toggle_power_output(codec, 0); |
| 4430 | msleep(150); | 4675 | msleep(150); |
| 4431 | } | 4676 | } |
| @@ -4434,19 +4679,19 @@ static void alc269_shutup(struct hda_codec *codec) | |||
| 4434 | #ifdef CONFIG_PM | 4679 | #ifdef CONFIG_PM |
| 4435 | static int alc269_resume(struct hda_codec *codec) | 4680 | static int alc269_resume(struct hda_codec *codec) |
| 4436 | { | 4681 | { |
| 4437 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 4682 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
| 4438 | alc269_toggle_power_output(codec, 0); | 4683 | alc269_toggle_power_output(codec, 0); |
| 4439 | msleep(150); | 4684 | msleep(150); |
| 4440 | } | 4685 | } |
| 4441 | 4686 | ||
| 4442 | codec->patch_ops.init(codec); | 4687 | codec->patch_ops.init(codec); |
| 4443 | 4688 | ||
| 4444 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | 4689 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
| 4445 | alc269_toggle_power_output(codec, 1); | 4690 | alc269_toggle_power_output(codec, 1); |
| 4446 | msleep(200); | 4691 | msleep(200); |
| 4447 | } | 4692 | } |
| 4448 | 4693 | ||
| 4449 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) | 4694 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) |
| 4450 | alc269_toggle_power_output(codec, 1); | 4695 | alc269_toggle_power_output(codec, 1); |
| 4451 | 4696 | ||
| 4452 | snd_hda_codec_resume_amp(codec); | 4697 | snd_hda_codec_resume_amp(codec); |
| @@ -4515,6 +4760,30 @@ static void alc269_fixup_stereo_dmic(struct hda_codec *codec, | |||
| 4515 | alc_write_coef_idx(codec, 0x07, coef | 0x80); | 4760 | alc_write_coef_idx(codec, 0x07, coef | 0x80); |
| 4516 | } | 4761 | } |
| 4517 | 4762 | ||
| 4763 | static void alc269_quanta_automute(struct hda_codec *codec) | ||
| 4764 | { | ||
| 4765 | update_outputs(codec); | ||
| 4766 | |||
| 4767 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 4768 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
| 4769 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 4770 | AC_VERB_SET_PROC_COEF, 0x680); | ||
| 4771 | |||
| 4772 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 4773 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
| 4774 | snd_hda_codec_write(codec, 0x20, 0, | ||
| 4775 | AC_VERB_SET_PROC_COEF, 0x480); | ||
| 4776 | } | ||
| 4777 | |||
| 4778 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, | ||
| 4779 | const struct alc_fixup *fix, int action) | ||
| 4780 | { | ||
| 4781 | struct alc_spec *spec = codec->spec; | ||
| 4782 | if (action != ALC_FIXUP_ACT_PROBE) | ||
| 4783 | return; | ||
| 4784 | spec->automute_hook = alc269_quanta_automute; | ||
| 4785 | } | ||
| 4786 | |||
| 4518 | enum { | 4787 | enum { |
| 4519 | ALC269_FIXUP_SONY_VAIO, | 4788 | ALC269_FIXUP_SONY_VAIO, |
| 4520 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 4789 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
| @@ -4526,6 +4795,12 @@ enum { | |||
| 4526 | ALC271_FIXUP_DMIC, | 4795 | ALC271_FIXUP_DMIC, |
| 4527 | ALC269_FIXUP_PCM_44K, | 4796 | ALC269_FIXUP_PCM_44K, |
| 4528 | ALC269_FIXUP_STEREO_DMIC, | 4797 | ALC269_FIXUP_STEREO_DMIC, |
| 4798 | ALC269_FIXUP_QUANTA_MUTE, | ||
| 4799 | ALC269_FIXUP_LIFEBOOK, | ||
| 4800 | ALC269_FIXUP_AMIC, | ||
| 4801 | ALC269_FIXUP_DMIC, | ||
| 4802 | ALC269VB_FIXUP_AMIC, | ||
| 4803 | ALC269VB_FIXUP_DMIC, | ||
| 4529 | }; | 4804 | }; |
| 4530 | 4805 | ||
| 4531 | static const struct alc_fixup alc269_fixups[] = { | 4806 | static const struct alc_fixup alc269_fixups[] = { |
| @@ -4592,6 +4867,60 @@ static const struct alc_fixup alc269_fixups[] = { | |||
| 4592 | .type = ALC_FIXUP_FUNC, | 4867 | .type = ALC_FIXUP_FUNC, |
| 4593 | .v.func = alc269_fixup_stereo_dmic, | 4868 | .v.func = alc269_fixup_stereo_dmic, |
| 4594 | }, | 4869 | }, |
| 4870 | [ALC269_FIXUP_QUANTA_MUTE] = { | ||
| 4871 | .type = ALC_FIXUP_FUNC, | ||
| 4872 | .v.func = alc269_fixup_quanta_mute, | ||
| 4873 | }, | ||
| 4874 | [ALC269_FIXUP_LIFEBOOK] = { | ||
| 4875 | .type = ALC_FIXUP_PINS, | ||
| 4876 | .v.pins = (const struct alc_pincfg[]) { | ||
| 4877 | { 0x1a, 0x2101103f }, /* dock line-out */ | ||
| 4878 | { 0x1b, 0x23a11040 }, /* dock mic-in */ | ||
| 4879 | { } | ||
| 4880 | }, | ||
| 4881 | .chained = true, | ||
| 4882 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | ||
| 4883 | }, | ||
| 4884 | [ALC269_FIXUP_AMIC] = { | ||
| 4885 | .type = ALC_FIXUP_PINS, | ||
| 4886 | .v.pins = (const struct alc_pincfg[]) { | ||
| 4887 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 4888 | { 0x15, 0x0121401f }, /* HP out */ | ||
| 4889 | { 0x18, 0x01a19c20 }, /* mic */ | ||
| 4890 | { 0x19, 0x99a3092f }, /* int-mic */ | ||
| 4891 | { } | ||
| 4892 | }, | ||
| 4893 | }, | ||
| 4894 | [ALC269_FIXUP_DMIC] = { | ||
| 4895 | .type = ALC_FIXUP_PINS, | ||
| 4896 | .v.pins = (const struct alc_pincfg[]) { | ||
| 4897 | { 0x12, 0x99a3092f }, /* int-mic */ | ||
| 4898 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 4899 | { 0x15, 0x0121401f }, /* HP out */ | ||
| 4900 | { 0x18, 0x01a19c20 }, /* mic */ | ||
| 4901 | { } | ||
| 4902 | }, | ||
| 4903 | }, | ||
| 4904 | [ALC269VB_FIXUP_AMIC] = { | ||
| 4905 | .type = ALC_FIXUP_PINS, | ||
| 4906 | .v.pins = (const struct alc_pincfg[]) { | ||
| 4907 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 4908 | { 0x18, 0x01a19c20 }, /* mic */ | ||
| 4909 | { 0x19, 0x99a3092f }, /* int-mic */ | ||
| 4910 | { 0x21, 0x0121401f }, /* HP out */ | ||
| 4911 | { } | ||
| 4912 | }, | ||
| 4913 | }, | ||
| 4914 | [ALC269_FIXUP_DMIC] = { | ||
| 4915 | .type = ALC_FIXUP_PINS, | ||
| 4916 | .v.pins = (const struct alc_pincfg[]) { | ||
| 4917 | { 0x12, 0x99a3092f }, /* int-mic */ | ||
| 4918 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 4919 | { 0x18, 0x01a19c20 }, /* mic */ | ||
| 4920 | { 0x21, 0x0121401f }, /* HP out */ | ||
| 4921 | { } | ||
| 4922 | }, | ||
| 4923 | }, | ||
| 4595 | }; | 4924 | }; |
| 4596 | 4925 | ||
| 4597 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4926 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
| @@ -4607,13 +4936,71 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
| 4607 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 4936 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
| 4608 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 4937 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
| 4609 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), | 4938 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), |
| 4939 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), | ||
| 4610 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 4940 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
| 4611 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 4941 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
| 4612 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 4942 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
| 4613 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), | 4943 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), |
| 4614 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), | 4944 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
| 4945 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), | ||
| 4615 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), | 4946 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), |
| 4616 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 4947 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
| 4948 | |||
| 4949 | #if 1 | ||
| 4950 | /* Below is a quirk table taken from the old code. | ||
| 4951 | * Basically the device should work as is without the fixup table. | ||
| 4952 | * If BIOS doesn't give a proper info, enable the corresponding | ||
| 4953 | * fixup entry. | ||
| 4954 | */ | ||
| 4955 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | ||
| 4956 | ALC269_FIXUP_AMIC), | ||
| 4957 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | ||
| 4958 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269_FIXUP_AMIC), | ||
| 4959 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), | ||
| 4960 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | ||
| 4961 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | ||
| 4962 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), | ||
| 4963 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), | ||
| 4964 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), | ||
| 4965 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), | ||
| 4966 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), | ||
| 4967 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), | ||
| 4968 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), | ||
| 4969 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), | ||
| 4970 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), | ||
| 4971 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), | ||
| 4972 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), | ||
| 4973 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), | ||
| 4974 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), | ||
| 4975 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), | ||
| 4976 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), | ||
| 4977 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), | ||
| 4978 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), | ||
| 4979 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), | ||
| 4980 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), | ||
| 4981 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), | ||
| 4982 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), | ||
| 4983 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), | ||
| 4984 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), | ||
| 4985 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), | ||
| 4986 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), | ||
| 4987 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), | ||
| 4988 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), | ||
| 4989 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), | ||
| 4990 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), | ||
| 4991 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), | ||
| 4992 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), | ||
| 4993 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), | ||
| 4994 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), | ||
| 4995 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), | ||
| 4996 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), | ||
| 4997 | #endif | ||
| 4998 | {} | ||
| 4999 | }; | ||
| 5000 | |||
| 5001 | static const struct alc_model_fixup alc269_fixup_models[] = { | ||
| 5002 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | ||
| 5003 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | ||
| 4617 | {} | 5004 | {} |
| 4618 | }; | 5005 | }; |
| 4619 | 5006 | ||
| @@ -4622,23 +5009,23 @@ static int alc269_fill_coef(struct hda_codec *codec) | |||
| 4622 | { | 5009 | { |
| 4623 | int val; | 5010 | int val; |
| 4624 | 5011 | ||
| 4625 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) { | 5012 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
| 4626 | alc_write_coef_idx(codec, 0xf, 0x960b); | 5013 | alc_write_coef_idx(codec, 0xf, 0x960b); |
| 4627 | alc_write_coef_idx(codec, 0xe, 0x8817); | 5014 | alc_write_coef_idx(codec, 0xe, 0x8817); |
| 4628 | } | 5015 | } |
| 4629 | 5016 | ||
| 4630 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) { | 5017 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { |
| 4631 | alc_write_coef_idx(codec, 0xf, 0x960b); | 5018 | alc_write_coef_idx(codec, 0xf, 0x960b); |
| 4632 | alc_write_coef_idx(codec, 0xe, 0x8814); | 5019 | alc_write_coef_idx(codec, 0xe, 0x8814); |
| 4633 | } | 5020 | } |
| 4634 | 5021 | ||
| 4635 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) { | 5022 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
| 4636 | val = alc_read_coef_idx(codec, 0x04); | 5023 | val = alc_read_coef_idx(codec, 0x04); |
| 4637 | /* Power up output pin */ | 5024 | /* Power up output pin */ |
| 4638 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | 5025 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); |
| 4639 | } | 5026 | } |
| 4640 | 5027 | ||
| 4641 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 5028 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
| 4642 | val = alc_read_coef_idx(codec, 0xd); | 5029 | val = alc_read_coef_idx(codec, 0xd); |
| 4643 | if ((val & 0x0c00) >> 10 != 0x1) { | 5030 | if ((val & 0x0c00) >> 10 != 0x1) { |
| 4644 | /* Capless ramp up clock control */ | 5031 | /* Capless ramp up clock control */ |
| @@ -4662,15 +5049,10 @@ static int alc269_fill_coef(struct hda_codec *codec) | |||
| 4662 | 5049 | ||
| 4663 | /* | 5050 | /* |
| 4664 | */ | 5051 | */ |
| 4665 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4666 | #include "alc269_quirks.c" | ||
| 4667 | #endif | ||
| 4668 | |||
| 4669 | static int patch_alc269(struct hda_codec *codec) | 5052 | static int patch_alc269(struct hda_codec *codec) |
| 4670 | { | 5053 | { |
| 4671 | struct alc_spec *spec; | 5054 | struct alc_spec *spec; |
| 4672 | int board_config, coef; | 5055 | int err = 0; |
| 4673 | int err; | ||
| 4674 | 5056 | ||
| 4675 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5057 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| 4676 | if (spec == NULL) | 5058 | if (spec == NULL) |
| @@ -4682,72 +5064,41 @@ static int patch_alc269(struct hda_codec *codec) | |||
| 4682 | 5064 | ||
| 4683 | alc_auto_parse_customize_define(codec); | 5065 | alc_auto_parse_customize_define(codec); |
| 4684 | 5066 | ||
| 5067 | err = alc_codec_rename_from_preset(codec); | ||
| 5068 | if (err < 0) | ||
| 5069 | goto error; | ||
| 5070 | |||
| 4685 | if (codec->vendor_id == 0x10ec0269) { | 5071 | if (codec->vendor_id == 0x10ec0269) { |
| 4686 | spec->codec_variant = ALC269_TYPE_ALC269VA; | 5072 | spec->codec_variant = ALC269_TYPE_ALC269VA; |
| 4687 | coef = alc_read_coef_idx(codec, 0); | 5073 | switch (alc_get_coef0(codec) & 0x00f0) { |
| 4688 | if ((coef & 0x00f0) == 0x0010) { | 5074 | case 0x0010: |
| 4689 | if (codec->bus->pci->subsystem_vendor == 0x1025 && | 5075 | if (codec->bus->pci->subsystem_vendor == 0x1025 && |
| 4690 | spec->cdefine.platform_type == 1) { | 5076 | spec->cdefine.platform_type == 1) |
| 4691 | alc_codec_rename(codec, "ALC271X"); | 5077 | err = alc_codec_rename(codec, "ALC271X"); |
| 4692 | } else if ((coef & 0xf000) == 0x2000) { | ||
| 4693 | alc_codec_rename(codec, "ALC259"); | ||
| 4694 | } else if ((coef & 0xf000) == 0x3000) { | ||
| 4695 | alc_codec_rename(codec, "ALC258"); | ||
| 4696 | } else if ((coef & 0xfff0) == 0x3010) { | ||
| 4697 | alc_codec_rename(codec, "ALC277"); | ||
| 4698 | } else { | ||
| 4699 | alc_codec_rename(codec, "ALC269VB"); | ||
| 4700 | } | ||
| 4701 | spec->codec_variant = ALC269_TYPE_ALC269VB; | 5078 | spec->codec_variant = ALC269_TYPE_ALC269VB; |
| 4702 | } else if ((coef & 0x00f0) == 0x0020) { | 5079 | break; |
| 4703 | if (coef == 0xa023) | 5080 | case 0x0020: |
| 4704 | alc_codec_rename(codec, "ALC259"); | 5081 | if (codec->bus->pci->subsystem_vendor == 0x17aa && |
| 4705 | else if (coef == 0x6023) | 5082 | codec->bus->pci->subsystem_device == 0x21f3) |
| 4706 | alc_codec_rename(codec, "ALC281X"); | 5083 | err = alc_codec_rename(codec, "ALC3202"); |
| 4707 | else if (codec->bus->pci->subsystem_vendor == 0x17aa && | ||
| 4708 | codec->bus->pci->subsystem_device == 0x21f3) | ||
| 4709 | alc_codec_rename(codec, "ALC3202"); | ||
| 4710 | else | ||
| 4711 | alc_codec_rename(codec, "ALC269VC"); | ||
| 4712 | spec->codec_variant = ALC269_TYPE_ALC269VC; | 5084 | spec->codec_variant = ALC269_TYPE_ALC269VC; |
| 4713 | } else | 5085 | break; |
| 5086 | default: | ||
| 4714 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 5087 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
| 5088 | } | ||
| 5089 | if (err < 0) | ||
| 5090 | goto error; | ||
| 4715 | alc269_fill_coef(codec); | 5091 | alc269_fill_coef(codec); |
| 4716 | } | 5092 | } |
| 4717 | 5093 | ||
| 4718 | board_config = alc_board_config(codec, ALC269_MODEL_LAST, | 5094 | alc_pick_fixup(codec, alc269_fixup_models, |
| 4719 | alc269_models, alc269_cfg_tbl); | 5095 | alc269_fixup_tbl, alc269_fixups); |
| 4720 | 5096 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | |
| 4721 | if (board_config < 0) { | ||
| 4722 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
| 4723 | codec->chip_name); | ||
| 4724 | board_config = ALC_MODEL_AUTO; | ||
| 4725 | } | ||
| 4726 | |||
| 4727 | if (board_config == ALC_MODEL_AUTO) { | ||
| 4728 | alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); | ||
| 4729 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
| 4730 | } | ||
| 4731 | 5097 | ||
| 4732 | if (board_config == ALC_MODEL_AUTO) { | 5098 | /* automatic parse from the BIOS config */ |
| 4733 | /* automatic parse from the BIOS config */ | 5099 | err = alc269_parse_auto_config(codec); |
| 4734 | err = alc269_parse_auto_config(codec); | 5100 | if (err < 0) |
| 4735 | if (err < 0) { | 5101 | goto error; |
| 4736 | alc_free(codec); | ||
| 4737 | return err; | ||
| 4738 | } | ||
| 4739 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4740 | else if (!err) { | ||
| 4741 | printk(KERN_INFO | ||
| 4742 | "hda_codec: Cannot set up configuration " | ||
| 4743 | "from BIOS. Using base mode...\n"); | ||
| 4744 | board_config = ALC269_BASIC; | ||
| 4745 | } | ||
| 4746 | #endif | ||
| 4747 | } | ||
| 4748 | |||
| 4749 | if (board_config != ALC_MODEL_AUTO) | ||
| 4750 | setup_preset(codec, &alc269_presets[board_config]); | ||
| 4751 | 5102 | ||
| 4752 | if (!spec->no_analog && !spec->adc_nids) { | 5103 | if (!spec->no_analog && !spec->adc_nids) { |
| 4753 | alc_auto_fill_adc_caps(codec); | 5104 | alc_auto_fill_adc_caps(codec); |
| @@ -4760,10 +5111,8 @@ static int patch_alc269(struct hda_codec *codec) | |||
| 4760 | 5111 | ||
| 4761 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 5112 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
| 4762 | err = snd_hda_attach_beep_device(codec, 0x1); | 5113 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 4763 | if (err < 0) { | 5114 | if (err < 0) |
| 4764 | alc_free(codec); | 5115 | goto error; |
| 4765 | return err; | ||
| 4766 | } | ||
| 4767 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 5116 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
| 4768 | } | 5117 | } |
| 4769 | 5118 | ||
| @@ -4775,8 +5124,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
| 4775 | #ifdef CONFIG_PM | 5124 | #ifdef CONFIG_PM |
| 4776 | codec->patch_ops.resume = alc269_resume; | 5125 | codec->patch_ops.resume = alc269_resume; |
| 4777 | #endif | 5126 | #endif |
| 4778 | if (board_config == ALC_MODEL_AUTO) | 5127 | spec->init_hook = alc_auto_init_std; |
| 4779 | spec->init_hook = alc_auto_init_std; | ||
| 4780 | spec->shutup = alc269_shutup; | 5128 | spec->shutup = alc269_shutup; |
| 4781 | 5129 | ||
| 4782 | alc_init_jacks(codec); | 5130 | alc_init_jacks(codec); |
| @@ -4788,6 +5136,10 @@ static int patch_alc269(struct hda_codec *codec) | |||
| 4788 | #endif | 5136 | #endif |
| 4789 | 5137 | ||
| 4790 | return 0; | 5138 | return 0; |
| 5139 | |||
| 5140 | error: | ||
| 5141 | alc_free(codec); | ||
| 5142 | return err; | ||
| 4791 | } | 5143 | } |
| 4792 | 5144 | ||
| 4793 | /* | 5145 | /* |
| @@ -4835,14 +5187,9 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = { | |||
| 4835 | 5187 | ||
| 4836 | /* | 5188 | /* |
| 4837 | */ | 5189 | */ |
| 4838 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4839 | #include "alc861_quirks.c" | ||
| 4840 | #endif | ||
| 4841 | |||
| 4842 | static int patch_alc861(struct hda_codec *codec) | 5190 | static int patch_alc861(struct hda_codec *codec) |
| 4843 | { | 5191 | { |
| 4844 | struct alc_spec *spec; | 5192 | struct alc_spec *spec; |
| 4845 | int board_config; | ||
| 4846 | int err; | 5193 | int err; |
| 4847 | 5194 | ||
| 4848 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5195 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| @@ -4853,39 +5200,13 @@ static int patch_alc861(struct hda_codec *codec) | |||
| 4853 | 5200 | ||
| 4854 | spec->mixer_nid = 0x15; | 5201 | spec->mixer_nid = 0x15; |
| 4855 | 5202 | ||
| 4856 | board_config = alc_board_config(codec, ALC861_MODEL_LAST, | 5203 | alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); |
| 4857 | alc861_models, alc861_cfg_tbl); | 5204 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
| 4858 | |||
| 4859 | if (board_config < 0) { | ||
| 4860 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
| 4861 | codec->chip_name); | ||
| 4862 | board_config = ALC_MODEL_AUTO; | ||
| 4863 | } | ||
| 4864 | |||
| 4865 | if (board_config == ALC_MODEL_AUTO) { | ||
| 4866 | alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); | ||
| 4867 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
| 4868 | } | ||
| 4869 | |||
| 4870 | if (board_config == ALC_MODEL_AUTO) { | ||
| 4871 | /* automatic parse from the BIOS config */ | ||
| 4872 | err = alc861_parse_auto_config(codec); | ||
| 4873 | if (err < 0) { | ||
| 4874 | alc_free(codec); | ||
| 4875 | return err; | ||
| 4876 | } | ||
| 4877 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4878 | else if (!err) { | ||
| 4879 | printk(KERN_INFO | ||
| 4880 | "hda_codec: Cannot set up configuration " | ||
| 4881 | "from BIOS. Using base mode...\n"); | ||
| 4882 | board_config = ALC861_3ST_DIG; | ||
| 4883 | } | ||
| 4884 | #endif | ||
| 4885 | } | ||
| 4886 | 5205 | ||
| 4887 | if (board_config != ALC_MODEL_AUTO) | 5206 | /* automatic parse from the BIOS config */ |
| 4888 | setup_preset(codec, &alc861_presets[board_config]); | 5207 | err = alc861_parse_auto_config(codec); |
| 5208 | if (err < 0) | ||
| 5209 | goto error; | ||
| 4889 | 5210 | ||
| 4890 | if (!spec->no_analog && !spec->adc_nids) { | 5211 | if (!spec->no_analog && !spec->adc_nids) { |
| 4891 | alc_auto_fill_adc_caps(codec); | 5212 | alc_auto_fill_adc_caps(codec); |
| @@ -4898,10 +5219,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
| 4898 | 5219 | ||
| 4899 | if (!spec->no_analog) { | 5220 | if (!spec->no_analog) { |
| 4900 | err = snd_hda_attach_beep_device(codec, 0x23); | 5221 | err = snd_hda_attach_beep_device(codec, 0x23); |
| 4901 | if (err < 0) { | 5222 | if (err < 0) |
| 4902 | alc_free(codec); | 5223 | goto error; |
| 4903 | return err; | ||
| 4904 | } | ||
| 4905 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 5224 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
| 4906 | } | 5225 | } |
| 4907 | 5226 | ||
| @@ -4910,18 +5229,18 @@ static int patch_alc861(struct hda_codec *codec) | |||
| 4910 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5229 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
| 4911 | 5230 | ||
| 4912 | codec->patch_ops = alc_patch_ops; | 5231 | codec->patch_ops = alc_patch_ops; |
| 4913 | if (board_config == ALC_MODEL_AUTO) { | 5232 | spec->init_hook = alc_auto_init_std; |
| 4914 | spec->init_hook = alc_auto_init_std; | ||
| 4915 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
| 4916 | spec->power_hook = alc_power_eapd; | ||
| 4917 | #endif | ||
| 4918 | } | ||
| 4919 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5233 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
| 5234 | spec->power_hook = alc_power_eapd; | ||
| 4920 | if (!spec->loopback.amplist) | 5235 | if (!spec->loopback.amplist) |
| 4921 | spec->loopback.amplist = alc861_loopbacks; | 5236 | spec->loopback.amplist = alc861_loopbacks; |
| 4922 | #endif | 5237 | #endif |
| 4923 | 5238 | ||
| 4924 | return 0; | 5239 | return 0; |
| 5240 | |||
| 5241 | error: | ||
| 5242 | alc_free(codec); | ||
| 5243 | return err; | ||
| 4925 | } | 5244 | } |
| 4926 | 5245 | ||
| 4927 | /* | 5246 | /* |
| @@ -4943,24 +5262,41 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
| 4943 | } | 5262 | } |
| 4944 | 5263 | ||
| 4945 | enum { | 5264 | enum { |
| 4946 | ALC660VD_FIX_ASUS_GPIO1 | 5265 | ALC660VD_FIX_ASUS_GPIO1, |
| 5266 | ALC861VD_FIX_DALLAS, | ||
| 4947 | }; | 5267 | }; |
| 4948 | 5268 | ||
| 4949 | /* reset GPIO1 */ | 5269 | /* exclude VREF80 */ |
| 5270 | static void alc861vd_fixup_dallas(struct hda_codec *codec, | ||
| 5271 | const struct alc_fixup *fix, int action) | ||
| 5272 | { | ||
| 5273 | if (action == ALC_FIXUP_ACT_PRE_PROBE) { | ||
| 5274 | snd_hda_override_pin_caps(codec, 0x18, 0x00001714); | ||
| 5275 | snd_hda_override_pin_caps(codec, 0x19, 0x0000171c); | ||
| 5276 | } | ||
| 5277 | } | ||
| 5278 | |||
| 4950 | static const struct alc_fixup alc861vd_fixups[] = { | 5279 | static const struct alc_fixup alc861vd_fixups[] = { |
| 4951 | [ALC660VD_FIX_ASUS_GPIO1] = { | 5280 | [ALC660VD_FIX_ASUS_GPIO1] = { |
| 4952 | .type = ALC_FIXUP_VERBS, | 5281 | .type = ALC_FIXUP_VERBS, |
| 4953 | .v.verbs = (const struct hda_verb[]) { | 5282 | .v.verbs = (const struct hda_verb[]) { |
| 5283 | /* reset GPIO1 */ | ||
| 4954 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 5284 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
| 4955 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 5285 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
| 4956 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 5286 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
| 4957 | { } | 5287 | { } |
| 4958 | } | 5288 | } |
| 4959 | }, | 5289 | }, |
| 5290 | [ALC861VD_FIX_DALLAS] = { | ||
| 5291 | .type = ALC_FIXUP_FUNC, | ||
| 5292 | .v.func = alc861vd_fixup_dallas, | ||
| 5293 | }, | ||
| 4960 | }; | 5294 | }; |
| 4961 | 5295 | ||
| 4962 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { | 5296 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { |
| 5297 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), | ||
| 4963 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), | 5298 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), |
| 5299 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), | ||
| 4964 | {} | 5300 | {} |
| 4965 | }; | 5301 | }; |
| 4966 | 5302 | ||
| @@ -4972,14 +5308,10 @@ static const struct hda_verb alc660vd_eapd_verbs[] = { | |||
| 4972 | 5308 | ||
| 4973 | /* | 5309 | /* |
| 4974 | */ | 5310 | */ |
| 4975 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 4976 | #include "alc861vd_quirks.c" | ||
| 4977 | #endif | ||
| 4978 | |||
| 4979 | static int patch_alc861vd(struct hda_codec *codec) | 5311 | static int patch_alc861vd(struct hda_codec *codec) |
| 4980 | { | 5312 | { |
| 4981 | struct alc_spec *spec; | 5313 | struct alc_spec *spec; |
| 4982 | int err, board_config; | 5314 | int err; |
| 4983 | 5315 | ||
| 4984 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5316 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| 4985 | if (spec == NULL) | 5317 | if (spec == NULL) |
| @@ -4989,39 +5321,13 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
| 4989 | 5321 | ||
| 4990 | spec->mixer_nid = 0x0b; | 5322 | spec->mixer_nid = 0x0b; |
| 4991 | 5323 | ||
| 4992 | board_config = alc_board_config(codec, ALC861VD_MODEL_LAST, | 5324 | alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); |
| 4993 | alc861vd_models, alc861vd_cfg_tbl); | 5325 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
| 4994 | 5326 | ||
| 4995 | if (board_config < 0) { | 5327 | /* automatic parse from the BIOS config */ |
| 4996 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | 5328 | err = alc861vd_parse_auto_config(codec); |
| 4997 | codec->chip_name); | 5329 | if (err < 0) |
| 4998 | board_config = ALC_MODEL_AUTO; | 5330 | goto error; |
| 4999 | } | ||
| 5000 | |||
| 5001 | if (board_config == ALC_MODEL_AUTO) { | ||
| 5002 | alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); | ||
| 5003 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
| 5004 | } | ||
| 5005 | |||
| 5006 | if (board_config == ALC_MODEL_AUTO) { | ||
| 5007 | /* automatic parse from the BIOS config */ | ||
| 5008 | err = alc861vd_parse_auto_config(codec); | ||
| 5009 | if (err < 0) { | ||
| 5010 | alc_free(codec); | ||
| 5011 | return err; | ||
| 5012 | } | ||
| 5013 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 5014 | else if (!err) { | ||
| 5015 | printk(KERN_INFO | ||
| 5016 | "hda_codec: Cannot set up configuration " | ||
| 5017 | "from BIOS. Using base mode...\n"); | ||
| 5018 | board_config = ALC861VD_3ST; | ||
| 5019 | } | ||
| 5020 | #endif | ||
| 5021 | } | ||
| 5022 | |||
| 5023 | if (board_config != ALC_MODEL_AUTO) | ||
| 5024 | setup_preset(codec, &alc861vd_presets[board_config]); | ||
| 5025 | 5331 | ||
| 5026 | if (codec->vendor_id == 0x10ec0660) { | 5332 | if (codec->vendor_id == 0x10ec0660) { |
| 5027 | /* always turn on EAPD */ | 5333 | /* always turn on EAPD */ |
| @@ -5039,10 +5345,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
| 5039 | 5345 | ||
| 5040 | if (!spec->no_analog) { | 5346 | if (!spec->no_analog) { |
| 5041 | err = snd_hda_attach_beep_device(codec, 0x23); | 5347 | err = snd_hda_attach_beep_device(codec, 0x23); |
| 5042 | if (err < 0) { | 5348 | if (err < 0) |
| 5043 | alc_free(codec); | 5349 | goto error; |
| 5044 | return err; | ||
| 5045 | } | ||
| 5046 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5350 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
| 5047 | } | 5351 | } |
| 5048 | 5352 | ||
| @@ -5052,8 +5356,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
| 5052 | 5356 | ||
| 5053 | codec->patch_ops = alc_patch_ops; | 5357 | codec->patch_ops = alc_patch_ops; |
| 5054 | 5358 | ||
| 5055 | if (board_config == ALC_MODEL_AUTO) | 5359 | spec->init_hook = alc_auto_init_std; |
| 5056 | spec->init_hook = alc_auto_init_std; | ||
| 5057 | spec->shutup = alc_eapd_shutup; | 5360 | spec->shutup = alc_eapd_shutup; |
| 5058 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5361 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
| 5059 | if (!spec->loopback.amplist) | 5362 | if (!spec->loopback.amplist) |
| @@ -5061,6 +5364,10 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
| 5061 | #endif | 5364 | #endif |
| 5062 | 5365 | ||
| 5063 | return 0; | 5366 | return 0; |
| 5367 | |||
| 5368 | error: | ||
| 5369 | alc_free(codec); | ||
| 5370 | return err; | ||
| 5064 | } | 5371 | } |
| 5065 | 5372 | ||
| 5066 | /* | 5373 | /* |
| @@ -5118,6 +5425,14 @@ enum { | |||
| 5118 | ALC662_FIXUP_CZC_P10T, | 5425 | ALC662_FIXUP_CZC_P10T, |
| 5119 | ALC662_FIXUP_SKU_IGNORE, | 5426 | ALC662_FIXUP_SKU_IGNORE, |
| 5120 | ALC662_FIXUP_HP_RP5800, | 5427 | ALC662_FIXUP_HP_RP5800, |
| 5428 | ALC662_FIXUP_ASUS_MODE1, | ||
| 5429 | ALC662_FIXUP_ASUS_MODE2, | ||
| 5430 | ALC662_FIXUP_ASUS_MODE3, | ||
| 5431 | ALC662_FIXUP_ASUS_MODE4, | ||
| 5432 | ALC662_FIXUP_ASUS_MODE5, | ||
| 5433 | ALC662_FIXUP_ASUS_MODE6, | ||
| 5434 | ALC662_FIXUP_ASUS_MODE7, | ||
| 5435 | ALC662_FIXUP_ASUS_MODE8, | ||
| 5121 | }; | 5436 | }; |
| 5122 | 5437 | ||
| 5123 | static const struct alc_fixup alc662_fixups[] = { | 5438 | static const struct alc_fixup alc662_fixups[] = { |
| @@ -5159,37 +5474,204 @@ static const struct alc_fixup alc662_fixups[] = { | |||
| 5159 | .chained = true, | 5474 | .chained = true, |
| 5160 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5475 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
| 5161 | }, | 5476 | }, |
| 5477 | [ALC662_FIXUP_ASUS_MODE1] = { | ||
| 5478 | .type = ALC_FIXUP_PINS, | ||
| 5479 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5480 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5481 | { 0x18, 0x01a19c20 }, /* mic */ | ||
| 5482 | { 0x19, 0x99a3092f }, /* int-mic */ | ||
| 5483 | { 0x21, 0x0121401f }, /* HP out */ | ||
| 5484 | { } | ||
| 5485 | }, | ||
| 5486 | .chained = true, | ||
| 5487 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5488 | }, | ||
| 5489 | [ALC662_FIXUP_ASUS_MODE2] = { | ||
| 5490 | .type = ALC_FIXUP_PINS, | ||
| 5491 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5492 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5493 | { 0x18, 0x01a19820 }, /* mic */ | ||
| 5494 | { 0x19, 0x99a3092f }, /* int-mic */ | ||
| 5495 | { 0x1b, 0x0121401f }, /* HP out */ | ||
| 5496 | { } | ||
| 5497 | }, | ||
| 5498 | .chained = true, | ||
| 5499 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5500 | }, | ||
| 5501 | [ALC662_FIXUP_ASUS_MODE3] = { | ||
| 5502 | .type = ALC_FIXUP_PINS, | ||
| 5503 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5504 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5505 | { 0x15, 0x0121441f }, /* HP */ | ||
| 5506 | { 0x18, 0x01a19840 }, /* mic */ | ||
| 5507 | { 0x19, 0x99a3094f }, /* int-mic */ | ||
| 5508 | { 0x21, 0x01211420 }, /* HP2 */ | ||
| 5509 | { } | ||
| 5510 | }, | ||
| 5511 | .chained = true, | ||
| 5512 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5513 | }, | ||
| 5514 | [ALC662_FIXUP_ASUS_MODE4] = { | ||
| 5515 | .type = ALC_FIXUP_PINS, | ||
| 5516 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5517 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5518 | { 0x16, 0x99130111 }, /* speaker */ | ||
| 5519 | { 0x18, 0x01a19840 }, /* mic */ | ||
| 5520 | { 0x19, 0x99a3094f }, /* int-mic */ | ||
| 5521 | { 0x21, 0x0121441f }, /* HP */ | ||
| 5522 | { } | ||
| 5523 | }, | ||
| 5524 | .chained = true, | ||
| 5525 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5526 | }, | ||
| 5527 | [ALC662_FIXUP_ASUS_MODE5] = { | ||
| 5528 | .type = ALC_FIXUP_PINS, | ||
| 5529 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5530 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5531 | { 0x15, 0x0121441f }, /* HP */ | ||
| 5532 | { 0x16, 0x99130111 }, /* speaker */ | ||
| 5533 | { 0x18, 0x01a19840 }, /* mic */ | ||
| 5534 | { 0x19, 0x99a3094f }, /* int-mic */ | ||
| 5535 | { } | ||
| 5536 | }, | ||
| 5537 | .chained = true, | ||
| 5538 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5539 | }, | ||
| 5540 | [ALC662_FIXUP_ASUS_MODE6] = { | ||
| 5541 | .type = ALC_FIXUP_PINS, | ||
| 5542 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5543 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5544 | { 0x15, 0x01211420 }, /* HP2 */ | ||
| 5545 | { 0x18, 0x01a19840 }, /* mic */ | ||
| 5546 | { 0x19, 0x99a3094f }, /* int-mic */ | ||
| 5547 | { 0x1b, 0x0121441f }, /* HP */ | ||
| 5548 | { } | ||
| 5549 | }, | ||
| 5550 | .chained = true, | ||
| 5551 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5552 | }, | ||
| 5553 | [ALC662_FIXUP_ASUS_MODE7] = { | ||
| 5554 | .type = ALC_FIXUP_PINS, | ||
| 5555 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5556 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5557 | { 0x17, 0x99130111 }, /* speaker */ | ||
| 5558 | { 0x18, 0x01a19840 }, /* mic */ | ||
| 5559 | { 0x19, 0x99a3094f }, /* int-mic */ | ||
| 5560 | { 0x1b, 0x01214020 }, /* HP */ | ||
| 5561 | { 0x21, 0x0121401f }, /* HP */ | ||
| 5562 | { } | ||
| 5563 | }, | ||
| 5564 | .chained = true, | ||
| 5565 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5566 | }, | ||
| 5567 | [ALC662_FIXUP_ASUS_MODE8] = { | ||
| 5568 | .type = ALC_FIXUP_PINS, | ||
| 5569 | .v.pins = (const struct alc_pincfg[]) { | ||
| 5570 | { 0x14, 0x99130110 }, /* speaker */ | ||
| 5571 | { 0x12, 0x99a30970 }, /* int-mic */ | ||
| 5572 | { 0x15, 0x01214020 }, /* HP */ | ||
| 5573 | { 0x17, 0x99130111 }, /* speaker */ | ||
| 5574 | { 0x18, 0x01a19840 }, /* mic */ | ||
| 5575 | { 0x21, 0x0121401f }, /* HP */ | ||
| 5576 | { } | ||
| 5577 | }, | ||
| 5578 | .chained = true, | ||
| 5579 | .chain_id = ALC662_FIXUP_SKU_IGNORE | ||
| 5580 | }, | ||
| 5162 | }; | 5581 | }; |
| 5163 | 5582 | ||
| 5164 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 5583 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
| 5584 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), | ||
| 5165 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 5585 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
| 5166 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 5586 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
| 5167 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 5587 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
| 5168 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 5588 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
| 5589 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | ||
| 5169 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 5590 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
| 5170 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 5591 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
| 5171 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | 5592 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
| 5172 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), | 5593 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), |
| 5594 | |||
| 5595 | #if 0 | ||
| 5596 | /* Below is a quirk table taken from the old code. | ||
| 5597 | * Basically the device should work as is without the fixup table. | ||
| 5598 | * If BIOS doesn't give a proper info, enable the corresponding | ||
| 5599 | * fixup entry. | ||
| 5600 | */ | ||
| 5601 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), | ||
| 5602 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), | ||
| 5603 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), | ||
| 5604 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), | ||
| 5605 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | ||
| 5606 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5607 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | ||
| 5608 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), | ||
| 5609 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), | ||
| 5610 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5611 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), | ||
| 5612 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), | ||
| 5613 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), | ||
| 5614 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), | ||
| 5615 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), | ||
| 5616 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5617 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), | ||
| 5618 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), | ||
| 5619 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5620 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | ||
| 5621 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | ||
| 5622 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5623 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), | ||
| 5624 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), | ||
| 5625 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), | ||
| 5626 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5627 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), | ||
| 5628 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | ||
| 5629 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5630 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), | ||
| 5631 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5632 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5633 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), | ||
| 5634 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), | ||
| 5635 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), | ||
| 5636 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), | ||
| 5637 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), | ||
| 5638 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), | ||
| 5639 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), | ||
| 5640 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | ||
| 5641 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), | ||
| 5642 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), | ||
| 5643 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | ||
| 5644 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), | ||
| 5645 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), | ||
| 5646 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), | ||
| 5647 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), | ||
| 5648 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), | ||
| 5649 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | ||
| 5650 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), | ||
| 5651 | #endif | ||
| 5173 | {} | 5652 | {} |
| 5174 | }; | 5653 | }; |
| 5175 | 5654 | ||
| 5176 | static const struct alc_model_fixup alc662_fixup_models[] = { | 5655 | static const struct alc_model_fixup alc662_fixup_models[] = { |
| 5177 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, | 5656 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, |
| 5657 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, | ||
| 5658 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, | ||
| 5659 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, | ||
| 5660 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, | ||
| 5661 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, | ||
| 5662 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, | ||
| 5663 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | ||
| 5664 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | ||
| 5178 | {} | 5665 | {} |
| 5179 | }; | 5666 | }; |
| 5180 | 5667 | ||
| 5181 | 5668 | ||
| 5182 | /* | 5669 | /* |
| 5183 | */ | 5670 | */ |
| 5184 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 5185 | #include "alc662_quirks.c" | ||
| 5186 | #endif | ||
| 5187 | |||
| 5188 | static int patch_alc662(struct hda_codec *codec) | 5671 | static int patch_alc662(struct hda_codec *codec) |
| 5189 | { | 5672 | { |
| 5190 | struct alc_spec *spec; | 5673 | struct alc_spec *spec; |
| 5191 | int err, board_config; | 5674 | int err = 0; |
| 5192 | int coef; | ||
| 5193 | 5675 | ||
| 5194 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5676 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| 5195 | if (!spec) | 5677 | if (!spec) |
| @@ -5199,50 +5681,31 @@ static int patch_alc662(struct hda_codec *codec) | |||
| 5199 | 5681 | ||
| 5200 | spec->mixer_nid = 0x0b; | 5682 | spec->mixer_nid = 0x0b; |
| 5201 | 5683 | ||
| 5684 | /* handle multiple HPs as is */ | ||
| 5685 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | ||
| 5686 | |||
| 5202 | alc_auto_parse_customize_define(codec); | 5687 | alc_auto_parse_customize_define(codec); |
| 5203 | 5688 | ||
| 5204 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 5689 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
| 5205 | 5690 | ||
| 5206 | coef = alc_read_coef_idx(codec, 0); | 5691 | err = alc_codec_rename_from_preset(codec); |
| 5207 | if (coef == 0x8020 || coef == 0x8011) | 5692 | if (err < 0) |
| 5208 | alc_codec_rename(codec, "ALC661"); | 5693 | goto error; |
| 5209 | else if (coef & (1 << 14) && | ||
| 5210 | codec->bus->pci->subsystem_vendor == 0x1025 && | ||
| 5211 | spec->cdefine.platform_type == 1) | ||
| 5212 | alc_codec_rename(codec, "ALC272X"); | ||
| 5213 | else if (coef == 0x4011) | ||
| 5214 | alc_codec_rename(codec, "ALC656"); | ||
| 5215 | |||
| 5216 | board_config = alc_board_config(codec, ALC662_MODEL_LAST, | ||
| 5217 | alc662_models, alc662_cfg_tbl); | ||
| 5218 | if (board_config < 0) { | ||
| 5219 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
| 5220 | codec->chip_name); | ||
| 5221 | board_config = ALC_MODEL_AUTO; | ||
| 5222 | } | ||
| 5223 | 5694 | ||
| 5224 | if (board_config == ALC_MODEL_AUTO) { | 5695 | if ((alc_get_coef0(codec) & (1 << 14)) && |
| 5225 | alc_pick_fixup(codec, alc662_fixup_models, | 5696 | codec->bus->pci->subsystem_vendor == 0x1025 && |
| 5226 | alc662_fixup_tbl, alc662_fixups); | 5697 | spec->cdefine.platform_type == 1) { |
| 5227 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 5698 | if (alc_codec_rename(codec, "ALC272X") < 0) |
| 5228 | /* automatic parse from the BIOS config */ | 5699 | goto error; |
| 5229 | err = alc662_parse_auto_config(codec); | ||
| 5230 | if (err < 0) { | ||
| 5231 | alc_free(codec); | ||
| 5232 | return err; | ||
| 5233 | } | ||
| 5234 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 5235 | else if (!err) { | ||
| 5236 | printk(KERN_INFO | ||
| 5237 | "hda_codec: Cannot set up configuration " | ||
| 5238 | "from BIOS. Using base mode...\n"); | ||
| 5239 | board_config = ALC662_3ST_2ch_DIG; | ||
| 5240 | } | ||
| 5241 | #endif | ||
| 5242 | } | 5700 | } |
| 5243 | 5701 | ||
| 5244 | if (board_config != ALC_MODEL_AUTO) | 5702 | alc_pick_fixup(codec, alc662_fixup_models, |
| 5245 | setup_preset(codec, &alc662_presets[board_config]); | 5703 | alc662_fixup_tbl, alc662_fixups); |
| 5704 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
| 5705 | /* automatic parse from the BIOS config */ | ||
| 5706 | err = alc662_parse_auto_config(codec); | ||
| 5707 | if (err < 0) | ||
| 5708 | goto error; | ||
| 5246 | 5709 | ||
| 5247 | if (!spec->no_analog && !spec->adc_nids) { | 5710 | if (!spec->no_analog && !spec->adc_nids) { |
| 5248 | alc_auto_fill_adc_caps(codec); | 5711 | alc_auto_fill_adc_caps(codec); |
| @@ -5255,10 +5718,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
| 5255 | 5718 | ||
| 5256 | if (!spec->no_analog && has_cdefine_beep(codec)) { | 5719 | if (!spec->no_analog && has_cdefine_beep(codec)) { |
| 5257 | err = snd_hda_attach_beep_device(codec, 0x1); | 5720 | err = snd_hda_attach_beep_device(codec, 0x1); |
| 5258 | if (err < 0) { | 5721 | if (err < 0) |
| 5259 | alc_free(codec); | 5722 | goto error; |
| 5260 | return err; | ||
| 5261 | } | ||
| 5262 | switch (codec->vendor_id) { | 5723 | switch (codec->vendor_id) { |
| 5263 | case 0x10ec0662: | 5724 | case 0x10ec0662: |
| 5264 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5725 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
| @@ -5278,8 +5739,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
| 5278 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5739 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
| 5279 | 5740 | ||
| 5280 | codec->patch_ops = alc_patch_ops; | 5741 | codec->patch_ops = alc_patch_ops; |
| 5281 | if (board_config == ALC_MODEL_AUTO) | 5742 | spec->init_hook = alc_auto_init_std; |
| 5282 | spec->init_hook = alc_auto_init_std; | ||
| 5283 | spec->shutup = alc_eapd_shutup; | 5743 | spec->shutup = alc_eapd_shutup; |
| 5284 | 5744 | ||
| 5285 | alc_init_jacks(codec); | 5745 | alc_init_jacks(codec); |
| @@ -5290,32 +5750,10 @@ static int patch_alc662(struct hda_codec *codec) | |||
| 5290 | #endif | 5750 | #endif |
| 5291 | 5751 | ||
| 5292 | return 0; | 5752 | return 0; |
| 5293 | } | ||
| 5294 | 5753 | ||
| 5295 | static int patch_alc888(struct hda_codec *codec) | 5754 | error: |
| 5296 | { | 5755 | alc_free(codec); |
| 5297 | if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){ | 5756 | return err; |
| 5298 | kfree(codec->chip_name); | ||
| 5299 | if (codec->vendor_id == 0x10ec0887) | ||
| 5300 | codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL); | ||
| 5301 | else | ||
| 5302 | codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL); | ||
| 5303 | if (!codec->chip_name) { | ||
| 5304 | alc_free(codec); | ||
| 5305 | return -ENOMEM; | ||
| 5306 | } | ||
| 5307 | return patch_alc662(codec); | ||
| 5308 | } | ||
| 5309 | return patch_alc882(codec); | ||
| 5310 | } | ||
| 5311 | |||
| 5312 | static int patch_alc899(struct hda_codec *codec) | ||
| 5313 | { | ||
| 5314 | if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) { | ||
| 5315 | kfree(codec->chip_name); | ||
| 5316 | codec->chip_name = kstrdup("ALC898", GFP_KERNEL); | ||
| 5317 | } | ||
| 5318 | return patch_alc882(codec); | ||
| 5319 | } | 5757 | } |
| 5320 | 5758 | ||
| 5321 | /* | 5759 | /* |
| @@ -5329,14 +5767,9 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
| 5329 | 5767 | ||
| 5330 | /* | 5768 | /* |
| 5331 | */ | 5769 | */ |
| 5332 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 5333 | #include "alc680_quirks.c" | ||
| 5334 | #endif | ||
| 5335 | |||
| 5336 | static int patch_alc680(struct hda_codec *codec) | 5770 | static int patch_alc680(struct hda_codec *codec) |
| 5337 | { | 5771 | { |
| 5338 | struct alc_spec *spec; | 5772 | struct alc_spec *spec; |
| 5339 | int board_config; | ||
| 5340 | int err; | 5773 | int err; |
| 5341 | 5774 | ||
| 5342 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5775 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| @@ -5347,43 +5780,11 @@ static int patch_alc680(struct hda_codec *codec) | |||
| 5347 | 5780 | ||
| 5348 | /* ALC680 has no aa-loopback mixer */ | 5781 | /* ALC680 has no aa-loopback mixer */ |
| 5349 | 5782 | ||
| 5350 | board_config = alc_board_config(codec, ALC680_MODEL_LAST, | 5783 | /* automatic parse from the BIOS config */ |
| 5351 | alc680_models, alc680_cfg_tbl); | 5784 | err = alc680_parse_auto_config(codec); |
| 5352 | 5785 | if (err < 0) { | |
| 5353 | if (board_config < 0) { | 5786 | alc_free(codec); |
| 5354 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | 5787 | return err; |
| 5355 | codec->chip_name); | ||
| 5356 | board_config = ALC_MODEL_AUTO; | ||
| 5357 | } | ||
| 5358 | |||
| 5359 | if (board_config == ALC_MODEL_AUTO) { | ||
| 5360 | /* automatic parse from the BIOS config */ | ||
| 5361 | err = alc680_parse_auto_config(codec); | ||
| 5362 | if (err < 0) { | ||
| 5363 | alc_free(codec); | ||
| 5364 | return err; | ||
| 5365 | } | ||
| 5366 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 5367 | else if (!err) { | ||
| 5368 | printk(KERN_INFO | ||
| 5369 | "hda_codec: Cannot set up configuration " | ||
| 5370 | "from BIOS. Using base mode...\n"); | ||
| 5371 | board_config = ALC680_BASE; | ||
| 5372 | } | ||
| 5373 | #endif | ||
| 5374 | } | ||
| 5375 | |||
| 5376 | if (board_config != ALC_MODEL_AUTO) { | ||
| 5377 | setup_preset(codec, &alc680_presets[board_config]); | ||
| 5378 | #ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS | ||
| 5379 | spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; | ||
| 5380 | #endif | ||
| 5381 | } | ||
| 5382 | |||
| 5383 | if (!spec->no_analog && !spec->adc_nids) { | ||
| 5384 | alc_auto_fill_adc_caps(codec); | ||
| 5385 | alc_rebuild_imux_for_auto_mic(codec); | ||
| 5386 | alc_remove_invalid_adc_nids(codec); | ||
| 5387 | } | 5788 | } |
| 5388 | 5789 | ||
| 5389 | if (!spec->no_analog && !spec->cap_mixer) | 5790 | if (!spec->no_analog && !spec->cap_mixer) |
| @@ -5392,8 +5793,7 @@ static int patch_alc680(struct hda_codec *codec) | |||
| 5392 | spec->vmaster_nid = 0x02; | 5793 | spec->vmaster_nid = 0x02; |
| 5393 | 5794 | ||
| 5394 | codec->patch_ops = alc_patch_ops; | 5795 | codec->patch_ops = alc_patch_ops; |
| 5395 | if (board_config == ALC_MODEL_AUTO) | 5796 | spec->init_hook = alc_auto_init_std; |
| 5396 | spec->init_hook = alc_auto_init_std; | ||
| 5397 | 5797 | ||
| 5398 | return 0; | 5798 | return 0; |
| 5399 | } | 5799 | } |
| @@ -5421,6 +5821,8 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
| 5421 | .patch = patch_alc882 }, | 5821 | .patch = patch_alc882 }, |
| 5422 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | 5822 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", |
| 5423 | .patch = patch_alc662 }, | 5823 | .patch = patch_alc662 }, |
| 5824 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", | ||
| 5825 | .patch = patch_alc662 }, | ||
| 5424 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 5826 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
| 5425 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 5827 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
| 5426 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 5828 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
| @@ -5433,13 +5835,13 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
| 5433 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", | 5835 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", |
| 5434 | .patch = patch_alc882 }, | 5836 | .patch = patch_alc882 }, |
| 5435 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 5837 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
| 5436 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 }, | 5838 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
| 5437 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", | 5839 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
| 5438 | .patch = patch_alc882 }, | 5840 | .patch = patch_alc882 }, |
| 5439 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, | 5841 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, |
| 5440 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 5842 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
| 5441 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | 5843 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
| 5442 | { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 }, | 5844 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
| 5443 | {} /* terminator */ | 5845 | {} /* terminator */ |
| 5444 | }; | 5846 | }; |
| 5445 | 5847 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 987e3cf71a0b..59a52a430f24 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
| @@ -2972,8 +2972,9 @@ static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | |||
| 2972 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | 2972 | static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) |
| 2973 | { | 2973 | { |
| 2974 | struct sigmatel_spec *spec = codec->spec; | 2974 | struct sigmatel_spec *spec = codec->spec; |
| 2975 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
| 2975 | int j, conn_len; | 2976 | int j, conn_len; |
| 2976 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; | 2977 | hda_nid_t conn[HDA_MAX_CONNECTIONS], fallback_dac; |
| 2977 | unsigned int wcaps, wtype; | 2978 | unsigned int wcaps, wtype; |
| 2978 | 2979 | ||
| 2979 | conn_len = snd_hda_get_connections(codec, nid, conn, | 2980 | conn_len = snd_hda_get_connections(codec, nid, conn, |
| @@ -3001,10 +3002,21 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
| 3001 | return conn[j]; | 3002 | return conn[j]; |
| 3002 | } | 3003 | } |
| 3003 | } | 3004 | } |
| 3004 | /* if all DACs are already assigned, connect to the primary DAC */ | 3005 | |
| 3006 | /* if all DACs are already assigned, connect to the primary DAC, | ||
| 3007 | unless we're assigning a secondary headphone */ | ||
| 3008 | fallback_dac = spec->multiout.dac_nids[0]; | ||
| 3009 | if (spec->multiout.hp_nid) { | ||
| 3010 | for (j = 0; j < cfg->hp_outs; j++) | ||
| 3011 | if (cfg->hp_pins[j] == nid) { | ||
| 3012 | fallback_dac = spec->multiout.hp_nid; | ||
| 3013 | break; | ||
| 3014 | } | ||
| 3015 | } | ||
| 3016 | |||
| 3005 | if (conn_len > 1) { | 3017 | if (conn_len > 1) { |
| 3006 | for (j = 0; j < conn_len; j++) { | 3018 | for (j = 0; j < conn_len; j++) { |
| 3007 | if (conn[j] == spec->multiout.dac_nids[0]) { | 3019 | if (conn[j] == fallback_dac) { |
| 3008 | snd_hda_codec_write_cache(codec, nid, 0, | 3020 | snd_hda_codec_write_cache(codec, nid, 0, |
| 3009 | AC_VERB_SET_CONNECT_SEL, j); | 3021 | AC_VERB_SET_CONNECT_SEL, j); |
| 3010 | break; | 3022 | break; |
| @@ -4130,22 +4142,14 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
| 4130 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 4142 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
| 4131 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4143 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
| 4132 | int connectivity = get_defcfg_connect(def_conf); | 4144 | int connectivity = get_defcfg_connect(def_conf); |
| 4133 | char name[32]; | ||
| 4134 | int err; | ||
| 4135 | 4145 | ||
| 4136 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) | 4146 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) |
| 4137 | return 0; | 4147 | return 0; |
| 4138 | 4148 | ||
| 4139 | snprintf(name, sizeof(name), "%s at %s %s Jack", | 4149 | return snd_hda_input_jack_add(codec, nid, type, NULL); |
| 4140 | snd_hda_get_jack_type(def_conf), | 4150 | #else |
| 4141 | snd_hda_get_jack_connectivity(def_conf), | ||
| 4142 | snd_hda_get_jack_location(def_conf)); | ||
| 4143 | |||
| 4144 | err = snd_hda_input_jack_add(codec, nid, type, name); | ||
| 4145 | if (err < 0) | ||
| 4146 | return err; | ||
| 4147 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
| 4148 | return 0; | 4151 | return 0; |
| 4152 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | ||
| 4149 | } | 4153 | } |
| 4150 | 4154 | ||
| 4151 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | 4155 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, |
| @@ -5585,9 +5589,7 @@ static void stac92hd8x_fill_auto_spec(struct hda_codec *codec) | |||
| 5585 | static int patch_stac92hd83xxx(struct hda_codec *codec) | 5589 | static int patch_stac92hd83xxx(struct hda_codec *codec) |
| 5586 | { | 5590 | { |
| 5587 | struct sigmatel_spec *spec; | 5591 | struct sigmatel_spec *spec; |
| 5588 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; | ||
| 5589 | int err; | 5592 | int err; |
| 5590 | int num_dacs; | ||
| 5591 | 5593 | ||
| 5592 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5594 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
| 5593 | if (spec == NULL) | 5595 | if (spec == NULL) |
| @@ -5689,22 +5691,6 @@ again: | |||
| 5689 | return err; | 5691 | return err; |
| 5690 | } | 5692 | } |
| 5691 | 5693 | ||
| 5692 | /* docking output support */ | ||
| 5693 | num_dacs = snd_hda_get_connections(codec, 0xF, | ||
| 5694 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | ||
| 5695 | /* skip non-DAC connections */ | ||
| 5696 | while (num_dacs >= 0 && | ||
| 5697 | (get_wcaps_type(get_wcaps(codec, conn[num_dacs])) | ||
| 5698 | != AC_WID_AUD_OUT)) | ||
| 5699 | num_dacs--; | ||
| 5700 | /* set port E and F to select the last DAC */ | ||
| 5701 | if (num_dacs >= 0) { | ||
| 5702 | snd_hda_codec_write_cache(codec, 0xE, 0, | ||
| 5703 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
| 5704 | snd_hda_codec_write_cache(codec, 0xF, 0, | ||
| 5705 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
| 5706 | } | ||
| 5707 | |||
| 5708 | codec->proc_widget_hook = stac92hd_proc_hook; | 5694 | codec->proc_widget_hook = stac92hd_proc_hook; |
| 5709 | 5695 | ||
| 5710 | return 0; | 5696 | return 0; |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 4ebfbd874c9a..417d62ad3b96 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
| @@ -1506,39 +1506,49 @@ static int via_build_pcms(struct hda_codec *codec) | |||
| 1506 | struct via_spec *spec = codec->spec; | 1506 | struct via_spec *spec = codec->spec; |
| 1507 | struct hda_pcm *info = spec->pcm_rec; | 1507 | struct hda_pcm *info = spec->pcm_rec; |
| 1508 | 1508 | ||
| 1509 | codec->num_pcms = 1; | 1509 | codec->num_pcms = 0; |
| 1510 | codec->pcm_info = info; | 1510 | codec->pcm_info = info; |
| 1511 | 1511 | ||
| 1512 | snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog), | 1512 | if (spec->multiout.num_dacs || spec->num_adc_nids) { |
| 1513 | "%s Analog", codec->chip_name); | 1513 | snprintf(spec->stream_name_analog, |
| 1514 | info->name = spec->stream_name_analog; | 1514 | sizeof(spec->stream_name_analog), |
| 1515 | "%s Analog", codec->chip_name); | ||
| 1516 | info->name = spec->stream_name_analog; | ||
| 1515 | 1517 | ||
| 1516 | if (!spec->stream_analog_playback) | 1518 | if (spec->multiout.num_dacs) { |
| 1517 | spec->stream_analog_playback = &via_pcm_analog_playback; | 1519 | if (!spec->stream_analog_playback) |
| 1518 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = | 1520 | spec->stream_analog_playback = |
| 1519 | *spec->stream_analog_playback; | 1521 | &via_pcm_analog_playback; |
| 1520 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | 1522 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = |
| 1521 | spec->multiout.dac_nids[0]; | 1523 | *spec->stream_analog_playback; |
| 1522 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | 1524 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = |
| 1523 | spec->multiout.max_channels; | 1525 | spec->multiout.dac_nids[0]; |
| 1526 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = | ||
| 1527 | spec->multiout.max_channels; | ||
| 1528 | } | ||
| 1524 | 1529 | ||
| 1525 | if (!spec->stream_analog_capture) { | 1530 | if (!spec->stream_analog_capture) { |
| 1526 | if (spec->dyn_adc_switch) | 1531 | if (spec->dyn_adc_switch) |
| 1527 | spec->stream_analog_capture = | 1532 | spec->stream_analog_capture = |
| 1528 | &via_pcm_dyn_adc_analog_capture; | 1533 | &via_pcm_dyn_adc_analog_capture; |
| 1529 | else | 1534 | else |
| 1530 | spec->stream_analog_capture = &via_pcm_analog_capture; | 1535 | spec->stream_analog_capture = |
| 1536 | &via_pcm_analog_capture; | ||
| 1537 | } | ||
| 1538 | if (spec->num_adc_nids) { | ||
| 1539 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
| 1540 | *spec->stream_analog_capture; | ||
| 1541 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | ||
| 1542 | spec->adc_nids[0]; | ||
| 1543 | if (!spec->dyn_adc_switch) | ||
| 1544 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = | ||
| 1545 | spec->num_adc_nids; | ||
| 1546 | } | ||
| 1547 | codec->num_pcms++; | ||
| 1548 | info++; | ||
| 1531 | } | 1549 | } |
| 1532 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
| 1533 | *spec->stream_analog_capture; | ||
| 1534 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | ||
| 1535 | if (!spec->dyn_adc_switch) | ||
| 1536 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = | ||
| 1537 | spec->num_adc_nids; | ||
| 1538 | 1550 | ||
| 1539 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { | 1551 | if (spec->multiout.dig_out_nid || spec->dig_in_nid) { |
| 1540 | codec->num_pcms++; | ||
| 1541 | info++; | ||
| 1542 | snprintf(spec->stream_name_digital, | 1552 | snprintf(spec->stream_name_digital, |
| 1543 | sizeof(spec->stream_name_digital), | 1553 | sizeof(spec->stream_name_digital), |
| 1544 | "%s Digital", codec->chip_name); | 1554 | "%s Digital", codec->chip_name); |
| @@ -1562,17 +1572,19 @@ static int via_build_pcms(struct hda_codec *codec) | |||
| 1562 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | 1572 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = |
| 1563 | spec->dig_in_nid; | 1573 | spec->dig_in_nid; |
| 1564 | } | 1574 | } |
| 1575 | codec->num_pcms++; | ||
| 1576 | info++; | ||
| 1565 | } | 1577 | } |
| 1566 | 1578 | ||
| 1567 | if (spec->hp_dac_nid) { | 1579 | if (spec->hp_dac_nid) { |
| 1568 | codec->num_pcms++; | ||
| 1569 | info++; | ||
| 1570 | snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp), | 1580 | snprintf(spec->stream_name_hp, sizeof(spec->stream_name_hp), |
| 1571 | "%s HP", codec->chip_name); | 1581 | "%s HP", codec->chip_name); |
| 1572 | info->name = spec->stream_name_hp; | 1582 | info->name = spec->stream_name_hp; |
| 1573 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback; | 1583 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = via_pcm_hp_playback; |
| 1574 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | 1584 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = |
| 1575 | spec->hp_dac_nid; | 1585 | spec->hp_dac_nid; |
| 1586 | codec->num_pcms++; | ||
| 1587 | info++; | ||
| 1576 | } | 1588 | } |
| 1577 | return 0; | 1589 | return 0; |
| 1578 | } | 1590 | } |
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 0ccc0eb75775..8531b983f3af 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c | |||
| @@ -2748,8 +2748,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, | |||
| 2748 | if (!c->no_mpu401) { | 2748 | if (!c->no_mpu401) { |
| 2749 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, | 2749 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, |
| 2750 | ICEREG(ice, MPU1_CTRL), | 2750 | ICEREG(ice, MPU1_CTRL), |
| 2751 | (c->mpu401_1_info_flags | MPU401_INFO_INTEGRATED), | 2751 | c->mpu401_1_info_flags | |
| 2752 | ice->irq, 0, &ice->rmidi[0]); | 2752 | MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, |
| 2753 | -1, &ice->rmidi[0]); | ||
| 2753 | if (err < 0) { | 2754 | if (err < 0) { |
| 2754 | snd_card_free(card); | 2755 | snd_card_free(card); |
| 2755 | return err; | 2756 | return err; |
| @@ -2764,8 +2765,9 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, | |||
| 2764 | /* 2nd port used */ | 2765 | /* 2nd port used */ |
| 2765 | err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, | 2766 | err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, |
| 2766 | ICEREG(ice, MPU2_CTRL), | 2767 | ICEREG(ice, MPU2_CTRL), |
| 2767 | (c->mpu401_2_info_flags | MPU401_INFO_INTEGRATED), | 2768 | c->mpu401_2_info_flags | |
| 2768 | ice->irq, 0, &ice->rmidi[1]); | 2769 | MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, |
| 2770 | -1, &ice->rmidi[1]); | ||
| 2769 | 2771 | ||
| 2770 | if (err < 0) { | 2772 | if (err < 0) { |
| 2771 | snd_card_free(card); | 2773 | snd_card_free(card); |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 0378126e6272..2fd4bf2d6653 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
| @@ -2820,8 +2820,8 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
| 2820 | /* TODO enable MIDI IRQ and I/O */ | 2820 | /* TODO enable MIDI IRQ and I/O */ |
| 2821 | err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, | 2821 | err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, |
| 2822 | chip->iobase + MPU401_DATA_PORT, | 2822 | chip->iobase + MPU401_DATA_PORT, |
| 2823 | MPU401_INFO_INTEGRATED, | 2823 | MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK, |
| 2824 | chip->irq, 0, &chip->rmidi); | 2824 | -1, &chip->rmidi); |
| 2825 | if (err < 0) | 2825 | if (err < 0) |
| 2826 | printk(KERN_WARNING "maestro3: no MIDI support.\n"); | 2826 | printk(KERN_WARNING "maestro3: no MIDI support.\n"); |
| 2827 | #endif | 2827 | #endif |
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 82311fcb86f6..53e5508abcbf 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c | |||
| @@ -678,15 +678,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, | |||
| 678 | goto err_card; | 678 | goto err_card; |
| 679 | 679 | ||
| 680 | if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) { | 680 | if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) { |
| 681 | unsigned int info_flags = MPU401_INFO_INTEGRATED; | 681 | unsigned int info_flags = |
| 682 | MPU401_INFO_INTEGRATED | MPU401_INFO_IRQ_HOOK; | ||
| 682 | if (chip->model.device_config & MIDI_OUTPUT) | 683 | if (chip->model.device_config & MIDI_OUTPUT) |
| 683 | info_flags |= MPU401_INFO_OUTPUT; | 684 | info_flags |= MPU401_INFO_OUTPUT; |
| 684 | if (chip->model.device_config & MIDI_INPUT) | 685 | if (chip->model.device_config & MIDI_INPUT) |
| 685 | info_flags |= MPU401_INFO_INPUT; | 686 | info_flags |= MPU401_INFO_INPUT; |
| 686 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, | 687 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, |
| 687 | chip->addr + OXYGEN_MPU401, | 688 | chip->addr + OXYGEN_MPU401, |
| 688 | info_flags, 0, 0, | 689 | info_flags, -1, &chip->midi); |
| 689 | &chip->midi); | ||
| 690 | if (err < 0) | 690 | if (err < 0) |
| 691 | goto err_card; | 691 | goto err_card; |
| 692 | } | 692 | } |
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 32d096c98f5b..8433aa7c3d75 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c | |||
| @@ -1074,6 +1074,7 @@ static const struct oxygen_model model_xonar_st = { | |||
| 1074 | .device_config = PLAYBACK_0_TO_I2S | | 1074 | .device_config = PLAYBACK_0_TO_I2S | |
| 1075 | PLAYBACK_1_TO_SPDIF | | 1075 | PLAYBACK_1_TO_SPDIF | |
| 1076 | CAPTURE_0_FROM_I2S_2 | | 1076 | CAPTURE_0_FROM_I2S_2 | |
| 1077 | CAPTURE_1_FROM_SPDIF | | ||
| 1077 | AC97_FMIC_SWITCH, | 1078 | AC97_FMIC_SWITCH, |
| 1078 | .dac_channels_pcm = 2, | 1079 | .dac_channels_pcm = 2, |
| 1079 | .dac_channels_mixer = 2, | 1080 | .dac_channels_mixer = 2, |
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index e34ae14908b3..88cc776aa38b 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c | |||
| @@ -2109,7 +2109,7 @@ snd_card_riptide_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
| 2109 | val = mpu_port[dev]; | 2109 | val = mpu_port[dev]; |
| 2110 | pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val); | 2110 | pci_write_config_word(chip->pci, PCI_EXT_MPU_Base, val); |
| 2111 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, | 2111 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_RIPTIDE, |
| 2112 | val, 0, chip->irq, 0, | 2112 | val, MPU401_INFO_IRQ_HOOK, -1, |
| 2113 | &chip->rmidi); | 2113 | &chip->rmidi); |
| 2114 | if (err < 0) | 2114 | if (err < 0) |
| 2115 | snd_printk(KERN_WARNING | 2115 | snd_printk(KERN_WARNING |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 493e3946756f..6e2f7ef7ddb1 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
| @@ -1241,10 +1241,30 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm) | |||
| 1241 | return rate; | 1241 | return rate; |
| 1242 | } | 1242 | } |
| 1243 | 1243 | ||
| 1244 | /* return latency in samples per period */ | ||
| 1245 | static int hdspm_get_latency(struct hdspm *hdspm) | ||
| 1246 | { | ||
| 1247 | int n; | ||
| 1248 | |||
| 1249 | n = hdspm_decode_latency(hdspm->control_register); | ||
| 1250 | |||
| 1251 | /* Special case for new RME cards with 32 samples period size. | ||
| 1252 | * The three latency bits in the control register | ||
| 1253 | * (HDSP_LatencyMask) encode latency values of 64 samples as | ||
| 1254 | * 0, 128 samples as 1 ... 4096 samples as 6. For old cards, 7 | ||
| 1255 | * denotes 8192 samples, but on new cards like RayDAT or AIO, | ||
| 1256 | * it corresponds to 32 samples. | ||
| 1257 | */ | ||
| 1258 | if ((7 == n) && (RayDAT == hdspm->io_type || AIO == hdspm->io_type)) | ||
| 1259 | n = -1; | ||
| 1260 | |||
| 1261 | return 1 << (n + 6); | ||
| 1262 | } | ||
| 1263 | |||
| 1244 | /* Latency function */ | 1264 | /* Latency function */ |
| 1245 | static inline void hdspm_compute_period_size(struct hdspm *hdspm) | 1265 | static inline void hdspm_compute_period_size(struct hdspm *hdspm) |
| 1246 | { | 1266 | { |
| 1247 | hdspm->period_bytes = 1 << ((hdspm_decode_latency(hdspm->control_register) + 8)); | 1267 | hdspm->period_bytes = 4 * hdspm_get_latency(hdspm); |
| 1248 | } | 1268 | } |
| 1249 | 1269 | ||
| 1250 | 1270 | ||
| @@ -1303,12 +1323,27 @@ static int hdspm_set_interrupt_interval(struct hdspm *s, unsigned int frames) | |||
| 1303 | 1323 | ||
| 1304 | spin_lock_irq(&s->lock); | 1324 | spin_lock_irq(&s->lock); |
| 1305 | 1325 | ||
| 1306 | frames >>= 7; | 1326 | if (32 == frames) { |
| 1307 | n = 0; | 1327 | /* Special case for new RME cards like RayDAT/AIO which |
| 1308 | while (frames) { | 1328 | * support period sizes of 32 samples. Since latency is |
| 1309 | n++; | 1329 | * encoded in the three bits of HDSP_LatencyMask, we can only |
| 1310 | frames >>= 1; | 1330 | * have values from 0 .. 7. While 0 still means 64 samples and |
| 1331 | * 6 represents 4096 samples on all cards, 7 represents 8192 | ||
| 1332 | * on older cards and 32 samples on new cards. | ||
| 1333 | * | ||
| 1334 | * In other words, period size in samples is calculated by | ||
| 1335 | * 2^(n+6) with n ranging from 0 .. 7. | ||
| 1336 | */ | ||
| 1337 | n = 7; | ||
| 1338 | } else { | ||
| 1339 | frames >>= 7; | ||
| 1340 | n = 0; | ||
| 1341 | while (frames) { | ||
| 1342 | n++; | ||
| 1343 | frames >>= 1; | ||
| 1344 | } | ||
| 1311 | } | 1345 | } |
| 1346 | |||
| 1312 | s->control_register &= ~HDSPM_LatencyMask; | 1347 | s->control_register &= ~HDSPM_LatencyMask; |
| 1313 | s->control_register |= hdspm_encode_latency(n); | 1348 | s->control_register |= hdspm_encode_latency(n); |
| 1314 | 1349 | ||
| @@ -4801,8 +4836,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry, | |||
| 4801 | 4836 | ||
| 4802 | snd_iprintf(buffer, "--- Settings ---\n"); | 4837 | snd_iprintf(buffer, "--- Settings ---\n"); |
| 4803 | 4838 | ||
| 4804 | x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & | 4839 | x = hdspm_get_latency(hdspm); |
| 4805 | HDSPM_LatencyMask)); | ||
| 4806 | 4840 | ||
| 4807 | snd_iprintf(buffer, | 4841 | snd_iprintf(buffer, |
| 4808 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", | 4842 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", |
| @@ -4965,8 +4999,7 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, | |||
| 4965 | 4999 | ||
| 4966 | snd_iprintf(buffer, "--- Settings ---\n"); | 5000 | snd_iprintf(buffer, "--- Settings ---\n"); |
| 4967 | 5001 | ||
| 4968 | x = 1 << (6 + hdspm_decode_latency(hdspm->control_register & | 5002 | x = hdspm_get_latency(hdspm); |
| 4969 | HDSPM_LatencyMask)); | ||
| 4970 | 5003 | ||
| 4971 | snd_iprintf(buffer, | 5004 | snd_iprintf(buffer, |
| 4972 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", | 5005 | "Size (Latency): %d samples (2 periods of %lu bytes)\n", |
| @@ -5672,19 +5705,6 @@ static int snd_hdspm_prepare(struct snd_pcm_substream *substream) | |||
| 5672 | return 0; | 5705 | return 0; |
| 5673 | } | 5706 | } |
| 5674 | 5707 | ||
| 5675 | static unsigned int period_sizes_old[] = { | ||
| 5676 | 64, 128, 256, 512, 1024, 2048, 4096 | ||
| 5677 | }; | ||
| 5678 | |||
| 5679 | static unsigned int period_sizes_new[] = { | ||
| 5680 | 32, 64, 128, 256, 512, 1024, 2048, 4096 | ||
| 5681 | }; | ||
| 5682 | |||
| 5683 | /* RayDAT and AIO always have a buffer of 16384 samples per channel */ | ||
| 5684 | static unsigned int raydat_aio_buffer_sizes[] = { | ||
| 5685 | 16384 | ||
| 5686 | }; | ||
| 5687 | |||
| 5688 | static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { | 5708 | static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { |
| 5689 | .info = (SNDRV_PCM_INFO_MMAP | | 5709 | .info = (SNDRV_PCM_INFO_MMAP | |
| 5690 | SNDRV_PCM_INFO_MMAP_VALID | | 5710 | SNDRV_PCM_INFO_MMAP_VALID | |
| @@ -5703,8 +5723,8 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = { | |||
| 5703 | .channels_max = HDSPM_MAX_CHANNELS, | 5723 | .channels_max = HDSPM_MAX_CHANNELS, |
| 5704 | .buffer_bytes_max = | 5724 | .buffer_bytes_max = |
| 5705 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, | 5725 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, |
| 5706 | .period_bytes_min = (64 * 4), | 5726 | .period_bytes_min = (32 * 4), |
| 5707 | .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS, | 5727 | .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, |
| 5708 | .periods_min = 2, | 5728 | .periods_min = 2, |
| 5709 | .periods_max = 512, | 5729 | .periods_max = 512, |
| 5710 | .fifo_size = 0 | 5730 | .fifo_size = 0 |
| @@ -5728,31 +5748,13 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = { | |||
| 5728 | .channels_max = HDSPM_MAX_CHANNELS, | 5748 | .channels_max = HDSPM_MAX_CHANNELS, |
| 5729 | .buffer_bytes_max = | 5749 | .buffer_bytes_max = |
| 5730 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, | 5750 | HDSPM_CHANNEL_BUFFER_BYTES * HDSPM_MAX_CHANNELS, |
| 5731 | .period_bytes_min = (64 * 4), | 5751 | .period_bytes_min = (32 * 4), |
| 5732 | .period_bytes_max = (4096 * 4) * HDSPM_MAX_CHANNELS, | 5752 | .period_bytes_max = (8192 * 4) * HDSPM_MAX_CHANNELS, |
| 5733 | .periods_min = 2, | 5753 | .periods_min = 2, |
| 5734 | .periods_max = 512, | 5754 | .periods_max = 512, |
| 5735 | .fifo_size = 0 | 5755 | .fifo_size = 0 |
| 5736 | }; | 5756 | }; |
| 5737 | 5757 | ||
| 5738 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_old = { | ||
| 5739 | .count = ARRAY_SIZE(period_sizes_old), | ||
| 5740 | .list = period_sizes_old, | ||
| 5741 | .mask = 0 | ||
| 5742 | }; | ||
| 5743 | |||
| 5744 | static struct snd_pcm_hw_constraint_list hw_constraints_period_sizes_new = { | ||
| 5745 | .count = ARRAY_SIZE(period_sizes_new), | ||
| 5746 | .list = period_sizes_new, | ||
| 5747 | .mask = 0 | ||
| 5748 | }; | ||
| 5749 | |||
| 5750 | static struct snd_pcm_hw_constraint_list hw_constraints_raydat_io_buffer = { | ||
| 5751 | .count = ARRAY_SIZE(raydat_aio_buffer_sizes), | ||
| 5752 | .list = raydat_aio_buffer_sizes, | ||
| 5753 | .mask = 0 | ||
| 5754 | }; | ||
| 5755 | |||
| 5756 | static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params, | 5758 | static int snd_hdspm_hw_rule_in_channels_rate(struct snd_pcm_hw_params *params, |
| 5757 | struct snd_pcm_hw_rule *rule) | 5759 | struct snd_pcm_hw_rule *rule) |
| 5758 | { | 5760 | { |
| @@ -5953,26 +5955,29 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) | |||
| 5953 | spin_unlock_irq(&hdspm->lock); | 5955 | spin_unlock_irq(&hdspm->lock); |
| 5954 | 5956 | ||
| 5955 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 5957 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
| 5958 | snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | ||
| 5956 | 5959 | ||
| 5957 | switch (hdspm->io_type) { | 5960 | switch (hdspm->io_type) { |
| 5958 | case AIO: | 5961 | case AIO: |
| 5959 | case RayDAT: | 5962 | case RayDAT: |
| 5960 | snd_pcm_hw_constraint_list(runtime, 0, | 5963 | snd_pcm_hw_constraint_minmax(runtime, |
| 5961 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 5964 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
| 5962 | &hw_constraints_period_sizes_new); | 5965 | 32, 4096); |
| 5963 | snd_pcm_hw_constraint_list(runtime, 0, | 5966 | /* RayDAT & AIO have a fixed buffer of 16384 samples per channel */ |
| 5964 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | 5967 | snd_pcm_hw_constraint_minmax(runtime, |
| 5965 | &hw_constraints_raydat_io_buffer); | 5968 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, |
| 5966 | 5969 | 16384, 16384); | |
| 5967 | break; | 5970 | break; |
| 5968 | 5971 | ||
| 5969 | default: | 5972 | default: |
| 5970 | snd_pcm_hw_constraint_list(runtime, 0, | 5973 | snd_pcm_hw_constraint_minmax(runtime, |
| 5971 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 5974 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
| 5972 | &hw_constraints_period_sizes_old); | 5975 | 64, 8192); |
| 5976 | break; | ||
| 5973 | } | 5977 | } |
| 5974 | 5978 | ||
| 5975 | if (AES32 == hdspm->io_type) { | 5979 | if (AES32 == hdspm->io_type) { |
| 5980 | runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; | ||
| 5976 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 5981 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
| 5977 | &hdspm_hw_constraints_aes32_sample_rates); | 5982 | &hdspm_hw_constraints_aes32_sample_rates); |
| 5978 | } else { | 5983 | } else { |
| @@ -6025,24 +6030,28 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) | |||
| 6025 | spin_unlock_irq(&hdspm->lock); | 6030 | spin_unlock_irq(&hdspm->lock); |
| 6026 | 6031 | ||
| 6027 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); | 6032 | snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24); |
| 6033 | snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); | ||
| 6034 | |||
| 6028 | switch (hdspm->io_type) { | 6035 | switch (hdspm->io_type) { |
| 6029 | case AIO: | 6036 | case AIO: |
| 6030 | case RayDAT: | 6037 | case RayDAT: |
| 6031 | snd_pcm_hw_constraint_list(runtime, 0, | 6038 | snd_pcm_hw_constraint_minmax(runtime, |
| 6032 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 6039 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
| 6033 | &hw_constraints_period_sizes_new); | 6040 | 32, 4096); |
| 6034 | snd_pcm_hw_constraint_list(runtime, 0, | 6041 | snd_pcm_hw_constraint_minmax(runtime, |
| 6035 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | 6042 | SNDRV_PCM_HW_PARAM_BUFFER_SIZE, |
| 6036 | &hw_constraints_raydat_io_buffer); | 6043 | 16384, 16384); |
| 6037 | break; | 6044 | break; |
| 6038 | 6045 | ||
| 6039 | default: | 6046 | default: |
| 6040 | snd_pcm_hw_constraint_list(runtime, 0, | 6047 | snd_pcm_hw_constraint_minmax(runtime, |
| 6041 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | 6048 | SNDRV_PCM_HW_PARAM_PERIOD_SIZE, |
| 6042 | &hw_constraints_period_sizes_old); | 6049 | 64, 8192); |
| 6050 | break; | ||
| 6043 | } | 6051 | } |
| 6044 | 6052 | ||
| 6045 | if (AES32 == hdspm->io_type) { | 6053 | if (AES32 == hdspm->io_type) { |
| 6054 | runtime->hw.rates |= SNDRV_PCM_RATE_KNOT; | ||
| 6046 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, | 6055 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, |
| 6047 | &hdspm_hw_constraints_aes32_sample_rates); | 6056 | &hdspm_hw_constraints_aes32_sample_rates); |
| 6048 | } else { | 6057 | } else { |
| @@ -6088,7 +6097,7 @@ static inline int copy_u32_le(void __user *dest, void __iomem *src) | |||
| 6088 | } | 6097 | } |
| 6089 | 6098 | ||
| 6090 | static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | 6099 | static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, |
| 6091 | unsigned int cmd, unsigned long __user arg) | 6100 | unsigned int cmd, unsigned long arg) |
| 6092 | { | 6101 | { |
| 6093 | void __user *argp = (void __user *)arg; | 6102 | void __user *argp = (void __user *)arg; |
| 6094 | struct hdspm *hdspm = hw->private_data; | 6103 | struct hdspm *hdspm = hw->private_data; |
| @@ -6213,11 +6222,13 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | |||
| 6213 | info.line_out = hdspm_line_out(hdspm); | 6222 | info.line_out = hdspm_line_out(hdspm); |
| 6214 | info.passthru = 0; | 6223 | info.passthru = 0; |
| 6215 | spin_unlock_irq(&hdspm->lock); | 6224 | spin_unlock_irq(&hdspm->lock); |
| 6216 | if (copy_to_user((void __user *) arg, &info, sizeof(info))) | 6225 | if (copy_to_user(argp, &info, sizeof(info))) |
| 6217 | return -EFAULT; | 6226 | return -EFAULT; |
| 6218 | break; | 6227 | break; |
| 6219 | 6228 | ||
| 6220 | case SNDRV_HDSPM_IOCTL_GET_STATUS: | 6229 | case SNDRV_HDSPM_IOCTL_GET_STATUS: |
| 6230 | memset(&status, 0, sizeof(status)); | ||
| 6231 | |||
| 6221 | status.card_type = hdspm->io_type; | 6232 | status.card_type = hdspm->io_type; |
| 6222 | 6233 | ||
| 6223 | status.autosync_source = hdspm_autosync_ref(hdspm); | 6234 | status.autosync_source = hdspm_autosync_ref(hdspm); |
| @@ -6250,13 +6261,15 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | |||
| 6250 | break; | 6261 | break; |
| 6251 | } | 6262 | } |
| 6252 | 6263 | ||
| 6253 | if (copy_to_user((void __user *) arg, &status, sizeof(status))) | 6264 | if (copy_to_user(argp, &status, sizeof(status))) |
| 6254 | return -EFAULT; | 6265 | return -EFAULT; |
| 6255 | 6266 | ||
| 6256 | 6267 | ||
| 6257 | break; | 6268 | break; |
| 6258 | 6269 | ||
| 6259 | case SNDRV_HDSPM_IOCTL_GET_VERSION: | 6270 | case SNDRV_HDSPM_IOCTL_GET_VERSION: |
| 6271 | memset(&hdspm_version, 0, sizeof(hdspm_version)); | ||
| 6272 | |||
| 6260 | hdspm_version.card_type = hdspm->io_type; | 6273 | hdspm_version.card_type = hdspm->io_type; |
| 6261 | strncpy(hdspm_version.cardname, hdspm->card_name, | 6274 | strncpy(hdspm_version.cardname, hdspm->card_name, |
| 6262 | sizeof(hdspm_version.cardname)); | 6275 | sizeof(hdspm_version.cardname)); |
| @@ -6267,13 +6280,13 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, | |||
| 6267 | if (hdspm->tco) | 6280 | if (hdspm->tco) |
| 6268 | hdspm_version.addons |= HDSPM_ADDON_TCO; | 6281 | hdspm_version.addons |= HDSPM_ADDON_TCO; |
| 6269 | 6282 | ||
| 6270 | if (copy_to_user((void __user *) arg, &hdspm_version, | 6283 | if (copy_to_user(argp, &hdspm_version, |
| 6271 | sizeof(hdspm_version))) | 6284 | sizeof(hdspm_version))) |
| 6272 | return -EFAULT; | 6285 | return -EFAULT; |
| 6273 | break; | 6286 | break; |
| 6274 | 6287 | ||
| 6275 | case SNDRV_HDSPM_IOCTL_GET_MIXER: | 6288 | case SNDRV_HDSPM_IOCTL_GET_MIXER: |
| 6276 | if (copy_from_user(&mixer, (void __user *)arg, sizeof(mixer))) | 6289 | if (copy_from_user(&mixer, argp, sizeof(mixer))) |
| 6277 | return -EFAULT; | 6290 | return -EFAULT; |
| 6278 | if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, | 6291 | if (copy_to_user((void __user *)mixer.mixer, hdspm->mixer, |
| 6279 | sizeof(struct hdspm_mixer))) | 6292 | sizeof(struct hdspm_mixer))) |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index bcf61524a13f..5ffb20b18786 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
| @@ -1234,7 +1234,7 @@ static int sis_resume(struct pci_dev *pci) | |||
| 1234 | goto error; | 1234 | goto error; |
| 1235 | } | 1235 | } |
| 1236 | 1236 | ||
| 1237 | if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED, | 1237 | if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, |
| 1238 | KBUILD_MODNAME, sis)) { | 1238 | KBUILD_MODNAME, sis)) { |
| 1239 | printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq); | 1239 | printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq); |
| 1240 | goto error; | 1240 | goto error; |
| @@ -1340,7 +1340,7 @@ static int __devinit sis_chip_create(struct snd_card *card, | |||
| 1340 | if (rc) | 1340 | if (rc) |
| 1341 | goto error_out_cleanup; | 1341 | goto error_out_cleanup; |
| 1342 | 1342 | ||
| 1343 | if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED, | 1343 | if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, |
| 1344 | KBUILD_MODNAME, sis)) { | 1344 | KBUILD_MODNAME, sis)) { |
| 1345 | printk(KERN_ERR "unable to allocate irq %d\n", sis->irq); | 1345 | printk(KERN_ERR "unable to allocate irq %d\n", sis->irq); |
| 1346 | goto error_out_cleanup; | 1346 | goto error_out_cleanup; |
diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 2571a67b389a..c5008166cf1f 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c | |||
| @@ -1493,9 +1493,10 @@ static int __devinit snd_sonic_probe(struct pci_dev *pci, | |||
| 1493 | return err; | 1493 | return err; |
| 1494 | } | 1494 | } |
| 1495 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, | 1495 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_SONICVIBES, |
| 1496 | sonic->midi_port, MPU401_INFO_INTEGRATED, | 1496 | sonic->midi_port, |
| 1497 | sonic->irq, 0, | 1497 | MPU401_INFO_INTEGRATED | |
| 1498 | &midi_uart)) < 0) { | 1498 | MPU401_INFO_IRQ_HOOK, |
| 1499 | -1, &midi_uart)) < 0) { | ||
| 1499 | snd_card_free(card); | 1500 | snd_card_free(card); |
| 1500 | return err; | 1501 | return err; |
| 1501 | } | 1502 | } |
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c index d8a128f6fc02..5e707effdc7c 100644 --- a/sound/pci/trident/trident.c +++ b/sound/pci/trident/trident.c | |||
| @@ -148,8 +148,9 @@ static int __devinit snd_trident_probe(struct pci_dev *pci, | |||
| 148 | if (trident->device != TRIDENT_DEVICE_ID_SI7018 && | 148 | if (trident->device != TRIDENT_DEVICE_ID_SI7018 && |
| 149 | (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, | 149 | (err = snd_mpu401_uart_new(card, 0, MPU401_HW_TRID4DWAVE, |
| 150 | trident->midi_port, | 150 | trident->midi_port, |
| 151 | MPU401_INFO_INTEGRATED, | 151 | MPU401_INFO_INTEGRATED | |
| 152 | trident->irq, 0, &trident->rmidi)) < 0) { | 152 | MPU401_INFO_IRQ_HOOK, |
| 153 | -1, &trident->rmidi)) < 0) { | ||
| 153 | snd_card_free(card); | 154 | snd_card_free(card); |
| 154 | return err; | 155 | return err; |
| 155 | } | 156 | } |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index f03fd620a2a0..c3656fffdb50 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
| @@ -1175,6 +1175,7 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev, | |||
| 1175 | struct snd_pcm_runtime *runtime = substream->runtime; | 1175 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1176 | int err; | 1176 | int err; |
| 1177 | struct via_rate_lock *ratep; | 1177 | struct via_rate_lock *ratep; |
| 1178 | bool use_src = false; | ||
| 1178 | 1179 | ||
| 1179 | runtime->hw = snd_via82xx_hw; | 1180 | runtime->hw = snd_via82xx_hw; |
| 1180 | 1181 | ||
| @@ -1196,6 +1197,7 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev, | |||
| 1196 | SNDRV_PCM_RATE_8000_48000); | 1197 | SNDRV_PCM_RATE_8000_48000); |
| 1197 | runtime->hw.rate_min = 8000; | 1198 | runtime->hw.rate_min = 8000; |
| 1198 | runtime->hw.rate_max = 48000; | 1199 | runtime->hw.rate_max = 48000; |
| 1200 | use_src = true; | ||
| 1199 | } else if (! ratep->rate) { | 1201 | } else if (! ratep->rate) { |
| 1200 | int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; | 1202 | int idx = viadev->direction ? AC97_RATES_ADC : AC97_RATES_FRONT_DAC; |
| 1201 | runtime->hw.rates = chip->ac97->rates[idx]; | 1203 | runtime->hw.rates = chip->ac97->rates[idx]; |
| @@ -1212,6 +1214,12 @@ static int snd_via82xx_pcm_open(struct via82xx *chip, struct viadev *viadev, | |||
| 1212 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | 1214 | if ((err = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS)) < 0) |
| 1213 | return err; | 1215 | return err; |
| 1214 | 1216 | ||
| 1217 | if (use_src) { | ||
| 1218 | err = snd_pcm_hw_rule_noresample(runtime, 48000); | ||
| 1219 | if (err < 0) | ||
| 1220 | return err; | ||
| 1221 | } | ||
| 1222 | |||
| 1215 | runtime->private_data = viadev; | 1223 | runtime->private_data = viadev; |
| 1216 | viadev->substream = substream; | 1224 | viadev->substream = substream; |
| 1217 | 1225 | ||
| @@ -2068,8 +2076,9 @@ static int __devinit snd_via686_init_misc(struct via82xx *chip) | |||
| 2068 | pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); | 2076 | pci_write_config_byte(chip->pci, VIA_PNP_CONTROL, legacy_cfg); |
| 2069 | if (chip->mpu_res) { | 2077 | if (chip->mpu_res) { |
| 2070 | if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, | 2078 | if (snd_mpu401_uart_new(chip->card, 0, MPU401_HW_VIA686A, |
| 2071 | mpu_port, MPU401_INFO_INTEGRATED, | 2079 | mpu_port, MPU401_INFO_INTEGRATED | |
| 2072 | chip->irq, 0, &chip->rmidi) < 0) { | 2080 | MPU401_INFO_IRQ_HOOK, -1, |
| 2081 | &chip->rmidi) < 0) { | ||
| 2073 | printk(KERN_WARNING "unable to initialize MPU-401" | 2082 | printk(KERN_WARNING "unable to initialize MPU-401" |
| 2074 | " at 0x%lx, skipping\n", mpu_port); | 2083 | " at 0x%lx, skipping\n", mpu_port); |
| 2075 | legacy &= ~VIA_FUNC_ENABLE_MIDI; | 2084 | legacy &= ~VIA_FUNC_ENABLE_MIDI; |
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c index 511d57653124..3253b04da184 100644 --- a/sound/pci/ymfpci/ymfpci.c +++ b/sound/pci/ymfpci/ymfpci.c | |||
| @@ -305,8 +305,9 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, | |||
| 305 | if (chip->mpu_res) { | 305 | if (chip->mpu_res) { |
| 306 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, | 306 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_YMFPCI, |
| 307 | mpu_port[dev], | 307 | mpu_port[dev], |
| 308 | MPU401_INFO_INTEGRATED, | 308 | MPU401_INFO_INTEGRATED | |
| 309 | pci->irq, 0, &chip->rawmidi)) < 0) { | 309 | MPU401_INFO_IRQ_HOOK, |
| 310 | -1, &chip->rawmidi)) < 0) { | ||
| 310 | printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); | 311 | printk(KERN_WARNING "ymfpci: cannot initialize MPU401 at 0x%lx, skipping...\n", mpu_port[dev]); |
| 311 | legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */ | 312 | legacy_ctrl &= ~YMFPCI_LEGACY_MIEN; /* disable MPU401 irq */ |
| 312 | pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); | 313 | pci_write_config_word(pci, PCIR_DSXG_LEGACY, legacy_ctrl); |
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index f3260e658b8a..66ea71b2a70d 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c | |||
| @@ -897,6 +897,18 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream) | |||
| 897 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); | 897 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); |
| 898 | struct snd_pcm_runtime *runtime = substream->runtime; | 898 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 899 | struct snd_ymfpci_pcm *ypcm; | 899 | struct snd_ymfpci_pcm *ypcm; |
| 900 | int err; | ||
| 901 | |||
| 902 | runtime->hw = snd_ymfpci_playback; | ||
| 903 | /* FIXME? True value is 256/48 = 5.33333 ms */ | ||
| 904 | err = snd_pcm_hw_constraint_minmax(runtime, | ||
| 905 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
| 906 | 5334, UINT_MAX); | ||
| 907 | if (err < 0) | ||
| 908 | return err; | ||
| 909 | err = snd_pcm_hw_rule_noresample(runtime, 48000); | ||
| 910 | if (err < 0) | ||
| 911 | return err; | ||
| 900 | 912 | ||
| 901 | ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); | 913 | ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); |
| 902 | if (ypcm == NULL) | 914 | if (ypcm == NULL) |
| @@ -904,11 +916,8 @@ static int snd_ymfpci_playback_open_1(struct snd_pcm_substream *substream) | |||
| 904 | ypcm->chip = chip; | 916 | ypcm->chip = chip; |
| 905 | ypcm->type = PLAYBACK_VOICE; | 917 | ypcm->type = PLAYBACK_VOICE; |
| 906 | ypcm->substream = substream; | 918 | ypcm->substream = substream; |
| 907 | runtime->hw = snd_ymfpci_playback; | ||
| 908 | runtime->private_data = ypcm; | 919 | runtime->private_data = ypcm; |
| 909 | runtime->private_free = snd_ymfpci_pcm_free_substream; | 920 | runtime->private_free = snd_ymfpci_pcm_free_substream; |
| 910 | /* FIXME? True value is 256/48 = 5.33333 ms */ | ||
| 911 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX); | ||
| 912 | return 0; | 921 | return 0; |
| 913 | } | 922 | } |
| 914 | 923 | ||
| @@ -1013,6 +1022,18 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream, | |||
| 1013 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); | 1022 | struct snd_ymfpci *chip = snd_pcm_substream_chip(substream); |
| 1014 | struct snd_pcm_runtime *runtime = substream->runtime; | 1023 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 1015 | struct snd_ymfpci_pcm *ypcm; | 1024 | struct snd_ymfpci_pcm *ypcm; |
| 1025 | int err; | ||
| 1026 | |||
| 1027 | runtime->hw = snd_ymfpci_capture; | ||
| 1028 | /* FIXME? True value is 256/48 = 5.33333 ms */ | ||
| 1029 | err = snd_pcm_hw_constraint_minmax(runtime, | ||
| 1030 | SNDRV_PCM_HW_PARAM_PERIOD_TIME, | ||
| 1031 | 5334, UINT_MAX); | ||
| 1032 | if (err < 0) | ||
| 1033 | return err; | ||
| 1034 | err = snd_pcm_hw_rule_noresample(runtime, 48000); | ||
| 1035 | if (err < 0) | ||
| 1036 | return err; | ||
| 1016 | 1037 | ||
| 1017 | ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); | 1038 | ypcm = kzalloc(sizeof(*ypcm), GFP_KERNEL); |
| 1018 | if (ypcm == NULL) | 1039 | if (ypcm == NULL) |
| @@ -1022,9 +1043,6 @@ static int snd_ymfpci_capture_open(struct snd_pcm_substream *substream, | |||
| 1022 | ypcm->substream = substream; | 1043 | ypcm->substream = substream; |
| 1023 | ypcm->capture_bank_number = capture_bank_number; | 1044 | ypcm->capture_bank_number = capture_bank_number; |
| 1024 | chip->capture_substream[capture_bank_number] = substream; | 1045 | chip->capture_substream[capture_bank_number] = substream; |
| 1025 | runtime->hw = snd_ymfpci_capture; | ||
| 1026 | /* FIXME? True value is 256/48 = 5.33333 ms */ | ||
| 1027 | snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 5333, UINT_MAX); | ||
| 1028 | runtime->private_data = ypcm; | 1046 | runtime->private_data = ypcm; |
| 1029 | runtime->private_free = snd_ymfpci_pcm_free_substream; | 1047 | runtime->private_free = snd_ymfpci_pcm_free_substream; |
| 1030 | snd_ymfpci_hw_start(chip); | 1048 | snd_ymfpci_hw_start(chip); |
| @@ -1615,7 +1633,7 @@ YMFPCI_DOUBLE("ADC Playback Volume", 0, YDSXGR_PRIADCOUTVOL), | |||
| 1615 | YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL), | 1633 | YMFPCI_DOUBLE("ADC Capture Volume", 0, YDSXGR_PRIADCLOOPVOL), |
| 1616 | YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL), | 1634 | YMFPCI_DOUBLE("ADC Playback Volume", 1, YDSXGR_SECADCOUTVOL), |
| 1617 | YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL), | 1635 | YMFPCI_DOUBLE("ADC Capture Volume", 1, YDSXGR_SECADCLOOPVOL), |
| 1618 | YMFPCI_DOUBLE("FM Legacy Volume", 0, YDSXGR_LEGACYOUTVOL), | 1636 | YMFPCI_DOUBLE("FM Legacy Playback Volume", 0, YDSXGR_LEGACYOUTVOL), |
| 1619 | YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL), | 1637 | YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ", PLAYBACK,VOLUME), 0, YDSXGR_ZVOUTVOL), |
| 1620 | YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL), | 1638 | YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("", CAPTURE,VOLUME), 0, YDSXGR_ZVLOOPVOL), |
| 1621 | YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL), | 1639 | YMFPCI_DOUBLE(SNDRV_CTL_NAME_IEC958("AC97 ",PLAYBACK,VOLUME), 1, YDSXGR_SPDIFOUTVOL), |
diff --git a/sound/ppc/keywest.c b/sound/ppc/keywest.c index 8f064c7ce745..4080becf4cef 100644 --- a/sound/ppc/keywest.c +++ b/sound/ppc/keywest.c | |||
| @@ -82,7 +82,6 @@ static int keywest_attach_adapter(struct i2c_adapter *adapter) | |||
| 82 | 82 | ||
| 83 | static int keywest_remove(struct i2c_client *client) | 83 | static int keywest_remove(struct i2c_client *client) |
| 84 | { | 84 | { |
| 85 | i2c_set_clientdata(client, NULL); | ||
| 86 | if (! keywest_ctx) | 85 | if (! keywest_ctx) |
| 87 | return 0; | 86 | return 0; |
| 88 | if (client == keywest_ctx->client) | 87 | if (client == keywest_ctx->client) |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index bc823a547550..775bd95d4be6 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
| @@ -845,7 +845,7 @@ static int __devinit snd_ps3_allocate_irq(void) | |||
| 845 | return ret; | 845 | return ret; |
| 846 | } | 846 | } |
| 847 | 847 | ||
| 848 | ret = request_irq(the_card.irq_no, snd_ps3_interrupt, IRQF_DISABLED, | 848 | ret = request_irq(the_card.irq_no, snd_ps3_interrupt, 0, |
| 849 | SND_PS3_DRIVER_NAME, &the_card); | 849 | SND_PS3_DRIVER_NAME, &the_card); |
| 850 | if (ret) { | 850 | if (ret) { |
| 851 | pr_info("%s: request_irq failed (%d)\n", __func__, ret); | 851 | pr_info("%s: request_irq failed (%d)\n", __func__, ret); |
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 8224db5f0434..1381db853ef0 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig | |||
| @@ -7,6 +7,8 @@ menuconfig SND_SOC | |||
| 7 | select SND_PCM | 7 | select SND_PCM |
| 8 | select AC97_BUS if SND_SOC_AC97_BUS | 8 | select AC97_BUS if SND_SOC_AC97_BUS |
| 9 | select SND_JACK if INPUT=y || INPUT=SND | 9 | select SND_JACK if INPUT=y || INPUT=SND |
| 10 | select REGMAP_I2C if I2C | ||
| 11 | select REGMAP_SPI if SPI_MASTER | ||
| 10 | ---help--- | 12 | ---help--- |
| 11 | 13 | ||
| 12 | If you want ASoC support, you should say Y here and also to the | 14 | If you want ASoC support, you should say Y here and also to the |
| @@ -51,6 +53,7 @@ source "sound/soc/nuc900/Kconfig" | |||
| 51 | source "sound/soc/omap/Kconfig" | 53 | source "sound/soc/omap/Kconfig" |
| 52 | source "sound/soc/kirkwood/Kconfig" | 54 | source "sound/soc/kirkwood/Kconfig" |
| 53 | source "sound/soc/mid-x86/Kconfig" | 55 | source "sound/soc/mid-x86/Kconfig" |
| 56 | source "sound/soc/mxs/Kconfig" | ||
| 54 | source "sound/soc/pxa/Kconfig" | 57 | source "sound/soc/pxa/Kconfig" |
| 55 | source "sound/soc/samsung/Kconfig" | 58 | source "sound/soc/samsung/Kconfig" |
| 56 | source "sound/soc/s6000/Kconfig" | 59 | source "sound/soc/s6000/Kconfig" |
diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 4f913876f332..9ea8ac827adc 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile | |||
| @@ -12,6 +12,7 @@ obj-$(CONFIG_SND_SOC) += fsl/ | |||
| 12 | obj-$(CONFIG_SND_SOC) += imx/ | 12 | obj-$(CONFIG_SND_SOC) += imx/ |
| 13 | obj-$(CONFIG_SND_SOC) += jz4740/ | 13 | obj-$(CONFIG_SND_SOC) += jz4740/ |
| 14 | obj-$(CONFIG_SND_SOC) += mid-x86/ | 14 | obj-$(CONFIG_SND_SOC) += mid-x86/ |
| 15 | obj-$(CONFIG_SND_SOC) += mxs/ | ||
| 15 | obj-$(CONFIG_SND_SOC) += nuc900/ | 16 | obj-$(CONFIG_SND_SOC) += nuc900/ |
| 16 | obj-$(CONFIG_SND_SOC) += omap/ | 17 | obj-$(CONFIG_SND_SOC) += omap/ |
| 17 | obj-$(CONFIG_SND_SOC) += kirkwood/ | 18 | obj-$(CONFIG_SND_SOC) += kirkwood/ |
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c index 1aac2f4dbcf6..73ae99ad4578 100644 --- a/sound/soc/atmel/playpaq_wm8510.c +++ b/sound/soc/atmel/playpaq_wm8510.c | |||
| @@ -338,7 +338,6 @@ static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) | |||
| 338 | /* always connected pins */ | 338 | /* always connected pins */ |
| 339 | snd_soc_dapm_enable_pin(dapm, "Int Mic"); | 339 | snd_soc_dapm_enable_pin(dapm, "Int Mic"); |
| 340 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 340 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); |
| 341 | snd_soc_dapm_sync(dapm); | ||
| 342 | 341 | ||
| 343 | 342 | ||
| 344 | 343 | ||
| @@ -383,14 +382,17 @@ static int __init playpaq_asoc_init(void) | |||
| 383 | _gclk0 = clk_get(NULL, "gclk0"); | 382 | _gclk0 = clk_get(NULL, "gclk0"); |
| 384 | if (IS_ERR(_gclk0)) { | 383 | if (IS_ERR(_gclk0)) { |
| 385 | _gclk0 = NULL; | 384 | _gclk0 = NULL; |
| 385 | ret = PTR_ERR(_gclk0); | ||
| 386 | goto err_gclk0; | 386 | goto err_gclk0; |
| 387 | } | 387 | } |
| 388 | _pll0 = clk_get(NULL, "pll0"); | 388 | _pll0 = clk_get(NULL, "pll0"); |
| 389 | if (IS_ERR(_pll0)) { | 389 | if (IS_ERR(_pll0)) { |
| 390 | _pll0 = NULL; | 390 | _pll0 = NULL; |
| 391 | ret = PTR_ERR(_pll0); | ||
| 391 | goto err_pll0; | 392 | goto err_pll0; |
| 392 | } | 393 | } |
| 393 | if (clk_set_parent(_gclk0, _pll0)) { | 394 | ret = clk_set_parent(_gclk0, _pll0); |
| 395 | if (ret) { | ||
| 394 | pr_warning("snd-soc-playpaq: " | 396 | pr_warning("snd-soc-playpaq: " |
| 395 | "Failed to set PLL0 as parent for DAC clock\n"); | 397 | "Failed to set PLL0 as parent for DAC clock\n"); |
| 396 | goto err_set_clk; | 398 | goto err_set_clk; |
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index bad3aa14d5b3..0377c5451aed 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c | |||
| @@ -173,8 +173,6 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
| 173 | /* always connected */ | 173 | /* always connected */ |
| 174 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 174 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); |
| 175 | 175 | ||
| 176 | snd_soc_dapm_sync(dapm); | ||
| 177 | |||
| 178 | return 0; | 176 | return 0; |
| 179 | } | 177 | } |
| 180 | 178 | ||
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index 5e4d499d8434..d427e9217ce4 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c | |||
| @@ -117,8 +117,6 @@ static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | |||
| 117 | snd_soc_dapm_enable_pin(dapm, "Line In"); | 117 | snd_soc_dapm_enable_pin(dapm, "Line In"); |
| 118 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 118 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 119 | 119 | ||
| 120 | snd_soc_dapm_sync(dapm); | ||
| 121 | |||
| 122 | return 0; | 120 | return 0; |
| 123 | } | 121 | } |
| 124 | 122 | ||
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig index 4b67140fdec3..6d592546e8fc 100644 --- a/sound/soc/au1x/Kconfig +++ b/sound/soc/au1x/Kconfig | |||
| @@ -18,10 +18,38 @@ config SND_SOC_AU1XPSC_AC97 | |||
| 18 | select SND_AC97_CODEC | 18 | select SND_AC97_CODEC |
| 19 | select SND_SOC_AC97_BUS | 19 | select SND_SOC_AC97_BUS |
| 20 | 20 | ||
| 21 | ## | ||
| 22 | ## Au1000/1500/1100 DMA + AC97C/I2SC | ||
| 23 | ## | ||
| 24 | config SND_SOC_AU1XAUDIO | ||
| 25 | tristate "SoC Audio for Au1000/Au1500/Au1100" | ||
| 26 | depends on MIPS_ALCHEMY | ||
| 27 | help | ||
| 28 | This is a driver set for the AC97 unit and the | ||
| 29 | old DMA controller as found on the Au1000/Au1500/Au1100 chips. | ||
| 30 | |||
| 31 | config SND_SOC_AU1XAC97C | ||
| 32 | tristate | ||
| 33 | select AC97_BUS | ||
| 34 | select SND_AC97_CODEC | ||
| 35 | select SND_SOC_AC97_BUS | ||
| 36 | |||
| 37 | config SND_SOC_AU1XI2SC | ||
| 38 | tristate | ||
| 39 | |||
| 21 | 40 | ||
| 22 | ## | 41 | ## |
| 23 | ## Boards | 42 | ## Boards |
| 24 | ## | 43 | ## |
| 44 | config SND_SOC_DB1000 | ||
| 45 | tristate "DB1000 Audio support" | ||
| 46 | depends on SND_SOC_AU1XAUDIO | ||
| 47 | select SND_SOC_AU1XAC97C | ||
| 48 | select SND_SOC_AC97_CODEC | ||
| 49 | help | ||
| 50 | Select this option to enable AC97 audio on the early DB1x00 series | ||
| 51 | of boards (DB1000/DB1500/DB1100). | ||
| 52 | |||
| 25 | config SND_SOC_DB1200 | 53 | config SND_SOC_DB1200 |
| 26 | tristate "DB1200 AC97+I2S audio support" | 54 | tristate "DB1200 AC97+I2S audio support" |
| 27 | depends on SND_SOC_AU1XPSC | 55 | depends on SND_SOC_AU1XPSC |
diff --git a/sound/soc/au1x/Makefile b/sound/soc/au1x/Makefile index 16873076e8c4..920710514ea0 100644 --- a/sound/soc/au1x/Makefile +++ b/sound/soc/au1x/Makefile | |||
| @@ -3,11 +3,21 @@ snd-soc-au1xpsc-dbdma-objs := dbdma2.o | |||
| 3 | snd-soc-au1xpsc-i2s-objs := psc-i2s.o | 3 | snd-soc-au1xpsc-i2s-objs := psc-i2s.o |
| 4 | snd-soc-au1xpsc-ac97-objs := psc-ac97.o | 4 | snd-soc-au1xpsc-ac97-objs := psc-ac97.o |
| 5 | 5 | ||
| 6 | # Au1000/1500/1100 Audio units | ||
| 7 | snd-soc-au1x-dma-objs := dma.o | ||
| 8 | snd-soc-au1x-ac97c-objs := ac97c.o | ||
| 9 | snd-soc-au1x-i2sc-objs := i2sc.o | ||
| 10 | |||
| 6 | obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o | 11 | obj-$(CONFIG_SND_SOC_AU1XPSC) += snd-soc-au1xpsc-dbdma.o |
| 7 | obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o | 12 | obj-$(CONFIG_SND_SOC_AU1XPSC_I2S) += snd-soc-au1xpsc-i2s.o |
| 8 | obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o | 13 | obj-$(CONFIG_SND_SOC_AU1XPSC_AC97) += snd-soc-au1xpsc-ac97.o |
| 14 | obj-$(CONFIG_SND_SOC_AU1XAUDIO) += snd-soc-au1x-dma.o | ||
| 15 | obj-$(CONFIG_SND_SOC_AU1XAC97C) += snd-soc-au1x-ac97c.o | ||
| 16 | obj-$(CONFIG_SND_SOC_AU1XI2SC) += snd-soc-au1x-i2sc.o | ||
| 9 | 17 | ||
| 10 | # Boards | 18 | # Boards |
| 19 | snd-soc-db1000-objs := db1000.o | ||
| 11 | snd-soc-db1200-objs := db1200.o | 20 | snd-soc-db1200-objs := db1200.o |
| 12 | 21 | ||
| 22 | obj-$(CONFIG_SND_SOC_DB1000) += snd-soc-db1000.o | ||
| 13 | obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o | 23 | obj-$(CONFIG_SND_SOC_DB1200) += snd-soc-db1200.o |
diff --git a/sound/soc/au1x/ac97c.c b/sound/soc/au1x/ac97c.c new file mode 100644 index 000000000000..726bd651a105 --- /dev/null +++ b/sound/soc/au1x/ac97c.c | |||
| @@ -0,0 +1,366 @@ | |||
| 1 | /* | ||
| 2 | * Au1000/Au1500/Au1100 AC97C controller driver for ASoC | ||
| 3 | * | ||
| 4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> | ||
| 5 | * | ||
| 6 | * based on the old ALSA driver originally written by | ||
| 7 | * Charles Eidsness <charles@cooper-street.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/init.h> | ||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/slab.h> | ||
| 13 | #include <linux/device.h> | ||
| 14 | #include <linux/delay.h> | ||
| 15 | #include <linux/mutex.h> | ||
| 16 | #include <linux/platform_device.h> | ||
| 17 | #include <linux/suspend.h> | ||
| 18 | #include <sound/core.h> | ||
| 19 | #include <sound/pcm.h> | ||
| 20 | #include <sound/initval.h> | ||
| 21 | #include <sound/soc.h> | ||
| 22 | #include <asm/mach-au1x00/au1000.h> | ||
| 23 | |||
| 24 | #include "psc.h" | ||
| 25 | |||
| 26 | /* register offsets and bits */ | ||
| 27 | #define AC97_CONFIG 0x00 | ||
| 28 | #define AC97_STATUS 0x04 | ||
| 29 | #define AC97_DATA 0x08 | ||
| 30 | #define AC97_CMDRESP 0x0c | ||
| 31 | #define AC97_ENABLE 0x10 | ||
| 32 | |||
| 33 | #define CFG_RC(x) (((x) & 0x3ff) << 13) /* valid rx slots mask */ | ||
| 34 | #define CFG_XS(x) (((x) & 0x3ff) << 3) /* valid tx slots mask */ | ||
| 35 | #define CFG_SG (1 << 2) /* sync gate */ | ||
| 36 | #define CFG_SN (1 << 1) /* sync control */ | ||
| 37 | #define CFG_RS (1 << 0) /* acrst# control */ | ||
| 38 | #define STAT_XU (1 << 11) /* tx underflow */ | ||
| 39 | #define STAT_XO (1 << 10) /* tx overflow */ | ||
| 40 | #define STAT_RU (1 << 9) /* rx underflow */ | ||
| 41 | #define STAT_RO (1 << 8) /* rx overflow */ | ||
| 42 | #define STAT_RD (1 << 7) /* codec ready */ | ||
| 43 | #define STAT_CP (1 << 6) /* command pending */ | ||
| 44 | #define STAT_TE (1 << 4) /* tx fifo empty */ | ||
| 45 | #define STAT_TF (1 << 3) /* tx fifo full */ | ||
| 46 | #define STAT_RE (1 << 1) /* rx fifo empty */ | ||
| 47 | #define STAT_RF (1 << 0) /* rx fifo full */ | ||
| 48 | #define CMD_SET_DATA(x) (((x) & 0xffff) << 16) | ||
| 49 | #define CMD_GET_DATA(x) ((x) & 0xffff) | ||
| 50 | #define CMD_READ (1 << 7) | ||
| 51 | #define CMD_WRITE (0 << 7) | ||
| 52 | #define CMD_IDX(x) ((x) & 0x7f) | ||
| 53 | #define EN_D (1 << 1) /* DISable bit */ | ||
| 54 | #define EN_CE (1 << 0) /* clock enable bit */ | ||
| 55 | |||
| 56 | /* how often to retry failed codec register reads/writes */ | ||
| 57 | #define AC97_RW_RETRIES 5 | ||
| 58 | |||
| 59 | #define AC97_RATES \ | ||
| 60 | SNDRV_PCM_RATE_CONTINUOUS | ||
| 61 | |||
| 62 | #define AC97_FMTS \ | ||
| 63 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE) | ||
| 64 | |||
| 65 | /* instance data. There can be only one, MacLeod!!!!, fortunately there IS only | ||
| 66 | * once AC97C on early Alchemy chips. The newer ones aren't so lucky. | ||
| 67 | */ | ||
| 68 | static struct au1xpsc_audio_data *ac97c_workdata; | ||
| 69 | #define ac97_to_ctx(x) ac97c_workdata | ||
| 70 | |||
| 71 | static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg) | ||
| 72 | { | ||
| 73 | return __raw_readl(ctx->mmio + reg); | ||
| 74 | } | ||
| 75 | |||
| 76 | static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v) | ||
| 77 | { | ||
| 78 | __raw_writel(v, ctx->mmio + reg); | ||
| 79 | wmb(); | ||
| 80 | } | ||
| 81 | |||
| 82 | static unsigned short au1xac97c_ac97_read(struct snd_ac97 *ac97, | ||
| 83 | unsigned short r) | ||
| 84 | { | ||
| 85 | struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97); | ||
| 86 | unsigned int tmo, retry; | ||
| 87 | unsigned long data; | ||
| 88 | |||
| 89 | data = ~0; | ||
| 90 | retry = AC97_RW_RETRIES; | ||
| 91 | do { | ||
| 92 | mutex_lock(&ctx->lock); | ||
| 93 | |||
| 94 | tmo = 5; | ||
| 95 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--) | ||
| 96 | udelay(21); /* wait an ac97 frame time */ | ||
| 97 | if (!tmo) { | ||
| 98 | pr_debug("ac97rd timeout #1\n"); | ||
| 99 | goto next; | ||
| 100 | } | ||
| 101 | |||
| 102 | WR(ctx, AC97_CMDRESP, CMD_IDX(r) | CMD_READ); | ||
| 103 | |||
| 104 | /* stupid errata: data is only valid for 21us, so | ||
| 105 | * poll, Forrest, poll... | ||
| 106 | */ | ||
| 107 | tmo = 0x10000; | ||
| 108 | while ((RD(ctx, AC97_STATUS) & STAT_CP) && tmo--) | ||
| 109 | asm volatile ("nop"); | ||
| 110 | data = RD(ctx, AC97_CMDRESP); | ||
| 111 | |||
| 112 | if (!tmo) | ||
| 113 | pr_debug("ac97rd timeout #2\n"); | ||
| 114 | |||
| 115 | next: | ||
| 116 | mutex_unlock(&ctx->lock); | ||
| 117 | } while (--retry && !tmo); | ||
| 118 | |||
| 119 | pr_debug("AC97RD %04x %04lx %d\n", r, data, retry); | ||
| 120 | |||
| 121 | return retry ? data & 0xffff : 0xffff; | ||
| 122 | } | ||
| 123 | |||
| 124 | static void au1xac97c_ac97_write(struct snd_ac97 *ac97, unsigned short r, | ||
| 125 | unsigned short v) | ||
| 126 | { | ||
| 127 | struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97); | ||
| 128 | unsigned int tmo, retry; | ||
| 129 | |||
| 130 | retry = AC97_RW_RETRIES; | ||
| 131 | do { | ||
| 132 | mutex_lock(&ctx->lock); | ||
| 133 | |||
| 134 | for (tmo = 5; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--) | ||
| 135 | udelay(21); | ||
| 136 | if (!tmo) { | ||
| 137 | pr_debug("ac97wr timeout #1\n"); | ||
| 138 | goto next; | ||
| 139 | } | ||
| 140 | |||
| 141 | WR(ctx, AC97_CMDRESP, CMD_WRITE | CMD_IDX(r) | CMD_SET_DATA(v)); | ||
| 142 | |||
| 143 | for (tmo = 10; (RD(ctx, AC97_STATUS) & STAT_CP) && tmo; tmo--) | ||
| 144 | udelay(21); | ||
| 145 | if (!tmo) | ||
| 146 | pr_debug("ac97wr timeout #2\n"); | ||
| 147 | next: | ||
| 148 | mutex_unlock(&ctx->lock); | ||
| 149 | } while (--retry && !tmo); | ||
| 150 | |||
| 151 | pr_debug("AC97WR %04x %04x %d\n", r, v, retry); | ||
| 152 | } | ||
| 153 | |||
| 154 | static void au1xac97c_ac97_warm_reset(struct snd_ac97 *ac97) | ||
| 155 | { | ||
| 156 | struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97); | ||
| 157 | |||
| 158 | WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG | CFG_SN); | ||
| 159 | msleep(20); | ||
| 160 | WR(ctx, AC97_CONFIG, ctx->cfg | CFG_SG); | ||
| 161 | WR(ctx, AC97_CONFIG, ctx->cfg); | ||
| 162 | } | ||
| 163 | |||
| 164 | static void au1xac97c_ac97_cold_reset(struct snd_ac97 *ac97) | ||
| 165 | { | ||
| 166 | struct au1xpsc_audio_data *ctx = ac97_to_ctx(ac97); | ||
| 167 | int i; | ||
| 168 | |||
| 169 | WR(ctx, AC97_CONFIG, ctx->cfg | CFG_RS); | ||
| 170 | msleep(500); | ||
| 171 | WR(ctx, AC97_CONFIG, ctx->cfg); | ||
| 172 | |||
| 173 | /* wait for codec ready */ | ||
| 174 | i = 50; | ||
| 175 | while (((RD(ctx, AC97_STATUS) & STAT_RD) == 0) && --i) | ||
| 176 | msleep(20); | ||
| 177 | if (!i) | ||
| 178 | printk(KERN_ERR "ac97c: codec not ready after cold reset\n"); | ||
| 179 | } | ||
| 180 | |||
| 181 | /* AC97 controller operations */ | ||
| 182 | struct snd_ac97_bus_ops soc_ac97_ops = { | ||
| 183 | .read = au1xac97c_ac97_read, | ||
| 184 | .write = au1xac97c_ac97_write, | ||
| 185 | .reset = au1xac97c_ac97_cold_reset, | ||
| 186 | .warm_reset = au1xac97c_ac97_warm_reset, | ||
| 187 | }; | ||
| 188 | EXPORT_SYMBOL_GPL(soc_ac97_ops); /* globals be gone! */ | ||
| 189 | |||
| 190 | static int alchemy_ac97c_startup(struct snd_pcm_substream *substream, | ||
| 191 | struct snd_soc_dai *dai) | ||
| 192 | { | ||
| 193 | struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai); | ||
| 194 | snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]); | ||
| 195 | return 0; | ||
| 196 | } | ||
| 197 | |||
| 198 | static struct snd_soc_dai_ops alchemy_ac97c_ops = { | ||
| 199 | .startup = alchemy_ac97c_startup, | ||
| 200 | }; | ||
| 201 | |||
| 202 | static int au1xac97c_dai_probe(struct snd_soc_dai *dai) | ||
| 203 | { | ||
| 204 | return ac97c_workdata ? 0 : -ENODEV; | ||
| 205 | } | ||
| 206 | |||
| 207 | static struct snd_soc_dai_driver au1xac97c_dai_driver = { | ||
| 208 | .name = "alchemy-ac97c", | ||
| 209 | .ac97_control = 1, | ||
| 210 | .probe = au1xac97c_dai_probe, | ||
| 211 | .playback = { | ||
| 212 | .rates = AC97_RATES, | ||
| 213 | .formats = AC97_FMTS, | ||
| 214 | .channels_min = 2, | ||
| 215 | .channels_max = 2, | ||
| 216 | }, | ||
| 217 | .capture = { | ||
| 218 | .rates = AC97_RATES, | ||
| 219 | .formats = AC97_FMTS, | ||
| 220 | .channels_min = 2, | ||
| 221 | .channels_max = 2, | ||
| 222 | }, | ||
| 223 | .ops = &alchemy_ac97c_ops, | ||
| 224 | }; | ||
| 225 | |||
| 226 | static int __devinit au1xac97c_drvprobe(struct platform_device *pdev) | ||
| 227 | { | ||
| 228 | int ret; | ||
| 229 | struct resource *iores, *dmares; | ||
| 230 | struct au1xpsc_audio_data *ctx; | ||
| 231 | |||
| 232 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
| 233 | if (!ctx) | ||
| 234 | return -ENOMEM; | ||
| 235 | |||
| 236 | mutex_init(&ctx->lock); | ||
| 237 | |||
| 238 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 239 | if (!iores) { | ||
| 240 | ret = -ENODEV; | ||
| 241 | goto out0; | ||
| 242 | } | ||
| 243 | |||
| 244 | ret = -EBUSY; | ||
| 245 | if (!request_mem_region(iores->start, resource_size(iores), | ||
| 246 | pdev->name)) | ||
| 247 | goto out0; | ||
| 248 | |||
| 249 | ctx->mmio = ioremap_nocache(iores->start, resource_size(iores)); | ||
| 250 | if (!ctx->mmio) | ||
| 251 | goto out1; | ||
| 252 | |||
| 253 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 254 | if (!dmares) | ||
| 255 | goto out2; | ||
| 256 | ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; | ||
| 257 | |||
| 258 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 259 | if (!dmares) | ||
| 260 | goto out2; | ||
| 261 | ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; | ||
| 262 | |||
| 263 | /* switch it on */ | ||
| 264 | WR(ctx, AC97_ENABLE, EN_D | EN_CE); | ||
| 265 | WR(ctx, AC97_ENABLE, EN_CE); | ||
| 266 | |||
| 267 | ctx->cfg = CFG_RC(3) | CFG_XS(3); | ||
| 268 | WR(ctx, AC97_CONFIG, ctx->cfg); | ||
| 269 | |||
| 270 | platform_set_drvdata(pdev, ctx); | ||
| 271 | |||
| 272 | ret = snd_soc_register_dai(&pdev->dev, &au1xac97c_dai_driver); | ||
| 273 | if (ret) | ||
| 274 | goto out2; | ||
| 275 | |||
| 276 | ac97c_workdata = ctx; | ||
| 277 | return 0; | ||
| 278 | |||
| 279 | out2: | ||
| 280 | iounmap(ctx->mmio); | ||
| 281 | out1: | ||
| 282 | release_mem_region(iores->start, resource_size(iores)); | ||
| 283 | out0: | ||
| 284 | kfree(ctx); | ||
| 285 | return ret; | ||
| 286 | } | ||
| 287 | |||
| 288 | static int __devexit au1xac97c_drvremove(struct platform_device *pdev) | ||
| 289 | { | ||
| 290 | struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); | ||
| 291 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 292 | |||
| 293 | snd_soc_unregister_dai(&pdev->dev); | ||
| 294 | |||
| 295 | WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ | ||
| 296 | |||
| 297 | iounmap(ctx->mmio); | ||
| 298 | release_mem_region(r->start, resource_size(r)); | ||
| 299 | kfree(ctx); | ||
| 300 | |||
| 301 | ac97c_workdata = NULL; /* MDEV */ | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | #ifdef CONFIG_PM | ||
| 307 | static int au1xac97c_drvsuspend(struct device *dev) | ||
| 308 | { | ||
| 309 | struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev); | ||
| 310 | |||
| 311 | WR(ctx, AC97_ENABLE, EN_D); /* clock off, disable */ | ||
| 312 | |||
| 313 | return 0; | ||
| 314 | } | ||
| 315 | |||
| 316 | static int au1xac97c_drvresume(struct device *dev) | ||
| 317 | { | ||
| 318 | struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev); | ||
| 319 | |||
| 320 | WR(ctx, AC97_ENABLE, EN_D | EN_CE); | ||
| 321 | WR(ctx, AC97_ENABLE, EN_CE); | ||
| 322 | WR(ctx, AC97_CONFIG, ctx->cfg); | ||
| 323 | |||
| 324 | return 0; | ||
| 325 | } | ||
| 326 | |||
| 327 | static const struct dev_pm_ops au1xpscac97_pmops = { | ||
| 328 | .suspend = au1xac97c_drvsuspend, | ||
| 329 | .resume = au1xac97c_drvresume, | ||
| 330 | }; | ||
| 331 | |||
| 332 | #define AU1XPSCAC97_PMOPS (&au1xpscac97_pmops) | ||
| 333 | |||
| 334 | #else | ||
| 335 | |||
| 336 | #define AU1XPSCAC97_PMOPS NULL | ||
| 337 | |||
| 338 | #endif | ||
| 339 | |||
| 340 | static struct platform_driver au1xac97c_driver = { | ||
| 341 | .driver = { | ||
| 342 | .name = "alchemy-ac97c", | ||
| 343 | .owner = THIS_MODULE, | ||
| 344 | .pm = AU1XPSCAC97_PMOPS, | ||
| 345 | }, | ||
| 346 | .probe = au1xac97c_drvprobe, | ||
| 347 | .remove = __devexit_p(au1xac97c_drvremove), | ||
| 348 | }; | ||
| 349 | |||
| 350 | static int __init au1xac97c_load(void) | ||
| 351 | { | ||
| 352 | ac97c_workdata = NULL; | ||
| 353 | return platform_driver_register(&au1xac97c_driver); | ||
| 354 | } | ||
| 355 | |||
| 356 | static void __exit au1xac97c_unload(void) | ||
| 357 | { | ||
| 358 | platform_driver_unregister(&au1xac97c_driver); | ||
| 359 | } | ||
| 360 | |||
| 361 | module_init(au1xac97c_load); | ||
| 362 | module_exit(au1xac97c_unload); | ||
| 363 | |||
| 364 | MODULE_LICENSE("GPL"); | ||
| 365 | MODULE_DESCRIPTION("Au1000/1500/1100 AC97C ASoC driver"); | ||
| 366 | MODULE_AUTHOR("Manuel Lauss"); | ||
diff --git a/sound/soc/au1x/db1000.c b/sound/soc/au1x/db1000.c new file mode 100644 index 000000000000..127477a5e0c7 --- /dev/null +++ b/sound/soc/au1x/db1000.c | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /* | ||
| 2 | * DB1000/DB1500/DB1100 ASoC audio fabric support code. | ||
| 3 | * | ||
| 4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> | ||
| 5 | * | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <linux/module.h> | ||
| 9 | #include <linux/moduleparam.h> | ||
| 10 | #include <linux/timer.h> | ||
| 11 | #include <linux/interrupt.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <sound/core.h> | ||
| 14 | #include <sound/pcm.h> | ||
| 15 | #include <sound/soc.h> | ||
| 16 | #include <asm/mach-au1x00/au1000.h> | ||
| 17 | #include <asm/mach-db1x00/bcsr.h> | ||
| 18 | |||
| 19 | #include "psc.h" | ||
| 20 | |||
| 21 | static struct snd_soc_dai_link db1000_ac97_dai = { | ||
| 22 | .name = "AC97", | ||
| 23 | .stream_name = "AC97 HiFi", | ||
| 24 | .codec_dai_name = "ac97-hifi", | ||
| 25 | .cpu_dai_name = "alchemy-ac97c", | ||
| 26 | .platform_name = "alchemy-pcm-dma.0", | ||
| 27 | .codec_name = "ac97-codec", | ||
| 28 | }; | ||
| 29 | |||
| 30 | static struct snd_soc_card db1000_ac97 = { | ||
| 31 | .name = "DB1000_AC97", | ||
| 32 | .dai_link = &db1000_ac97_dai, | ||
| 33 | .num_links = 1, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static int __devinit db1000_audio_probe(struct platform_device *pdev) | ||
| 37 | { | ||
| 38 | struct snd_soc_card *card = &db1000_ac97; | ||
| 39 | card->dev = &pdev->dev; | ||
| 40 | return snd_soc_register_card(card); | ||
| 41 | } | ||
| 42 | |||
| 43 | static int __devexit db1000_audio_remove(struct platform_device *pdev) | ||
| 44 | { | ||
| 45 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 46 | snd_soc_unregister_card(card); | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | |||
| 50 | static struct platform_driver db1000_audio_driver = { | ||
| 51 | .driver = { | ||
| 52 | .name = "db1000-audio", | ||
| 53 | .owner = THIS_MODULE, | ||
| 54 | .pm = &snd_soc_pm_ops, | ||
| 55 | }, | ||
| 56 | .probe = db1000_audio_probe, | ||
| 57 | .remove = __devexit_p(db1000_audio_remove), | ||
| 58 | }; | ||
| 59 | |||
| 60 | static int __init db1000_audio_load(void) | ||
| 61 | { | ||
| 62 | return platform_driver_register(&db1000_audio_driver); | ||
| 63 | } | ||
| 64 | |||
| 65 | static void __exit db1000_audio_unload(void) | ||
| 66 | { | ||
| 67 | platform_driver_unregister(&db1000_audio_driver); | ||
| 68 | } | ||
| 69 | |||
| 70 | module_init(db1000_audio_load); | ||
| 71 | module_exit(db1000_audio_unload); | ||
| 72 | |||
| 73 | MODULE_LICENSE("GPL"); | ||
| 74 | MODULE_DESCRIPTION("DB1000/DB1500/DB1100 ASoC audio"); | ||
| 75 | MODULE_AUTHOR("Manuel Lauss"); | ||
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index 1d3e258c9ea8..289312c14b99 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * DB1200 ASoC audio fabric support code. | 2 | * DB1200 ASoC audio fabric support code. |
| 3 | * | 3 | * |
| 4 | * (c) 2008-9 Manuel Lauss <manuel.lauss@gmail.com> | 4 | * (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com> |
| 5 | * | 5 | * |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| @@ -21,6 +21,17 @@ | |||
| 21 | #include "../codecs/wm8731.h" | 21 | #include "../codecs/wm8731.h" |
| 22 | #include "psc.h" | 22 | #include "psc.h" |
| 23 | 23 | ||
| 24 | static struct platform_device_id db1200_pids[] = { | ||
| 25 | { | ||
| 26 | .name = "db1200-ac97", | ||
| 27 | .driver_data = 0, | ||
| 28 | }, { | ||
| 29 | .name = "db1200-i2s", | ||
| 30 | .driver_data = 1, | ||
| 31 | }, | ||
| 32 | {}, | ||
| 33 | }; | ||
| 34 | |||
| 24 | /*------------------------- AC97 PART ---------------------------*/ | 35 | /*------------------------- AC97 PART ---------------------------*/ |
| 25 | 36 | ||
| 26 | static struct snd_soc_dai_link db1200_ac97_dai = { | 37 | static struct snd_soc_dai_link db1200_ac97_dai = { |
| @@ -89,36 +100,47 @@ static struct snd_soc_card db1200_i2s_machine = { | |||
| 89 | 100 | ||
| 90 | /*------------------------- COMMON PART ---------------------------*/ | 101 | /*------------------------- COMMON PART ---------------------------*/ |
| 91 | 102 | ||
| 92 | static struct platform_device *db1200_asoc_dev; | 103 | static struct snd_soc_card *db1200_cards[] __devinitdata = { |
| 104 | &db1200_ac97_machine, | ||
| 105 | &db1200_i2s_machine, | ||
| 106 | }; | ||
| 93 | 107 | ||
| 94 | static int __init db1200_audio_load(void) | 108 | static int __devinit db1200_audio_probe(struct platform_device *pdev) |
| 95 | { | 109 | { |
| 96 | int ret; | 110 | const struct platform_device_id *pid = platform_get_device_id(pdev); |
| 111 | struct snd_soc_card *card; | ||
| 97 | 112 | ||
| 98 | ret = -ENOMEM; | 113 | card = db1200_cards[pid->driver_data]; |
| 99 | db1200_asoc_dev = platform_device_alloc("soc-audio", 1); /* PSC1 */ | 114 | card->dev = &pdev->dev; |
| 100 | if (!db1200_asoc_dev) | 115 | return snd_soc_register_card(card); |
| 101 | goto out; | 116 | } |
| 102 | 117 | ||
| 103 | /* DB1200 board setup set PSC1MUX to preferred audio device */ | 118 | static int __devexit db1200_audio_remove(struct platform_device *pdev) |
| 104 | if (bcsr_read(BCSR_RESETS) & BCSR_RESETS_PSC1MUX) | 119 | { |
| 105 | platform_set_drvdata(db1200_asoc_dev, &db1200_i2s_machine); | 120 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
| 106 | else | 121 | snd_soc_unregister_card(card); |
| 107 | platform_set_drvdata(db1200_asoc_dev, &db1200_ac97_machine); | 122 | return 0; |
| 123 | } | ||
| 108 | 124 | ||
| 109 | ret = platform_device_add(db1200_asoc_dev); | 125 | static struct platform_driver db1200_audio_driver = { |
| 126 | .driver = { | ||
| 127 | .name = "db1200-ac97", | ||
| 128 | .owner = THIS_MODULE, | ||
| 129 | .pm = &snd_soc_pm_ops, | ||
| 130 | }, | ||
| 131 | .id_table = db1200_pids, | ||
| 132 | .probe = db1200_audio_probe, | ||
| 133 | .remove = __devexit_p(db1200_audio_remove), | ||
| 134 | }; | ||
| 110 | 135 | ||
| 111 | if (ret) { | 136 | static int __init db1200_audio_load(void) |
| 112 | platform_device_put(db1200_asoc_dev); | 137 | { |
| 113 | db1200_asoc_dev = NULL; | 138 | return platform_driver_register(&db1200_audio_driver); |
| 114 | } | ||
| 115 | out: | ||
| 116 | return ret; | ||
| 117 | } | 139 | } |
| 118 | 140 | ||
| 119 | static void __exit db1200_audio_unload(void) | 141 | static void __exit db1200_audio_unload(void) |
| 120 | { | 142 | { |
| 121 | platform_device_unregister(db1200_asoc_dev); | 143 | platform_driver_unregister(&db1200_audio_driver); |
| 122 | } | 144 | } |
| 123 | 145 | ||
| 124 | module_init(db1200_audio_load); | 146 | module_init(db1200_audio_load); |
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c index 20bb53a837b1..d7d04e26eee5 100644 --- a/sound/soc/au1x/dbdma2.c +++ b/sound/soc/au1x/dbdma2.c | |||
| @@ -169,7 +169,7 @@ static int au1x_pcm_dbdma_realloc(struct au1xpsc_audio_dmadata *pcd, | |||
| 169 | 169 | ||
| 170 | au1x_pcm_dbdma_free(pcd); | 170 | au1x_pcm_dbdma_free(pcd); |
| 171 | 171 | ||
| 172 | if (stype == PCM_RX) | 172 | if (stype == SNDRV_PCM_STREAM_CAPTURE) |
| 173 | pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id, | 173 | pcd->ddma_chan = au1xxx_dbdma_chan_alloc(pcd->ddma_id, |
| 174 | DSCR_CMD0_ALWAYS, | 174 | DSCR_CMD0_ALWAYS, |
| 175 | au1x_pcm_dmarx_cb, (void *)pcd); | 175 | au1x_pcm_dmarx_cb, (void *)pcd); |
| @@ -198,7 +198,7 @@ static inline struct au1xpsc_audio_dmadata *to_dmadata(struct snd_pcm_substream | |||
| 198 | struct snd_soc_pcm_runtime *rtd = ss->private_data; | 198 | struct snd_soc_pcm_runtime *rtd = ss->private_data; |
| 199 | struct au1xpsc_audio_dmadata *pcd = | 199 | struct au1xpsc_audio_dmadata *pcd = |
| 200 | snd_soc_platform_get_drvdata(rtd->platform); | 200 | snd_soc_platform_get_drvdata(rtd->platform); |
| 201 | return &pcd[SUBSTREAM_TYPE(ss)]; | 201 | return &pcd[ss->stream]; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, | 204 | static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, |
| @@ -212,7 +212,7 @@ static int au1xpsc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 212 | if (ret < 0) | 212 | if (ret < 0) |
| 213 | goto out; | 213 | goto out; |
| 214 | 214 | ||
| 215 | stype = SUBSTREAM_TYPE(substream); | 215 | stype = substream->stream; |
| 216 | pcd = to_dmadata(substream); | 216 | pcd = to_dmadata(substream); |
| 217 | 217 | ||
| 218 | DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " | 218 | DBG("runtime->dma_area = 0x%08lx dma_addr_t = 0x%08lx dma_size = %d " |
| @@ -255,7 +255,7 @@ static int au1xpsc_pcm_prepare(struct snd_pcm_substream *substream) | |||
| 255 | 255 | ||
| 256 | au1xxx_dbdma_reset(pcd->ddma_chan); | 256 | au1xxx_dbdma_reset(pcd->ddma_chan); |
| 257 | 257 | ||
| 258 | if (SUBSTREAM_TYPE(substream) == PCM_RX) { | 258 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { |
| 259 | au1x_pcm_queue_rx(pcd); | 259 | au1x_pcm_queue_rx(pcd); |
| 260 | au1x_pcm_queue_rx(pcd); | 260 | au1x_pcm_queue_rx(pcd); |
| 261 | } else { | 261 | } else { |
| @@ -293,6 +293,16 @@ au1xpsc_pcm_pointer(struct snd_pcm_substream *substream) | |||
| 293 | 293 | ||
| 294 | static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) | 294 | static int au1xpsc_pcm_open(struct snd_pcm_substream *substream) |
| 295 | { | 295 | { |
| 296 | struct au1xpsc_audio_dmadata *pcd = to_dmadata(substream); | ||
| 297 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 298 | int stype = substream->stream, *dmaids; | ||
| 299 | |||
| 300 | dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
| 301 | if (!dmaids) | ||
| 302 | return -ENODEV; /* whoa, has ordering changed? */ | ||
| 303 | |||
| 304 | pcd->ddma_id = dmaids[stype]; | ||
| 305 | |||
| 296 | snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); | 306 | snd_soc_set_runtime_hwparams(substream, &au1xpsc_pcm_hardware); |
| 297 | return 0; | 307 | return 0; |
| 298 | } | 308 | } |
| @@ -340,36 +350,18 @@ struct snd_soc_platform_driver au1xpsc_soc_platform = { | |||
| 340 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) | 350 | static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev) |
| 341 | { | 351 | { |
| 342 | struct au1xpsc_audio_dmadata *dmadata; | 352 | struct au1xpsc_audio_dmadata *dmadata; |
| 343 | struct resource *r; | ||
| 344 | int ret; | 353 | int ret; |
| 345 | 354 | ||
| 346 | dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); | 355 | dmadata = kzalloc(2 * sizeof(struct au1xpsc_audio_dmadata), GFP_KERNEL); |
| 347 | if (!dmadata) | 356 | if (!dmadata) |
| 348 | return -ENOMEM; | 357 | return -ENOMEM; |
| 349 | 358 | ||
| 350 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 351 | if (!r) { | ||
| 352 | ret = -ENODEV; | ||
| 353 | goto out1; | ||
| 354 | } | ||
| 355 | dmadata[PCM_TX].ddma_id = r->start; | ||
| 356 | |||
| 357 | /* RX DMA */ | ||
| 358 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 359 | if (!r) { | ||
| 360 | ret = -ENODEV; | ||
| 361 | goto out1; | ||
| 362 | } | ||
| 363 | dmadata[PCM_RX].ddma_id = r->start; | ||
| 364 | |||
| 365 | platform_set_drvdata(pdev, dmadata); | 359 | platform_set_drvdata(pdev, dmadata); |
| 366 | 360 | ||
| 367 | ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); | 361 | ret = snd_soc_register_platform(&pdev->dev, &au1xpsc_soc_platform); |
| 368 | if (!ret) | 362 | if (ret) |
| 369 | return ret; | 363 | kfree(dmadata); |
| 370 | 364 | ||
| 371 | out1: | ||
| 372 | kfree(dmadata); | ||
| 373 | return ret; | 365 | return ret; |
| 374 | } | 366 | } |
| 375 | 367 | ||
| @@ -405,57 +397,6 @@ static void __exit au1xpsc_audio_dbdma_unload(void) | |||
| 405 | module_init(au1xpsc_audio_dbdma_load); | 397 | module_init(au1xpsc_audio_dbdma_load); |
| 406 | module_exit(au1xpsc_audio_dbdma_unload); | 398 | module_exit(au1xpsc_audio_dbdma_unload); |
| 407 | 399 | ||
| 408 | |||
| 409 | struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev) | ||
| 410 | { | ||
| 411 | struct resource *res, *r; | ||
| 412 | struct platform_device *pd; | ||
| 413 | int id[2]; | ||
| 414 | int ret; | ||
| 415 | |||
| 416 | r = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 417 | if (!r) | ||
| 418 | return NULL; | ||
| 419 | id[0] = r->start; | ||
| 420 | |||
| 421 | r = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 422 | if (!r) | ||
| 423 | return NULL; | ||
| 424 | id[1] = r->start; | ||
| 425 | |||
| 426 | res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL); | ||
| 427 | if (!res) | ||
| 428 | return NULL; | ||
| 429 | |||
| 430 | res[0].start = res[0].end = id[0]; | ||
| 431 | res[1].start = res[1].end = id[1]; | ||
| 432 | res[0].flags = res[1].flags = IORESOURCE_DMA; | ||
| 433 | |||
| 434 | pd = platform_device_alloc("au1xpsc-pcm", pdev->id); | ||
| 435 | if (!pd) | ||
| 436 | goto out; | ||
| 437 | |||
| 438 | pd->resource = res; | ||
| 439 | pd->num_resources = 2; | ||
| 440 | |||
| 441 | ret = platform_device_add(pd); | ||
| 442 | if (!ret) | ||
| 443 | return pd; | ||
| 444 | |||
| 445 | platform_device_put(pd); | ||
| 446 | out: | ||
| 447 | kfree(res); | ||
| 448 | return NULL; | ||
| 449 | } | ||
| 450 | EXPORT_SYMBOL_GPL(au1xpsc_pcm_add); | ||
| 451 | |||
| 452 | void au1xpsc_pcm_destroy(struct platform_device *dmapd) | ||
| 453 | { | ||
| 454 | if (dmapd) | ||
| 455 | platform_device_unregister(dmapd); | ||
| 456 | } | ||
| 457 | EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy); | ||
| 458 | |||
| 459 | MODULE_LICENSE("GPL"); | 400 | MODULE_LICENSE("GPL"); |
| 460 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); | 401 | MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); |
| 461 | MODULE_AUTHOR("Manuel Lauss"); | 402 | MODULE_AUTHOR("Manuel Lauss"); |
diff --git a/sound/soc/au1x/dma.c b/sound/soc/au1x/dma.c new file mode 100644 index 000000000000..177f7137a9c8 --- /dev/null +++ b/sound/soc/au1x/dma.c | |||
| @@ -0,0 +1,377 @@ | |||
| 1 | /* | ||
| 2 | * Au1000/Au1500/Au1100 Audio DMA support. | ||
| 3 | * | ||
| 4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> | ||
| 5 | * | ||
| 6 | * copied almost verbatim from the old ALSA driver, written by | ||
| 7 | * Charles Eidsness <charles@cooper-street.com> | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/platform_device.h> | ||
| 13 | #include <linux/slab.h> | ||
| 14 | #include <linux/dma-mapping.h> | ||
| 15 | #include <sound/core.h> | ||
| 16 | #include <sound/pcm.h> | ||
| 17 | #include <sound/pcm_params.h> | ||
| 18 | #include <sound/soc.h> | ||
| 19 | #include <asm/mach-au1x00/au1000.h> | ||
| 20 | #include <asm/mach-au1x00/au1000_dma.h> | ||
| 21 | |||
| 22 | #include "psc.h" | ||
| 23 | |||
| 24 | #define ALCHEMY_PCM_FMTS \ | ||
| 25 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ | ||
| 26 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ | ||
| 27 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \ | ||
| 28 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE | \ | ||
| 29 | SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE | \ | ||
| 30 | 0) | ||
| 31 | |||
| 32 | struct pcm_period { | ||
| 33 | u32 start; | ||
| 34 | u32 relative_end; /* relative to start of buffer */ | ||
| 35 | struct pcm_period *next; | ||
| 36 | }; | ||
| 37 | |||
| 38 | struct audio_stream { | ||
| 39 | struct snd_pcm_substream *substream; | ||
| 40 | int dma; | ||
| 41 | struct pcm_period *buffer; | ||
| 42 | unsigned int period_size; | ||
| 43 | unsigned int periods; | ||
| 44 | }; | ||
| 45 | |||
| 46 | struct alchemy_pcm_ctx { | ||
| 47 | struct audio_stream stream[2]; /* playback & capture */ | ||
| 48 | }; | ||
| 49 | |||
| 50 | static void au1000_release_dma_link(struct audio_stream *stream) | ||
| 51 | { | ||
| 52 | struct pcm_period *pointer; | ||
| 53 | struct pcm_period *pointer_next; | ||
| 54 | |||
| 55 | stream->period_size = 0; | ||
| 56 | stream->periods = 0; | ||
| 57 | pointer = stream->buffer; | ||
| 58 | if (!pointer) | ||
| 59 | return; | ||
| 60 | do { | ||
| 61 | pointer_next = pointer->next; | ||
| 62 | kfree(pointer); | ||
| 63 | pointer = pointer_next; | ||
| 64 | } while (pointer != stream->buffer); | ||
| 65 | stream->buffer = NULL; | ||
| 66 | } | ||
| 67 | |||
| 68 | static int au1000_setup_dma_link(struct audio_stream *stream, | ||
| 69 | unsigned int period_bytes, | ||
| 70 | unsigned int periods) | ||
| 71 | { | ||
| 72 | struct snd_pcm_substream *substream = stream->substream; | ||
| 73 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 74 | struct pcm_period *pointer; | ||
| 75 | unsigned long dma_start; | ||
| 76 | int i; | ||
| 77 | |||
| 78 | dma_start = virt_to_phys(runtime->dma_area); | ||
| 79 | |||
| 80 | if (stream->period_size == period_bytes && | ||
| 81 | stream->periods == periods) | ||
| 82 | return 0; /* not changed */ | ||
| 83 | |||
| 84 | au1000_release_dma_link(stream); | ||
| 85 | |||
| 86 | stream->period_size = period_bytes; | ||
| 87 | stream->periods = periods; | ||
| 88 | |||
| 89 | stream->buffer = kmalloc(sizeof(struct pcm_period), GFP_KERNEL); | ||
| 90 | if (!stream->buffer) | ||
| 91 | return -ENOMEM; | ||
| 92 | pointer = stream->buffer; | ||
| 93 | for (i = 0; i < periods; i++) { | ||
| 94 | pointer->start = (u32)(dma_start + (i * period_bytes)); | ||
| 95 | pointer->relative_end = (u32) (((i+1) * period_bytes) - 0x1); | ||
| 96 | if (i < periods - 1) { | ||
| 97 | pointer->next = kmalloc(sizeof(struct pcm_period), | ||
| 98 | GFP_KERNEL); | ||
| 99 | if (!pointer->next) { | ||
| 100 | au1000_release_dma_link(stream); | ||
| 101 | return -ENOMEM; | ||
| 102 | } | ||
| 103 | pointer = pointer->next; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | pointer->next = stream->buffer; | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | |||
| 110 | static void au1000_dma_stop(struct audio_stream *stream) | ||
| 111 | { | ||
| 112 | if (stream->buffer) | ||
| 113 | disable_dma(stream->dma); | ||
| 114 | } | ||
| 115 | |||
| 116 | static void au1000_dma_start(struct audio_stream *stream) | ||
| 117 | { | ||
| 118 | if (!stream->buffer) | ||
| 119 | return; | ||
| 120 | |||
| 121 | init_dma(stream->dma); | ||
| 122 | if (get_dma_active_buffer(stream->dma) == 0) { | ||
| 123 | clear_dma_done0(stream->dma); | ||
| 124 | set_dma_addr0(stream->dma, stream->buffer->start); | ||
| 125 | set_dma_count0(stream->dma, stream->period_size >> 1); | ||
| 126 | set_dma_addr1(stream->dma, stream->buffer->next->start); | ||
| 127 | set_dma_count1(stream->dma, stream->period_size >> 1); | ||
| 128 | } else { | ||
| 129 | clear_dma_done1(stream->dma); | ||
| 130 | set_dma_addr1(stream->dma, stream->buffer->start); | ||
| 131 | set_dma_count1(stream->dma, stream->period_size >> 1); | ||
| 132 | set_dma_addr0(stream->dma, stream->buffer->next->start); | ||
| 133 | set_dma_count0(stream->dma, stream->period_size >> 1); | ||
| 134 | } | ||
| 135 | enable_dma_buffers(stream->dma); | ||
| 136 | start_dma(stream->dma); | ||
| 137 | } | ||
| 138 | |||
| 139 | static irqreturn_t au1000_dma_interrupt(int irq, void *ptr) | ||
| 140 | { | ||
| 141 | struct audio_stream *stream = (struct audio_stream *)ptr; | ||
| 142 | struct snd_pcm_substream *substream = stream->substream; | ||
| 143 | |||
| 144 | switch (get_dma_buffer_done(stream->dma)) { | ||
| 145 | case DMA_D0: | ||
| 146 | stream->buffer = stream->buffer->next; | ||
| 147 | clear_dma_done0(stream->dma); | ||
| 148 | set_dma_addr0(stream->dma, stream->buffer->next->start); | ||
| 149 | set_dma_count0(stream->dma, stream->period_size >> 1); | ||
| 150 | enable_dma_buffer0(stream->dma); | ||
| 151 | break; | ||
| 152 | case DMA_D1: | ||
| 153 | stream->buffer = stream->buffer->next; | ||
| 154 | clear_dma_done1(stream->dma); | ||
| 155 | set_dma_addr1(stream->dma, stream->buffer->next->start); | ||
| 156 | set_dma_count1(stream->dma, stream->period_size >> 1); | ||
| 157 | enable_dma_buffer1(stream->dma); | ||
| 158 | break; | ||
| 159 | case (DMA_D0 | DMA_D1): | ||
| 160 | pr_debug("DMA %d missed interrupt.\n", stream->dma); | ||
| 161 | au1000_dma_stop(stream); | ||
| 162 | au1000_dma_start(stream); | ||
| 163 | break; | ||
| 164 | case (~DMA_D0 & ~DMA_D1): | ||
| 165 | pr_debug("DMA %d empty irq.\n", stream->dma); | ||
| 166 | } | ||
| 167 | snd_pcm_period_elapsed(substream); | ||
| 168 | return IRQ_HANDLED; | ||
| 169 | } | ||
| 170 | |||
| 171 | static const struct snd_pcm_hardware alchemy_pcm_hardware = { | ||
| 172 | .info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | | ||
| 173 | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BATCH, | ||
| 174 | .formats = ALCHEMY_PCM_FMTS, | ||
| 175 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
| 176 | .rate_min = SNDRV_PCM_RATE_8000, | ||
| 177 | .rate_max = SNDRV_PCM_RATE_192000, | ||
| 178 | .channels_min = 2, | ||
| 179 | .channels_max = 2, | ||
| 180 | .period_bytes_min = 1024, | ||
| 181 | .period_bytes_max = 16 * 1024 - 1, | ||
| 182 | .periods_min = 4, | ||
| 183 | .periods_max = 255, | ||
| 184 | .buffer_bytes_max = 128 * 1024, | ||
| 185 | .fifo_size = 16, | ||
| 186 | }; | ||
| 187 | |||
| 188 | static inline struct alchemy_pcm_ctx *ss_to_ctx(struct snd_pcm_substream *ss) | ||
| 189 | { | ||
| 190 | struct snd_soc_pcm_runtime *rtd = ss->private_data; | ||
| 191 | return snd_soc_platform_get_drvdata(rtd->platform); | ||
| 192 | } | ||
| 193 | |||
| 194 | static inline struct audio_stream *ss_to_as(struct snd_pcm_substream *ss) | ||
| 195 | { | ||
| 196 | struct alchemy_pcm_ctx *ctx = ss_to_ctx(ss); | ||
| 197 | return &(ctx->stream[ss->stream]); | ||
| 198 | } | ||
| 199 | |||
| 200 | static int alchemy_pcm_open(struct snd_pcm_substream *substream) | ||
| 201 | { | ||
| 202 | struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream); | ||
| 203 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 204 | int *dmaids, s = substream->stream; | ||
| 205 | char *name; | ||
| 206 | |||
| 207 | dmaids = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
| 208 | if (!dmaids) | ||
| 209 | return -ENODEV; /* whoa, has ordering changed? */ | ||
| 210 | |||
| 211 | /* DMA setup */ | ||
| 212 | name = (s == SNDRV_PCM_STREAM_PLAYBACK) ? "audio-tx" : "audio-rx"; | ||
| 213 | ctx->stream[s].dma = request_au1000_dma(dmaids[s], name, | ||
| 214 | au1000_dma_interrupt, 0, | ||
| 215 | &ctx->stream[s]); | ||
| 216 | set_dma_mode(ctx->stream[s].dma, | ||
| 217 | get_dma_mode(ctx->stream[s].dma) & ~DMA_NC); | ||
| 218 | |||
| 219 | ctx->stream[s].substream = substream; | ||
| 220 | ctx->stream[s].buffer = NULL; | ||
| 221 | snd_soc_set_runtime_hwparams(substream, &alchemy_pcm_hardware); | ||
| 222 | |||
| 223 | return 0; | ||
| 224 | } | ||
| 225 | |||
| 226 | static int alchemy_pcm_close(struct snd_pcm_substream *substream) | ||
| 227 | { | ||
| 228 | struct alchemy_pcm_ctx *ctx = ss_to_ctx(substream); | ||
| 229 | int stype = substream->stream; | ||
| 230 | |||
| 231 | ctx->stream[stype].substream = NULL; | ||
| 232 | free_au1000_dma(ctx->stream[stype].dma); | ||
| 233 | |||
| 234 | return 0; | ||
| 235 | } | ||
| 236 | |||
| 237 | static int alchemy_pcm_hw_params(struct snd_pcm_substream *substream, | ||
| 238 | struct snd_pcm_hw_params *hw_params) | ||
| 239 | { | ||
| 240 | struct audio_stream *stream = ss_to_as(substream); | ||
| 241 | int err; | ||
| 242 | |||
| 243 | err = snd_pcm_lib_malloc_pages(substream, | ||
| 244 | params_buffer_bytes(hw_params)); | ||
| 245 | if (err < 0) | ||
| 246 | return err; | ||
| 247 | err = au1000_setup_dma_link(stream, | ||
| 248 | params_period_bytes(hw_params), | ||
| 249 | params_periods(hw_params)); | ||
| 250 | if (err) | ||
| 251 | snd_pcm_lib_free_pages(substream); | ||
| 252 | |||
| 253 | return err; | ||
| 254 | } | ||
| 255 | |||
| 256 | static int alchemy_pcm_hw_free(struct snd_pcm_substream *substream) | ||
| 257 | { | ||
| 258 | struct audio_stream *stream = ss_to_as(substream); | ||
| 259 | au1000_release_dma_link(stream); | ||
| 260 | return snd_pcm_lib_free_pages(substream); | ||
| 261 | } | ||
| 262 | |||
| 263 | static int alchemy_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
| 264 | { | ||
| 265 | struct audio_stream *stream = ss_to_as(substream); | ||
| 266 | int err = 0; | ||
| 267 | |||
| 268 | switch (cmd) { | ||
| 269 | case SNDRV_PCM_TRIGGER_START: | ||
| 270 | au1000_dma_start(stream); | ||
| 271 | break; | ||
| 272 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 273 | au1000_dma_stop(stream); | ||
| 274 | break; | ||
| 275 | default: | ||
| 276 | err = -EINVAL; | ||
| 277 | break; | ||
| 278 | } | ||
| 279 | return err; | ||
| 280 | } | ||
| 281 | |||
| 282 | static snd_pcm_uframes_t alchemy_pcm_pointer(struct snd_pcm_substream *ss) | ||
| 283 | { | ||
| 284 | struct audio_stream *stream = ss_to_as(ss); | ||
| 285 | long location; | ||
| 286 | |||
| 287 | location = get_dma_residue(stream->dma); | ||
| 288 | location = stream->buffer->relative_end - location; | ||
| 289 | if (location == -1) | ||
| 290 | location = 0; | ||
| 291 | return bytes_to_frames(ss->runtime, location); | ||
| 292 | } | ||
| 293 | |||
| 294 | static struct snd_pcm_ops alchemy_pcm_ops = { | ||
| 295 | .open = alchemy_pcm_open, | ||
| 296 | .close = alchemy_pcm_close, | ||
| 297 | .ioctl = snd_pcm_lib_ioctl, | ||
| 298 | .hw_params = alchemy_pcm_hw_params, | ||
| 299 | .hw_free = alchemy_pcm_hw_free, | ||
| 300 | .trigger = alchemy_pcm_trigger, | ||
| 301 | .pointer = alchemy_pcm_pointer, | ||
| 302 | }; | ||
| 303 | |||
| 304 | static void alchemy_pcm_free_dma_buffers(struct snd_pcm *pcm) | ||
| 305 | { | ||
| 306 | snd_pcm_lib_preallocate_free_for_all(pcm); | ||
| 307 | } | ||
| 308 | |||
| 309 | static int alchemy_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
| 310 | { | ||
| 311 | struct snd_pcm *pcm = rtd->pcm; | ||
| 312 | |||
| 313 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, | ||
| 314 | snd_dma_continuous_data(GFP_KERNEL), 65536, (4096 * 1024) - 1); | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | struct snd_soc_platform_driver alchemy_pcm_soc_platform = { | ||
| 320 | .ops = &alchemy_pcm_ops, | ||
| 321 | .pcm_new = alchemy_pcm_new, | ||
| 322 | .pcm_free = alchemy_pcm_free_dma_buffers, | ||
| 323 | }; | ||
| 324 | |||
| 325 | static int __devinit alchemy_pcm_drvprobe(struct platform_device *pdev) | ||
| 326 | { | ||
| 327 | struct alchemy_pcm_ctx *ctx; | ||
| 328 | int ret; | ||
| 329 | |||
| 330 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
| 331 | if (!ctx) | ||
| 332 | return -ENOMEM; | ||
| 333 | |||
| 334 | platform_set_drvdata(pdev, ctx); | ||
| 335 | |||
| 336 | ret = snd_soc_register_platform(&pdev->dev, &alchemy_pcm_soc_platform); | ||
| 337 | if (ret) | ||
| 338 | kfree(ctx); | ||
| 339 | |||
| 340 | return ret; | ||
| 341 | } | ||
| 342 | |||
| 343 | static int __devexit alchemy_pcm_drvremove(struct platform_device *pdev) | ||
| 344 | { | ||
| 345 | struct alchemy_pcm_ctx *ctx = platform_get_drvdata(pdev); | ||
| 346 | |||
| 347 | snd_soc_unregister_platform(&pdev->dev); | ||
| 348 | kfree(ctx); | ||
| 349 | |||
| 350 | return 0; | ||
| 351 | } | ||
| 352 | |||
| 353 | static struct platform_driver alchemy_pcmdma_driver = { | ||
| 354 | .driver = { | ||
| 355 | .name = "alchemy-pcm-dma", | ||
| 356 | .owner = THIS_MODULE, | ||
| 357 | }, | ||
| 358 | .probe = alchemy_pcm_drvprobe, | ||
| 359 | .remove = __devexit_p(alchemy_pcm_drvremove), | ||
| 360 | }; | ||
| 361 | |||
| 362 | static int __init alchemy_pcmdma_load(void) | ||
| 363 | { | ||
| 364 | return platform_driver_register(&alchemy_pcmdma_driver); | ||
| 365 | } | ||
| 366 | |||
| 367 | static void __exit alchemy_pcmdma_unload(void) | ||
| 368 | { | ||
| 369 | platform_driver_unregister(&alchemy_pcmdma_driver); | ||
| 370 | } | ||
| 371 | |||
| 372 | module_init(alchemy_pcmdma_load); | ||
| 373 | module_exit(alchemy_pcmdma_unload); | ||
| 374 | |||
| 375 | MODULE_LICENSE("GPL"); | ||
| 376 | MODULE_DESCRIPTION("Au1000/Au1500/Au1100 Audio DMA driver"); | ||
| 377 | MODULE_AUTHOR("Manuel Lauss"); | ||
diff --git a/sound/soc/au1x/i2sc.c b/sound/soc/au1x/i2sc.c new file mode 100644 index 000000000000..6bcf48f5884c --- /dev/null +++ b/sound/soc/au1x/i2sc.c | |||
| @@ -0,0 +1,349 @@ | |||
| 1 | /* | ||
| 2 | * Au1000/Au1500/Au1100 I2S controller driver for ASoC | ||
| 3 | * | ||
| 4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> | ||
| 5 | * | ||
| 6 | * Note: clock supplied to the I2S controller must be 256x samplerate. | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/init.h> | ||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/slab.h> | ||
| 12 | #include <linux/suspend.h> | ||
| 13 | #include <sound/core.h> | ||
| 14 | #include <sound/pcm.h> | ||
| 15 | #include <sound/initval.h> | ||
| 16 | #include <sound/soc.h> | ||
| 17 | #include <asm/mach-au1x00/au1000.h> | ||
| 18 | |||
| 19 | #include "psc.h" | ||
| 20 | |||
| 21 | #define I2S_RXTX 0x00 | ||
| 22 | #define I2S_CFG 0x04 | ||
| 23 | #define I2S_ENABLE 0x08 | ||
| 24 | |||
| 25 | #define CFG_XU (1 << 25) /* tx underflow */ | ||
| 26 | #define CFG_XO (1 << 24) | ||
| 27 | #define CFG_RU (1 << 23) | ||
| 28 | #define CFG_RO (1 << 22) | ||
| 29 | #define CFG_TR (1 << 21) | ||
| 30 | #define CFG_TE (1 << 20) | ||
| 31 | #define CFG_TF (1 << 19) | ||
| 32 | #define CFG_RR (1 << 18) | ||
| 33 | #define CFG_RF (1 << 17) | ||
| 34 | #define CFG_ICK (1 << 12) /* clock invert */ | ||
| 35 | #define CFG_PD (1 << 11) /* set to make I2SDIO INPUT */ | ||
| 36 | #define CFG_LB (1 << 10) /* loopback */ | ||
| 37 | #define CFG_IC (1 << 9) /* word select invert */ | ||
| 38 | #define CFG_FM_I2S (0 << 7) /* I2S format */ | ||
| 39 | #define CFG_FM_LJ (1 << 7) /* left-justified */ | ||
| 40 | #define CFG_FM_RJ (2 << 7) /* right-justified */ | ||
| 41 | #define CFG_FM_MASK (3 << 7) | ||
| 42 | #define CFG_TN (1 << 6) /* tx fifo en */ | ||
| 43 | #define CFG_RN (1 << 5) /* rx fifo en */ | ||
| 44 | #define CFG_SZ_8 (0x08) | ||
| 45 | #define CFG_SZ_16 (0x10) | ||
| 46 | #define CFG_SZ_18 (0x12) | ||
| 47 | #define CFG_SZ_20 (0x14) | ||
| 48 | #define CFG_SZ_24 (0x18) | ||
| 49 | #define CFG_SZ_MASK (0x1f) | ||
| 50 | #define EN_D (1 << 1) /* DISable */ | ||
| 51 | #define EN_CE (1 << 0) /* clock enable */ | ||
| 52 | |||
| 53 | /* only limited by clock generator and board design */ | ||
| 54 | #define AU1XI2SC_RATES \ | ||
| 55 | SNDRV_PCM_RATE_CONTINUOUS | ||
| 56 | |||
| 57 | #define AU1XI2SC_FMTS \ | ||
| 58 | (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ | ||
| 59 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | \ | ||
| 60 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE | \ | ||
| 61 | SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_U18_3LE | \ | ||
| 62 | SNDRV_PCM_FMTBIT_S18_3BE | SNDRV_PCM_FMTBIT_U18_3BE | \ | ||
| 63 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ | ||
| 64 | SNDRV_PCM_FMTBIT_S20_3BE | SNDRV_PCM_FMTBIT_U20_3BE | \ | ||
| 65 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE | \ | ||
| 66 | SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE | \ | ||
| 67 | 0) | ||
| 68 | |||
| 69 | static inline unsigned long RD(struct au1xpsc_audio_data *ctx, int reg) | ||
| 70 | { | ||
| 71 | return __raw_readl(ctx->mmio + reg); | ||
| 72 | } | ||
| 73 | |||
| 74 | static inline void WR(struct au1xpsc_audio_data *ctx, int reg, unsigned long v) | ||
| 75 | { | ||
| 76 | __raw_writel(v, ctx->mmio + reg); | ||
| 77 | wmb(); | ||
| 78 | } | ||
| 79 | |||
| 80 | static int au1xi2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | ||
| 81 | { | ||
| 82 | struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 83 | unsigned long c; | ||
| 84 | int ret; | ||
| 85 | |||
| 86 | ret = -EINVAL; | ||
| 87 | c = ctx->cfg; | ||
| 88 | |||
| 89 | c &= ~CFG_FM_MASK; | ||
| 90 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 91 | case SND_SOC_DAIFMT_I2S: | ||
| 92 | c |= CFG_FM_I2S; | ||
| 93 | break; | ||
| 94 | case SND_SOC_DAIFMT_MSB: | ||
| 95 | c |= CFG_FM_RJ; | ||
| 96 | break; | ||
| 97 | case SND_SOC_DAIFMT_LSB: | ||
| 98 | c |= CFG_FM_LJ; | ||
| 99 | break; | ||
| 100 | default: | ||
| 101 | goto out; | ||
| 102 | } | ||
| 103 | |||
| 104 | c &= ~(CFG_IC | CFG_ICK); /* IB-IF */ | ||
| 105 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
| 106 | case SND_SOC_DAIFMT_NB_NF: | ||
| 107 | c |= CFG_IC | CFG_ICK; | ||
| 108 | break; | ||
| 109 | case SND_SOC_DAIFMT_NB_IF: | ||
| 110 | c |= CFG_IC; | ||
| 111 | break; | ||
| 112 | case SND_SOC_DAIFMT_IB_NF: | ||
| 113 | c |= CFG_ICK; | ||
| 114 | break; | ||
| 115 | case SND_SOC_DAIFMT_IB_IF: | ||
| 116 | break; | ||
| 117 | default: | ||
| 118 | goto out; | ||
| 119 | } | ||
| 120 | |||
| 121 | /* I2S controller only supports master */ | ||
| 122 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 123 | case SND_SOC_DAIFMT_CBS_CFS: /* CODEC slave */ | ||
| 124 | break; | ||
| 125 | default: | ||
| 126 | goto out; | ||
| 127 | } | ||
| 128 | |||
| 129 | ret = 0; | ||
| 130 | ctx->cfg = c; | ||
| 131 | out: | ||
| 132 | return ret; | ||
| 133 | } | ||
| 134 | |||
| 135 | static int au1xi2s_trigger(struct snd_pcm_substream *substream, | ||
| 136 | int cmd, struct snd_soc_dai *dai) | ||
| 137 | { | ||
| 138 | struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai); | ||
| 139 | int stype = SUBSTREAM_TYPE(substream); | ||
| 140 | |||
| 141 | switch (cmd) { | ||
| 142 | case SNDRV_PCM_TRIGGER_START: | ||
| 143 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 144 | /* power up */ | ||
| 145 | WR(ctx, I2S_ENABLE, EN_D | EN_CE); | ||
| 146 | WR(ctx, I2S_ENABLE, EN_CE); | ||
| 147 | ctx->cfg |= (stype == PCM_TX) ? CFG_TN : CFG_RN; | ||
| 148 | WR(ctx, I2S_CFG, ctx->cfg); | ||
| 149 | break; | ||
| 150 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 151 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 152 | ctx->cfg &= ~((stype == PCM_TX) ? CFG_TN : CFG_RN); | ||
| 153 | WR(ctx, I2S_CFG, ctx->cfg); | ||
| 154 | WR(ctx, I2S_ENABLE, EN_D); /* power off */ | ||
| 155 | break; | ||
| 156 | default: | ||
| 157 | return -EINVAL; | ||
| 158 | } | ||
| 159 | |||
| 160 | return 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | static unsigned long msbits_to_reg(int msbits) | ||
| 164 | { | ||
| 165 | switch (msbits) { | ||
| 166 | case 8: | ||
| 167 | return CFG_SZ_8; | ||
| 168 | case 16: | ||
| 169 | return CFG_SZ_16; | ||
| 170 | case 18: | ||
| 171 | return CFG_SZ_18; | ||
| 172 | case 20: | ||
| 173 | return CFG_SZ_20; | ||
| 174 | case 24: | ||
| 175 | return CFG_SZ_24; | ||
| 176 | } | ||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 180 | static int au1xi2s_hw_params(struct snd_pcm_substream *substream, | ||
| 181 | struct snd_pcm_hw_params *params, | ||
| 182 | struct snd_soc_dai *dai) | ||
| 183 | { | ||
| 184 | struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai); | ||
| 185 | unsigned long v; | ||
| 186 | |||
| 187 | v = msbits_to_reg(params->msbits); | ||
| 188 | if (!v) | ||
| 189 | return -EINVAL; | ||
| 190 | |||
| 191 | ctx->cfg &= ~CFG_SZ_MASK; | ||
| 192 | ctx->cfg |= v; | ||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | static int au1xi2s_startup(struct snd_pcm_substream *substream, | ||
| 197 | struct snd_soc_dai *dai) | ||
| 198 | { | ||
| 199 | struct au1xpsc_audio_data *ctx = snd_soc_dai_get_drvdata(dai); | ||
| 200 | snd_soc_dai_set_dma_data(dai, substream, &ctx->dmaids[0]); | ||
| 201 | return 0; | ||
| 202 | } | ||
| 203 | |||
| 204 | static const struct snd_soc_dai_ops au1xi2s_dai_ops = { | ||
| 205 | .startup = au1xi2s_startup, | ||
| 206 | .trigger = au1xi2s_trigger, | ||
| 207 | .hw_params = au1xi2s_hw_params, | ||
| 208 | .set_fmt = au1xi2s_set_fmt, | ||
| 209 | }; | ||
| 210 | |||
| 211 | static struct snd_soc_dai_driver au1xi2s_dai_driver = { | ||
| 212 | .symmetric_rates = 1, | ||
| 213 | .playback = { | ||
| 214 | .rates = AU1XI2SC_RATES, | ||
| 215 | .formats = AU1XI2SC_FMTS, | ||
| 216 | .channels_min = 2, | ||
| 217 | .channels_max = 2, | ||
| 218 | }, | ||
| 219 | .capture = { | ||
| 220 | .rates = AU1XI2SC_RATES, | ||
| 221 | .formats = AU1XI2SC_FMTS, | ||
| 222 | .channels_min = 2, | ||
| 223 | .channels_max = 2, | ||
| 224 | }, | ||
| 225 | .ops = &au1xi2s_dai_ops, | ||
| 226 | }; | ||
| 227 | |||
| 228 | static int __devinit au1xi2s_drvprobe(struct platform_device *pdev) | ||
| 229 | { | ||
| 230 | int ret; | ||
| 231 | struct resource *iores, *dmares; | ||
| 232 | struct au1xpsc_audio_data *ctx; | ||
| 233 | |||
| 234 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | ||
| 235 | if (!ctx) | ||
| 236 | return -ENOMEM; | ||
| 237 | |||
| 238 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 239 | if (!iores) { | ||
| 240 | ret = -ENODEV; | ||
| 241 | goto out0; | ||
| 242 | } | ||
| 243 | |||
| 244 | ret = -EBUSY; | ||
| 245 | if (!request_mem_region(iores->start, resource_size(iores), | ||
| 246 | pdev->name)) | ||
| 247 | goto out0; | ||
| 248 | |||
| 249 | ctx->mmio = ioremap_nocache(iores->start, resource_size(iores)); | ||
| 250 | if (!ctx->mmio) | ||
| 251 | goto out1; | ||
| 252 | |||
| 253 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 254 | if (!dmares) | ||
| 255 | goto out2; | ||
| 256 | ctx->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; | ||
| 257 | |||
| 258 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 259 | if (!dmares) | ||
| 260 | goto out2; | ||
| 261 | ctx->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; | ||
| 262 | |||
| 263 | platform_set_drvdata(pdev, ctx); | ||
| 264 | |||
| 265 | ret = snd_soc_register_dai(&pdev->dev, &au1xi2s_dai_driver); | ||
| 266 | if (ret) | ||
| 267 | goto out2; | ||
| 268 | |||
| 269 | return 0; | ||
| 270 | |||
| 271 | out2: | ||
| 272 | iounmap(ctx->mmio); | ||
| 273 | out1: | ||
| 274 | release_mem_region(iores->start, resource_size(iores)); | ||
| 275 | out0: | ||
| 276 | kfree(ctx); | ||
| 277 | return ret; | ||
| 278 | } | ||
| 279 | |||
| 280 | static int __devexit au1xi2s_drvremove(struct platform_device *pdev) | ||
| 281 | { | ||
| 282 | struct au1xpsc_audio_data *ctx = platform_get_drvdata(pdev); | ||
| 283 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 284 | |||
| 285 | snd_soc_unregister_dai(&pdev->dev); | ||
| 286 | |||
| 287 | WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ | ||
| 288 | |||
| 289 | iounmap(ctx->mmio); | ||
| 290 | release_mem_region(r->start, resource_size(r)); | ||
| 291 | kfree(ctx); | ||
| 292 | |||
| 293 | return 0; | ||
| 294 | } | ||
| 295 | |||
| 296 | #ifdef CONFIG_PM | ||
| 297 | static int au1xi2s_drvsuspend(struct device *dev) | ||
| 298 | { | ||
| 299 | struct au1xpsc_audio_data *ctx = dev_get_drvdata(dev); | ||
| 300 | |||
| 301 | WR(ctx, I2S_ENABLE, EN_D); /* clock off, disable */ | ||
| 302 | |||
| 303 | return 0; | ||
| 304 | } | ||
| 305 | |||
| 306 | static int au1xi2s_drvresume(struct device *dev) | ||
| 307 | { | ||
| 308 | return 0; | ||
| 309 | } | ||
| 310 | |||
| 311 | static const struct dev_pm_ops au1xi2sc_pmops = { | ||
| 312 | .suspend = au1xi2s_drvsuspend, | ||
| 313 | .resume = au1xi2s_drvresume, | ||
| 314 | }; | ||
| 315 | |||
| 316 | #define AU1XI2SC_PMOPS (&au1xi2sc_pmops) | ||
| 317 | |||
| 318 | #else | ||
| 319 | |||
| 320 | #define AU1XI2SC_PMOPS NULL | ||
| 321 | |||
| 322 | #endif | ||
| 323 | |||
| 324 | static struct platform_driver au1xi2s_driver = { | ||
| 325 | .driver = { | ||
| 326 | .name = "alchemy-i2sc", | ||
| 327 | .owner = THIS_MODULE, | ||
| 328 | .pm = AU1XI2SC_PMOPS, | ||
| 329 | }, | ||
| 330 | .probe = au1xi2s_drvprobe, | ||
| 331 | .remove = __devexit_p(au1xi2s_drvremove), | ||
| 332 | }; | ||
| 333 | |||
| 334 | static int __init au1xi2s_load(void) | ||
| 335 | { | ||
| 336 | return platform_driver_register(&au1xi2s_driver); | ||
| 337 | } | ||
| 338 | |||
| 339 | static void __exit au1xi2s_unload(void) | ||
| 340 | { | ||
| 341 | platform_driver_unregister(&au1xi2s_driver); | ||
| 342 | } | ||
| 343 | |||
| 344 | module_init(au1xi2s_load); | ||
| 345 | module_exit(au1xi2s_unload); | ||
| 346 | |||
| 347 | MODULE_LICENSE("GPL"); | ||
| 348 | MODULE_DESCRIPTION("Au1000/1500/1100 I2S ASoC driver"); | ||
| 349 | MODULE_AUTHOR("Manuel Lauss"); | ||
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c index d0db66f24a00..0c6acd547141 100644 --- a/sound/soc/au1x/psc-ac97.c +++ b/sound/soc/au1x/psc-ac97.c | |||
| @@ -41,14 +41,14 @@ | |||
| 41 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE) | 41 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3BE) |
| 42 | 42 | ||
| 43 | #define AC97PCR_START(stype) \ | 43 | #define AC97PCR_START(stype) \ |
| 44 | ((stype) == PCM_TX ? PSC_AC97PCR_TS : PSC_AC97PCR_RS) | 44 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TS : PSC_AC97PCR_RS) |
| 45 | #define AC97PCR_STOP(stype) \ | 45 | #define AC97PCR_STOP(stype) \ |
| 46 | ((stype) == PCM_TX ? PSC_AC97PCR_TP : PSC_AC97PCR_RP) | 46 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TP : PSC_AC97PCR_RP) |
| 47 | #define AC97PCR_CLRFIFO(stype) \ | 47 | #define AC97PCR_CLRFIFO(stype) \ |
| 48 | ((stype) == PCM_TX ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) | 48 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97PCR_TC : PSC_AC97PCR_RC) |
| 49 | 49 | ||
| 50 | #define AC97STAT_BUSY(stype) \ | 50 | #define AC97STAT_BUSY(stype) \ |
| 51 | ((stype) == PCM_TX ? PSC_AC97STAT_TB : PSC_AC97STAT_RB) | 51 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_AC97STAT_TB : PSC_AC97STAT_RB) |
| 52 | 52 | ||
| 53 | /* instance data. There can be only one, MacLeod!!!! */ | 53 | /* instance data. There can be only one, MacLeod!!!! */ |
| 54 | static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; | 54 | static struct au1xpsc_audio_data *au1xpsc_ac97_workdata; |
| @@ -215,7 +215,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, | |||
| 215 | { | 215 | { |
| 216 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | 216 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); |
| 217 | unsigned long r, ro, stat; | 217 | unsigned long r, ro, stat; |
| 218 | int chans, t, stype = SUBSTREAM_TYPE(substream); | 218 | int chans, t, stype = substream->stream; |
| 219 | 219 | ||
| 220 | chans = params_channels(params); | 220 | chans = params_channels(params); |
| 221 | 221 | ||
| @@ -235,7 +235,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, | |||
| 235 | r |= PSC_AC97CFG_SET_LEN(params->msbits); | 235 | r |= PSC_AC97CFG_SET_LEN(params->msbits); |
| 236 | 236 | ||
| 237 | /* channels: enable slots for front L/R channel */ | 237 | /* channels: enable slots for front L/R channel */ |
| 238 | if (stype == PCM_TX) { | 238 | if (stype == SNDRV_PCM_STREAM_PLAYBACK) { |
| 239 | r &= ~PSC_AC97CFG_TXSLOT_MASK; | 239 | r &= ~PSC_AC97CFG_TXSLOT_MASK; |
| 240 | r |= PSC_AC97CFG_TXSLOT_ENA(3); | 240 | r |= PSC_AC97CFG_TXSLOT_ENA(3); |
| 241 | r |= PSC_AC97CFG_TXSLOT_ENA(4); | 241 | r |= PSC_AC97CFG_TXSLOT_ENA(4); |
| @@ -294,7 +294,7 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, | |||
| 294 | int cmd, struct snd_soc_dai *dai) | 294 | int cmd, struct snd_soc_dai *dai) |
| 295 | { | 295 | { |
| 296 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | 296 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); |
| 297 | int ret, stype = SUBSTREAM_TYPE(substream); | 297 | int ret, stype = substream->stream; |
| 298 | 298 | ||
| 299 | ret = 0; | 299 | ret = 0; |
| 300 | 300 | ||
| @@ -324,12 +324,21 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, | |||
| 324 | return ret; | 324 | return ret; |
| 325 | } | 325 | } |
| 326 | 326 | ||
| 327 | static int au1xpsc_ac97_startup(struct snd_pcm_substream *substream, | ||
| 328 | struct snd_soc_dai *dai) | ||
| 329 | { | ||
| 330 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | ||
| 331 | snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]); | ||
| 332 | return 0; | ||
| 333 | } | ||
| 334 | |||
| 327 | static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) | 335 | static int au1xpsc_ac97_probe(struct snd_soc_dai *dai) |
| 328 | { | 336 | { |
| 329 | return au1xpsc_ac97_workdata ? 0 : -ENODEV; | 337 | return au1xpsc_ac97_workdata ? 0 : -ENODEV; |
| 330 | } | 338 | } |
| 331 | 339 | ||
| 332 | static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { | 340 | static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { |
| 341 | .startup = au1xpsc_ac97_startup, | ||
| 333 | .trigger = au1xpsc_ac97_trigger, | 342 | .trigger = au1xpsc_ac97_trigger, |
| 334 | .hw_params = au1xpsc_ac97_hw_params, | 343 | .hw_params = au1xpsc_ac97_hw_params, |
| 335 | }; | 344 | }; |
| @@ -355,7 +364,7 @@ static const struct snd_soc_dai_driver au1xpsc_ac97_dai_template = { | |||
| 355 | static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) | 364 | static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) |
| 356 | { | 365 | { |
| 357 | int ret; | 366 | int ret; |
| 358 | struct resource *r; | 367 | struct resource *iores, *dmares; |
| 359 | unsigned long sel; | 368 | unsigned long sel; |
| 360 | struct au1xpsc_audio_data *wd; | 369 | struct au1xpsc_audio_data *wd; |
| 361 | 370 | ||
| @@ -365,20 +374,31 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) | |||
| 365 | 374 | ||
| 366 | mutex_init(&wd->lock); | 375 | mutex_init(&wd->lock); |
| 367 | 376 | ||
| 368 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 377 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 369 | if (!r) { | 378 | if (!iores) { |
| 370 | ret = -ENODEV; | 379 | ret = -ENODEV; |
| 371 | goto out0; | 380 | goto out0; |
| 372 | } | 381 | } |
| 373 | 382 | ||
| 374 | ret = -EBUSY; | 383 | ret = -EBUSY; |
| 375 | if (!request_mem_region(r->start, resource_size(r), pdev->name)) | 384 | if (!request_mem_region(iores->start, resource_size(iores), |
| 385 | pdev->name)) | ||
| 376 | goto out0; | 386 | goto out0; |
| 377 | 387 | ||
| 378 | wd->mmio = ioremap(r->start, resource_size(r)); | 388 | wd->mmio = ioremap(iores->start, resource_size(iores)); |
| 379 | if (!wd->mmio) | 389 | if (!wd->mmio) |
| 380 | goto out1; | 390 | goto out1; |
| 381 | 391 | ||
| 392 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 393 | if (!dmares) | ||
| 394 | goto out2; | ||
| 395 | wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; | ||
| 396 | |||
| 397 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 398 | if (!dmares) | ||
| 399 | goto out2; | ||
| 400 | wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; | ||
| 401 | |||
| 382 | /* configuration: max dma trigger threshold, enable ac97 */ | 402 | /* configuration: max dma trigger threshold, enable ac97 */ |
| 383 | wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | | 403 | wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 | |
| 384 | PSC_AC97CFG_DE_ENABLE; | 404 | PSC_AC97CFG_DE_ENABLE; |
| @@ -401,17 +421,15 @@ static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev) | |||
| 401 | 421 | ||
| 402 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); | 422 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); |
| 403 | if (ret) | 423 | if (ret) |
| 404 | goto out1; | 424 | goto out2; |
| 405 | 425 | ||
| 406 | wd->dmapd = au1xpsc_pcm_add(pdev); | 426 | au1xpsc_ac97_workdata = wd; |
| 407 | if (wd->dmapd) { | 427 | return 0; |
| 408 | au1xpsc_ac97_workdata = wd; | ||
| 409 | return 0; | ||
| 410 | } | ||
| 411 | 428 | ||
| 412 | snd_soc_unregister_dai(&pdev->dev); | 429 | out2: |
| 430 | iounmap(wd->mmio); | ||
| 413 | out1: | 431 | out1: |
| 414 | release_mem_region(r->start, resource_size(r)); | 432 | release_mem_region(iores->start, resource_size(iores)); |
| 415 | out0: | 433 | out0: |
| 416 | kfree(wd); | 434 | kfree(wd); |
| 417 | return ret; | 435 | return ret; |
| @@ -422,9 +440,6 @@ static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev) | |||
| 422 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); | 440 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); |
| 423 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 441 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 424 | 442 | ||
| 425 | if (wd->dmapd) | ||
| 426 | au1xpsc_pcm_destroy(wd->dmapd); | ||
| 427 | |||
| 428 | snd_soc_unregister_dai(&pdev->dev); | 443 | snd_soc_unregister_dai(&pdev->dev); |
| 429 | 444 | ||
| 430 | /* disable PSC completely */ | 445 | /* disable PSC completely */ |
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c index fca091276320..e03c5ce01b30 100644 --- a/sound/soc/au1x/psc-i2s.c +++ b/sound/soc/au1x/psc-i2s.c | |||
| @@ -42,13 +42,13 @@ | |||
| 42 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | 42 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) |
| 43 | 43 | ||
| 44 | #define I2SSTAT_BUSY(stype) \ | 44 | #define I2SSTAT_BUSY(stype) \ |
| 45 | ((stype) == PCM_TX ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB) | 45 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SSTAT_TB : PSC_I2SSTAT_RB) |
| 46 | #define I2SPCR_START(stype) \ | 46 | #define I2SPCR_START(stype) \ |
| 47 | ((stype) == PCM_TX ? PSC_I2SPCR_TS : PSC_I2SPCR_RS) | 47 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TS : PSC_I2SPCR_RS) |
| 48 | #define I2SPCR_STOP(stype) \ | 48 | #define I2SPCR_STOP(stype) \ |
| 49 | ((stype) == PCM_TX ? PSC_I2SPCR_TP : PSC_I2SPCR_RP) | 49 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TP : PSC_I2SPCR_RP) |
| 50 | #define I2SPCR_CLRFIFO(stype) \ | 50 | #define I2SPCR_CLRFIFO(stype) \ |
| 51 | ((stype) == PCM_TX ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) | 51 | ((stype) == SNDRV_PCM_STREAM_PLAYBACK ? PSC_I2SPCR_TC : PSC_I2SPCR_RC) |
| 52 | 52 | ||
| 53 | 53 | ||
| 54 | static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, | 54 | static int au1xpsc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, |
| @@ -240,7 +240,7 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 240 | struct snd_soc_dai *dai) | 240 | struct snd_soc_dai *dai) |
| 241 | { | 241 | { |
| 242 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | 242 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); |
| 243 | int ret, stype = SUBSTREAM_TYPE(substream); | 243 | int ret, stype = substream->stream; |
| 244 | 244 | ||
| 245 | switch (cmd) { | 245 | switch (cmd) { |
| 246 | case SNDRV_PCM_TRIGGER_START: | 246 | case SNDRV_PCM_TRIGGER_START: |
| @@ -257,7 +257,16 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 257 | return ret; | 257 | return ret; |
| 258 | } | 258 | } |
| 259 | 259 | ||
| 260 | static int au1xpsc_i2s_startup(struct snd_pcm_substream *substream, | ||
| 261 | struct snd_soc_dai *dai) | ||
| 262 | { | ||
| 263 | struct au1xpsc_audio_data *pscdata = snd_soc_dai_get_drvdata(dai); | ||
| 264 | snd_soc_dai_set_dma_data(dai, substream, &pscdata->dmaids[0]); | ||
| 265 | return 0; | ||
| 266 | } | ||
| 267 | |||
| 260 | static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { | 268 | static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { |
| 269 | .startup = au1xpsc_i2s_startup, | ||
| 261 | .trigger = au1xpsc_i2s_trigger, | 270 | .trigger = au1xpsc_i2s_trigger, |
| 262 | .hw_params = au1xpsc_i2s_hw_params, | 271 | .hw_params = au1xpsc_i2s_hw_params, |
| 263 | .set_fmt = au1xpsc_i2s_set_fmt, | 272 | .set_fmt = au1xpsc_i2s_set_fmt, |
| @@ -281,7 +290,7 @@ static const struct snd_soc_dai_driver au1xpsc_i2s_dai_template = { | |||
| 281 | 290 | ||
| 282 | static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) | 291 | static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) |
| 283 | { | 292 | { |
| 284 | struct resource *r; | 293 | struct resource *iores, *dmares; |
| 285 | unsigned long sel; | 294 | unsigned long sel; |
| 286 | int ret; | 295 | int ret; |
| 287 | struct au1xpsc_audio_data *wd; | 296 | struct au1xpsc_audio_data *wd; |
| @@ -290,20 +299,31 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) | |||
| 290 | if (!wd) | 299 | if (!wd) |
| 291 | return -ENOMEM; | 300 | return -ENOMEM; |
| 292 | 301 | ||
| 293 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 302 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 294 | if (!r) { | 303 | if (!iores) { |
| 295 | ret = -ENODEV; | 304 | ret = -ENODEV; |
| 296 | goto out0; | 305 | goto out0; |
| 297 | } | 306 | } |
| 298 | 307 | ||
| 299 | ret = -EBUSY; | 308 | ret = -EBUSY; |
| 300 | if (!request_mem_region(r->start, resource_size(r), pdev->name)) | 309 | if (!request_mem_region(iores->start, resource_size(iores), |
| 310 | pdev->name)) | ||
| 301 | goto out0; | 311 | goto out0; |
| 302 | 312 | ||
| 303 | wd->mmio = ioremap(r->start, resource_size(r)); | 313 | wd->mmio = ioremap(iores->start, resource_size(iores)); |
| 304 | if (!wd->mmio) | 314 | if (!wd->mmio) |
| 305 | goto out1; | 315 | goto out1; |
| 306 | 316 | ||
| 317 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 318 | if (!dmares) | ||
| 319 | goto out2; | ||
| 320 | wd->dmaids[SNDRV_PCM_STREAM_PLAYBACK] = dmares->start; | ||
| 321 | |||
| 322 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 1); | ||
| 323 | if (!dmares) | ||
| 324 | goto out2; | ||
| 325 | wd->dmaids[SNDRV_PCM_STREAM_CAPTURE] = dmares->start; | ||
| 326 | |||
| 307 | /* preserve PSC clock source set up by platform (dev.platform_data | 327 | /* preserve PSC clock source set up by platform (dev.platform_data |
| 308 | * is already occupied by soc layer) | 328 | * is already occupied by soc layer) |
| 309 | */ | 329 | */ |
| @@ -330,17 +350,13 @@ static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev) | |||
| 330 | platform_set_drvdata(pdev, wd); | 350 | platform_set_drvdata(pdev, wd); |
| 331 | 351 | ||
| 332 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); | 352 | ret = snd_soc_register_dai(&pdev->dev, &wd->dai_drv); |
| 333 | if (ret) | 353 | if (!ret) |
| 334 | goto out1; | ||
| 335 | |||
| 336 | /* finally add the DMA device for this PSC */ | ||
| 337 | wd->dmapd = au1xpsc_pcm_add(pdev); | ||
| 338 | if (wd->dmapd) | ||
| 339 | return 0; | 354 | return 0; |
| 340 | 355 | ||
| 341 | snd_soc_unregister_dai(&pdev->dev); | 356 | out2: |
| 357 | iounmap(wd->mmio); | ||
| 342 | out1: | 358 | out1: |
| 343 | release_mem_region(r->start, resource_size(r)); | 359 | release_mem_region(iores->start, resource_size(iores)); |
| 344 | out0: | 360 | out0: |
| 345 | kfree(wd); | 361 | kfree(wd); |
| 346 | return ret; | 362 | return ret; |
| @@ -351,9 +367,6 @@ static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev) | |||
| 351 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); | 367 | struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev); |
| 352 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 368 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 353 | 369 | ||
| 354 | if (wd->dmapd) | ||
| 355 | au1xpsc_pcm_destroy(wd->dmapd); | ||
| 356 | |||
| 357 | snd_soc_unregister_dai(&pdev->dev); | 370 | snd_soc_unregister_dai(&pdev->dev); |
| 358 | 371 | ||
| 359 | au_writel(0, I2S_CFG(wd)); | 372 | au_writel(0, I2S_CFG(wd)); |
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h index b30eadd422a7..b16b2e02e0c9 100644 --- a/sound/soc/au1x/psc.h +++ b/sound/soc/au1x/psc.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Au12x0/Au1550 PSC ALSA ASoC audio support. | 2 | * Alchemy ALSA ASoC audio support. |
| 3 | * | 3 | * |
| 4 | * (c) 2007-2008 MSC Vertriebsges.m.b.H., | 4 | * (c) 2007-2011 MSC Vertriebsges.m.b.H., |
| 5 | * Manuel Lauss <manuel.lauss@gmail.com> | 5 | * Manuel Lauss <manuel.lauss@gmail.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -13,10 +13,6 @@ | |||
| 13 | #ifndef _AU1X_PCM_H | 13 | #ifndef _AU1X_PCM_H |
| 14 | #define _AU1X_PCM_H | 14 | #define _AU1X_PCM_H |
| 15 | 15 | ||
| 16 | /* DBDMA helpers */ | ||
| 17 | extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev); | ||
| 18 | extern void au1xpsc_pcm_destroy(struct platform_device *dmapd); | ||
| 19 | |||
| 20 | struct au1xpsc_audio_data { | 16 | struct au1xpsc_audio_data { |
| 21 | void __iomem *mmio; | 17 | void __iomem *mmio; |
| 22 | 18 | ||
| @@ -27,15 +23,9 @@ struct au1xpsc_audio_data { | |||
| 27 | 23 | ||
| 28 | unsigned long pm[2]; | 24 | unsigned long pm[2]; |
| 29 | struct mutex lock; | 25 | struct mutex lock; |
| 30 | struct platform_device *dmapd; | 26 | int dmaids[2]; |
| 31 | }; | 27 | }; |
| 32 | 28 | ||
| 33 | #define PCM_TX 0 | ||
| 34 | #define PCM_RX 1 | ||
| 35 | |||
| 36 | #define SUBSTREAM_TYPE(substream) \ | ||
| 37 | ((substream)->stream == SNDRV_PCM_STREAM_PLAYBACK ? PCM_TX : PCM_RX) | ||
| 38 | |||
| 39 | /* easy access macros */ | 29 | /* easy access macros */ |
| 40 | #define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) | 30 | #define PSC_CTRL(x) ((unsigned long)((x)->mmio) + PSC_CTRL_OFFSET) |
| 41 | #define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) | 31 | #define PSC_SEL(x) ((unsigned long)((x)->mmio) + PSC_SEL_OFFSET) |
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig index fe9d548a6837..9f6bc55fc399 100644 --- a/sound/soc/blackfin/Kconfig +++ b/sound/soc/blackfin/Kconfig | |||
| @@ -27,6 +27,19 @@ config SND_SOC_BFIN_EVAL_ADAU1701 | |||
| 27 | board connected to one of the Blackfin evaluation boards like the | 27 | board connected to one of the Blackfin evaluation boards like the |
| 28 | BF5XX-STAMP or BF5XX-EZKIT. | 28 | BF5XX-STAMP or BF5XX-EZKIT. |
| 29 | 29 | ||
| 30 | config SND_SOC_BFIN_EVAL_ADAU1373 | ||
| 31 | tristate "Support for the EVAL-ADAU1373 board on Blackfin eval boards" | ||
| 32 | depends on SND_BF5XX_I2S && I2C | ||
| 33 | select SND_BF5XX_SOC_I2S | ||
| 34 | select SND_SOC_ADAU1373 | ||
| 35 | help | ||
| 36 | Say Y if you want to add support for the Analog Devices EVAL-ADAU1373 | ||
| 37 | board connected to one of the Blackfin evaluation boards like the | ||
| 38 | BF5XX-STAMP or BF5XX-EZKIT. | ||
| 39 | |||
| 40 | Note: This driver assumes that first ADAU1373 DAI is connected to the | ||
| 41 | first SPORT port on the BF5XX board. | ||
| 42 | |||
| 30 | config SND_SOC_BFIN_EVAL_ADAV80X | 43 | config SND_SOC_BFIN_EVAL_ADAV80X |
| 31 | tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" | 44 | tristate "Support for the EVAL-ADAV80X boards on Blackfin eval boards" |
| 32 | depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) | 45 | depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) |
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile index 6018bf52a234..1bf86ccaa8de 100644 --- a/sound/soc/blackfin/Makefile +++ b/sound/soc/blackfin/Makefile | |||
| @@ -21,6 +21,7 @@ snd-ad1980-objs := bf5xx-ad1980.o | |||
| 21 | snd-ssm2602-objs := bf5xx-ssm2602.o | 21 | snd-ssm2602-objs := bf5xx-ssm2602.o |
| 22 | snd-ad73311-objs := bf5xx-ad73311.o | 22 | snd-ad73311-objs := bf5xx-ad73311.o |
| 23 | snd-ad193x-objs := bf5xx-ad193x.o | 23 | snd-ad193x-objs := bf5xx-ad193x.o |
| 24 | snd-soc-bfin-eval-adau1373-objs := bfin-eval-adau1373.o | ||
| 24 | snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o | 25 | snd-soc-bfin-eval-adau1701-objs := bfin-eval-adau1701.o |
| 25 | snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o | 26 | snd-soc-bfin-eval-adav80x-objs := bfin-eval-adav80x.o |
| 26 | 27 | ||
| @@ -29,5 +30,6 @@ obj-$(CONFIG_SND_BF5XX_SOC_AD1980) += snd-ad1980.o | |||
| 29 | obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o | 30 | obj-$(CONFIG_SND_BF5XX_SOC_SSM2602) += snd-ssm2602.o |
| 30 | obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o | 31 | obj-$(CONFIG_SND_BF5XX_SOC_AD73311) += snd-ad73311.o |
| 31 | obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o | 32 | obj-$(CONFIG_SND_BF5XX_SOC_AD193X) += snd-ad193x.o |
| 33 | obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1373) += snd-soc-bfin-eval-adau1373.o | ||
| 32 | obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o | 34 | obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAU1701) += snd-soc-bfin-eval-adau1701.o |
| 33 | obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o | 35 | obj-$(CONFIG_SND_SOC_BFIN_EVAL_ADAV80X) += snd-soc-bfin-eval-adav80x.o |
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c index 9e59f680bc19..56815c1d47b3 100644 --- a/sound/soc/blackfin/bf5xx-ac97-pcm.c +++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c | |||
| @@ -418,7 +418,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | |||
| 418 | 418 | ||
| 419 | static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); | 419 | static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); |
| 420 | 420 | ||
| 421 | int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd) | 421 | static int bf5xx_pcm_ac97_new(struct snd_soc_pcm_runtime *rtd) |
| 422 | { | 422 | { |
| 423 | struct snd_card *card = rtd->card->snd_card; | 423 | struct snd_card *card = rtd->card->snd_card; |
| 424 | struct snd_soc_dai *dai = rtd->cpu_dai; | 424 | struct snd_soc_dai *dai = rtd->cpu_dai; |
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index 61ddf942fd4d..7565e1576ffa 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c | |||
| @@ -257,7 +257,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm) | |||
| 257 | 257 | ||
| 258 | static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); | 258 | static u64 bf5xx_pcm_dmamask = DMA_BIT_MASK(32); |
| 259 | 259 | ||
| 260 | int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) | 260 | static int bf5xx_pcm_i2s_new(struct snd_soc_pcm_runtime *rtd) |
| 261 | { | 261 | { |
| 262 | struct snd_card *card = rtd->card->snd_card; | 262 | struct snd_card *card = rtd->card->snd_card; |
| 263 | struct snd_soc_dai *dai = rtd->cpu_dai; | 263 | struct snd_soc_dai *dai = rtd->cpu_dai; |
diff --git a/sound/soc/blackfin/bfin-eval-adau1373.c b/sound/soc/blackfin/bfin-eval-adau1373.c new file mode 100644 index 000000000000..8df2a3b0cb36 --- /dev/null +++ b/sound/soc/blackfin/bfin-eval-adau1373.c | |||
| @@ -0,0 +1,202 @@ | |||
| 1 | /* | ||
| 2 | * Machine driver for EVAL-ADAU1373 on Analog Devices bfin | ||
| 3 | * evaluation boards. | ||
| 4 | * | ||
| 5 | * Copyright 2011 Analog Devices Inc. | ||
| 6 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
| 7 | * | ||
| 8 | * Licensed under the GPL-2 or later. | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/module.h> | ||
| 12 | #include <linux/device.h> | ||
| 13 | #include <sound/core.h> | ||
| 14 | #include <sound/pcm.h> | ||
| 15 | #include <sound/soc.h> | ||
| 16 | #include <sound/pcm_params.h> | ||
| 17 | |||
| 18 | #include "../codecs/adau1373.h" | ||
| 19 | |||
| 20 | static const struct snd_soc_dapm_widget bfin_eval_adau1373_dapm_widgets[] = { | ||
| 21 | SND_SOC_DAPM_LINE("Line In1", NULL), | ||
| 22 | SND_SOC_DAPM_LINE("Line In2", NULL), | ||
| 23 | SND_SOC_DAPM_LINE("Line In3", NULL), | ||
| 24 | SND_SOC_DAPM_LINE("Line In4", NULL), | ||
| 25 | |||
| 26 | SND_SOC_DAPM_LINE("Line Out1", NULL), | ||
| 27 | SND_SOC_DAPM_LINE("Line Out2", NULL), | ||
| 28 | SND_SOC_DAPM_LINE("Stereo Out", NULL), | ||
| 29 | SND_SOC_DAPM_HP("Headphone", NULL), | ||
| 30 | SND_SOC_DAPM_HP("Earpiece", NULL), | ||
| 31 | SND_SOC_DAPM_SPK("Speaker", NULL), | ||
| 32 | }; | ||
| 33 | |||
| 34 | static const struct snd_soc_dapm_route bfin_eval_adau1373_dapm_routes[] = { | ||
| 35 | { "AIN1L", NULL, "Line In1" }, | ||
| 36 | { "AIN1R", NULL, "Line In1" }, | ||
| 37 | { "AIN2L", NULL, "Line In2" }, | ||
| 38 | { "AIN2R", NULL, "Line In2" }, | ||
| 39 | { "AIN3L", NULL, "Line In3" }, | ||
| 40 | { "AIN3R", NULL, "Line In3" }, | ||
| 41 | { "AIN4L", NULL, "Line In4" }, | ||
| 42 | { "AIN4R", NULL, "Line In4" }, | ||
| 43 | |||
| 44 | /* MICBIAS can be connected via a jumper to the line-in jack, since w | ||
| 45 | don't know which one is going to be used, just power both. */ | ||
| 46 | { "Line In1", NULL, "MICBIAS1" }, | ||
| 47 | { "Line In2", NULL, "MICBIAS1" }, | ||
| 48 | { "Line In3", NULL, "MICBIAS1" }, | ||
| 49 | { "Line In4", NULL, "MICBIAS1" }, | ||
| 50 | { "Line In1", NULL, "MICBIAS2" }, | ||
| 51 | { "Line In2", NULL, "MICBIAS2" }, | ||
| 52 | { "Line In3", NULL, "MICBIAS2" }, | ||
| 53 | { "Line In4", NULL, "MICBIAS2" }, | ||
| 54 | |||
| 55 | { "Line Out1", NULL, "LOUT1L" }, | ||
| 56 | { "Line Out1", NULL, "LOUT1R" }, | ||
| 57 | { "Line Out2", NULL, "LOUT2L" }, | ||
| 58 | { "Line Out2", NULL, "LOUT2R" }, | ||
| 59 | { "Headphone", NULL, "HPL" }, | ||
| 60 | { "Headphone", NULL, "HPR" }, | ||
| 61 | { "Earpiece", NULL, "EP" }, | ||
| 62 | { "Speaker", NULL, "SPKL" }, | ||
| 63 | { "Stereo Out", NULL, "SPKR" }, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static int bfin_eval_adau1373_hw_params(struct snd_pcm_substream *substream, | ||
| 67 | struct snd_pcm_hw_params *params) | ||
| 68 | { | ||
| 69 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 70 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 71 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 72 | int ret; | ||
| 73 | int pll_rate; | ||
| 74 | |||
| 75 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | | ||
| 76 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
| 77 | if (ret) | ||
| 78 | return ret; | ||
| 79 | |||
| 80 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | | ||
| 81 | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); | ||
| 82 | if (ret) | ||
| 83 | return ret; | ||
| 84 | |||
| 85 | switch (params_rate(params)) { | ||
| 86 | case 48000: | ||
| 87 | case 8000: | ||
| 88 | case 12000: | ||
| 89 | case 16000: | ||
| 90 | case 24000: | ||
| 91 | case 32000: | ||
| 92 | pll_rate = 48000 * 1024; | ||
| 93 | break; | ||
| 94 | case 44100: | ||
| 95 | case 7350: | ||
| 96 | case 11025: | ||
| 97 | case 14700: | ||
| 98 | case 22050: | ||
| 99 | case 29400: | ||
| 100 | pll_rate = 44100 * 1024; | ||
| 101 | break; | ||
| 102 | default: | ||
| 103 | return -EINVAL; | ||
| 104 | } | ||
| 105 | |||
| 106 | ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1, | ||
| 107 | ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate); | ||
| 108 | if (ret) | ||
| 109 | return ret; | ||
| 110 | |||
| 111 | ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate, | ||
| 112 | SND_SOC_CLOCK_IN); | ||
| 113 | |||
| 114 | return ret; | ||
| 115 | } | ||
| 116 | |||
| 117 | static int bfin_eval_adau1373_codec_init(struct snd_soc_pcm_runtime *rtd) | ||
| 118 | { | ||
| 119 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 120 | unsigned int pll_rate = 48000 * 1024; | ||
| 121 | int ret; | ||
| 122 | |||
| 123 | ret = snd_soc_dai_set_pll(codec_dai, ADAU1373_PLL1, | ||
| 124 | ADAU1373_PLL_SRC_MCLK1, 12288000, pll_rate); | ||
| 125 | if (ret) | ||
| 126 | return ret; | ||
| 127 | |||
| 128 | ret = snd_soc_dai_set_sysclk(codec_dai, ADAU1373_CLK_SRC_PLL1, pll_rate, | ||
| 129 | SND_SOC_CLOCK_IN); | ||
| 130 | |||
| 131 | return ret; | ||
| 132 | } | ||
| 133 | static struct snd_soc_ops bfin_eval_adau1373_ops = { | ||
| 134 | .hw_params = bfin_eval_adau1373_hw_params, | ||
| 135 | }; | ||
| 136 | |||
| 137 | static struct snd_soc_dai_link bfin_eval_adau1373_dai = { | ||
| 138 | .name = "adau1373", | ||
| 139 | .stream_name = "adau1373", | ||
| 140 | .cpu_dai_name = "bfin-i2s.0", | ||
| 141 | .codec_dai_name = "adau1373-aif1", | ||
| 142 | .platform_name = "bfin-i2s-pcm-audio", | ||
| 143 | .codec_name = "adau1373.0-001a", | ||
| 144 | .ops = &bfin_eval_adau1373_ops, | ||
| 145 | .init = bfin_eval_adau1373_codec_init, | ||
| 146 | }; | ||
| 147 | |||
| 148 | static struct snd_soc_card bfin_eval_adau1373 = { | ||
| 149 | .name = "bfin-eval-adau1373", | ||
| 150 | .dai_link = &bfin_eval_adau1373_dai, | ||
| 151 | .num_links = 1, | ||
| 152 | |||
| 153 | .dapm_widgets = bfin_eval_adau1373_dapm_widgets, | ||
| 154 | .num_dapm_widgets = ARRAY_SIZE(bfin_eval_adau1373_dapm_widgets), | ||
| 155 | .dapm_routes = bfin_eval_adau1373_dapm_routes, | ||
| 156 | .num_dapm_routes = ARRAY_SIZE(bfin_eval_adau1373_dapm_routes), | ||
| 157 | }; | ||
| 158 | |||
| 159 | static int bfin_eval_adau1373_probe(struct platform_device *pdev) | ||
| 160 | { | ||
| 161 | struct snd_soc_card *card = &bfin_eval_adau1373; | ||
| 162 | |||
| 163 | card->dev = &pdev->dev; | ||
| 164 | |||
| 165 | return snd_soc_register_card(&bfin_eval_adau1373); | ||
| 166 | } | ||
| 167 | |||
| 168 | static int __devexit bfin_eval_adau1373_remove(struct platform_device *pdev) | ||
| 169 | { | ||
| 170 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 171 | |||
| 172 | snd_soc_unregister_card(card); | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
| 176 | |||
| 177 | static struct platform_driver bfin_eval_adau1373_driver = { | ||
| 178 | .driver = { | ||
| 179 | .name = "bfin-eval-adau1373", | ||
| 180 | .owner = THIS_MODULE, | ||
| 181 | .pm = &snd_soc_pm_ops, | ||
| 182 | }, | ||
| 183 | .probe = bfin_eval_adau1373_probe, | ||
| 184 | .remove = __devexit_p(bfin_eval_adau1373_remove), | ||
| 185 | }; | ||
| 186 | |||
| 187 | static int __init bfin_eval_adau1373_init(void) | ||
| 188 | { | ||
| 189 | return platform_driver_register(&bfin_eval_adau1373_driver); | ||
| 190 | } | ||
| 191 | module_init(bfin_eval_adau1373_init); | ||
| 192 | |||
| 193 | static void __exit bfin_eval_adau1373_exit(void) | ||
| 194 | { | ||
| 195 | platform_driver_unregister(&bfin_eval_adau1373_driver); | ||
| 196 | } | ||
| 197 | module_exit(bfin_eval_adau1373_exit); | ||
| 198 | |||
| 199 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
| 200 | MODULE_DESCRIPTION("ALSA SoC bfin adau1373 driver"); | ||
| 201 | MODULE_LICENSE("GPL"); | ||
| 202 | MODULE_ALIAS("platform:bfin-eval-adau1373"); | ||
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 19241576b6b5..5ca122e51183 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| 16 | #include <linux/mfd/88pm860x.h> | 16 | #include <linux/mfd/88pm860x.h> |
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | #include <linux/delay.h> | ||
| 18 | #include <sound/core.h> | 19 | #include <sound/core.h> |
| 19 | #include <sound/pcm.h> | 20 | #include <sound/pcm.h> |
| 20 | #include <sound/pcm_params.h> | 21 | #include <sound/pcm_params.h> |
| @@ -772,11 +773,12 @@ static const struct snd_soc_dapm_widget pm860x_dapm_widgets[] = { | |||
| 772 | 773 | ||
| 773 | 774 | ||
| 774 | SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0, | 775 | SND_SOC_DAPM_AIF_IN("I2S DIN", "I2S Playback", 0, |
| 775 | PM860X_DAC_EN_2, 0, 0), | 776 | SND_SOC_NOPM, 0, 0), |
| 776 | SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0, | 777 | SND_SOC_DAPM_AIF_IN("I2S DIN1", "I2S Playback", 0, |
| 777 | PM860X_DAC_EN_2, 0, 0), | 778 | SND_SOC_NOPM, 0, 0), |
| 778 | SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0, | 779 | SND_SOC_DAPM_AIF_OUT("I2S DOUT", "I2S Capture", 0, |
| 779 | PM860X_I2S_IFACE_3, 5, 1), | 780 | PM860X_I2S_IFACE_3, 5, 1), |
| 781 | SND_SOC_DAPM_SUPPLY("I2S CLK", PM860X_DAC_EN_2, 0, 0, NULL, 0), | ||
| 780 | SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux), | 782 | SND_SOC_DAPM_MUX("I2S Mic Mux", SND_SOC_NOPM, 0, 0, &i2s_mic_mux), |
| 781 | SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux), | 783 | SND_SOC_DAPM_MUX("ADC Left Mux", SND_SOC_NOPM, 0, 0, &adcl_mux), |
| 782 | SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), | 784 | SND_SOC_DAPM_MUX("ADC Right Mux", SND_SOC_NOPM, 0, 0, &adcr_mux), |
| @@ -868,6 +870,11 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 868 | {"Left ADC", NULL, "Left ADC MOD"}, | 870 | {"Left ADC", NULL, "Left ADC MOD"}, |
| 869 | {"Right ADC", NULL, "Right ADC MOD"}, | 871 | {"Right ADC", NULL, "Right ADC MOD"}, |
| 870 | 872 | ||
| 873 | /* I2S Clock */ | ||
| 874 | {"I2S DIN", NULL, "I2S CLK"}, | ||
| 875 | {"I2S DIN1", NULL, "I2S CLK"}, | ||
| 876 | {"I2S DOUT", NULL, "I2S CLK"}, | ||
| 877 | |||
| 871 | /* PCM/AIF1 Inputs */ | 878 | /* PCM/AIF1 Inputs */ |
| 872 | {"PCM SDO", NULL, "ADC Left Mux"}, | 879 | {"PCM SDO", NULL, "ADC Left Mux"}, |
| 873 | {"PCM SDO", NULL, "ADCR EC Mux"}, | 880 | {"PCM SDO", NULL, "ADCR EC Mux"}, |
| @@ -1173,6 +1180,9 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, | |||
| 1173 | case SND_SOC_BIAS_STANDBY: | 1180 | case SND_SOC_BIAS_STANDBY: |
| 1174 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 1181 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 1175 | /* Enable Audio PLL & Audio section */ | 1182 | /* Enable Audio PLL & Audio section */ |
| 1183 | data = AUDIO_PLL | AUDIO_SECTION_ON; | ||
| 1184 | pm860x_reg_write(codec->control_data, REG_MISC2, data); | ||
| 1185 | udelay(300); | ||
| 1176 | data = AUDIO_PLL | AUDIO_SECTION_RESET | 1186 | data = AUDIO_PLL | AUDIO_SECTION_RESET |
| 1177 | | AUDIO_SECTION_ON; | 1187 | | AUDIO_SECTION_ON; |
| 1178 | pm860x_reg_write(codec->control_data, REG_MISC2, data); | 1188 | pm860x_reg_write(codec->control_data, REG_MISC2, data); |
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 665d9240c4ae..4584514d93d4 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig | |||
| @@ -17,6 +17,7 @@ config SND_SOC_ALL_CODECS | |||
| 17 | select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI | 17 | select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI |
| 18 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS | 18 | select SND_SOC_AD1980 if SND_SOC_AC97_BUS |
| 19 | select SND_SOC_AD73311 | 19 | select SND_SOC_AD73311 |
| 20 | select SND_SOC_ADAU1373 if I2C | ||
| 20 | select SND_SOC_ADAV80X | 21 | select SND_SOC_ADAV80X |
| 21 | select SND_SOC_ADS117X | 22 | select SND_SOC_ADS117X |
| 22 | select SND_SOC_AK4104 if SPI_MASTER | 23 | select SND_SOC_AK4104 if SPI_MASTER |
| @@ -39,6 +40,7 @@ config SND_SOC_ALL_CODECS | |||
| 39 | select SND_SOC_MAX9850 if I2C | 40 | select SND_SOC_MAX9850 if I2C |
| 40 | select SND_SOC_MAX9877 if I2C | 41 | select SND_SOC_MAX9877 if I2C |
| 41 | select SND_SOC_PCM3008 | 42 | select SND_SOC_PCM3008 |
| 43 | select SND_SOC_RT5631 if I2C | ||
| 42 | select SND_SOC_SGTL5000 if I2C | 44 | select SND_SOC_SGTL5000 if I2C |
| 43 | select SND_SOC_SN95031 if INTEL_SCU_IPC | 45 | select SND_SOC_SN95031 if INTEL_SCU_IPC |
| 44 | select SND_SOC_SPDIF | 46 | select SND_SOC_SPDIF |
| @@ -47,7 +49,7 @@ config SND_SOC_ALL_CODECS | |||
| 47 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS | 49 | select SND_SOC_STAC9766 if SND_SOC_AC97_BUS |
| 48 | select SND_SOC_TLV320AIC23 if I2C | 50 | select SND_SOC_TLV320AIC23 if I2C |
| 49 | select SND_SOC_TLV320AIC26 if SPI_MASTER | 51 | select SND_SOC_TLV320AIC26 if SPI_MASTER |
| 50 | select SND_SOC_TVL320AIC32X4 if I2C | 52 | select SND_SOC_TLV320AIC32X4 if I2C |
| 51 | select SND_SOC_TLV320AIC3X if I2C | 53 | select SND_SOC_TLV320AIC3X if I2C |
| 52 | select SND_SOC_TPA6130A2 if I2C | 54 | select SND_SOC_TPA6130A2 if I2C |
| 53 | select SND_SOC_TLV320DAC33 if I2C | 55 | select SND_SOC_TLV320DAC33 if I2C |
| @@ -58,6 +60,7 @@ config SND_SOC_ALL_CODECS | |||
| 58 | select SND_SOC_WL1273 if MFD_WL1273_CORE | 60 | select SND_SOC_WL1273 if MFD_WL1273_CORE |
| 59 | select SND_SOC_WM1250_EV1 if I2C | 61 | select SND_SOC_WM1250_EV1 if I2C |
| 60 | select SND_SOC_WM2000 if I2C | 62 | select SND_SOC_WM2000 if I2C |
| 63 | select SND_SOC_WM5100 if I2C | ||
| 61 | select SND_SOC_WM8350 if MFD_WM8350 | 64 | select SND_SOC_WM8350 if MFD_WM8350 |
| 62 | select SND_SOC_WM8400 if MFD_WM8400 | 65 | select SND_SOC_WM8400 if MFD_WM8400 |
| 63 | select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI | 66 | select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI |
| @@ -139,6 +142,9 @@ config SND_SOC_ADAU1701 | |||
| 139 | select SIGMA | 142 | select SIGMA |
| 140 | tristate | 143 | tristate |
| 141 | 144 | ||
| 145 | config SND_SOC_ADAU1373 | ||
| 146 | tristate | ||
| 147 | |||
| 142 | config SND_SOC_ADAV80X | 148 | config SND_SOC_ADAV80X |
| 143 | tristate | 149 | tristate |
| 144 | 150 | ||
| @@ -214,6 +220,9 @@ config SND_SOC_MAX9850 | |||
| 214 | config SND_SOC_PCM3008 | 220 | config SND_SOC_PCM3008 |
| 215 | tristate | 221 | tristate |
| 216 | 222 | ||
| 223 | config SND_SOC_RT5631 | ||
| 224 | tristate | ||
| 225 | |||
| 217 | #Freescale sgtl5000 codec | 226 | #Freescale sgtl5000 codec |
| 218 | config SND_SOC_SGTL5000 | 227 | config SND_SOC_SGTL5000 |
| 219 | tristate | 228 | tristate |
| @@ -240,7 +249,7 @@ config SND_SOC_TLV320AIC26 | |||
| 240 | tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE | 249 | tristate "TI TLV320AIC26 Codec support" if SND_SOC_OF_SIMPLE |
| 241 | depends on SPI | 250 | depends on SPI |
| 242 | 251 | ||
| 243 | config SND_SOC_TVL320AIC32X4 | 252 | config SND_SOC_TLV320AIC32X4 |
| 244 | tristate | 253 | tristate |
| 245 | 254 | ||
| 246 | config SND_SOC_TLV320AIC3X | 255 | config SND_SOC_TLV320AIC3X |
| @@ -269,6 +278,9 @@ config SND_SOC_WL1273 | |||
| 269 | config SND_SOC_WM1250_EV1 | 278 | config SND_SOC_WM1250_EV1 |
| 270 | tristate | 279 | tristate |
| 271 | 280 | ||
| 281 | config SND_SOC_WM5100 | ||
| 282 | tristate | ||
| 283 | |||
| 272 | config SND_SOC_WM8350 | 284 | config SND_SOC_WM8350 |
| 273 | tristate | 285 | tristate |
| 274 | 286 | ||
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 5119a7e2c1a8..a2c7842e357b 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile | |||
| @@ -5,6 +5,7 @@ snd-soc-ad193x-objs := ad193x.o | |||
| 5 | snd-soc-ad1980-objs := ad1980.o | 5 | snd-soc-ad1980-objs := ad1980.o |
| 6 | snd-soc-ad73311-objs := ad73311.o | 6 | snd-soc-ad73311-objs := ad73311.o |
| 7 | snd-soc-adau1701-objs := adau1701.o | 7 | snd-soc-adau1701-objs := adau1701.o |
| 8 | snd-soc-adau1373-objs := adau1373.o | ||
| 8 | snd-soc-adav80x-objs := adav80x.o | 9 | snd-soc-adav80x-objs := adav80x.o |
| 9 | snd-soc-ads117x-objs := ads117x.o | 10 | snd-soc-ads117x-objs := ads117x.o |
| 10 | snd-soc-ak4104-objs := ak4104.o | 11 | snd-soc-ak4104-objs := ak4104.o |
| @@ -25,6 +26,7 @@ snd-soc-max98088-objs := max98088.o | |||
| 25 | snd-soc-max98095-objs := max98095.o | 26 | snd-soc-max98095-objs := max98095.o |
| 26 | snd-soc-max9850-objs := max9850.o | 27 | snd-soc-max9850-objs := max9850.o |
| 27 | snd-soc-pcm3008-objs := pcm3008.o | 28 | snd-soc-pcm3008-objs := pcm3008.o |
| 29 | snd-soc-rt5631-objs := rt5631.o | ||
| 28 | snd-soc-sgtl5000-objs := sgtl5000.o | 30 | snd-soc-sgtl5000-objs := sgtl5000.o |
| 29 | snd-soc-alc5623-objs := alc5623.o | 31 | snd-soc-alc5623-objs := alc5623.o |
| 30 | snd-soc-sn95031-objs := sn95031.o | 32 | snd-soc-sn95031-objs := sn95031.o |
| @@ -43,6 +45,7 @@ snd-soc-uda134x-objs := uda134x.o | |||
| 43 | snd-soc-uda1380-objs := uda1380.o | 45 | snd-soc-uda1380-objs := uda1380.o |
| 44 | snd-soc-wl1273-objs := wl1273.o | 46 | snd-soc-wl1273-objs := wl1273.o |
| 45 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o | 47 | snd-soc-wm1250-ev1-objs := wm1250-ev1.o |
| 48 | snd-soc-wm5100-objs := wm5100.o wm5100-tables.o | ||
| 46 | snd-soc-wm8350-objs := wm8350.o | 49 | snd-soc-wm8350-objs := wm8350.o |
| 47 | snd-soc-wm8400-objs := wm8400.o | 50 | snd-soc-wm8400-objs := wm8400.o |
| 48 | snd-soc-wm8510-objs := wm8510.o | 51 | snd-soc-wm8510-objs := wm8510.o |
| @@ -100,6 +103,7 @@ obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o | |||
| 100 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o | 103 | obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o |
| 101 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o | 104 | obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o |
| 102 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o | 105 | obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o |
| 106 | obj-$(CONFIG_SND_SOC_ADAU1373) += snd-soc-adau1373.o | ||
| 103 | obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o | 107 | obj-$(CONFIG_SND_SOC_ADAU1701) += snd-soc-adau1701.o |
| 104 | obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o | 108 | obj-$(CONFIG_SND_SOC_ADAV80X) += snd-soc-adav80x.o |
| 105 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o | 109 | obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o |
| @@ -123,6 +127,7 @@ obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o | |||
| 123 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o | 127 | obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o |
| 124 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o | 128 | obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o |
| 125 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o | 129 | obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o |
| 130 | obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o | ||
| 126 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o | 131 | obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o |
| 127 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o | 132 | obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o |
| 128 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o | 133 | obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o |
| @@ -132,7 +137,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o | |||
| 132 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o | 137 | obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o |
| 133 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o | 138 | obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o |
| 134 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o | 139 | obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o |
| 135 | obj-$(CONFIG_SND_SOC_TVL320AIC32X4) += snd-soc-tlv320aic32x4.o | 140 | obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o |
| 136 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o | 141 | obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o |
| 137 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o | 142 | obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o |
| 138 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o | 143 | obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o |
| @@ -140,6 +145,7 @@ obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o | |||
| 140 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o | 145 | obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o |
| 141 | obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o | 146 | obj-$(CONFIG_SND_SOC_WL1273) += snd-soc-wl1273.o |
| 142 | obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o | 147 | obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o |
| 148 | obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o | ||
| 143 | obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o | 149 | obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o |
| 144 | obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o | 150 | obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o |
| 145 | obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o | 151 | obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o |
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index eedb6f5e5823..120602130b5c 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | 23 | ||
| 24 | /* codec private data */ | 24 | /* codec private data */ |
| 25 | struct ad193x_priv { | 25 | struct ad193x_priv { |
| 26 | enum snd_soc_control_type control_type; | 26 | struct regmap *regmap; |
| 27 | int sysclk; | 27 | int sysclk; |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| @@ -103,12 +103,14 @@ static const struct snd_soc_dapm_route audio_paths[] = { | |||
| 103 | static int ad193x_mute(struct snd_soc_dai *dai, int mute) | 103 | static int ad193x_mute(struct snd_soc_dai *dai, int mute) |
| 104 | { | 104 | { |
| 105 | struct snd_soc_codec *codec = dai->codec; | 105 | struct snd_soc_codec *codec = dai->codec; |
| 106 | int reg; | ||
| 107 | 106 | ||
| 108 | reg = snd_soc_read(codec, AD193X_DAC_CTRL2); | 107 | if (mute) |
| 109 | reg = (mute > 0) ? reg | AD193X_DAC_MASTER_MUTE : reg & | 108 | snd_soc_update_bits(codec, AD193X_DAC_CTRL2, |
| 110 | (~AD193X_DAC_MASTER_MUTE); | 109 | AD193X_DAC_MASTER_MUTE, |
| 111 | snd_soc_write(codec, AD193X_DAC_CTRL2, reg); | 110 | AD193X_DAC_MASTER_MUTE); |
| 111 | else | ||
| 112 | snd_soc_update_bits(codec, AD193X_DAC_CTRL2, | ||
| 113 | AD193X_DAC_MASTER_MUTE, 0); | ||
| 112 | 114 | ||
| 113 | return 0; | 115 | return 0; |
| 114 | } | 116 | } |
| @@ -262,7 +264,7 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, | |||
| 262 | struct snd_pcm_hw_params *params, | 264 | struct snd_pcm_hw_params *params, |
| 263 | struct snd_soc_dai *dai) | 265 | struct snd_soc_dai *dai) |
| 264 | { | 266 | { |
| 265 | int word_len = 0, reg = 0, master_rate = 0; | 267 | int word_len = 0, master_rate = 0; |
| 266 | 268 | ||
| 267 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 269 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 268 | struct snd_soc_codec *codec = rtd->codec; | 270 | struct snd_soc_codec *codec = rtd->codec; |
| @@ -297,18 +299,15 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, | |||
| 297 | break; | 299 | break; |
| 298 | } | 300 | } |
| 299 | 301 | ||
| 300 | reg = snd_soc_read(codec, AD193X_PLL_CLK_CTRL0); | 302 | snd_soc_update_bits(codec, AD193X_PLL_CLK_CTRL0, |
| 301 | reg = (reg & AD193X_PLL_INPUT_MASK) | master_rate; | 303 | AD193X_PLL_INPUT_MASK, master_rate); |
| 302 | snd_soc_write(codec, AD193X_PLL_CLK_CTRL0, reg); | ||
| 303 | 304 | ||
| 304 | reg = snd_soc_read(codec, AD193X_DAC_CTRL2); | 305 | snd_soc_update_bits(codec, AD193X_DAC_CTRL2, |
| 305 | reg = (reg & (~AD193X_DAC_WORD_LEN_MASK)) | 306 | AD193X_DAC_WORD_LEN_MASK, |
| 306 | | (word_len << AD193X_DAC_WORD_LEN_SHFT); | 307 | word_len << AD193X_DAC_WORD_LEN_SHFT); |
| 307 | snd_soc_write(codec, AD193X_DAC_CTRL2, reg); | ||
| 308 | 308 | ||
| 309 | reg = snd_soc_read(codec, AD193X_ADC_CTRL1); | 309 | snd_soc_update_bits(codec, AD193X_ADC_CTRL1, |
| 310 | reg = (reg & (~AD193X_ADC_WORD_LEN_MASK)) | word_len; | 310 | AD193X_ADC_WORD_LEN_MASK, word_len); |
| 311 | snd_soc_write(codec, AD193X_ADC_CTRL1, reg); | ||
| 312 | 311 | ||
| 313 | return 0; | 312 | return 0; |
| 314 | } | 313 | } |
| @@ -349,10 +348,8 @@ static int ad193x_probe(struct snd_soc_codec *codec) | |||
| 349 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 348 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 350 | int ret; | 349 | int ret; |
| 351 | 350 | ||
| 352 | if (ad193x->control_type == SND_SOC_I2C) | 351 | codec->control_data = ad193x->regmap; |
| 353 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ad193x->control_type); | 352 | ret = snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); |
| 354 | else | ||
| 355 | ret = snd_soc_codec_set_cache_io(codec, 16, 8, ad193x->control_type); | ||
| 356 | if (ret < 0) { | 353 | if (ret < 0) { |
| 357 | dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); | 354 | dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); |
| 358 | return ret; | 355 | return ret; |
| @@ -388,6 +385,14 @@ static struct snd_soc_codec_driver soc_codec_dev_ad193x = { | |||
| 388 | }; | 385 | }; |
| 389 | 386 | ||
| 390 | #if defined(CONFIG_SPI_MASTER) | 387 | #if defined(CONFIG_SPI_MASTER) |
| 388 | |||
| 389 | static const struct regmap_config ad193x_spi_regmap_config = { | ||
| 390 | .val_bits = 8, | ||
| 391 | .reg_bits = 16, | ||
| 392 | .read_flag_mask = 0x09, | ||
| 393 | .write_flag_mask = 0x08, | ||
| 394 | }; | ||
| 395 | |||
| 391 | static int __devinit ad193x_spi_probe(struct spi_device *spi) | 396 | static int __devinit ad193x_spi_probe(struct spi_device *spi) |
| 392 | { | 397 | { |
| 393 | struct ad193x_priv *ad193x; | 398 | struct ad193x_priv *ad193x; |
| @@ -397,20 +402,36 @@ static int __devinit ad193x_spi_probe(struct spi_device *spi) | |||
| 397 | if (ad193x == NULL) | 402 | if (ad193x == NULL) |
| 398 | return -ENOMEM; | 403 | return -ENOMEM; |
| 399 | 404 | ||
| 405 | ad193x->regmap = regmap_init_spi(spi, &ad193x_spi_regmap_config); | ||
| 406 | if (IS_ERR(ad193x->regmap)) { | ||
| 407 | ret = PTR_ERR(ad193x->regmap); | ||
| 408 | goto err_free; | ||
| 409 | } | ||
| 410 | |||
| 400 | spi_set_drvdata(spi, ad193x); | 411 | spi_set_drvdata(spi, ad193x); |
| 401 | ad193x->control_type = SND_SOC_SPI; | ||
| 402 | 412 | ||
| 403 | ret = snd_soc_register_codec(&spi->dev, | 413 | ret = snd_soc_register_codec(&spi->dev, |
| 404 | &soc_codec_dev_ad193x, &ad193x_dai, 1); | 414 | &soc_codec_dev_ad193x, &ad193x_dai, 1); |
| 405 | if (ret < 0) | 415 | if (ret < 0) |
| 406 | kfree(ad193x); | 416 | goto err_regmap_exit; |
| 417 | |||
| 418 | return 0; | ||
| 419 | |||
| 420 | err_regmap_exit: | ||
| 421 | regmap_exit(ad193x->regmap); | ||
| 422 | err_free: | ||
| 423 | kfree(ad193x); | ||
| 424 | |||
| 407 | return ret; | 425 | return ret; |
| 408 | } | 426 | } |
| 409 | 427 | ||
| 410 | static int __devexit ad193x_spi_remove(struct spi_device *spi) | 428 | static int __devexit ad193x_spi_remove(struct spi_device *spi) |
| 411 | { | 429 | { |
| 430 | struct ad193x_priv *ad193x = spi_get_drvdata(spi); | ||
| 431 | |||
| 412 | snd_soc_unregister_codec(&spi->dev); | 432 | snd_soc_unregister_codec(&spi->dev); |
| 413 | kfree(spi_get_drvdata(spi)); | 433 | regmap_exit(ad193x->regmap); |
| 434 | kfree(ad193x); | ||
| 414 | return 0; | 435 | return 0; |
| 415 | } | 436 | } |
| 416 | 437 | ||
| @@ -425,6 +446,12 @@ static struct spi_driver ad193x_spi_driver = { | |||
| 425 | #endif | 446 | #endif |
| 426 | 447 | ||
| 427 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 448 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 449 | |||
| 450 | static const struct regmap_config ad193x_i2c_regmap_config = { | ||
| 451 | .val_bits = 8, | ||
| 452 | .reg_bits = 8, | ||
| 453 | }; | ||
| 454 | |||
| 428 | static const struct i2c_device_id ad193x_id[] = { | 455 | static const struct i2c_device_id ad193x_id[] = { |
| 429 | { "ad1936", 0 }, | 456 | { "ad1936", 0 }, |
| 430 | { "ad1937", 0 }, | 457 | { "ad1937", 0 }, |
| @@ -442,20 +469,35 @@ static int __devinit ad193x_i2c_probe(struct i2c_client *client, | |||
| 442 | if (ad193x == NULL) | 469 | if (ad193x == NULL) |
| 443 | return -ENOMEM; | 470 | return -ENOMEM; |
| 444 | 471 | ||
| 472 | ad193x->regmap = regmap_init_i2c(client, &ad193x_i2c_regmap_config); | ||
| 473 | if (IS_ERR(ad193x->regmap)) { | ||
| 474 | ret = PTR_ERR(ad193x->regmap); | ||
| 475 | goto err_free; | ||
| 476 | } | ||
| 477 | |||
| 445 | i2c_set_clientdata(client, ad193x); | 478 | i2c_set_clientdata(client, ad193x); |
| 446 | ad193x->control_type = SND_SOC_I2C; | ||
| 447 | 479 | ||
| 448 | ret = snd_soc_register_codec(&client->dev, | 480 | ret = snd_soc_register_codec(&client->dev, |
| 449 | &soc_codec_dev_ad193x, &ad193x_dai, 1); | 481 | &soc_codec_dev_ad193x, &ad193x_dai, 1); |
| 450 | if (ret < 0) | 482 | if (ret < 0) |
| 451 | kfree(ad193x); | 483 | goto err_regmap_exit; |
| 484 | |||
| 485 | return 0; | ||
| 486 | |||
| 487 | err_regmap_exit: | ||
| 488 | regmap_exit(ad193x->regmap); | ||
| 489 | err_free: | ||
| 490 | kfree(ad193x); | ||
| 452 | return ret; | 491 | return ret; |
| 453 | } | 492 | } |
| 454 | 493 | ||
| 455 | static int __devexit ad193x_i2c_remove(struct i2c_client *client) | 494 | static int __devexit ad193x_i2c_remove(struct i2c_client *client) |
| 456 | { | 495 | { |
| 496 | struct ad193x_priv *ad193x = i2c_get_clientdata(client); | ||
| 497 | |||
| 457 | snd_soc_unregister_codec(&client->dev); | 498 | snd_soc_unregister_codec(&client->dev); |
| 458 | kfree(i2c_get_clientdata(client)); | 499 | regmap_exit(ad193x->regmap); |
| 500 | kfree(ad193x); | ||
| 459 | return 0; | 501 | return 0; |
| 460 | } | 502 | } |
| 461 | 503 | ||
diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h index cccc2e8e5fbd..1507eaa425a3 100644 --- a/sound/soc/codecs/ad193x.h +++ b/sound/soc/codecs/ad193x.h | |||
| @@ -9,20 +9,20 @@ | |||
| 9 | #ifndef __AD193X_H__ | 9 | #ifndef __AD193X_H__ |
| 10 | #define __AD193X_H__ | 10 | #define __AD193X_H__ |
| 11 | 11 | ||
| 12 | #define AD193X_PLL_CLK_CTRL0 0x800 | 12 | #define AD193X_PLL_CLK_CTRL0 0x00 |
| 13 | #define AD193X_PLL_POWERDOWN 0x01 | 13 | #define AD193X_PLL_POWERDOWN 0x01 |
| 14 | #define AD193X_PLL_INPUT_MASK (~0x6) | 14 | #define AD193X_PLL_INPUT_MASK 0x6 |
| 15 | #define AD193X_PLL_INPUT_256 (0 << 1) | 15 | #define AD193X_PLL_INPUT_256 (0 << 1) |
| 16 | #define AD193X_PLL_INPUT_384 (1 << 1) | 16 | #define AD193X_PLL_INPUT_384 (1 << 1) |
| 17 | #define AD193X_PLL_INPUT_512 (2 << 1) | 17 | #define AD193X_PLL_INPUT_512 (2 << 1) |
| 18 | #define AD193X_PLL_INPUT_768 (3 << 1) | 18 | #define AD193X_PLL_INPUT_768 (3 << 1) |
| 19 | #define AD193X_PLL_CLK_CTRL1 0x801 | 19 | #define AD193X_PLL_CLK_CTRL1 0x01 |
| 20 | #define AD193X_DAC_CTRL0 0x802 | 20 | #define AD193X_DAC_CTRL0 0x02 |
| 21 | #define AD193X_DAC_POWERDOWN 0x01 | 21 | #define AD193X_DAC_POWERDOWN 0x01 |
| 22 | #define AD193X_DAC_SERFMT_MASK 0xC0 | 22 | #define AD193X_DAC_SERFMT_MASK 0xC0 |
| 23 | #define AD193X_DAC_SERFMT_STEREO (0 << 6) | 23 | #define AD193X_DAC_SERFMT_STEREO (0 << 6) |
| 24 | #define AD193X_DAC_SERFMT_TDM (1 << 6) | 24 | #define AD193X_DAC_SERFMT_TDM (1 << 6) |
| 25 | #define AD193X_DAC_CTRL1 0x803 | 25 | #define AD193X_DAC_CTRL1 0x03 |
| 26 | #define AD193X_DAC_2_CHANNELS 0 | 26 | #define AD193X_DAC_2_CHANNELS 0 |
| 27 | #define AD193X_DAC_4_CHANNELS 1 | 27 | #define AD193X_DAC_4_CHANNELS 1 |
| 28 | #define AD193X_DAC_8_CHANNELS 2 | 28 | #define AD193X_DAC_8_CHANNELS 2 |
| @@ -33,11 +33,11 @@ | |||
| 33 | #define AD193X_DAC_BCLK_MASTER (1 << 5) | 33 | #define AD193X_DAC_BCLK_MASTER (1 << 5) |
| 34 | #define AD193X_DAC_LEFT_HIGH (1 << 3) | 34 | #define AD193X_DAC_LEFT_HIGH (1 << 3) |
| 35 | #define AD193X_DAC_BCLK_INV (1 << 7) | 35 | #define AD193X_DAC_BCLK_INV (1 << 7) |
| 36 | #define AD193X_DAC_CTRL2 0x804 | 36 | #define AD193X_DAC_CTRL2 0x04 |
| 37 | #define AD193X_DAC_WORD_LEN_SHFT 3 | 37 | #define AD193X_DAC_WORD_LEN_SHFT 3 |
| 38 | #define AD193X_DAC_WORD_LEN_MASK 0x18 | 38 | #define AD193X_DAC_WORD_LEN_MASK 0x18 |
| 39 | #define AD193X_DAC_MASTER_MUTE 1 | 39 | #define AD193X_DAC_MASTER_MUTE 1 |
| 40 | #define AD193X_DAC_CHNL_MUTE 0x805 | 40 | #define AD193X_DAC_CHNL_MUTE 0x05 |
| 41 | #define AD193X_DACL1_MUTE 0 | 41 | #define AD193X_DACL1_MUTE 0 |
| 42 | #define AD193X_DACR1_MUTE 1 | 42 | #define AD193X_DACR1_MUTE 1 |
| 43 | #define AD193X_DACL2_MUTE 2 | 43 | #define AD193X_DACL2_MUTE 2 |
| @@ -46,28 +46,28 @@ | |||
| 46 | #define AD193X_DACR3_MUTE 5 | 46 | #define AD193X_DACR3_MUTE 5 |
| 47 | #define AD193X_DACL4_MUTE 6 | 47 | #define AD193X_DACL4_MUTE 6 |
| 48 | #define AD193X_DACR4_MUTE 7 | 48 | #define AD193X_DACR4_MUTE 7 |
| 49 | #define AD193X_DAC_L1_VOL 0x806 | 49 | #define AD193X_DAC_L1_VOL 0x06 |
| 50 | #define AD193X_DAC_R1_VOL 0x807 | 50 | #define AD193X_DAC_R1_VOL 0x07 |
| 51 | #define AD193X_DAC_L2_VOL 0x808 | 51 | #define AD193X_DAC_L2_VOL 0x08 |
| 52 | #define AD193X_DAC_R2_VOL 0x809 | 52 | #define AD193X_DAC_R2_VOL 0x09 |
| 53 | #define AD193X_DAC_L3_VOL 0x80a | 53 | #define AD193X_DAC_L3_VOL 0x0a |
| 54 | #define AD193X_DAC_R3_VOL 0x80b | 54 | #define AD193X_DAC_R3_VOL 0x0b |
| 55 | #define AD193X_DAC_L4_VOL 0x80c | 55 | #define AD193X_DAC_L4_VOL 0x0c |
| 56 | #define AD193X_DAC_R4_VOL 0x80d | 56 | #define AD193X_DAC_R4_VOL 0x0d |
| 57 | #define AD193X_ADC_CTRL0 0x80e | 57 | #define AD193X_ADC_CTRL0 0x0e |
| 58 | #define AD193X_ADC_POWERDOWN 0x01 | 58 | #define AD193X_ADC_POWERDOWN 0x01 |
| 59 | #define AD193X_ADC_HIGHPASS_FILTER 1 | 59 | #define AD193X_ADC_HIGHPASS_FILTER 1 |
| 60 | #define AD193X_ADCL1_MUTE 2 | 60 | #define AD193X_ADCL1_MUTE 2 |
| 61 | #define AD193X_ADCR1_MUTE 3 | 61 | #define AD193X_ADCR1_MUTE 3 |
| 62 | #define AD193X_ADCL2_MUTE 4 | 62 | #define AD193X_ADCL2_MUTE 4 |
| 63 | #define AD193X_ADCR2_MUTE 5 | 63 | #define AD193X_ADCR2_MUTE 5 |
| 64 | #define AD193X_ADC_CTRL1 0x80f | 64 | #define AD193X_ADC_CTRL1 0x0f |
| 65 | #define AD193X_ADC_SERFMT_MASK 0x60 | 65 | #define AD193X_ADC_SERFMT_MASK 0x60 |
| 66 | #define AD193X_ADC_SERFMT_STEREO (0 << 5) | 66 | #define AD193X_ADC_SERFMT_STEREO (0 << 5) |
| 67 | #define AD193X_ADC_SERFMT_TDM (1 << 5) | 67 | #define AD193X_ADC_SERFMT_TDM (1 << 5) |
| 68 | #define AD193X_ADC_SERFMT_AUX (2 << 5) | 68 | #define AD193X_ADC_SERFMT_AUX (2 << 5) |
| 69 | #define AD193X_ADC_WORD_LEN_MASK 0x3 | 69 | #define AD193X_ADC_WORD_LEN_MASK 0x3 |
| 70 | #define AD193X_ADC_CTRL2 0x810 | 70 | #define AD193X_ADC_CTRL2 0x10 |
| 71 | #define AD193X_ADC_2_CHANNELS 0 | 71 | #define AD193X_ADC_2_CHANNELS 0 |
| 72 | #define AD193X_ADC_4_CHANNELS 1 | 72 | #define AD193X_ADC_4_CHANNELS 1 |
| 73 | #define AD193X_ADC_8_CHANNELS 2 | 73 | #define AD193X_ADC_8_CHANNELS 2 |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 923b364a3e41..e3931cc5e66c 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
| @@ -148,7 +148,6 @@ static struct snd_soc_dai_driver ad1980_dai = { | |||
| 148 | .rates = SNDRV_PCM_RATE_48000, | 148 | .rates = SNDRV_PCM_RATE_48000, |
| 149 | .formats = SND_SOC_STD_AC97_FMTS, }, | 149 | .formats = SND_SOC_STD_AC97_FMTS, }, |
| 150 | }; | 150 | }; |
| 151 | EXPORT_SYMBOL_GPL(ad1980_dai); | ||
| 152 | 151 | ||
| 153 | static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) | 152 | static int ad1980_reset(struct snd_soc_codec *codec, int try_warm) |
| 154 | { | 153 | { |
| @@ -200,18 +199,22 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) | |||
| 200 | } | 199 | } |
| 201 | 200 | ||
| 202 | /* Read out vendor ID to make sure it is ad1980 */ | 201 | /* Read out vendor ID to make sure it is ad1980 */ |
| 203 | if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) | 202 | if (ac97_read(codec, AC97_VENDOR_ID1) != 0x4144) { |
| 203 | ret = -ENODEV; | ||
| 204 | goto reset_err; | 204 | goto reset_err; |
| 205 | } | ||
| 205 | 206 | ||
| 206 | vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2); | 207 | vendor_id2 = ac97_read(codec, AC97_VENDOR_ID2); |
| 207 | 208 | ||
| 208 | if (vendor_id2 != 0x5370) { | 209 | if (vendor_id2 != 0x5370) { |
| 209 | if (vendor_id2 != 0x5374) | 210 | if (vendor_id2 != 0x5374) { |
| 211 | ret = -ENODEV; | ||
| 210 | goto reset_err; | 212 | goto reset_err; |
| 211 | else | 213 | } else { |
| 212 | printk(KERN_WARNING "ad1980: " | 214 | printk(KERN_WARNING "ad1980: " |
| 213 | "Found AD1981 - only 2/2 IN/OUT Channels " | 215 | "Found AD1981 - only 2/2 IN/OUT Channels " |
| 214 | "supported\n"); | 216 | "supported\n"); |
| 217 | } | ||
| 215 | } | 218 | } |
| 216 | 219 | ||
| 217 | /* unmute captures and playbacks volume */ | 220 | /* unmute captures and playbacks volume */ |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c new file mode 100644 index 000000000000..1ccf8dd47576 --- /dev/null +++ b/sound/soc/codecs/adau1373.c | |||
| @@ -0,0 +1,1414 @@ | |||
| 1 | /* | ||
| 2 | * Analog Devices ADAU1373 Audio Codec drive | ||
| 3 | * | ||
| 4 | * Copyright 2011 Analog Devices Inc. | ||
| 5 | * Author: Lars-Peter Clausen <lars@metafoo.de> | ||
| 6 | * | ||
| 7 | * Licensed under the GPL-2 or later. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/module.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/delay.h> | ||
| 13 | #include <linux/pm.h> | ||
| 14 | #include <linux/i2c.h> | ||
| 15 | #include <linux/slab.h> | ||
| 16 | #include <linux/gcd.h> | ||
| 17 | |||
| 18 | #include <sound/core.h> | ||
| 19 | #include <sound/pcm.h> | ||
| 20 | #include <sound/pcm_params.h> | ||
| 21 | #include <sound/tlv.h> | ||
| 22 | #include <sound/soc.h> | ||
| 23 | #include <sound/adau1373.h> | ||
| 24 | |||
| 25 | #include "adau1373.h" | ||
| 26 | |||
| 27 | struct adau1373_dai { | ||
| 28 | unsigned int clk_src; | ||
| 29 | unsigned int sysclk; | ||
| 30 | bool enable_src; | ||
| 31 | bool master; | ||
| 32 | }; | ||
| 33 | |||
| 34 | struct adau1373 { | ||
| 35 | struct adau1373_dai dais[3]; | ||
| 36 | }; | ||
| 37 | |||
| 38 | #define ADAU1373_INPUT_MODE 0x00 | ||
| 39 | #define ADAU1373_AINL_CTRL(x) (0x01 + (x) * 2) | ||
| 40 | #define ADAU1373_AINR_CTRL(x) (0x02 + (x) * 2) | ||
| 41 | #define ADAU1373_LLINE_OUT(x) (0x9 + (x) * 2) | ||
| 42 | #define ADAU1373_RLINE_OUT(x) (0xa + (x) * 2) | ||
| 43 | #define ADAU1373_LSPK_OUT 0x0d | ||
| 44 | #define ADAU1373_RSPK_OUT 0x0e | ||
| 45 | #define ADAU1373_LHP_OUT 0x0f | ||
| 46 | #define ADAU1373_RHP_OUT 0x10 | ||
| 47 | #define ADAU1373_ADC_GAIN 0x11 | ||
| 48 | #define ADAU1373_LADC_MIXER 0x12 | ||
| 49 | #define ADAU1373_RADC_MIXER 0x13 | ||
| 50 | #define ADAU1373_LLINE1_MIX 0x14 | ||
| 51 | #define ADAU1373_RLINE1_MIX 0x15 | ||
| 52 | #define ADAU1373_LLINE2_MIX 0x16 | ||
| 53 | #define ADAU1373_RLINE2_MIX 0x17 | ||
| 54 | #define ADAU1373_LSPK_MIX 0x18 | ||
| 55 | #define ADAU1373_RSPK_MIX 0x19 | ||
| 56 | #define ADAU1373_LHP_MIX 0x1a | ||
| 57 | #define ADAU1373_RHP_MIX 0x1b | ||
| 58 | #define ADAU1373_EP_MIX 0x1c | ||
| 59 | #define ADAU1373_HP_CTRL 0x1d | ||
| 60 | #define ADAU1373_HP_CTRL2 0x1e | ||
| 61 | #define ADAU1373_LS_CTRL 0x1f | ||
| 62 | #define ADAU1373_EP_CTRL 0x21 | ||
| 63 | #define ADAU1373_MICBIAS_CTRL1 0x22 | ||
| 64 | #define ADAU1373_MICBIAS_CTRL2 0x23 | ||
| 65 | #define ADAU1373_OUTPUT_CTRL 0x24 | ||
| 66 | #define ADAU1373_PWDN_CTRL1 0x25 | ||
| 67 | #define ADAU1373_PWDN_CTRL2 0x26 | ||
| 68 | #define ADAU1373_PWDN_CTRL3 0x27 | ||
| 69 | #define ADAU1373_DPLL_CTRL(x) (0x28 + (x) * 7) | ||
| 70 | #define ADAU1373_PLL_CTRL1(x) (0x29 + (x) * 7) | ||
| 71 | #define ADAU1373_PLL_CTRL2(x) (0x2a + (x) * 7) | ||
| 72 | #define ADAU1373_PLL_CTRL3(x) (0x2b + (x) * 7) | ||
| 73 | #define ADAU1373_PLL_CTRL4(x) (0x2c + (x) * 7) | ||
| 74 | #define ADAU1373_PLL_CTRL5(x) (0x2d + (x) * 7) | ||
| 75 | #define ADAU1373_PLL_CTRL6(x) (0x2e + (x) * 7) | ||
| 76 | #define ADAU1373_PLL_CTRL7(x) (0x2f + (x) * 7) | ||
| 77 | #define ADAU1373_HEADDECT 0x36 | ||
| 78 | #define ADAU1373_ADC_DAC_STATUS 0x37 | ||
| 79 | #define ADAU1373_ADC_CTRL 0x3c | ||
| 80 | #define ADAU1373_DAI(x) (0x44 + (x)) | ||
| 81 | #define ADAU1373_CLK_SRC_DIV(x) (0x40 + (x) * 2) | ||
| 82 | #define ADAU1373_BCLKDIV(x) (0x47 + (x)) | ||
| 83 | #define ADAU1373_SRC_RATIOA(x) (0x4a + (x) * 2) | ||
| 84 | #define ADAU1373_SRC_RATIOB(x) (0x4b + (x) * 2) | ||
| 85 | #define ADAU1373_DEEMP_CTRL 0x50 | ||
| 86 | #define ADAU1373_SRC_DAI_CTRL(x) (0x51 + (x)) | ||
| 87 | #define ADAU1373_DIN_MIX_CTRL(x) (0x56 + (x)) | ||
| 88 | #define ADAU1373_DOUT_MIX_CTRL(x) (0x5b + (x)) | ||
| 89 | #define ADAU1373_DAI_PBL_VOL(x) (0x62 + (x) * 2) | ||
| 90 | #define ADAU1373_DAI_PBR_VOL(x) (0x63 + (x) * 2) | ||
| 91 | #define ADAU1373_DAI_RECL_VOL(x) (0x68 + (x) * 2) | ||
| 92 | #define ADAU1373_DAI_RECR_VOL(x) (0x69 + (x) * 2) | ||
| 93 | #define ADAU1373_DAC1_PBL_VOL 0x6e | ||
| 94 | #define ADAU1373_DAC1_PBR_VOL 0x6f | ||
| 95 | #define ADAU1373_DAC2_PBL_VOL 0x70 | ||
| 96 | #define ADAU1373_DAC2_PBR_VOL 0x71 | ||
| 97 | #define ADAU1373_ADC_RECL_VOL 0x72 | ||
| 98 | #define ADAU1373_ADC_RECR_VOL 0x73 | ||
| 99 | #define ADAU1373_DMIC_RECL_VOL 0x74 | ||
| 100 | #define ADAU1373_DMIC_RECR_VOL 0x75 | ||
| 101 | #define ADAU1373_VOL_GAIN1 0x76 | ||
| 102 | #define ADAU1373_VOL_GAIN2 0x77 | ||
| 103 | #define ADAU1373_VOL_GAIN3 0x78 | ||
| 104 | #define ADAU1373_HPF_CTRL 0x7d | ||
| 105 | #define ADAU1373_BASS1 0x7e | ||
| 106 | #define ADAU1373_BASS2 0x7f | ||
| 107 | #define ADAU1373_DRC(x) (0x80 + (x) * 0x10) | ||
| 108 | #define ADAU1373_3D_CTRL1 0xc0 | ||
| 109 | #define ADAU1373_3D_CTRL2 0xc1 | ||
| 110 | #define ADAU1373_FDSP_SEL1 0xdc | ||
| 111 | #define ADAU1373_FDSP_SEL2 0xdd | ||
| 112 | #define ADAU1373_FDSP_SEL3 0xde | ||
| 113 | #define ADAU1373_FDSP_SEL4 0xdf | ||
| 114 | #define ADAU1373_DIGMICCTRL 0xe2 | ||
| 115 | #define ADAU1373_DIGEN 0xeb | ||
| 116 | #define ADAU1373_SOFT_RESET 0xff | ||
| 117 | |||
| 118 | |||
| 119 | #define ADAU1373_PLL_CTRL6_DPLL_BYPASS BIT(1) | ||
| 120 | #define ADAU1373_PLL_CTRL6_PLL_EN BIT(0) | ||
| 121 | |||
| 122 | #define ADAU1373_DAI_INVERT_BCLK BIT(7) | ||
| 123 | #define ADAU1373_DAI_MASTER BIT(6) | ||
| 124 | #define ADAU1373_DAI_INVERT_LRCLK BIT(4) | ||
| 125 | #define ADAU1373_DAI_WLEN_16 0x0 | ||
| 126 | #define ADAU1373_DAI_WLEN_20 0x4 | ||
| 127 | #define ADAU1373_DAI_WLEN_24 0x8 | ||
| 128 | #define ADAU1373_DAI_WLEN_32 0xc | ||
| 129 | #define ADAU1373_DAI_WLEN_MASK 0xc | ||
| 130 | #define ADAU1373_DAI_FORMAT_RIGHT_J 0x0 | ||
| 131 | #define ADAU1373_DAI_FORMAT_LEFT_J 0x1 | ||
| 132 | #define ADAU1373_DAI_FORMAT_I2S 0x2 | ||
| 133 | #define ADAU1373_DAI_FORMAT_DSP 0x3 | ||
| 134 | |||
| 135 | #define ADAU1373_BCLKDIV_SOURCE BIT(5) | ||
| 136 | #define ADAU1373_BCLKDIV_32 0x03 | ||
| 137 | #define ADAU1373_BCLKDIV_64 0x02 | ||
| 138 | #define ADAU1373_BCLKDIV_128 0x01 | ||
| 139 | #define ADAU1373_BCLKDIV_256 0x00 | ||
| 140 | |||
| 141 | #define ADAU1373_ADC_CTRL_PEAK_DETECT BIT(0) | ||
| 142 | #define ADAU1373_ADC_CTRL_RESET BIT(1) | ||
| 143 | #define ADAU1373_ADC_CTRL_RESET_FORCE BIT(2) | ||
| 144 | |||
| 145 | #define ADAU1373_OUTPUT_CTRL_LDIFF BIT(3) | ||
| 146 | #define ADAU1373_OUTPUT_CTRL_LNFBEN BIT(2) | ||
| 147 | |||
| 148 | #define ADAU1373_PWDN_CTRL3_PWR_EN BIT(0) | ||
| 149 | |||
| 150 | #define ADAU1373_EP_CTRL_MICBIAS1_OFFSET 4 | ||
| 151 | #define ADAU1373_EP_CTRL_MICBIAS2_OFFSET 2 | ||
| 152 | |||
| 153 | static const uint8_t adau1373_default_regs[] = { | ||
| 154 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00 */ | ||
| 155 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 156 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10 */ | ||
| 157 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 158 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20 */ | ||
| 159 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, | ||
| 160 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, /* 0x30 */ | ||
| 161 | 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, | ||
| 162 | 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0a, 0x0a, 0x00, /* 0x40 */ | ||
| 163 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 164 | 0x00, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ | ||
| 165 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ | ||
| 167 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 168 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ | ||
| 169 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 170 | 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x80 */ | ||
| 171 | 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, | ||
| 172 | 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x90 */ | ||
| 173 | 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, | ||
| 174 | 0x78, 0x18, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0xa0 */ | ||
| 175 | 0x00, 0xc0, 0x88, 0x7a, 0xdf, 0x20, 0x00, 0x00, | ||
| 176 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xb0 */ | ||
| 177 | 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, | ||
| 178 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ | ||
| 179 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 180 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */ | ||
| 181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
| 182 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, /* 0xe0 */ | ||
| 183 | 0x00, 0x1f, 0x0f, 0x00, 0x00, | ||
| 184 | }; | ||
| 185 | |||
| 186 | static const unsigned int adau1373_out_tlv[] = { | ||
| 187 | TLV_DB_RANGE_HEAD(4), | ||
| 188 | 0, 7, TLV_DB_SCALE_ITEM(-7900, 400, 1), | ||
| 189 | 8, 15, TLV_DB_SCALE_ITEM(-4700, 300, 0), | ||
| 190 | 16, 23, TLV_DB_SCALE_ITEM(-2300, 200, 0), | ||
| 191 | 24, 31, TLV_DB_SCALE_ITEM(-700, 100, 0), | ||
| 192 | }; | ||
| 193 | |||
| 194 | static const DECLARE_TLV_DB_MINMAX(adau1373_digital_tlv, -9563, 0); | ||
| 195 | static const DECLARE_TLV_DB_SCALE(adau1373_in_pga_tlv, -1300, 100, 1); | ||
| 196 | static const DECLARE_TLV_DB_SCALE(adau1373_ep_tlv, -600, 600, 1); | ||
| 197 | |||
| 198 | static const DECLARE_TLV_DB_SCALE(adau1373_input_boost_tlv, 0, 2000, 0); | ||
| 199 | static const DECLARE_TLV_DB_SCALE(adau1373_gain_boost_tlv, 0, 600, 0); | ||
| 200 | static const DECLARE_TLV_DB_SCALE(adau1373_speaker_boost_tlv, 1200, 600, 0); | ||
| 201 | |||
| 202 | static const char *adau1373_fdsp_sel_text[] = { | ||
| 203 | "None", | ||
| 204 | "Channel 1", | ||
| 205 | "Channel 2", | ||
| 206 | "Channel 3", | ||
| 207 | "Channel 4", | ||
| 208 | "Channel 5", | ||
| 209 | }; | ||
| 210 | |||
| 211 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc1_channel_enum, | ||
| 212 | ADAU1373_FDSP_SEL1, 4, adau1373_fdsp_sel_text); | ||
| 213 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc2_channel_enum, | ||
| 214 | ADAU1373_FDSP_SEL1, 0, adau1373_fdsp_sel_text); | ||
| 215 | static const SOC_ENUM_SINGLE_DECL(adau1373_drc3_channel_enum, | ||
| 216 | ADAU1373_FDSP_SEL2, 0, adau1373_fdsp_sel_text); | ||
| 217 | static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_channel_enum, | ||
| 218 | ADAU1373_FDSP_SEL3, 0, adau1373_fdsp_sel_text); | ||
| 219 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_channel_enum, | ||
| 220 | ADAU1373_FDSP_SEL4, 4, adau1373_fdsp_sel_text); | ||
| 221 | |||
| 222 | static const char *adau1373_hpf_cutoff_text[] = { | ||
| 223 | "3.7Hz", "50Hz", "100Hz", "150Hz", "200Hz", "250Hz", "300Hz", "350Hz", | ||
| 224 | "400Hz", "450Hz", "500Hz", "550Hz", "600Hz", "650Hz", "700Hz", "750Hz", | ||
| 225 | "800Hz", | ||
| 226 | }; | ||
| 227 | |||
| 228 | static const SOC_ENUM_SINGLE_DECL(adau1373_hpf_cutoff_enum, | ||
| 229 | ADAU1373_HPF_CTRL, 3, adau1373_hpf_cutoff_text); | ||
| 230 | |||
| 231 | static const char *adau1373_bass_lpf_cutoff_text[] = { | ||
| 232 | "801Hz", "1001Hz", | ||
| 233 | }; | ||
| 234 | |||
| 235 | static const char *adau1373_bass_clip_level_text[] = { | ||
| 236 | "0.125", "0.250", "0.370", "0.500", "0.625", "0.750", "0.875", | ||
| 237 | }; | ||
| 238 | |||
| 239 | static const unsigned int adau1373_bass_clip_level_values[] = { | ||
| 240 | 1, 2, 3, 4, 5, 6, 7, | ||
| 241 | }; | ||
| 242 | |||
| 243 | static const char *adau1373_bass_hpf_cutoff_text[] = { | ||
| 244 | "158Hz", "232Hz", "347Hz", "520Hz", | ||
| 245 | }; | ||
| 246 | |||
| 247 | static const unsigned int adau1373_bass_tlv[] = { | ||
| 248 | TLV_DB_RANGE_HEAD(4), | ||
| 249 | 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1), | ||
| 250 | 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0), | ||
| 251 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), | ||
| 252 | }; | ||
| 253 | |||
| 254 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_lpf_cutoff_enum, | ||
| 255 | ADAU1373_BASS1, 5, adau1373_bass_lpf_cutoff_text); | ||
| 256 | |||
| 257 | static const SOC_VALUE_ENUM_SINGLE_DECL(adau1373_bass_clip_level_enum, | ||
| 258 | ADAU1373_BASS1, 2, 7, adau1373_bass_clip_level_text, | ||
| 259 | adau1373_bass_clip_level_values); | ||
| 260 | |||
| 261 | static const SOC_ENUM_SINGLE_DECL(adau1373_bass_hpf_cutoff_enum, | ||
| 262 | ADAU1373_BASS1, 0, adau1373_bass_hpf_cutoff_text); | ||
| 263 | |||
| 264 | static const char *adau1373_3d_level_text[] = { | ||
| 265 | "0%", "6.67%", "13.33%", "20%", "26.67%", "33.33%", | ||
| 266 | "40%", "46.67%", "53.33%", "60%", "66.67%", "73.33%", | ||
| 267 | "80%", "86.67", "99.33%", "100%" | ||
| 268 | }; | ||
| 269 | |||
| 270 | static const char *adau1373_3d_cutoff_text[] = { | ||
| 271 | "No 3D", "0.03125 fs", "0.04583 fs", "0.075 fs", "0.11458 fs", | ||
| 272 | "0.16875 fs", "0.27083 fs" | ||
| 273 | }; | ||
| 274 | |||
| 275 | static const SOC_ENUM_SINGLE_DECL(adau1373_3d_level_enum, | ||
| 276 | ADAU1373_3D_CTRL1, 4, adau1373_3d_level_text); | ||
| 277 | static const SOC_ENUM_SINGLE_DECL(adau1373_3d_cutoff_enum, | ||
| 278 | ADAU1373_3D_CTRL1, 0, adau1373_3d_cutoff_text); | ||
| 279 | |||
| 280 | static const unsigned int adau1373_3d_tlv[] = { | ||
| 281 | TLV_DB_RANGE_HEAD(2), | ||
| 282 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
| 283 | 1, 7, TLV_DB_LINEAR_ITEM(-1800, -120), | ||
| 284 | }; | ||
| 285 | |||
| 286 | static const char *adau1373_lr_mux_text[] = { | ||
| 287 | "Mute", | ||
| 288 | "Right Channel (L+R)", | ||
| 289 | "Left Channel (L+R)", | ||
| 290 | "Stereo", | ||
| 291 | }; | ||
| 292 | |||
| 293 | static const SOC_ENUM_SINGLE_DECL(adau1373_lineout1_lr_mux_enum, | ||
| 294 | ADAU1373_OUTPUT_CTRL, 4, adau1373_lr_mux_text); | ||
| 295 | static const SOC_ENUM_SINGLE_DECL(adau1373_lineout2_lr_mux_enum, | ||
| 296 | ADAU1373_OUTPUT_CTRL, 6, adau1373_lr_mux_text); | ||
| 297 | static const SOC_ENUM_SINGLE_DECL(adau1373_speaker_lr_mux_enum, | ||
| 298 | ADAU1373_LS_CTRL, 4, adau1373_lr_mux_text); | ||
| 299 | |||
| 300 | static const struct snd_kcontrol_new adau1373_controls[] = { | ||
| 301 | SOC_DOUBLE_R_TLV("AIF1 Capture Volume", ADAU1373_DAI_RECL_VOL(0), | ||
| 302 | ADAU1373_DAI_RECR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv), | ||
| 303 | SOC_DOUBLE_R_TLV("AIF2 Capture Volume", ADAU1373_DAI_RECL_VOL(1), | ||
| 304 | ADAU1373_DAI_RECR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv), | ||
| 305 | SOC_DOUBLE_R_TLV("AIF3 Capture Volume", ADAU1373_DAI_RECL_VOL(2), | ||
| 306 | ADAU1373_DAI_RECR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv), | ||
| 307 | |||
| 308 | SOC_DOUBLE_R_TLV("ADC Capture Volume", ADAU1373_ADC_RECL_VOL, | ||
| 309 | ADAU1373_ADC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv), | ||
| 310 | SOC_DOUBLE_R_TLV("DMIC Capture Volume", ADAU1373_DMIC_RECL_VOL, | ||
| 311 | ADAU1373_DMIC_RECR_VOL, 0, 0xff, 1, adau1373_digital_tlv), | ||
| 312 | |||
| 313 | SOC_DOUBLE_R_TLV("AIF1 Playback Volume", ADAU1373_DAI_PBL_VOL(0), | ||
| 314 | ADAU1373_DAI_PBR_VOL(0), 0, 0xff, 1, adau1373_digital_tlv), | ||
| 315 | SOC_DOUBLE_R_TLV("AIF2 Playback Volume", ADAU1373_DAI_PBL_VOL(1), | ||
| 316 | ADAU1373_DAI_PBR_VOL(1), 0, 0xff, 1, adau1373_digital_tlv), | ||
| 317 | SOC_DOUBLE_R_TLV("AIF3 Playback Volume", ADAU1373_DAI_PBL_VOL(2), | ||
| 318 | ADAU1373_DAI_PBR_VOL(2), 0, 0xff, 1, adau1373_digital_tlv), | ||
| 319 | |||
| 320 | SOC_DOUBLE_R_TLV("DAC1 Playback Volume", ADAU1373_DAC1_PBL_VOL, | ||
| 321 | ADAU1373_DAC1_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv), | ||
| 322 | SOC_DOUBLE_R_TLV("DAC2 Playback Volume", ADAU1373_DAC2_PBL_VOL, | ||
| 323 | ADAU1373_DAC2_PBR_VOL, 0, 0xff, 1, adau1373_digital_tlv), | ||
| 324 | |||
| 325 | SOC_DOUBLE_R_TLV("Lineout1 Playback Volume", ADAU1373_LLINE_OUT(0), | ||
| 326 | ADAU1373_RLINE_OUT(0), 0, 0x1f, 0, adau1373_out_tlv), | ||
| 327 | SOC_DOUBLE_R_TLV("Speaker Playback Volume", ADAU1373_LSPK_OUT, | ||
| 328 | ADAU1373_RSPK_OUT, 0, 0x1f, 0, adau1373_out_tlv), | ||
| 329 | SOC_DOUBLE_R_TLV("Headphone Playback Volume", ADAU1373_LHP_OUT, | ||
| 330 | ADAU1373_RHP_OUT, 0, 0x1f, 0, adau1373_out_tlv), | ||
| 331 | |||
| 332 | SOC_DOUBLE_R_TLV("Input 1 Capture Volume", ADAU1373_AINL_CTRL(0), | ||
| 333 | ADAU1373_AINR_CTRL(0), 0, 0x1f, 0, adau1373_in_pga_tlv), | ||
| 334 | SOC_DOUBLE_R_TLV("Input 2 Capture Volume", ADAU1373_AINL_CTRL(1), | ||
| 335 | ADAU1373_AINR_CTRL(1), 0, 0x1f, 0, adau1373_in_pga_tlv), | ||
| 336 | SOC_DOUBLE_R_TLV("Input 3 Capture Volume", ADAU1373_AINL_CTRL(2), | ||
| 337 | ADAU1373_AINR_CTRL(2), 0, 0x1f, 0, adau1373_in_pga_tlv), | ||
| 338 | SOC_DOUBLE_R_TLV("Input 4 Capture Volume", ADAU1373_AINL_CTRL(3), | ||
| 339 | ADAU1373_AINR_CTRL(3), 0, 0x1f, 0, adau1373_in_pga_tlv), | ||
| 340 | |||
| 341 | SOC_SINGLE_TLV("Earpiece Playback Volume", ADAU1373_EP_CTRL, 0, 3, 0, | ||
| 342 | adau1373_ep_tlv), | ||
| 343 | |||
| 344 | SOC_DOUBLE_TLV("AIF3 Boost Playback Volume", ADAU1373_VOL_GAIN1, 4, 5, | ||
| 345 | 1, 0, adau1373_gain_boost_tlv), | ||
| 346 | SOC_DOUBLE_TLV("AIF2 Boost Playback Volume", ADAU1373_VOL_GAIN1, 2, 3, | ||
| 347 | 1, 0, adau1373_gain_boost_tlv), | ||
| 348 | SOC_DOUBLE_TLV("AIF1 Boost Playback Volume", ADAU1373_VOL_GAIN1, 0, 1, | ||
| 349 | 1, 0, adau1373_gain_boost_tlv), | ||
| 350 | SOC_DOUBLE_TLV("AIF3 Boost Capture Volume", ADAU1373_VOL_GAIN2, 4, 5, | ||
| 351 | 1, 0, adau1373_gain_boost_tlv), | ||
| 352 | SOC_DOUBLE_TLV("AIF2 Boost Capture Volume", ADAU1373_VOL_GAIN2, 2, 3, | ||
| 353 | 1, 0, adau1373_gain_boost_tlv), | ||
| 354 | SOC_DOUBLE_TLV("AIF1 Boost Capture Volume", ADAU1373_VOL_GAIN2, 0, 1, | ||
| 355 | 1, 0, adau1373_gain_boost_tlv), | ||
| 356 | SOC_DOUBLE_TLV("DMIC Boost Capture Volume", ADAU1373_VOL_GAIN3, 6, 7, | ||
| 357 | 1, 0, adau1373_gain_boost_tlv), | ||
| 358 | SOC_DOUBLE_TLV("ADC Boost Capture Volume", ADAU1373_VOL_GAIN3, 4, 5, | ||
| 359 | 1, 0, adau1373_gain_boost_tlv), | ||
| 360 | SOC_DOUBLE_TLV("DAC2 Boost Playback Volume", ADAU1373_VOL_GAIN3, 2, 3, | ||
| 361 | 1, 0, adau1373_gain_boost_tlv), | ||
| 362 | SOC_DOUBLE_TLV("DAC1 Boost Playback Volume", ADAU1373_VOL_GAIN3, 0, 1, | ||
| 363 | 1, 0, adau1373_gain_boost_tlv), | ||
| 364 | |||
| 365 | SOC_DOUBLE_TLV("Input 1 Boost Capture Volume", ADAU1373_ADC_GAIN, 0, 4, | ||
| 366 | 1, 0, adau1373_input_boost_tlv), | ||
| 367 | SOC_DOUBLE_TLV("Input 2 Boost Capture Volume", ADAU1373_ADC_GAIN, 1, 5, | ||
| 368 | 1, 0, adau1373_input_boost_tlv), | ||
| 369 | SOC_DOUBLE_TLV("Input 3 Boost Capture Volume", ADAU1373_ADC_GAIN, 2, 6, | ||
| 370 | 1, 0, adau1373_input_boost_tlv), | ||
| 371 | SOC_DOUBLE_TLV("Input 4 Boost Capture Volume", ADAU1373_ADC_GAIN, 3, 7, | ||
| 372 | 1, 0, adau1373_input_boost_tlv), | ||
| 373 | |||
| 374 | SOC_DOUBLE_TLV("Speaker Boost Playback Volume", ADAU1373_LS_CTRL, 2, 3, | ||
| 375 | 1, 0, adau1373_speaker_boost_tlv), | ||
| 376 | |||
| 377 | SOC_ENUM("Lineout1 LR Mux", adau1373_lineout1_lr_mux_enum), | ||
| 378 | SOC_ENUM("Speaker LR Mux", adau1373_speaker_lr_mux_enum), | ||
| 379 | |||
| 380 | SOC_ENUM("HPF Cutoff", adau1373_hpf_cutoff_enum), | ||
| 381 | SOC_DOUBLE("HPF Switch", ADAU1373_HPF_CTRL, 1, 0, 1, 0), | ||
| 382 | SOC_ENUM("HPF Channel", adau1373_hpf_channel_enum), | ||
| 383 | |||
| 384 | SOC_ENUM("Bass HPF Cutoff", adau1373_bass_hpf_cutoff_enum), | ||
| 385 | SOC_VALUE_ENUM("Bass Clip Level Threshold", | ||
| 386 | adau1373_bass_clip_level_enum), | ||
| 387 | SOC_ENUM("Bass LPF Cutoff", adau1373_bass_lpf_cutoff_enum), | ||
| 388 | SOC_DOUBLE("Bass Playback Switch", ADAU1373_BASS2, 0, 1, 1, 0), | ||
| 389 | SOC_SINGLE_TLV("Bass Playback Volume", ADAU1373_BASS2, 2, 7, 0, | ||
| 390 | adau1373_bass_tlv), | ||
| 391 | SOC_ENUM("Bass Channel", adau1373_bass_channel_enum), | ||
| 392 | |||
| 393 | SOC_ENUM("3D Freq", adau1373_3d_cutoff_enum), | ||
| 394 | SOC_ENUM("3D Level", adau1373_3d_level_enum), | ||
| 395 | SOC_SINGLE("3D Playback Switch", ADAU1373_3D_CTRL2, 0, 1, 0), | ||
| 396 | SOC_SINGLE_TLV("3D Playback Volume", ADAU1373_3D_CTRL2, 2, 7, 0, | ||
| 397 | adau1373_3d_tlv), | ||
| 398 | SOC_ENUM("3D Channel", adau1373_bass_channel_enum), | ||
| 399 | |||
| 400 | SOC_SINGLE("Zero Cross Switch", ADAU1373_PWDN_CTRL3, 7, 1, 0), | ||
| 401 | }; | ||
| 402 | |||
| 403 | static const struct snd_kcontrol_new adau1373_lineout2_controls[] = { | ||
| 404 | SOC_DOUBLE_R_TLV("Lineout2 Playback Volume", ADAU1373_LLINE_OUT(1), | ||
| 405 | ADAU1373_RLINE_OUT(1), 0, 0x1f, 0, adau1373_out_tlv), | ||
| 406 | SOC_ENUM("Lineout2 LR Mux", adau1373_lineout2_lr_mux_enum), | ||
| 407 | }; | ||
| 408 | |||
| 409 | static const struct snd_kcontrol_new adau1373_drc_controls[] = { | ||
| 410 | SOC_ENUM("DRC1 Channel", adau1373_drc1_channel_enum), | ||
| 411 | SOC_ENUM("DRC2 Channel", adau1373_drc2_channel_enum), | ||
| 412 | SOC_ENUM("DRC3 Channel", adau1373_drc3_channel_enum), | ||
| 413 | }; | ||
| 414 | |||
| 415 | static int adau1373_pll_event(struct snd_soc_dapm_widget *w, | ||
| 416 | struct snd_kcontrol *kcontrol, int event) | ||
| 417 | { | ||
| 418 | struct snd_soc_codec *codec = w->codec; | ||
| 419 | unsigned int pll_id = w->name[3] - '1'; | ||
| 420 | unsigned int val; | ||
| 421 | |||
| 422 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
| 423 | val = ADAU1373_PLL_CTRL6_PLL_EN; | ||
| 424 | else | ||
| 425 | val = 0; | ||
| 426 | |||
| 427 | snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), | ||
| 428 | ADAU1373_PLL_CTRL6_PLL_EN, val); | ||
| 429 | |||
| 430 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
| 431 | mdelay(5); | ||
| 432 | |||
| 433 | return 0; | ||
| 434 | } | ||
| 435 | |||
| 436 | static const char *adau1373_decimator_text[] = { | ||
| 437 | "ADC", | ||
| 438 | "DMIC1", | ||
| 439 | }; | ||
| 440 | |||
| 441 | static const struct soc_enum adau1373_decimator_enum = | ||
| 442 | SOC_ENUM_SINGLE(0, 0, 2, adau1373_decimator_text); | ||
| 443 | |||
| 444 | static const struct snd_kcontrol_new adau1373_decimator_mux = | ||
| 445 | SOC_DAPM_ENUM_VIRT("Decimator Mux", adau1373_decimator_enum); | ||
| 446 | |||
| 447 | static const struct snd_kcontrol_new adau1373_left_adc_mixer_controls[] = { | ||
| 448 | SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_LADC_MIXER, 4, 1, 0), | ||
| 449 | SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_LADC_MIXER, 3, 1, 0), | ||
| 450 | SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_LADC_MIXER, 2, 1, 0), | ||
| 451 | SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_LADC_MIXER, 1, 1, 0), | ||
| 452 | SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_LADC_MIXER, 0, 1, 0), | ||
| 453 | }; | ||
| 454 | |||
| 455 | static const struct snd_kcontrol_new adau1373_right_adc_mixer_controls[] = { | ||
| 456 | SOC_DAPM_SINGLE("DAC1 Switch", ADAU1373_RADC_MIXER, 4, 1, 0), | ||
| 457 | SOC_DAPM_SINGLE("Input 4 Switch", ADAU1373_RADC_MIXER, 3, 1, 0), | ||
| 458 | SOC_DAPM_SINGLE("Input 3 Switch", ADAU1373_RADC_MIXER, 2, 1, 0), | ||
| 459 | SOC_DAPM_SINGLE("Input 2 Switch", ADAU1373_RADC_MIXER, 1, 1, 0), | ||
| 460 | SOC_DAPM_SINGLE("Input 1 Switch", ADAU1373_RADC_MIXER, 0, 1, 0), | ||
| 461 | }; | ||
| 462 | |||
| 463 | #define DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(_name, _reg) \ | ||
| 464 | const struct snd_kcontrol_new _name[] = { \ | ||
| 465 | SOC_DAPM_SINGLE("Left DAC2 Switch", _reg, 7, 1, 0), \ | ||
| 466 | SOC_DAPM_SINGLE("Right DAC2 Switch", _reg, 6, 1, 0), \ | ||
| 467 | SOC_DAPM_SINGLE("Left DAC1 Switch", _reg, 5, 1, 0), \ | ||
| 468 | SOC_DAPM_SINGLE("Right DAC1 Switch", _reg, 4, 1, 0), \ | ||
| 469 | SOC_DAPM_SINGLE("Input 4 Bypass Switch", _reg, 3, 1, 0), \ | ||
| 470 | SOC_DAPM_SINGLE("Input 3 Bypass Switch", _reg, 2, 1, 0), \ | ||
| 471 | SOC_DAPM_SINGLE("Input 2 Bypass Switch", _reg, 1, 1, 0), \ | ||
| 472 | SOC_DAPM_SINGLE("Input 1 Bypass Switch", _reg, 0, 1, 0), \ | ||
| 473 | } | ||
| 474 | |||
| 475 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line1_mixer_controls, | ||
| 476 | ADAU1373_LLINE1_MIX); | ||
| 477 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line1_mixer_controls, | ||
| 478 | ADAU1373_RLINE1_MIX); | ||
| 479 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_line2_mixer_controls, | ||
| 480 | ADAU1373_LLINE2_MIX); | ||
| 481 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_line2_mixer_controls, | ||
| 482 | ADAU1373_RLINE2_MIX); | ||
| 483 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_left_spk_mixer_controls, | ||
| 484 | ADAU1373_LSPK_MIX); | ||
| 485 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_right_spk_mixer_controls, | ||
| 486 | ADAU1373_RSPK_MIX); | ||
| 487 | static DECLARE_ADAU1373_OUTPUT_MIXER_CTRLS(adau1373_ep_mixer_controls, | ||
| 488 | ADAU1373_EP_MIX); | ||
| 489 | |||
| 490 | static const struct snd_kcontrol_new adau1373_left_hp_mixer_controls[] = { | ||
| 491 | SOC_DAPM_SINGLE("Left DAC1 Switch", ADAU1373_LHP_MIX, 5, 1, 0), | ||
| 492 | SOC_DAPM_SINGLE("Left DAC2 Switch", ADAU1373_LHP_MIX, 4, 1, 0), | ||
| 493 | SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_LHP_MIX, 3, 1, 0), | ||
| 494 | SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_LHP_MIX, 2, 1, 0), | ||
| 495 | SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_LHP_MIX, 1, 1, 0), | ||
| 496 | SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_LHP_MIX, 0, 1, 0), | ||
| 497 | }; | ||
| 498 | |||
| 499 | static const struct snd_kcontrol_new adau1373_right_hp_mixer_controls[] = { | ||
| 500 | SOC_DAPM_SINGLE("Right DAC1 Switch", ADAU1373_RHP_MIX, 5, 1, 0), | ||
| 501 | SOC_DAPM_SINGLE("Right DAC2 Switch", ADAU1373_RHP_MIX, 4, 1, 0), | ||
| 502 | SOC_DAPM_SINGLE("Input 4 Bypass Switch", ADAU1373_RHP_MIX, 3, 1, 0), | ||
| 503 | SOC_DAPM_SINGLE("Input 3 Bypass Switch", ADAU1373_RHP_MIX, 2, 1, 0), | ||
| 504 | SOC_DAPM_SINGLE("Input 2 Bypass Switch", ADAU1373_RHP_MIX, 1, 1, 0), | ||
| 505 | SOC_DAPM_SINGLE("Input 1 Bypass Switch", ADAU1373_RHP_MIX, 0, 1, 0), | ||
| 506 | }; | ||
| 507 | |||
| 508 | #define DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(_name, _reg) \ | ||
| 509 | const struct snd_kcontrol_new _name[] = { \ | ||
| 510 | SOC_DAPM_SINGLE("DMIC2 Swapped Switch", _reg, 6, 1, 0), \ | ||
| 511 | SOC_DAPM_SINGLE("DMIC2 Switch", _reg, 5, 1, 0), \ | ||
| 512 | SOC_DAPM_SINGLE("ADC/DMIC1 Swapped Switch", _reg, 4, 1, 0), \ | ||
| 513 | SOC_DAPM_SINGLE("ADC/DMIC1 Switch", _reg, 3, 1, 0), \ | ||
| 514 | SOC_DAPM_SINGLE("AIF3 Switch", _reg, 2, 1, 0), \ | ||
| 515 | SOC_DAPM_SINGLE("AIF2 Switch", _reg, 1, 1, 0), \ | ||
| 516 | SOC_DAPM_SINGLE("AIF1 Switch", _reg, 0, 1, 0), \ | ||
| 517 | } | ||
| 518 | |||
| 519 | static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel1_mixer_controls, | ||
| 520 | ADAU1373_DIN_MIX_CTRL(0)); | ||
| 521 | static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel2_mixer_controls, | ||
| 522 | ADAU1373_DIN_MIX_CTRL(1)); | ||
| 523 | static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel3_mixer_controls, | ||
| 524 | ADAU1373_DIN_MIX_CTRL(2)); | ||
| 525 | static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel4_mixer_controls, | ||
| 526 | ADAU1373_DIN_MIX_CTRL(3)); | ||
| 527 | static DECLARE_ADAU1373_DSP_CHANNEL_MIXER_CTRLS(adau1373_dsp_channel5_mixer_controls, | ||
| 528 | ADAU1373_DIN_MIX_CTRL(4)); | ||
| 529 | |||
| 530 | #define DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(_name, _reg) \ | ||
| 531 | const struct snd_kcontrol_new _name[] = { \ | ||
| 532 | SOC_DAPM_SINGLE("DSP Channel5 Switch", _reg, 4, 1, 0), \ | ||
| 533 | SOC_DAPM_SINGLE("DSP Channel4 Switch", _reg, 3, 1, 0), \ | ||
| 534 | SOC_DAPM_SINGLE("DSP Channel3 Switch", _reg, 2, 1, 0), \ | ||
| 535 | SOC_DAPM_SINGLE("DSP Channel2 Switch", _reg, 1, 1, 0), \ | ||
| 536 | SOC_DAPM_SINGLE("DSP Channel1 Switch", _reg, 0, 1, 0), \ | ||
| 537 | } | ||
| 538 | |||
| 539 | static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif1_mixer_controls, | ||
| 540 | ADAU1373_DOUT_MIX_CTRL(0)); | ||
| 541 | static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif2_mixer_controls, | ||
| 542 | ADAU1373_DOUT_MIX_CTRL(1)); | ||
| 543 | static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_aif3_mixer_controls, | ||
| 544 | ADAU1373_DOUT_MIX_CTRL(2)); | ||
| 545 | static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac1_mixer_controls, | ||
| 546 | ADAU1373_DOUT_MIX_CTRL(3)); | ||
| 547 | static DECLARE_ADAU1373_DSP_OUTPUT_MIXER_CTRLS(adau1373_dac2_mixer_controls, | ||
| 548 | ADAU1373_DOUT_MIX_CTRL(4)); | ||
| 549 | |||
| 550 | static const struct snd_soc_dapm_widget adau1373_dapm_widgets[] = { | ||
| 551 | /* Datasheet claims Left ADC is bit 6 and Right ADC is bit 7, but that | ||
| 552 | * doesn't seem to be the case. */ | ||
| 553 | SND_SOC_DAPM_ADC("Left ADC", NULL, ADAU1373_PWDN_CTRL1, 7, 0), | ||
| 554 | SND_SOC_DAPM_ADC("Right ADC", NULL, ADAU1373_PWDN_CTRL1, 6, 0), | ||
| 555 | |||
| 556 | SND_SOC_DAPM_ADC("DMIC1", NULL, ADAU1373_DIGMICCTRL, 0, 0), | ||
| 557 | SND_SOC_DAPM_ADC("DMIC2", NULL, ADAU1373_DIGMICCTRL, 2, 0), | ||
| 558 | |||
| 559 | SND_SOC_DAPM_VIRT_MUX("Decimator Mux", SND_SOC_NOPM, 0, 0, | ||
| 560 | &adau1373_decimator_mux), | ||
| 561 | |||
| 562 | SND_SOC_DAPM_SUPPLY("MICBIAS2", ADAU1373_PWDN_CTRL1, 5, 0, NULL, 0), | ||
| 563 | SND_SOC_DAPM_SUPPLY("MICBIAS1", ADAU1373_PWDN_CTRL1, 4, 0, NULL, 0), | ||
| 564 | |||
| 565 | SND_SOC_DAPM_PGA("IN4PGA", ADAU1373_PWDN_CTRL1, 3, 0, NULL, 0), | ||
| 566 | SND_SOC_DAPM_PGA("IN3PGA", ADAU1373_PWDN_CTRL1, 2, 0, NULL, 0), | ||
| 567 | SND_SOC_DAPM_PGA("IN2PGA", ADAU1373_PWDN_CTRL1, 1, 0, NULL, 0), | ||
| 568 | SND_SOC_DAPM_PGA("IN1PGA", ADAU1373_PWDN_CTRL1, 0, 0, NULL, 0), | ||
| 569 | |||
| 570 | SND_SOC_DAPM_DAC("Left DAC2", NULL, ADAU1373_PWDN_CTRL2, 7, 0), | ||
| 571 | SND_SOC_DAPM_DAC("Right DAC2", NULL, ADAU1373_PWDN_CTRL2, 6, 0), | ||
| 572 | SND_SOC_DAPM_DAC("Left DAC1", NULL, ADAU1373_PWDN_CTRL2, 5, 0), | ||
| 573 | SND_SOC_DAPM_DAC("Right DAC1", NULL, ADAU1373_PWDN_CTRL2, 4, 0), | ||
| 574 | |||
| 575 | SOC_MIXER_ARRAY("Left ADC Mixer", SND_SOC_NOPM, 0, 0, | ||
| 576 | adau1373_left_adc_mixer_controls), | ||
| 577 | SOC_MIXER_ARRAY("Right ADC Mixer", SND_SOC_NOPM, 0, 0, | ||
| 578 | adau1373_right_adc_mixer_controls), | ||
| 579 | |||
| 580 | SOC_MIXER_ARRAY("Left Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 3, 0, | ||
| 581 | adau1373_left_line2_mixer_controls), | ||
| 582 | SOC_MIXER_ARRAY("Right Lineout2 Mixer", ADAU1373_PWDN_CTRL2, 2, 0, | ||
| 583 | adau1373_right_line2_mixer_controls), | ||
| 584 | SOC_MIXER_ARRAY("Left Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 1, 0, | ||
| 585 | adau1373_left_line1_mixer_controls), | ||
| 586 | SOC_MIXER_ARRAY("Right Lineout1 Mixer", ADAU1373_PWDN_CTRL2, 0, 0, | ||
| 587 | adau1373_right_line1_mixer_controls), | ||
| 588 | |||
| 589 | SOC_MIXER_ARRAY("Earpiece Mixer", ADAU1373_PWDN_CTRL3, 4, 0, | ||
| 590 | adau1373_ep_mixer_controls), | ||
| 591 | SOC_MIXER_ARRAY("Left Speaker Mixer", ADAU1373_PWDN_CTRL3, 3, 0, | ||
| 592 | adau1373_left_spk_mixer_controls), | ||
| 593 | SOC_MIXER_ARRAY("Right Speaker Mixer", ADAU1373_PWDN_CTRL3, 2, 0, | ||
| 594 | adau1373_right_spk_mixer_controls), | ||
| 595 | SOC_MIXER_ARRAY("Left Headphone Mixer", SND_SOC_NOPM, 0, 0, | ||
| 596 | adau1373_left_hp_mixer_controls), | ||
| 597 | SOC_MIXER_ARRAY("Right Headphone Mixer", SND_SOC_NOPM, 0, 0, | ||
| 598 | adau1373_right_hp_mixer_controls), | ||
| 599 | SND_SOC_DAPM_SUPPLY("Headphone Enable", ADAU1373_PWDN_CTRL3, 1, 0, | ||
| 600 | NULL, 0), | ||
| 601 | |||
| 602 | SND_SOC_DAPM_SUPPLY("AIF1 CLK", ADAU1373_SRC_DAI_CTRL(0), 0, 0, | ||
| 603 | NULL, 0), | ||
| 604 | SND_SOC_DAPM_SUPPLY("AIF2 CLK", ADAU1373_SRC_DAI_CTRL(1), 0, 0, | ||
| 605 | NULL, 0), | ||
| 606 | SND_SOC_DAPM_SUPPLY("AIF3 CLK", ADAU1373_SRC_DAI_CTRL(2), 0, 0, | ||
| 607 | NULL, 0), | ||
| 608 | SND_SOC_DAPM_SUPPLY("AIF1 IN SRC", ADAU1373_SRC_DAI_CTRL(0), 2, 0, | ||
| 609 | NULL, 0), | ||
| 610 | SND_SOC_DAPM_SUPPLY("AIF1 OUT SRC", ADAU1373_SRC_DAI_CTRL(0), 1, 0, | ||
| 611 | NULL, 0), | ||
| 612 | SND_SOC_DAPM_SUPPLY("AIF2 IN SRC", ADAU1373_SRC_DAI_CTRL(1), 2, 0, | ||
| 613 | NULL, 0), | ||
| 614 | SND_SOC_DAPM_SUPPLY("AIF2 OUT SRC", ADAU1373_SRC_DAI_CTRL(1), 1, 0, | ||
| 615 | NULL, 0), | ||
| 616 | SND_SOC_DAPM_SUPPLY("AIF3 IN SRC", ADAU1373_SRC_DAI_CTRL(2), 2, 0, | ||
| 617 | NULL, 0), | ||
| 618 | SND_SOC_DAPM_SUPPLY("AIF3 OUT SRC", ADAU1373_SRC_DAI_CTRL(2), 1, 0, | ||
| 619 | NULL, 0), | ||
| 620 | |||
| 621 | SND_SOC_DAPM_AIF_IN("AIF1 IN", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 622 | SND_SOC_DAPM_AIF_OUT("AIF1 OUT", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 623 | SND_SOC_DAPM_AIF_IN("AIF2 IN", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 624 | SND_SOC_DAPM_AIF_OUT("AIF2 OUT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 625 | SND_SOC_DAPM_AIF_IN("AIF3 IN", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), | ||
| 626 | SND_SOC_DAPM_AIF_OUT("AIF3 OUT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), | ||
| 627 | |||
| 628 | SOC_MIXER_ARRAY("DSP Channel1 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 629 | adau1373_dsp_channel1_mixer_controls), | ||
| 630 | SOC_MIXER_ARRAY("DSP Channel2 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 631 | adau1373_dsp_channel2_mixer_controls), | ||
| 632 | SOC_MIXER_ARRAY("DSP Channel3 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 633 | adau1373_dsp_channel3_mixer_controls), | ||
| 634 | SOC_MIXER_ARRAY("DSP Channel4 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 635 | adau1373_dsp_channel4_mixer_controls), | ||
| 636 | SOC_MIXER_ARRAY("DSP Channel5 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 637 | adau1373_dsp_channel5_mixer_controls), | ||
| 638 | |||
| 639 | SOC_MIXER_ARRAY("AIF1 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 640 | adau1373_aif1_mixer_controls), | ||
| 641 | SOC_MIXER_ARRAY("AIF2 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 642 | adau1373_aif2_mixer_controls), | ||
| 643 | SOC_MIXER_ARRAY("AIF3 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 644 | adau1373_aif3_mixer_controls), | ||
| 645 | SOC_MIXER_ARRAY("DAC1 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 646 | adau1373_dac1_mixer_controls), | ||
| 647 | SOC_MIXER_ARRAY("DAC2 Mixer", SND_SOC_NOPM, 0, 0, | ||
| 648 | adau1373_dac2_mixer_controls), | ||
| 649 | |||
| 650 | SND_SOC_DAPM_SUPPLY("DSP", ADAU1373_DIGEN, 4, 0, NULL, 0), | ||
| 651 | SND_SOC_DAPM_SUPPLY("Recording Engine B", ADAU1373_DIGEN, 3, 0, NULL, 0), | ||
| 652 | SND_SOC_DAPM_SUPPLY("Recording Engine A", ADAU1373_DIGEN, 2, 0, NULL, 0), | ||
| 653 | SND_SOC_DAPM_SUPPLY("Playback Engine B", ADAU1373_DIGEN, 1, 0, NULL, 0), | ||
| 654 | SND_SOC_DAPM_SUPPLY("Playback Engine A", ADAU1373_DIGEN, 0, 0, NULL, 0), | ||
| 655 | |||
| 656 | SND_SOC_DAPM_SUPPLY("PLL1", SND_SOC_NOPM, 0, 0, adau1373_pll_event, | ||
| 657 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 658 | SND_SOC_DAPM_SUPPLY("PLL2", SND_SOC_NOPM, 0, 0, adau1373_pll_event, | ||
| 659 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 660 | SND_SOC_DAPM_SUPPLY("SYSCLK1", ADAU1373_CLK_SRC_DIV(0), 7, 0, NULL, 0), | ||
| 661 | SND_SOC_DAPM_SUPPLY("SYSCLK2", ADAU1373_CLK_SRC_DIV(1), 7, 0, NULL, 0), | ||
| 662 | |||
| 663 | SND_SOC_DAPM_INPUT("AIN1L"), | ||
| 664 | SND_SOC_DAPM_INPUT("AIN1R"), | ||
| 665 | SND_SOC_DAPM_INPUT("AIN2L"), | ||
| 666 | SND_SOC_DAPM_INPUT("AIN2R"), | ||
| 667 | SND_SOC_DAPM_INPUT("AIN3L"), | ||
| 668 | SND_SOC_DAPM_INPUT("AIN3R"), | ||
| 669 | SND_SOC_DAPM_INPUT("AIN4L"), | ||
| 670 | SND_SOC_DAPM_INPUT("AIN4R"), | ||
| 671 | |||
| 672 | SND_SOC_DAPM_INPUT("DMIC1DAT"), | ||
| 673 | SND_SOC_DAPM_INPUT("DMIC2DAT"), | ||
| 674 | |||
| 675 | SND_SOC_DAPM_OUTPUT("LOUT1L"), | ||
| 676 | SND_SOC_DAPM_OUTPUT("LOUT1R"), | ||
| 677 | SND_SOC_DAPM_OUTPUT("LOUT2L"), | ||
| 678 | SND_SOC_DAPM_OUTPUT("LOUT2R"), | ||
| 679 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
| 680 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
| 681 | SND_SOC_DAPM_OUTPUT("SPKL"), | ||
| 682 | SND_SOC_DAPM_OUTPUT("SPKR"), | ||
| 683 | SND_SOC_DAPM_OUTPUT("EP"), | ||
| 684 | }; | ||
| 685 | |||
| 686 | static int adau1373_check_aif_clk(struct snd_soc_dapm_widget *source, | ||
| 687 | struct snd_soc_dapm_widget *sink) | ||
| 688 | { | ||
| 689 | struct snd_soc_codec *codec = source->codec; | ||
| 690 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); | ||
| 691 | unsigned int dai; | ||
| 692 | const char *clk; | ||
| 693 | |||
| 694 | dai = sink->name[3] - '1'; | ||
| 695 | |||
| 696 | if (!adau1373->dais[dai].master) | ||
| 697 | return 0; | ||
| 698 | |||
| 699 | if (adau1373->dais[dai].clk_src == ADAU1373_CLK_SRC_PLL1) | ||
| 700 | clk = "SYSCLK1"; | ||
| 701 | else | ||
| 702 | clk = "SYSCLK2"; | ||
| 703 | |||
| 704 | return strcmp(source->name, clk) == 0; | ||
| 705 | } | ||
| 706 | |||
| 707 | static int adau1373_check_src(struct snd_soc_dapm_widget *source, | ||
| 708 | struct snd_soc_dapm_widget *sink) | ||
| 709 | { | ||
| 710 | struct snd_soc_codec *codec = source->codec; | ||
| 711 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); | ||
| 712 | unsigned int dai; | ||
| 713 | |||
| 714 | dai = sink->name[3] - '1'; | ||
| 715 | |||
| 716 | return adau1373->dais[dai].enable_src; | ||
| 717 | } | ||
| 718 | |||
| 719 | #define DSP_CHANNEL_MIXER_ROUTES(_sink) \ | ||
| 720 | { _sink, "DMIC2 Swapped Switch", "DMIC2" }, \ | ||
| 721 | { _sink, "DMIC2 Switch", "DMIC2" }, \ | ||
| 722 | { _sink, "ADC/DMIC1 Swapped Switch", "Decimator Mux" }, \ | ||
| 723 | { _sink, "ADC/DMIC1 Switch", "Decimator Mux" }, \ | ||
| 724 | { _sink, "AIF1 Switch", "AIF1 IN" }, \ | ||
| 725 | { _sink, "AIF2 Switch", "AIF2 IN" }, \ | ||
| 726 | { _sink, "AIF3 Switch", "AIF3 IN" } | ||
| 727 | |||
| 728 | #define DSP_OUTPUT_MIXER_ROUTES(_sink) \ | ||
| 729 | { _sink, "DSP Channel1 Switch", "DSP Channel1 Mixer" }, \ | ||
| 730 | { _sink, "DSP Channel2 Switch", "DSP Channel2 Mixer" }, \ | ||
| 731 | { _sink, "DSP Channel3 Switch", "DSP Channel3 Mixer" }, \ | ||
| 732 | { _sink, "DSP Channel4 Switch", "DSP Channel4 Mixer" }, \ | ||
| 733 | { _sink, "DSP Channel5 Switch", "DSP Channel5 Mixer" } | ||
| 734 | |||
| 735 | #define LEFT_OUTPUT_MIXER_ROUTES(_sink) \ | ||
| 736 | { _sink, "Right DAC2 Switch", "Right DAC2" }, \ | ||
| 737 | { _sink, "Left DAC2 Switch", "Left DAC2" }, \ | ||
| 738 | { _sink, "Right DAC1 Switch", "Right DAC1" }, \ | ||
| 739 | { _sink, "Left DAC1 Switch", "Left DAC1" }, \ | ||
| 740 | { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \ | ||
| 741 | { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \ | ||
| 742 | { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \ | ||
| 743 | { _sink, "Input 4 Bypass Switch", "IN4PGA" } | ||
| 744 | |||
| 745 | #define RIGHT_OUTPUT_MIXER_ROUTES(_sink) \ | ||
| 746 | { _sink, "Right DAC2 Switch", "Right DAC2" }, \ | ||
| 747 | { _sink, "Left DAC2 Switch", "Left DAC2" }, \ | ||
| 748 | { _sink, "Right DAC1 Switch", "Right DAC1" }, \ | ||
| 749 | { _sink, "Left DAC1 Switch", "Left DAC1" }, \ | ||
| 750 | { _sink, "Input 1 Bypass Switch", "IN1PGA" }, \ | ||
| 751 | { _sink, "Input 2 Bypass Switch", "IN2PGA" }, \ | ||
| 752 | { _sink, "Input 3 Bypass Switch", "IN3PGA" }, \ | ||
| 753 | { _sink, "Input 4 Bypass Switch", "IN4PGA" } | ||
| 754 | |||
| 755 | static const struct snd_soc_dapm_route adau1373_dapm_routes[] = { | ||
| 756 | { "Left ADC Mixer", "DAC1 Switch", "Left DAC1" }, | ||
| 757 | { "Left ADC Mixer", "Input 1 Switch", "IN1PGA" }, | ||
| 758 | { "Left ADC Mixer", "Input 2 Switch", "IN2PGA" }, | ||
| 759 | { "Left ADC Mixer", "Input 3 Switch", "IN3PGA" }, | ||
| 760 | { "Left ADC Mixer", "Input 4 Switch", "IN4PGA" }, | ||
| 761 | |||
| 762 | { "Right ADC Mixer", "DAC1 Switch", "Right DAC1" }, | ||
| 763 | { "Right ADC Mixer", "Input 1 Switch", "IN1PGA" }, | ||
| 764 | { "Right ADC Mixer", "Input 2 Switch", "IN2PGA" }, | ||
| 765 | { "Right ADC Mixer", "Input 3 Switch", "IN3PGA" }, | ||
| 766 | { "Right ADC Mixer", "Input 4 Switch", "IN4PGA" }, | ||
| 767 | |||
| 768 | { "Left ADC", NULL, "Left ADC Mixer" }, | ||
| 769 | { "Right ADC", NULL, "Right ADC Mixer" }, | ||
| 770 | |||
| 771 | { "Decimator Mux", "ADC", "Left ADC" }, | ||
| 772 | { "Decimator Mux", "ADC", "Right ADC" }, | ||
| 773 | { "Decimator Mux", "DMIC1", "DMIC1" }, | ||
| 774 | |||
| 775 | DSP_CHANNEL_MIXER_ROUTES("DSP Channel1 Mixer"), | ||
| 776 | DSP_CHANNEL_MIXER_ROUTES("DSP Channel2 Mixer"), | ||
| 777 | DSP_CHANNEL_MIXER_ROUTES("DSP Channel3 Mixer"), | ||
| 778 | DSP_CHANNEL_MIXER_ROUTES("DSP Channel4 Mixer"), | ||
| 779 | DSP_CHANNEL_MIXER_ROUTES("DSP Channel5 Mixer"), | ||
| 780 | |||
| 781 | DSP_OUTPUT_MIXER_ROUTES("AIF1 Mixer"), | ||
| 782 | DSP_OUTPUT_MIXER_ROUTES("AIF2 Mixer"), | ||
| 783 | DSP_OUTPUT_MIXER_ROUTES("AIF3 Mixer"), | ||
| 784 | DSP_OUTPUT_MIXER_ROUTES("DAC1 Mixer"), | ||
| 785 | DSP_OUTPUT_MIXER_ROUTES("DAC2 Mixer"), | ||
| 786 | |||
| 787 | { "AIF1 OUT", NULL, "AIF1 Mixer" }, | ||
| 788 | { "AIF2 OUT", NULL, "AIF2 Mixer" }, | ||
| 789 | { "AIF3 OUT", NULL, "AIF3 Mixer" }, | ||
| 790 | { "Left DAC1", NULL, "DAC1 Mixer" }, | ||
| 791 | { "Right DAC1", NULL, "DAC1 Mixer" }, | ||
| 792 | { "Left DAC2", NULL, "DAC2 Mixer" }, | ||
| 793 | { "Right DAC2", NULL, "DAC2 Mixer" }, | ||
| 794 | |||
| 795 | LEFT_OUTPUT_MIXER_ROUTES("Left Lineout1 Mixer"), | ||
| 796 | RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout1 Mixer"), | ||
| 797 | LEFT_OUTPUT_MIXER_ROUTES("Left Lineout2 Mixer"), | ||
| 798 | RIGHT_OUTPUT_MIXER_ROUTES("Right Lineout2 Mixer"), | ||
| 799 | LEFT_OUTPUT_MIXER_ROUTES("Left Speaker Mixer"), | ||
| 800 | RIGHT_OUTPUT_MIXER_ROUTES("Right Speaker Mixer"), | ||
| 801 | |||
| 802 | { "Left Headphone Mixer", "Left DAC2 Switch", "Left DAC2" }, | ||
| 803 | { "Left Headphone Mixer", "Left DAC1 Switch", "Left DAC1" }, | ||
| 804 | { "Left Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" }, | ||
| 805 | { "Left Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" }, | ||
| 806 | { "Left Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" }, | ||
| 807 | { "Left Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" }, | ||
| 808 | { "Right Headphone Mixer", "Right DAC2 Switch", "Right DAC2" }, | ||
| 809 | { "Right Headphone Mixer", "Right DAC1 Switch", "Right DAC1" }, | ||
| 810 | { "Right Headphone Mixer", "Input 1 Bypass Switch", "IN1PGA" }, | ||
| 811 | { "Right Headphone Mixer", "Input 2 Bypass Switch", "IN2PGA" }, | ||
| 812 | { "Right Headphone Mixer", "Input 3 Bypass Switch", "IN3PGA" }, | ||
| 813 | { "Right Headphone Mixer", "Input 4 Bypass Switch", "IN4PGA" }, | ||
| 814 | |||
| 815 | { "Left Headphone Mixer", NULL, "Headphone Enable" }, | ||
| 816 | { "Right Headphone Mixer", NULL, "Headphone Enable" }, | ||
| 817 | |||
| 818 | { "Earpiece Mixer", "Right DAC2 Switch", "Right DAC2" }, | ||
| 819 | { "Earpiece Mixer", "Left DAC2 Switch", "Left DAC2" }, | ||
| 820 | { "Earpiece Mixer", "Right DAC1 Switch", "Right DAC1" }, | ||
| 821 | { "Earpiece Mixer", "Left DAC1 Switch", "Left DAC1" }, | ||
| 822 | { "Earpiece Mixer", "Input 1 Bypass Switch", "IN1PGA" }, | ||
| 823 | { "Earpiece Mixer", "Input 2 Bypass Switch", "IN2PGA" }, | ||
| 824 | { "Earpiece Mixer", "Input 3 Bypass Switch", "IN3PGA" }, | ||
| 825 | { "Earpiece Mixer", "Input 4 Bypass Switch", "IN4PGA" }, | ||
| 826 | |||
| 827 | { "LOUT1L", NULL, "Left Lineout1 Mixer" }, | ||
| 828 | { "LOUT1R", NULL, "Right Lineout1 Mixer" }, | ||
| 829 | { "LOUT2L", NULL, "Left Lineout2 Mixer" }, | ||
| 830 | { "LOUT2R", NULL, "Right Lineout2 Mixer" }, | ||
| 831 | { "SPKL", NULL, "Left Speaker Mixer" }, | ||
| 832 | { "SPKR", NULL, "Right Speaker Mixer" }, | ||
| 833 | { "HPL", NULL, "Left Headphone Mixer" }, | ||
| 834 | { "HPR", NULL, "Right Headphone Mixer" }, | ||
| 835 | { "EP", NULL, "Earpiece Mixer" }, | ||
| 836 | |||
| 837 | { "IN1PGA", NULL, "AIN1L" }, | ||
| 838 | { "IN2PGA", NULL, "AIN2L" }, | ||
| 839 | { "IN3PGA", NULL, "AIN3L" }, | ||
| 840 | { "IN4PGA", NULL, "AIN4L" }, | ||
| 841 | { "IN1PGA", NULL, "AIN1R" }, | ||
| 842 | { "IN2PGA", NULL, "AIN2R" }, | ||
| 843 | { "IN3PGA", NULL, "AIN3R" }, | ||
| 844 | { "IN4PGA", NULL, "AIN4R" }, | ||
| 845 | |||
| 846 | { "SYSCLK1", NULL, "PLL1" }, | ||
| 847 | { "SYSCLK2", NULL, "PLL2" }, | ||
| 848 | |||
| 849 | { "Left DAC1", NULL, "SYSCLK1" }, | ||
| 850 | { "Right DAC1", NULL, "SYSCLK1" }, | ||
| 851 | { "Left DAC2", NULL, "SYSCLK1" }, | ||
| 852 | { "Right DAC2", NULL, "SYSCLK1" }, | ||
| 853 | { "Left ADC", NULL, "SYSCLK1" }, | ||
| 854 | { "Right ADC", NULL, "SYSCLK1" }, | ||
| 855 | |||
| 856 | { "DSP", NULL, "SYSCLK1" }, | ||
| 857 | |||
| 858 | { "AIF1 Mixer", NULL, "DSP" }, | ||
| 859 | { "AIF2 Mixer", NULL, "DSP" }, | ||
| 860 | { "AIF3 Mixer", NULL, "DSP" }, | ||
| 861 | { "DAC1 Mixer", NULL, "DSP" }, | ||
| 862 | { "DAC2 Mixer", NULL, "DSP" }, | ||
| 863 | { "DAC1 Mixer", NULL, "Playback Engine A" }, | ||
| 864 | { "DAC2 Mixer", NULL, "Playback Engine B" }, | ||
| 865 | { "Left ADC Mixer", NULL, "Recording Engine A" }, | ||
| 866 | { "Right ADC Mixer", NULL, "Recording Engine A" }, | ||
| 867 | |||
| 868 | { "AIF1 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk }, | ||
| 869 | { "AIF2 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk }, | ||
| 870 | { "AIF3 CLK", NULL, "SYSCLK1", adau1373_check_aif_clk }, | ||
| 871 | { "AIF1 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk }, | ||
| 872 | { "AIF2 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk }, | ||
| 873 | { "AIF3 CLK", NULL, "SYSCLK2", adau1373_check_aif_clk }, | ||
| 874 | |||
| 875 | { "AIF1 IN", NULL, "AIF1 CLK" }, | ||
| 876 | { "AIF1 OUT", NULL, "AIF1 CLK" }, | ||
| 877 | { "AIF2 IN", NULL, "AIF2 CLK" }, | ||
| 878 | { "AIF2 OUT", NULL, "AIF2 CLK" }, | ||
| 879 | { "AIF3 IN", NULL, "AIF3 CLK" }, | ||
| 880 | { "AIF3 OUT", NULL, "AIF3 CLK" }, | ||
| 881 | { "AIF1 IN", NULL, "AIF1 IN SRC", adau1373_check_src }, | ||
| 882 | { "AIF1 OUT", NULL, "AIF1 OUT SRC", adau1373_check_src }, | ||
| 883 | { "AIF2 IN", NULL, "AIF2 IN SRC", adau1373_check_src }, | ||
| 884 | { "AIF2 OUT", NULL, "AIF2 OUT SRC", adau1373_check_src }, | ||
| 885 | { "AIF3 IN", NULL, "AIF3 IN SRC", adau1373_check_src }, | ||
| 886 | { "AIF3 OUT", NULL, "AIF3 OUT SRC", adau1373_check_src }, | ||
| 887 | |||
| 888 | { "DMIC1", NULL, "DMIC1DAT" }, | ||
| 889 | { "DMIC1", NULL, "SYSCLK1" }, | ||
| 890 | { "DMIC1", NULL, "Recording Engine A" }, | ||
| 891 | { "DMIC2", NULL, "DMIC2DAT" }, | ||
| 892 | { "DMIC2", NULL, "SYSCLK1" }, | ||
| 893 | { "DMIC2", NULL, "Recording Engine B" }, | ||
| 894 | }; | ||
| 895 | |||
| 896 | static int adau1373_hw_params(struct snd_pcm_substream *substream, | ||
| 897 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
| 898 | { | ||
| 899 | struct snd_soc_codec *codec = dai->codec; | ||
| 900 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); | ||
| 901 | struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id]; | ||
| 902 | unsigned int div; | ||
| 903 | unsigned int freq; | ||
| 904 | unsigned int ctrl; | ||
| 905 | |||
| 906 | freq = adau1373_dai->sysclk; | ||
| 907 | |||
| 908 | if (freq % params_rate(params) != 0) | ||
| 909 | return -EINVAL; | ||
| 910 | |||
| 911 | switch (freq / params_rate(params)) { | ||
| 912 | case 1024: /* sysclk / 256 */ | ||
| 913 | div = 0; | ||
| 914 | break; | ||
| 915 | case 1536: /* 2/3 sysclk / 256 */ | ||
| 916 | div = 1; | ||
| 917 | break; | ||
| 918 | case 2048: /* 1/2 sysclk / 256 */ | ||
| 919 | div = 2; | ||
| 920 | break; | ||
| 921 | case 3072: /* 1/3 sysclk / 256 */ | ||
| 922 | div = 3; | ||
| 923 | break; | ||
| 924 | case 4096: /* 1/4 sysclk / 256 */ | ||
| 925 | div = 4; | ||
| 926 | break; | ||
| 927 | case 6144: /* 1/6 sysclk / 256 */ | ||
| 928 | div = 5; | ||
| 929 | break; | ||
| 930 | case 5632: /* 2/11 sysclk / 256 */ | ||
| 931 | div = 6; | ||
| 932 | break; | ||
| 933 | default: | ||
| 934 | return -EINVAL; | ||
| 935 | } | ||
| 936 | |||
| 937 | adau1373_dai->enable_src = (div != 0); | ||
| 938 | |||
| 939 | snd_soc_update_bits(codec, ADAU1373_BCLKDIV(dai->id), | ||
| 940 | ~ADAU1373_BCLKDIV_SOURCE, (div << 2) | ADAU1373_BCLKDIV_64); | ||
| 941 | |||
| 942 | switch (params_format(params)) { | ||
| 943 | case SNDRV_PCM_FORMAT_S16_LE: | ||
| 944 | ctrl = ADAU1373_DAI_WLEN_16; | ||
| 945 | break; | ||
| 946 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
| 947 | ctrl = ADAU1373_DAI_WLEN_20; | ||
| 948 | break; | ||
| 949 | case SNDRV_PCM_FORMAT_S24_LE: | ||
| 950 | ctrl = ADAU1373_DAI_WLEN_24; | ||
| 951 | break; | ||
| 952 | case SNDRV_PCM_FORMAT_S32_LE: | ||
| 953 | ctrl = ADAU1373_DAI_WLEN_32; | ||
| 954 | break; | ||
| 955 | default: | ||
| 956 | return -EINVAL; | ||
| 957 | } | ||
| 958 | |||
| 959 | return snd_soc_update_bits(codec, ADAU1373_DAI(dai->id), | ||
| 960 | ADAU1373_DAI_WLEN_MASK, ctrl); | ||
| 961 | } | ||
| 962 | |||
| 963 | static int adau1373_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
| 964 | { | ||
| 965 | struct snd_soc_codec *codec = dai->codec; | ||
| 966 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(codec); | ||
| 967 | struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id]; | ||
| 968 | unsigned int ctrl; | ||
| 969 | |||
| 970 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 971 | case SND_SOC_DAIFMT_CBM_CFM: | ||
| 972 | ctrl = ADAU1373_DAI_MASTER; | ||
| 973 | adau1373_dai->master = true; | ||
| 974 | break; | ||
| 975 | case SND_SOC_DAIFMT_CBS_CFS: | ||
| 976 | ctrl = 0; | ||
| 977 | adau1373_dai->master = false; | ||
| 978 | break; | ||
| 979 | default: | ||
| 980 | return -EINVAL; | ||
| 981 | } | ||
| 982 | |||
| 983 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 984 | case SND_SOC_DAIFMT_I2S: | ||
| 985 | ctrl |= ADAU1373_DAI_FORMAT_I2S; | ||
| 986 | break; | ||
| 987 | case SND_SOC_DAIFMT_LEFT_J: | ||
| 988 | ctrl |= ADAU1373_DAI_FORMAT_LEFT_J; | ||
| 989 | break; | ||
| 990 | case SND_SOC_DAIFMT_RIGHT_J: | ||
| 991 | ctrl |= ADAU1373_DAI_FORMAT_RIGHT_J; | ||
| 992 | break; | ||
| 993 | case SND_SOC_DAIFMT_DSP_B: | ||
| 994 | ctrl |= ADAU1373_DAI_FORMAT_DSP; | ||
| 995 | break; | ||
| 996 | default: | ||
| 997 | return -EINVAL; | ||
| 998 | } | ||
| 999 | |||
| 1000 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
| 1001 | case SND_SOC_DAIFMT_NB_NF: | ||
| 1002 | break; | ||
| 1003 | case SND_SOC_DAIFMT_IB_NF: | ||
| 1004 | ctrl |= ADAU1373_DAI_INVERT_BCLK; | ||
| 1005 | break; | ||
| 1006 | case SND_SOC_DAIFMT_NB_IF: | ||
| 1007 | ctrl |= ADAU1373_DAI_INVERT_LRCLK; | ||
| 1008 | break; | ||
| 1009 | case SND_SOC_DAIFMT_IB_IF: | ||
| 1010 | ctrl |= ADAU1373_DAI_INVERT_LRCLK | ADAU1373_DAI_INVERT_BCLK; | ||
| 1011 | break; | ||
| 1012 | default: | ||
| 1013 | return -EINVAL; | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | snd_soc_update_bits(codec, ADAU1373_DAI(dai->id), | ||
| 1017 | ~ADAU1373_DAI_WLEN_MASK, ctrl); | ||
| 1018 | |||
| 1019 | return 0; | ||
| 1020 | } | ||
| 1021 | |||
| 1022 | static int adau1373_set_dai_sysclk(struct snd_soc_dai *dai, | ||
| 1023 | int clk_id, unsigned int freq, int dir) | ||
| 1024 | { | ||
| 1025 | struct adau1373 *adau1373 = snd_soc_codec_get_drvdata(dai->codec); | ||
| 1026 | struct adau1373_dai *adau1373_dai = &adau1373->dais[dai->id]; | ||
| 1027 | |||
| 1028 | switch (clk_id) { | ||
| 1029 | case ADAU1373_CLK_SRC_PLL1: | ||
| 1030 | case ADAU1373_CLK_SRC_PLL2: | ||
| 1031 | break; | ||
| 1032 | default: | ||
| 1033 | return -EINVAL; | ||
| 1034 | } | ||
| 1035 | |||
| 1036 | adau1373_dai->sysclk = freq; | ||
| 1037 | adau1373_dai->clk_src = clk_id; | ||
| 1038 | |||
| 1039 | snd_soc_update_bits(dai->codec, ADAU1373_BCLKDIV(dai->id), | ||
| 1040 | ADAU1373_BCLKDIV_SOURCE, clk_id << 5); | ||
| 1041 | |||
| 1042 | return 0; | ||
| 1043 | } | ||
| 1044 | |||
| 1045 | static const struct snd_soc_dai_ops adau1373_dai_ops = { | ||
| 1046 | .hw_params = adau1373_hw_params, | ||
| 1047 | .set_sysclk = adau1373_set_dai_sysclk, | ||
| 1048 | .set_fmt = adau1373_set_dai_fmt, | ||
| 1049 | }; | ||
| 1050 | |||
| 1051 | #define ADAU1373_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
| 1052 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
| 1053 | |||
| 1054 | static struct snd_soc_dai_driver adau1373_dai_driver[] = { | ||
| 1055 | { | ||
| 1056 | .id = 0, | ||
| 1057 | .name = "adau1373-aif1", | ||
| 1058 | .playback = { | ||
| 1059 | .stream_name = "AIF1 Playback", | ||
| 1060 | .channels_min = 2, | ||
| 1061 | .channels_max = 2, | ||
| 1062 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
| 1063 | .formats = ADAU1373_FORMATS, | ||
| 1064 | }, | ||
| 1065 | .capture = { | ||
| 1066 | .stream_name = "AIF1 Capture", | ||
| 1067 | .channels_min = 2, | ||
| 1068 | .channels_max = 2, | ||
| 1069 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
| 1070 | .formats = ADAU1373_FORMATS, | ||
| 1071 | }, | ||
| 1072 | .ops = &adau1373_dai_ops, | ||
| 1073 | .symmetric_rates = 1, | ||
| 1074 | }, | ||
| 1075 | { | ||
| 1076 | .id = 1, | ||
| 1077 | .name = "adau1373-aif2", | ||
| 1078 | .playback = { | ||
| 1079 | .stream_name = "AIF2 Playback", | ||
| 1080 | .channels_min = 2, | ||
| 1081 | .channels_max = 2, | ||
| 1082 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
| 1083 | .formats = ADAU1373_FORMATS, | ||
| 1084 | }, | ||
| 1085 | .capture = { | ||
| 1086 | .stream_name = "AIF2 Capture", | ||
| 1087 | .channels_min = 2, | ||
| 1088 | .channels_max = 2, | ||
| 1089 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
| 1090 | .formats = ADAU1373_FORMATS, | ||
| 1091 | }, | ||
| 1092 | .ops = &adau1373_dai_ops, | ||
| 1093 | .symmetric_rates = 1, | ||
| 1094 | }, | ||
| 1095 | { | ||
| 1096 | .id = 2, | ||
| 1097 | .name = "adau1373-aif3", | ||
| 1098 | .playback = { | ||
| 1099 | .stream_name = "AIF3 Playback", | ||
| 1100 | .channels_min = 2, | ||
| 1101 | .channels_max = 2, | ||
| 1102 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
| 1103 | .formats = ADAU1373_FORMATS, | ||
| 1104 | }, | ||
| 1105 | .capture = { | ||
| 1106 | .stream_name = "AIF3 Capture", | ||
| 1107 | .channels_min = 2, | ||
| 1108 | .channels_max = 2, | ||
| 1109 | .rates = SNDRV_PCM_RATE_8000_48000, | ||
| 1110 | .formats = ADAU1373_FORMATS, | ||
| 1111 | }, | ||
| 1112 | .ops = &adau1373_dai_ops, | ||
| 1113 | .symmetric_rates = 1, | ||
| 1114 | }, | ||
| 1115 | }; | ||
| 1116 | |||
| 1117 | static int adau1373_set_pll(struct snd_soc_codec *codec, int pll_id, | ||
| 1118 | int source, unsigned int freq_in, unsigned int freq_out) | ||
| 1119 | { | ||
| 1120 | unsigned int dpll_div = 0; | ||
| 1121 | unsigned int x, r, n, m, i, j, mode; | ||
| 1122 | |||
| 1123 | switch (pll_id) { | ||
| 1124 | case ADAU1373_PLL1: | ||
| 1125 | case ADAU1373_PLL2: | ||
| 1126 | break; | ||
| 1127 | default: | ||
| 1128 | return -EINVAL; | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | switch (source) { | ||
| 1132 | case ADAU1373_PLL_SRC_BCLK1: | ||
| 1133 | case ADAU1373_PLL_SRC_BCLK2: | ||
| 1134 | case ADAU1373_PLL_SRC_BCLK3: | ||
| 1135 | case ADAU1373_PLL_SRC_LRCLK1: | ||
| 1136 | case ADAU1373_PLL_SRC_LRCLK2: | ||
| 1137 | case ADAU1373_PLL_SRC_LRCLK3: | ||
| 1138 | case ADAU1373_PLL_SRC_MCLK1: | ||
| 1139 | case ADAU1373_PLL_SRC_MCLK2: | ||
| 1140 | case ADAU1373_PLL_SRC_GPIO1: | ||
| 1141 | case ADAU1373_PLL_SRC_GPIO2: | ||
| 1142 | case ADAU1373_PLL_SRC_GPIO3: | ||
| 1143 | case ADAU1373_PLL_SRC_GPIO4: | ||
| 1144 | break; | ||
| 1145 | default: | ||
| 1146 | return -EINVAL; | ||
| 1147 | } | ||
| 1148 | |||
| 1149 | if (freq_in < 7813 || freq_in > 27000000) | ||
| 1150 | return -EINVAL; | ||
| 1151 | |||
| 1152 | if (freq_out < 45158000 || freq_out > 49152000) | ||
| 1153 | return -EINVAL; | ||
| 1154 | |||
| 1155 | /* APLL input needs to be >= 8Mhz, so in case freq_in is less we use the | ||
| 1156 | * DPLL to get it there. DPLL_out = (DPLL_in / div) * 1024 */ | ||
| 1157 | while (freq_in < 8000000) { | ||
| 1158 | freq_in *= 2; | ||
| 1159 | dpll_div++; | ||
| 1160 | } | ||
| 1161 | |||
| 1162 | if (freq_out % freq_in != 0) { | ||
| 1163 | /* fout = fin * (r + (n/m)) / x */ | ||
| 1164 | x = DIV_ROUND_UP(freq_in, 13500000); | ||
| 1165 | freq_in /= x; | ||
| 1166 | r = freq_out / freq_in; | ||
| 1167 | i = freq_out % freq_in; | ||
| 1168 | j = gcd(i, freq_in); | ||
| 1169 | n = i / j; | ||
| 1170 | m = freq_in / j; | ||
| 1171 | x--; | ||
| 1172 | mode = 1; | ||
| 1173 | } else { | ||
| 1174 | /* fout = fin / r */ | ||
| 1175 | r = freq_out / freq_in; | ||
| 1176 | n = 0; | ||
| 1177 | m = 0; | ||
| 1178 | x = 0; | ||
| 1179 | mode = 0; | ||
| 1180 | } | ||
| 1181 | |||
| 1182 | if (r < 2 || r > 8 || x > 3 || m > 0xffff || n > 0xffff) | ||
| 1183 | return -EINVAL; | ||
| 1184 | |||
| 1185 | if (dpll_div) { | ||
| 1186 | dpll_div = 11 - dpll_div; | ||
| 1187 | snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), | ||
| 1188 | ADAU1373_PLL_CTRL6_DPLL_BYPASS, 0); | ||
| 1189 | } else { | ||
| 1190 | snd_soc_update_bits(codec, ADAU1373_PLL_CTRL6(pll_id), | ||
| 1191 | ADAU1373_PLL_CTRL6_DPLL_BYPASS, | ||
| 1192 | ADAU1373_PLL_CTRL6_DPLL_BYPASS); | ||
| 1193 | } | ||
| 1194 | |||
| 1195 | snd_soc_write(codec, ADAU1373_DPLL_CTRL(pll_id), | ||
| 1196 | (source << 4) | dpll_div); | ||
| 1197 | snd_soc_write(codec, ADAU1373_PLL_CTRL1(pll_id), (m >> 8) & 0xff); | ||
| 1198 | snd_soc_write(codec, ADAU1373_PLL_CTRL2(pll_id), m & 0xff); | ||
| 1199 | snd_soc_write(codec, ADAU1373_PLL_CTRL3(pll_id), (n >> 8) & 0xff); | ||
| 1200 | snd_soc_write(codec, ADAU1373_PLL_CTRL4(pll_id), n & 0xff); | ||
| 1201 | snd_soc_write(codec, ADAU1373_PLL_CTRL5(pll_id), | ||
| 1202 | (r << 3) | (x << 1) | mode); | ||
| 1203 | |||
| 1204 | /* Set sysclk to pll_rate / 4 */ | ||
| 1205 | snd_soc_update_bits(codec, ADAU1373_CLK_SRC_DIV(pll_id), 0x3f, 0x09); | ||
| 1206 | |||
| 1207 | return 0; | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | static void adau1373_load_drc_settings(struct snd_soc_codec *codec, | ||
| 1211 | unsigned int nr, uint8_t *drc) | ||
| 1212 | { | ||
| 1213 | unsigned int i; | ||
| 1214 | |||
| 1215 | for (i = 0; i < ADAU1373_DRC_SIZE; ++i) | ||
| 1216 | snd_soc_write(codec, ADAU1373_DRC(nr) + i, drc[i]); | ||
| 1217 | } | ||
| 1218 | |||
| 1219 | static bool adau1373_valid_micbias(enum adau1373_micbias_voltage micbias) | ||
| 1220 | { | ||
| 1221 | switch (micbias) { | ||
| 1222 | case ADAU1373_MICBIAS_2_9V: | ||
| 1223 | case ADAU1373_MICBIAS_2_2V: | ||
| 1224 | case ADAU1373_MICBIAS_2_6V: | ||
| 1225 | case ADAU1373_MICBIAS_1_8V: | ||
| 1226 | return true; | ||
| 1227 | default: | ||
| 1228 | break; | ||
| 1229 | } | ||
| 1230 | return false; | ||
| 1231 | } | ||
| 1232 | |||
| 1233 | static int adau1373_probe(struct snd_soc_codec *codec) | ||
| 1234 | { | ||
| 1235 | struct adau1373_platform_data *pdata = codec->dev->platform_data; | ||
| 1236 | bool lineout_differential = false; | ||
| 1237 | unsigned int val; | ||
| 1238 | int ret; | ||
| 1239 | int i; | ||
| 1240 | |||
| 1241 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); | ||
| 1242 | if (ret) { | ||
| 1243 | dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); | ||
| 1244 | return ret; | ||
| 1245 | } | ||
| 1246 | |||
| 1247 | codec->dapm.idle_bias_off = true; | ||
| 1248 | |||
| 1249 | if (pdata) { | ||
| 1250 | if (pdata->num_drc > ARRAY_SIZE(pdata->drc_setting)) | ||
| 1251 | return -EINVAL; | ||
| 1252 | |||
| 1253 | if (!adau1373_valid_micbias(pdata->micbias1) || | ||
| 1254 | !adau1373_valid_micbias(pdata->micbias2)) | ||
| 1255 | return -EINVAL; | ||
| 1256 | |||
| 1257 | for (i = 0; i < pdata->num_drc; ++i) { | ||
| 1258 | adau1373_load_drc_settings(codec, i, | ||
| 1259 | pdata->drc_setting[i]); | ||
| 1260 | } | ||
| 1261 | |||
| 1262 | snd_soc_add_controls(codec, adau1373_drc_controls, | ||
| 1263 | pdata->num_drc); | ||
| 1264 | |||
| 1265 | val = 0; | ||
| 1266 | for (i = 0; i < 4; ++i) { | ||
| 1267 | if (pdata->input_differential[i]) | ||
| 1268 | val |= BIT(i); | ||
| 1269 | } | ||
| 1270 | snd_soc_write(codec, ADAU1373_INPUT_MODE, val); | ||
| 1271 | |||
| 1272 | val = 0; | ||
| 1273 | if (pdata->lineout_differential) | ||
| 1274 | val |= ADAU1373_OUTPUT_CTRL_LDIFF; | ||
| 1275 | if (pdata->lineout_ground_sense) | ||
| 1276 | val |= ADAU1373_OUTPUT_CTRL_LNFBEN; | ||
| 1277 | snd_soc_write(codec, ADAU1373_OUTPUT_CTRL, val); | ||
| 1278 | |||
| 1279 | lineout_differential = pdata->lineout_differential; | ||
| 1280 | |||
| 1281 | snd_soc_write(codec, ADAU1373_EP_CTRL, | ||
| 1282 | (pdata->micbias1 << ADAU1373_EP_CTRL_MICBIAS1_OFFSET) | | ||
| 1283 | (pdata->micbias2 << ADAU1373_EP_CTRL_MICBIAS2_OFFSET)); | ||
| 1284 | } | ||
| 1285 | |||
| 1286 | if (!lineout_differential) { | ||
| 1287 | snd_soc_add_controls(codec, adau1373_lineout2_controls, | ||
| 1288 | ARRAY_SIZE(adau1373_lineout2_controls)); | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | snd_soc_write(codec, ADAU1373_ADC_CTRL, | ||
| 1292 | ADAU1373_ADC_CTRL_RESET_FORCE | ADAU1373_ADC_CTRL_PEAK_DETECT); | ||
| 1293 | |||
| 1294 | return 0; | ||
| 1295 | } | ||
| 1296 | |||
| 1297 | static int adau1373_set_bias_level(struct snd_soc_codec *codec, | ||
| 1298 | enum snd_soc_bias_level level) | ||
| 1299 | { | ||
| 1300 | switch (level) { | ||
| 1301 | case SND_SOC_BIAS_ON: | ||
| 1302 | break; | ||
| 1303 | case SND_SOC_BIAS_PREPARE: | ||
| 1304 | break; | ||
| 1305 | case SND_SOC_BIAS_STANDBY: | ||
| 1306 | snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3, | ||
| 1307 | ADAU1373_PWDN_CTRL3_PWR_EN, ADAU1373_PWDN_CTRL3_PWR_EN); | ||
| 1308 | break; | ||
| 1309 | case SND_SOC_BIAS_OFF: | ||
| 1310 | snd_soc_update_bits(codec, ADAU1373_PWDN_CTRL3, | ||
| 1311 | ADAU1373_PWDN_CTRL3_PWR_EN, 0); | ||
| 1312 | break; | ||
| 1313 | } | ||
| 1314 | codec->dapm.bias_level = level; | ||
| 1315 | return 0; | ||
| 1316 | } | ||
| 1317 | |||
| 1318 | static int adau1373_remove(struct snd_soc_codec *codec) | ||
| 1319 | { | ||
| 1320 | adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 1321 | return 0; | ||
| 1322 | } | ||
| 1323 | |||
| 1324 | static int adau1373_suspend(struct snd_soc_codec *codec, pm_message_t state) | ||
| 1325 | { | ||
| 1326 | return adau1373_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 1327 | } | ||
| 1328 | |||
| 1329 | static int adau1373_resume(struct snd_soc_codec *codec) | ||
| 1330 | { | ||
| 1331 | adau1373_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
| 1332 | snd_soc_cache_sync(codec); | ||
| 1333 | |||
| 1334 | return 0; | ||
| 1335 | } | ||
| 1336 | |||
| 1337 | static struct snd_soc_codec_driver adau1373_codec_driver = { | ||
| 1338 | .probe = adau1373_probe, | ||
| 1339 | .remove = adau1373_remove, | ||
| 1340 | .suspend = adau1373_suspend, | ||
| 1341 | .resume = adau1373_resume, | ||
| 1342 | .set_bias_level = adau1373_set_bias_level, | ||
| 1343 | .reg_cache_size = ARRAY_SIZE(adau1373_default_regs), | ||
| 1344 | .reg_cache_default = adau1373_default_regs, | ||
| 1345 | .reg_word_size = sizeof(uint8_t), | ||
| 1346 | |||
| 1347 | .set_pll = adau1373_set_pll, | ||
| 1348 | |||
| 1349 | .controls = adau1373_controls, | ||
| 1350 | .num_controls = ARRAY_SIZE(adau1373_controls), | ||
| 1351 | .dapm_widgets = adau1373_dapm_widgets, | ||
| 1352 | .num_dapm_widgets = ARRAY_SIZE(adau1373_dapm_widgets), | ||
| 1353 | .dapm_routes = adau1373_dapm_routes, | ||
| 1354 | .num_dapm_routes = ARRAY_SIZE(adau1373_dapm_routes), | ||
| 1355 | }; | ||
| 1356 | |||
| 1357 | static int __devinit adau1373_i2c_probe(struct i2c_client *client, | ||
| 1358 | const struct i2c_device_id *id) | ||
| 1359 | { | ||
| 1360 | struct adau1373 *adau1373; | ||
| 1361 | int ret; | ||
| 1362 | |||
| 1363 | adau1373 = kzalloc(sizeof(*adau1373), GFP_KERNEL); | ||
| 1364 | if (!adau1373) | ||
| 1365 | return -ENOMEM; | ||
| 1366 | |||
| 1367 | dev_set_drvdata(&client->dev, adau1373); | ||
| 1368 | |||
| 1369 | ret = snd_soc_register_codec(&client->dev, &adau1373_codec_driver, | ||
| 1370 | adau1373_dai_driver, ARRAY_SIZE(adau1373_dai_driver)); | ||
| 1371 | if (ret < 0) | ||
| 1372 | kfree(adau1373); | ||
| 1373 | |||
| 1374 | return ret; | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | static int __devexit adau1373_i2c_remove(struct i2c_client *client) | ||
| 1378 | { | ||
| 1379 | snd_soc_unregister_codec(&client->dev); | ||
| 1380 | kfree(dev_get_drvdata(&client->dev)); | ||
| 1381 | return 0; | ||
| 1382 | } | ||
| 1383 | |||
| 1384 | static const struct i2c_device_id adau1373_i2c_id[] = { | ||
| 1385 | { "adau1373", 0 }, | ||
| 1386 | { } | ||
| 1387 | }; | ||
| 1388 | MODULE_DEVICE_TABLE(i2c, adau1373_i2c_id); | ||
| 1389 | |||
| 1390 | static struct i2c_driver adau1373_i2c_driver = { | ||
| 1391 | .driver = { | ||
| 1392 | .name = "adau1373", | ||
| 1393 | .owner = THIS_MODULE, | ||
| 1394 | }, | ||
| 1395 | .probe = adau1373_i2c_probe, | ||
| 1396 | .remove = __devexit_p(adau1373_i2c_remove), | ||
| 1397 | .id_table = adau1373_i2c_id, | ||
| 1398 | }; | ||
| 1399 | |||
| 1400 | static int __init adau1373_init(void) | ||
| 1401 | { | ||
| 1402 | return i2c_add_driver(&adau1373_i2c_driver); | ||
| 1403 | } | ||
| 1404 | module_init(adau1373_init); | ||
| 1405 | |||
| 1406 | static void __exit adau1373_exit(void) | ||
| 1407 | { | ||
| 1408 | i2c_del_driver(&adau1373_i2c_driver); | ||
| 1409 | } | ||
| 1410 | module_exit(adau1373_exit); | ||
| 1411 | |||
| 1412 | MODULE_DESCRIPTION("ASoC ADAU1373 driver"); | ||
| 1413 | MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>"); | ||
| 1414 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/adau1373.h b/sound/soc/codecs/adau1373.h new file mode 100644 index 000000000000..c6ab5530760c --- /dev/null +++ b/sound/soc/codecs/adau1373.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | #ifndef __ADAU1373_H__ | ||
| 2 | #define __ADAU1373_H__ | ||
| 3 | |||
| 4 | enum adau1373_pll_src { | ||
| 5 | ADAU1373_PLL_SRC_MCLK1 = 0, | ||
| 6 | ADAU1373_PLL_SRC_BCLK1 = 1, | ||
| 7 | ADAU1373_PLL_SRC_BCLK2 = 2, | ||
| 8 | ADAU1373_PLL_SRC_BCLK3 = 3, | ||
| 9 | ADAU1373_PLL_SRC_LRCLK1 = 4, | ||
| 10 | ADAU1373_PLL_SRC_LRCLK2 = 5, | ||
| 11 | ADAU1373_PLL_SRC_LRCLK3 = 6, | ||
| 12 | ADAU1373_PLL_SRC_GPIO1 = 7, | ||
| 13 | ADAU1373_PLL_SRC_GPIO2 = 8, | ||
| 14 | ADAU1373_PLL_SRC_GPIO3 = 9, | ||
| 15 | ADAU1373_PLL_SRC_GPIO4 = 10, | ||
| 16 | ADAU1373_PLL_SRC_MCLK2 = 11, | ||
| 17 | }; | ||
| 18 | |||
| 19 | enum adau1373_pll { | ||
| 20 | ADAU1373_PLL1 = 0, | ||
| 21 | ADAU1373_PLL2 = 1, | ||
| 22 | }; | ||
| 23 | |||
| 24 | enum adau1373_clk_src { | ||
| 25 | ADAU1373_CLK_SRC_PLL1 = 0, | ||
| 26 | ADAU1373_CLK_SRC_PLL2 = 1, | ||
| 27 | }; | ||
| 28 | |||
| 29 | #endif | ||
diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index 2758d5fc60d6..8b7e1c50d6e9 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c | |||
| @@ -401,7 +401,7 @@ static int adau1701_digital_mute(struct snd_soc_dai *dai, int mute) | |||
| 401 | } | 401 | } |
| 402 | 402 | ||
| 403 | static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 403 | static int adau1701_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
| 404 | unsigned int freq, int dir) | 404 | int source, unsigned int freq, int dir) |
| 405 | { | 405 | { |
| 406 | unsigned int val; | 406 | unsigned int val; |
| 407 | 407 | ||
| @@ -458,6 +458,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) | |||
| 458 | int ret; | 458 | int ret; |
| 459 | 459 | ||
| 460 | codec->dapm.idle_bias_off = 1; | 460 | codec->dapm.idle_bias_off = 1; |
| 461 | codec->control_data = to_i2c_client(codec->dev); | ||
| 461 | 462 | ||
| 462 | ret = adau1701_load_firmware(codec); | 463 | ret = adau1701_load_firmware(codec); |
| 463 | if (ret) | 464 | if (ret) |
diff --git a/sound/soc/codecs/adav80x.c b/sound/soc/codecs/adav80x.c index 300c04b70e71..f9f08948e5e8 100644 --- a/sound/soc/codecs/adav80x.c +++ b/sound/soc/codecs/adav80x.c | |||
| @@ -523,7 +523,8 @@ static int adav80x_hw_params(struct snd_pcm_substream *substream, | |||
| 523 | } | 523 | } |
| 524 | 524 | ||
| 525 | static int adav80x_set_sysclk(struct snd_soc_codec *codec, | 525 | static int adav80x_set_sysclk(struct snd_soc_codec *codec, |
| 526 | int clk_id, unsigned int freq, int dir) | 526 | int clk_id, int source, |
| 527 | unsigned int freq, int dir) | ||
| 527 | { | 528 | { |
| 528 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); | 529 | struct adav80x *adav80x = snd_soc_codec_get_drvdata(codec); |
| 529 | 530 | ||
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h deleted file mode 100644 index 3ce028614002..000000000000 --- a/sound/soc/codecs/ads117x.h +++ /dev/null | |||
| @@ -1,13 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * ads117x.h -- Driver for ads1174/8 ADC chips | ||
| 3 | * | ||
| 4 | * Copyright 2009 ShotSpotter Inc. | ||
| 5 | * Author: Graeme Gregory <gg@slimlogic.co.uk> | ||
| 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 | extern struct snd_soc_dai_driver ads117x_dai; | ||
| 13 | extern struct snd_soc_codec_driver soc_codec_dev_ads117x; | ||
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c index cbf0b6d400b8..d3b29dce6ed7 100644 --- a/sound/soc/codecs/ak4104.c +++ b/sound/soc/codecs/ak4104.c | |||
| @@ -247,7 +247,7 @@ static struct snd_soc_codec_driver soc_codec_device_ak4104 = { | |||
| 247 | .probe = ak4104_probe, | 247 | .probe = ak4104_probe, |
| 248 | .remove = ak4104_remove, | 248 | .remove = ak4104_remove, |
| 249 | .reg_cache_size = AK4104_NUM_REGS, | 249 | .reg_cache_size = AK4104_NUM_REGS, |
| 250 | .reg_word_size = sizeof(u16), | 250 | .reg_word_size = sizeof(u8), |
| 251 | }; | 251 | }; |
| 252 | 252 | ||
| 253 | static int ak4104_spi_probe(struct spi_device *spi) | 253 | static int ak4104_spi_probe(struct spi_device *spi) |
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index e1a214ee757f..95d782d86e7d 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c | |||
| @@ -34,74 +34,16 @@ | |||
| 34 | struct ak4535_priv { | 34 | struct ak4535_priv { |
| 35 | unsigned int sysclk; | 35 | unsigned int sysclk; |
| 36 | enum snd_soc_control_type control_type; | 36 | enum snd_soc_control_type control_type; |
| 37 | void *control_data; | ||
| 38 | }; | 37 | }; |
| 39 | 38 | ||
| 40 | /* | 39 | /* |
| 41 | * ak4535 register cache | 40 | * ak4535 register cache |
| 42 | */ | 41 | */ |
| 43 | static const u16 ak4535_reg[AK4535_CACHEREGNUM] = { | 42 | static const u8 ak4535_reg[AK4535_CACHEREGNUM] = { |
| 44 | 0x0000, 0x0080, 0x0000, 0x0003, | 43 | 0x00, 0x80, 0x00, 0x03, |
| 45 | 0x0002, 0x0000, 0x0011, 0x0001, | 44 | 0x02, 0x00, 0x11, 0x01, |
| 46 | 0x0000, 0x0040, 0x0036, 0x0010, | 45 | 0x00, 0x40, 0x36, 0x10, |
| 47 | 0x0000, 0x0000, 0x0057, 0x0000, | 46 | 0x00, 0x00, 0x57, 0x00, |
| 48 | }; | ||
| 49 | |||
| 50 | /* | ||
| 51 | * read ak4535 register cache | ||
| 52 | */ | ||
| 53 | static inline unsigned int ak4535_read_reg_cache(struct snd_soc_codec *codec, | ||
| 54 | unsigned int reg) | ||
| 55 | { | ||
| 56 | u16 *cache = codec->reg_cache; | ||
| 57 | if (reg >= AK4535_CACHEREGNUM) | ||
| 58 | return -1; | ||
| 59 | return cache[reg]; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * write ak4535 register cache | ||
| 64 | */ | ||
| 65 | static inline void ak4535_write_reg_cache(struct snd_soc_codec *codec, | ||
| 66 | u16 reg, unsigned int value) | ||
| 67 | { | ||
| 68 | u16 *cache = codec->reg_cache; | ||
| 69 | if (reg >= AK4535_CACHEREGNUM) | ||
| 70 | return; | ||
| 71 | cache[reg] = value; | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * write to the AK4535 register space | ||
| 76 | */ | ||
| 77 | static int ak4535_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 78 | unsigned int value) | ||
| 79 | { | ||
| 80 | u8 data[2]; | ||
| 81 | |||
| 82 | /* data is | ||
| 83 | * D15..D8 AK4535 register offset | ||
| 84 | * D7...D0 register data | ||
| 85 | */ | ||
| 86 | data[0] = reg & 0xff; | ||
| 87 | data[1] = value & 0xff; | ||
| 88 | |||
| 89 | ak4535_write_reg_cache(codec, reg, value); | ||
| 90 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
| 91 | return 0; | ||
| 92 | else | ||
| 93 | return -EIO; | ||
| 94 | } | ||
| 95 | |||
| 96 | static int ak4535_sync(struct snd_soc_codec *codec) | ||
| 97 | { | ||
| 98 | u16 *cache = codec->reg_cache; | ||
| 99 | int i, r = 0; | ||
| 100 | |||
| 101 | for (i = 0; i < AK4535_CACHEREGNUM; i++) | ||
| 102 | r |= ak4535_write(codec, i, cache[i]); | ||
| 103 | |||
| 104 | return r; | ||
| 105 | }; | 47 | }; |
| 106 | 48 | ||
| 107 | static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; | 49 | static const char *ak4535_mono_gain[] = {"+6dB", "-17dB"}; |
| @@ -304,7 +246,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, | |||
| 304 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 246 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 305 | struct snd_soc_codec *codec = rtd->codec; | 247 | struct snd_soc_codec *codec = rtd->codec; |
| 306 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); | 248 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); |
| 307 | u8 mode2 = ak4535_read_reg_cache(codec, AK4535_MODE2) & ~(0x3 << 5); | 249 | u8 mode2 = snd_soc_read(codec, AK4535_MODE2) & ~(0x3 << 5); |
| 308 | int rate = params_rate(params), fs = 256; | 250 | int rate = params_rate(params), fs = 256; |
| 309 | 251 | ||
| 310 | if (rate) | 252 | if (rate) |
| @@ -323,7 +265,7 @@ static int ak4535_hw_params(struct snd_pcm_substream *substream, | |||
| 323 | } | 265 | } |
| 324 | 266 | ||
| 325 | /* set rate */ | 267 | /* set rate */ |
| 326 | ak4535_write(codec, AK4535_MODE2, mode2); | 268 | snd_soc_write(codec, AK4535_MODE2, mode2); |
| 327 | return 0; | 269 | return 0; |
| 328 | } | 270 | } |
| 329 | 271 | ||
| @@ -348,44 +290,37 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 348 | /* use 32 fs for BCLK to save power */ | 290 | /* use 32 fs for BCLK to save power */ |
| 349 | mode1 |= 0x4; | 291 | mode1 |= 0x4; |
| 350 | 292 | ||
| 351 | ak4535_write(codec, AK4535_MODE1, mode1); | 293 | snd_soc_write(codec, AK4535_MODE1, mode1); |
| 352 | return 0; | 294 | return 0; |
| 353 | } | 295 | } |
| 354 | 296 | ||
| 355 | static int ak4535_mute(struct snd_soc_dai *dai, int mute) | 297 | static int ak4535_mute(struct snd_soc_dai *dai, int mute) |
| 356 | { | 298 | { |
| 357 | struct snd_soc_codec *codec = dai->codec; | 299 | struct snd_soc_codec *codec = dai->codec; |
| 358 | u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); | 300 | u16 mute_reg = snd_soc_read(codec, AK4535_DAC); |
| 359 | if (!mute) | 301 | if (!mute) |
| 360 | ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); | 302 | snd_soc_write(codec, AK4535_DAC, mute_reg & ~0x20); |
| 361 | else | 303 | else |
| 362 | ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); | 304 | snd_soc_write(codec, AK4535_DAC, mute_reg | 0x20); |
| 363 | return 0; | 305 | return 0; |
| 364 | } | 306 | } |
| 365 | 307 | ||
| 366 | static int ak4535_set_bias_level(struct snd_soc_codec *codec, | 308 | static int ak4535_set_bias_level(struct snd_soc_codec *codec, |
| 367 | enum snd_soc_bias_level level) | 309 | enum snd_soc_bias_level level) |
| 368 | { | 310 | { |
| 369 | u16 i, mute_reg; | ||
| 370 | |||
| 371 | switch (level) { | 311 | switch (level) { |
| 372 | case SND_SOC_BIAS_ON: | 312 | case SND_SOC_BIAS_ON: |
| 373 | mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); | 313 | snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0); |
| 374 | ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); | ||
| 375 | break; | 314 | break; |
| 376 | case SND_SOC_BIAS_PREPARE: | 315 | case SND_SOC_BIAS_PREPARE: |
| 377 | mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); | 316 | snd_soc_update_bits(codec, AK4535_DAC, 0x20, 0x20); |
| 378 | ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); | ||
| 379 | break; | 317 | break; |
| 380 | case SND_SOC_BIAS_STANDBY: | 318 | case SND_SOC_BIAS_STANDBY: |
| 381 | i = ak4535_read_reg_cache(codec, AK4535_PM1); | 319 | snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0x80); |
| 382 | ak4535_write(codec, AK4535_PM1, i | 0x80); | 320 | snd_soc_update_bits(codec, AK4535_PM2, 0x80, 0); |
| 383 | i = ak4535_read_reg_cache(codec, AK4535_PM2); | ||
| 384 | ak4535_write(codec, AK4535_PM2, i & (~0x80)); | ||
| 385 | break; | 321 | break; |
| 386 | case SND_SOC_BIAS_OFF: | 322 | case SND_SOC_BIAS_OFF: |
| 387 | i = ak4535_read_reg_cache(codec, AK4535_PM1); | 323 | snd_soc_update_bits(codec, AK4535_PM1, 0x80, 0); |
| 388 | ak4535_write(codec, AK4535_PM1, i & (~0x80)); | ||
| 389 | break; | 324 | break; |
| 390 | } | 325 | } |
| 391 | codec->dapm.bias_level = level; | 326 | codec->dapm.bias_level = level; |
| @@ -428,7 +363,7 @@ static int ak4535_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 428 | 363 | ||
| 429 | static int ak4535_resume(struct snd_soc_codec *codec) | 364 | static int ak4535_resume(struct snd_soc_codec *codec) |
| 430 | { | 365 | { |
| 431 | ak4535_sync(codec); | 366 | snd_soc_cache_sync(codec); |
| 432 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 367 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 433 | return 0; | 368 | return 0; |
| 434 | } | 369 | } |
| @@ -436,11 +371,15 @@ static int ak4535_resume(struct snd_soc_codec *codec) | |||
| 436 | static int ak4535_probe(struct snd_soc_codec *codec) | 371 | static int ak4535_probe(struct snd_soc_codec *codec) |
| 437 | { | 372 | { |
| 438 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); | 373 | struct ak4535_priv *ak4535 = snd_soc_codec_get_drvdata(codec); |
| 374 | int ret; | ||
| 439 | 375 | ||
| 440 | printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); | 376 | printk(KERN_INFO "AK4535 Audio Codec %s", AK4535_VERSION); |
| 441 | 377 | ||
| 442 | codec->control_data = ak4535->control_data; | 378 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4535->control_type); |
| 443 | 379 | if (ret < 0) { | |
| 380 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
| 381 | return ret; | ||
| 382 | } | ||
| 444 | /* power on device */ | 383 | /* power on device */ |
| 445 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 384 | ak4535_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 446 | 385 | ||
| @@ -461,8 +400,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ak4535 = { | |||
| 461 | .remove = ak4535_remove, | 400 | .remove = ak4535_remove, |
| 462 | .suspend = ak4535_suspend, | 401 | .suspend = ak4535_suspend, |
| 463 | .resume = ak4535_resume, | 402 | .resume = ak4535_resume, |
| 464 | .read = ak4535_read_reg_cache, | ||
| 465 | .write = ak4535_write, | ||
| 466 | .set_bias_level = ak4535_set_bias_level, | 403 | .set_bias_level = ak4535_set_bias_level, |
| 467 | .reg_cache_size = ARRAY_SIZE(ak4535_reg), | 404 | .reg_cache_size = ARRAY_SIZE(ak4535_reg), |
| 468 | .reg_word_size = sizeof(u8), | 405 | .reg_word_size = sizeof(u8), |
| @@ -485,7 +422,6 @@ static __devinit int ak4535_i2c_probe(struct i2c_client *i2c, | |||
| 485 | return -ENOMEM; | 422 | return -ENOMEM; |
| 486 | 423 | ||
| 487 | i2c_set_clientdata(i2c, ak4535); | 424 | i2c_set_clientdata(i2c, ak4535); |
| 488 | ak4535->control_data = i2c; | ||
| 489 | ak4535->control_type = SND_SOC_I2C; | 425 | ak4535->control_type = SND_SOC_I2C; |
| 490 | 426 | ||
| 491 | ret = snd_soc_register_codec(&i2c->dev, | 427 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/ak4641.c b/sound/soc/codecs/ak4641.c index 7a64e58cddc4..77838586f358 100644 --- a/sound/soc/codecs/ak4641.c +++ b/sound/soc/codecs/ak4641.c | |||
| @@ -31,7 +31,6 @@ | |||
| 31 | 31 | ||
| 32 | /* codec private data */ | 32 | /* codec private data */ |
| 33 | struct ak4641_priv { | 33 | struct ak4641_priv { |
| 34 | struct snd_soc_codec *codec; | ||
| 35 | unsigned int sysclk; | 34 | unsigned int sysclk; |
| 36 | int deemph; | 35 | int deemph; |
| 37 | int playback_fs; | 36 | int playback_fs; |
| @@ -226,7 +225,7 @@ static const struct snd_soc_dapm_widget ak4641_dapm_widgets[] = { | |||
| 226 | SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0), | 225 | SND_SOC_DAPM_PGA("Mono Out 2", AK4641_PM2, 3, 0, NULL, 0), |
| 227 | 226 | ||
| 228 | SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0), | 227 | SND_SOC_DAPM_ADC("Voice ADC", "Voice Capture", AK4641_BTIF, 0, 0), |
| 229 | SND_SOC_DAPM_ADC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0), | 228 | SND_SOC_DAPM_DAC("Voice DAC", "Voice Playback", AK4641_BTIF, 1, 0), |
| 230 | 229 | ||
| 231 | SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0), | 230 | SND_SOC_DAPM_MICBIAS("Mic Int Bias", AK4641_MIC, 3, 0), |
| 232 | SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0), | 231 | SND_SOC_DAPM_MICBIAS("Mic Ext Bias", AK4641_MIC, 4, 0), |
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 65f46047b1cb..d8fc04486abb 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
| @@ -156,81 +156,22 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = { | |||
| 156 | struct ak4642_priv { | 156 | struct ak4642_priv { |
| 157 | unsigned int sysclk; | 157 | unsigned int sysclk; |
| 158 | enum snd_soc_control_type control_type; | 158 | enum snd_soc_control_type control_type; |
| 159 | void *control_data; | ||
| 160 | }; | 159 | }; |
| 161 | 160 | ||
| 162 | /* | 161 | /* |
| 163 | * ak4642 register cache | 162 | * ak4642 register cache |
| 164 | */ | 163 | */ |
| 165 | static const u16 ak4642_reg[AK4642_CACHEREGNUM] = { | 164 | static const u8 ak4642_reg[AK4642_CACHEREGNUM] = { |
| 166 | 0x0000, 0x0000, 0x0001, 0x0000, | 165 | 0x00, 0x00, 0x01, 0x00, |
| 167 | 0x0002, 0x0000, 0x0000, 0x0000, | 166 | 0x02, 0x00, 0x00, 0x00, |
| 168 | 0x00e1, 0x00e1, 0x0018, 0x0000, | 167 | 0xe1, 0xe1, 0x18, 0x00, |
| 169 | 0x00e1, 0x0018, 0x0011, 0x0008, | 168 | 0xe1, 0x18, 0x11, 0x08, |
| 170 | 0x0000, 0x0000, 0x0000, 0x0000, | 169 | 0x00, 0x00, 0x00, 0x00, |
| 171 | 0x0000, 0x0000, 0x0000, 0x0000, | 170 | 0x00, 0x00, 0x00, 0x00, |
| 172 | 0x0000, 0x0000, 0x0000, 0x0000, | 171 | 0x00, 0x00, 0x00, 0x00, |
| 173 | 0x0000, 0x0000, 0x0000, 0x0000, | 172 | 0x00, 0x00, 0x00, 0x00, |
| 174 | 0x0000, 0x0000, 0x0000, 0x0000, | 173 | 0x00, 0x00, 0x00, 0x00, |
| 175 | 0x0000, | 174 | 0x00, |
| 176 | }; | ||
| 177 | |||
| 178 | /* | ||
| 179 | * read ak4642 register cache | ||
| 180 | */ | ||
| 181 | static inline unsigned int ak4642_read_reg_cache(struct snd_soc_codec *codec, | ||
| 182 | unsigned int reg) | ||
| 183 | { | ||
| 184 | u16 *cache = codec->reg_cache; | ||
| 185 | if (reg >= AK4642_CACHEREGNUM) | ||
| 186 | return -1; | ||
| 187 | return cache[reg]; | ||
| 188 | } | ||
| 189 | |||
| 190 | /* | ||
| 191 | * write ak4642 register cache | ||
| 192 | */ | ||
| 193 | static inline void ak4642_write_reg_cache(struct snd_soc_codec *codec, | ||
| 194 | u16 reg, unsigned int value) | ||
| 195 | { | ||
| 196 | u16 *cache = codec->reg_cache; | ||
| 197 | if (reg >= AK4642_CACHEREGNUM) | ||
| 198 | return; | ||
| 199 | |||
| 200 | cache[reg] = value; | ||
| 201 | } | ||
| 202 | |||
| 203 | /* | ||
| 204 | * write to the AK4642 register space | ||
| 205 | */ | ||
| 206 | static int ak4642_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 207 | unsigned int value) | ||
| 208 | { | ||
| 209 | u8 data[2]; | ||
| 210 | |||
| 211 | /* data is | ||
| 212 | * D15..D8 AK4642 register offset | ||
| 213 | * D7...D0 register data | ||
| 214 | */ | ||
| 215 | data[0] = reg & 0xff; | ||
| 216 | data[1] = value & 0xff; | ||
| 217 | |||
| 218 | if (codec->hw_write(codec->control_data, data, 2) == 2) { | ||
| 219 | ak4642_write_reg_cache(codec, reg, value); | ||
| 220 | return 0; | ||
| 221 | } else | ||
| 222 | return -EIO; | ||
| 223 | } | ||
| 224 | |||
| 225 | static int ak4642_sync(struct snd_soc_codec *codec) | ||
| 226 | { | ||
| 227 | u16 *cache = codec->reg_cache; | ||
| 228 | int i, r = 0; | ||
| 229 | |||
| 230 | for (i = 0; i < AK4642_CACHEREGNUM; i++) | ||
| 231 | r |= ak4642_write(codec, i, cache[i]); | ||
| 232 | |||
| 233 | return r; | ||
| 234 | }; | 175 | }; |
| 235 | 176 | ||
| 236 | static int ak4642_dai_startup(struct snd_pcm_substream *substream, | 177 | static int ak4642_dai_startup(struct snd_pcm_substream *substream, |
| @@ -252,8 +193,8 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
| 252 | */ | 193 | */ |
| 253 | snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); | 194 | snd_soc_update_bits(codec, MD_CTL4, DACH, DACH); |
| 254 | snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); | 195 | snd_soc_update_bits(codec, MD_CTL3, BST1, BST1); |
| 255 | ak4642_write(codec, L_IVC, 0x91); /* volume */ | 196 | snd_soc_write(codec, L_IVC, 0x91); /* volume */ |
| 256 | ak4642_write(codec, R_IVC, 0x91); /* volume */ | 197 | snd_soc_write(codec, R_IVC, 0x91); /* volume */ |
| 257 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, | 198 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMMIN | PMDAC, |
| 258 | PMVCM | PMMIN | PMDAC); | 199 | PMVCM | PMMIN | PMDAC); |
| 259 | snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); | 200 | snd_soc_update_bits(codec, PW_MGMT2, PMHP_MASK, PMHP); |
| @@ -272,9 +213,9 @@ static int ak4642_dai_startup(struct snd_pcm_substream *substream, | |||
| 272 | * This operation came from example code of | 213 | * This operation came from example code of |
| 273 | * "ASAHI KASEI AK4642" (japanese) manual p94. | 214 | * "ASAHI KASEI AK4642" (japanese) manual p94. |
| 274 | */ | 215 | */ |
| 275 | ak4642_write(codec, SG_SL1, PMMP | MGAIN0); | 216 | snd_soc_write(codec, SG_SL1, PMMP | MGAIN0); |
| 276 | ak4642_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); | 217 | snd_soc_write(codec, TIMER, ZTM(0x3) | WTM(0x3)); |
| 277 | ak4642_write(codec, ALC_CTL1, ALC | LMTH0); | 218 | snd_soc_write(codec, ALC_CTL1, ALC | LMTH0); |
| 278 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, | 219 | snd_soc_update_bits(codec, PW_MGMT1, PMVCM | PMADL, |
| 279 | PMVCM | PMADL); | 220 | PMVCM | PMADL); |
| 280 | snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); | 221 | snd_soc_update_bits(codec, PW_MGMT3, PMADR, PMADR); |
| @@ -462,7 +403,7 @@ static struct snd_soc_dai_driver ak4642_dai = { | |||
| 462 | 403 | ||
| 463 | static int ak4642_resume(struct snd_soc_codec *codec) | 404 | static int ak4642_resume(struct snd_soc_codec *codec) |
| 464 | { | 405 | { |
| 465 | ak4642_sync(codec); | 406 | snd_soc_cache_sync(codec); |
| 466 | return 0; | 407 | return 0; |
| 467 | } | 408 | } |
| 468 | 409 | ||
| @@ -470,11 +411,15 @@ static int ak4642_resume(struct snd_soc_codec *codec) | |||
| 470 | static int ak4642_probe(struct snd_soc_codec *codec) | 411 | static int ak4642_probe(struct snd_soc_codec *codec) |
| 471 | { | 412 | { |
| 472 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); | 413 | struct ak4642_priv *ak4642 = snd_soc_codec_get_drvdata(codec); |
| 414 | int ret; | ||
| 473 | 415 | ||
| 474 | dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); | 416 | dev_info(codec->dev, "AK4642 Audio Codec %s", AK4642_VERSION); |
| 475 | 417 | ||
| 476 | codec->hw_write = (hw_write_t)i2c_master_send; | 418 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4642->control_type); |
| 477 | codec->control_data = ak4642->control_data; | 419 | if (ret < 0) { |
| 420 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
| 421 | return ret; | ||
| 422 | } | ||
| 478 | 423 | ||
| 479 | snd_soc_add_controls(codec, ak4642_snd_controls, | 424 | snd_soc_add_controls(codec, ak4642_snd_controls, |
| 480 | ARRAY_SIZE(ak4642_snd_controls)); | 425 | ARRAY_SIZE(ak4642_snd_controls)); |
| @@ -485,8 +430,6 @@ static int ak4642_probe(struct snd_soc_codec *codec) | |||
| 485 | static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { | 430 | static struct snd_soc_codec_driver soc_codec_dev_ak4642 = { |
| 486 | .probe = ak4642_probe, | 431 | .probe = ak4642_probe, |
| 487 | .resume = ak4642_resume, | 432 | .resume = ak4642_resume, |
| 488 | .read = ak4642_read_reg_cache, | ||
| 489 | .write = ak4642_write, | ||
| 490 | .reg_cache_size = ARRAY_SIZE(ak4642_reg), | 433 | .reg_cache_size = ARRAY_SIZE(ak4642_reg), |
| 491 | .reg_word_size = sizeof(u8), | 434 | .reg_word_size = sizeof(u8), |
| 492 | .reg_cache_default = ak4642_reg, | 435 | .reg_cache_default = ak4642_reg, |
| @@ -504,7 +447,6 @@ static __devinit int ak4642_i2c_probe(struct i2c_client *i2c, | |||
| 504 | return -ENOMEM; | 447 | return -ENOMEM; |
| 505 | 448 | ||
| 506 | i2c_set_clientdata(i2c, ak4642); | 449 | i2c_set_clientdata(i2c, ak4642); |
| 507 | ak4642->control_data = i2c; | ||
| 508 | ak4642->control_type = SND_SOC_I2C; | 450 | ak4642->control_type = SND_SOC_I2C; |
| 509 | 451 | ||
| 510 | ret = snd_soc_register_codec(&i2c->dev, | 452 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 88b29f8c748b..de9ff66d3721 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | /* codec private data */ | 26 | /* codec private data */ |
| 27 | struct ak4671_priv { | 27 | struct ak4671_priv { |
| 28 | enum snd_soc_control_type control_type; | 28 | enum snd_soc_control_type control_type; |
| 29 | void *control_data; | ||
| 30 | }; | 29 | }; |
| 31 | 30 | ||
| 32 | /* ak4671 register cache & default register settings */ | 31 | /* ak4671 register cache & default register settings */ |
| @@ -169,18 +168,15 @@ static int ak4671_out2_event(struct snd_soc_dapm_widget *w, | |||
| 169 | struct snd_kcontrol *kcontrol, int event) | 168 | struct snd_kcontrol *kcontrol, int event) |
| 170 | { | 169 | { |
| 171 | struct snd_soc_codec *codec = w->codec; | 170 | struct snd_soc_codec *codec = w->codec; |
| 172 | u8 reg; | ||
| 173 | 171 | ||
| 174 | switch (event) { | 172 | switch (event) { |
| 175 | case SND_SOC_DAPM_POST_PMU: | 173 | case SND_SOC_DAPM_POST_PMU: |
| 176 | reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT); | 174 | snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT, |
| 177 | reg |= AK4671_MUTEN; | 175 | AK4671_MUTEN, AK4671_MUTEN); |
| 178 | snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg); | ||
| 179 | break; | 176 | break; |
| 180 | case SND_SOC_DAPM_PRE_PMD: | 177 | case SND_SOC_DAPM_PRE_PMD: |
| 181 | reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT); | 178 | snd_soc_update_bits(codec, AK4671_LOUT2_POWER_MANAGERMENT, |
| 182 | reg &= ~AK4671_MUTEN; | 179 | AK4671_MUTEN, 0); |
| 183 | snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg); | ||
| 184 | break; | 180 | break; |
| 185 | } | 181 | } |
| 186 | 182 | ||
| @@ -576,15 +572,12 @@ static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
| 576 | static int ak4671_set_bias_level(struct snd_soc_codec *codec, | 572 | static int ak4671_set_bias_level(struct snd_soc_codec *codec, |
| 577 | enum snd_soc_bias_level level) | 573 | enum snd_soc_bias_level level) |
| 578 | { | 574 | { |
| 579 | u8 reg; | ||
| 580 | |||
| 581 | switch (level) { | 575 | switch (level) { |
| 582 | case SND_SOC_BIAS_ON: | 576 | case SND_SOC_BIAS_ON: |
| 583 | case SND_SOC_BIAS_PREPARE: | 577 | case SND_SOC_BIAS_PREPARE: |
| 584 | case SND_SOC_BIAS_STANDBY: | 578 | case SND_SOC_BIAS_STANDBY: |
| 585 | reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT); | 579 | snd_soc_update_bits(codec, AK4671_AD_DA_POWER_MANAGEMENT, |
| 586 | snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, | 580 | AK4671_PMVCM, AK4671_PMVCM); |
| 587 | reg | AK4671_PMVCM); | ||
| 588 | break; | 581 | break; |
| 589 | case SND_SOC_BIAS_OFF: | 582 | case SND_SOC_BIAS_OFF: |
| 590 | snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); | 583 | snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); |
| @@ -629,8 +622,6 @@ static int ak4671_probe(struct snd_soc_codec *codec) | |||
| 629 | struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); | 622 | struct ak4671_priv *ak4671 = snd_soc_codec_get_drvdata(codec); |
| 630 | int ret; | 623 | int ret; |
| 631 | 624 | ||
| 632 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
| 633 | |||
| 634 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); | 625 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, ak4671->control_type); |
| 635 | if (ret < 0) { | 626 | if (ret < 0) { |
| 636 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 627 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| @@ -675,7 +666,6 @@ static int __devinit ak4671_i2c_probe(struct i2c_client *client, | |||
| 675 | return -ENOMEM; | 666 | return -ENOMEM; |
| 676 | 667 | ||
| 677 | i2c_set_clientdata(client, ak4671); | 668 | i2c_set_clientdata(client, ak4671); |
| 678 | ak4671->control_data = client; | ||
| 679 | ak4671->control_type = SND_SOC_I2C; | 669 | ak4671->control_type = SND_SOC_I2C; |
| 680 | 670 | ||
| 681 | ret = snd_soc_register_codec(&client->dev, | 671 | ret = snd_soc_register_codec(&client->dev, |
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index eecffb548947..984b14bcb605 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c | |||
| @@ -40,8 +40,6 @@ MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)"); | |||
| 40 | /* codec private data */ | 40 | /* codec private data */ |
| 41 | struct alc5623_priv { | 41 | struct alc5623_priv { |
| 42 | enum snd_soc_control_type control_type; | 42 | enum snd_soc_control_type control_type; |
| 43 | void *control_data; | ||
| 44 | struct mutex mutex; | ||
| 45 | u8 id; | 43 | u8 id; |
| 46 | unsigned int sysclk; | 44 | unsigned int sysclk; |
| 47 | u16 reg_cache[ALC5623_VENDOR_ID2+2]; | 45 | u16 reg_cache[ALC5623_VENDOR_ID2+2]; |
| @@ -55,8 +53,10 @@ static void alc5623_fill_cache(struct snd_soc_codec *codec) | |||
| 55 | u16 *cache = codec->reg_cache; | 53 | u16 *cache = codec->reg_cache; |
| 56 | 54 | ||
| 57 | /* not really efficient ... */ | 55 | /* not really efficient ... */ |
| 56 | codec->cache_bypass = 1; | ||
| 58 | for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) | 57 | for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) |
| 59 | cache[i] = codec->hw_read(codec, i); | 58 | cache[i] = snd_soc_read(codec, i); |
| 59 | codec->cache_bypass = 0; | ||
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | static inline int alc5623_reset(struct snd_soc_codec *codec) | 62 | static inline int alc5623_reset(struct snd_soc_codec *codec) |
| @@ -1050,9 +1050,7 @@ static int alc5623_i2c_probe(struct i2c_client *client, | |||
| 1050 | } | 1050 | } |
| 1051 | 1051 | ||
| 1052 | i2c_set_clientdata(client, alc5623); | 1052 | i2c_set_clientdata(client, alc5623); |
| 1053 | alc5623->control_data = client; | ||
| 1054 | alc5623->control_type = SND_SOC_I2C; | 1053 | alc5623->control_type = SND_SOC_I2C; |
| 1055 | mutex_init(&alc5623->mutex); | ||
| 1056 | 1054 | ||
| 1057 | ret = snd_soc_register_codec(&client->dev, | 1055 | ret = snd_soc_register_codec(&client->dev, |
| 1058 | &soc_codec_device_alc5623, &alc5623_dai, 1); | 1056 | &soc_codec_device_alc5623, &alc5623_dai, 1); |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 6cc8678f49f3..f1f237ecec2a 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
| @@ -128,7 +128,6 @@ static const char *supply_names[] = { | |||
| 128 | /* Private data for the CS4270 */ | 128 | /* Private data for the CS4270 */ |
| 129 | struct cs4270_private { | 129 | struct cs4270_private { |
| 130 | enum snd_soc_control_type control_type; | 130 | enum snd_soc_control_type control_type; |
| 131 | void *control_data; | ||
| 132 | unsigned int mclk; /* Input frequency of the MCLK pin */ | 131 | unsigned int mclk; /* Input frequency of the MCLK pin */ |
| 133 | unsigned int mode; /* The mode (I2S or left-justified) */ | 132 | unsigned int mode; /* The mode (I2S or left-justified) */ |
| 134 | unsigned int slave_mode; | 133 | unsigned int slave_mode; |
| @@ -262,7 +261,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 262 | { | 261 | { |
| 263 | struct snd_soc_codec *codec = codec_dai->codec; | 262 | struct snd_soc_codec *codec = codec_dai->codec; |
| 264 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 263 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 265 | int ret = 0; | ||
| 266 | 264 | ||
| 267 | /* set DAI format */ | 265 | /* set DAI format */ |
| 268 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | 266 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { |
| @@ -272,7 +270,7 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 272 | break; | 270 | break; |
| 273 | default: | 271 | default: |
| 274 | dev_err(codec->dev, "invalid dai format\n"); | 272 | dev_err(codec->dev, "invalid dai format\n"); |
| 275 | ret = -EINVAL; | 273 | return -EINVAL; |
| 276 | } | 274 | } |
| 277 | 275 | ||
| 278 | /* set master/slave audio interface */ | 276 | /* set master/slave audio interface */ |
| @@ -285,10 +283,11 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 285 | break; | 283 | break; |
| 286 | default: | 284 | default: |
| 287 | /* all other modes are unsupported by the hardware */ | 285 | /* all other modes are unsupported by the hardware */ |
| 288 | ret = -EINVAL; | 286 | dev_err(codec->dev, "Unknown master/slave configuration\n"); |
| 287 | return -EINVAL; | ||
| 289 | } | 288 | } |
| 290 | 289 | ||
| 291 | return ret; | 290 | return 0; |
| 292 | } | 291 | } |
| 293 | 292 | ||
| 294 | /** | 293 | /** |
| @@ -490,8 +489,6 @@ static int cs4270_probe(struct snd_soc_codec *codec) | |||
| 490 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 489 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 491 | int i, ret; | 490 | int i, ret; |
| 492 | 491 | ||
| 493 | codec->control_data = cs4270->control_data; | ||
| 494 | |||
| 495 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will | 492 | /* Tell ASoC what kind of I/O to use to read the registers. ASoC will |
| 496 | * then do the I2C transactions itself. | 493 | * then do the I2C transactions itself. |
| 497 | */ | 494 | */ |
| @@ -604,7 +601,7 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) | |||
| 604 | static int cs4270_soc_resume(struct snd_soc_codec *codec) | 601 | static int cs4270_soc_resume(struct snd_soc_codec *codec) |
| 605 | { | 602 | { |
| 606 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 603 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 607 | struct i2c_client *i2c_client = codec->control_data; | 604 | struct i2c_client *i2c_client = to_i2c_client(codec->dev); |
| 608 | int reg; | 605 | int reg; |
| 609 | 606 | ||
| 610 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | 607 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), |
| @@ -690,7 +687,6 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client, | |||
| 690 | } | 687 | } |
| 691 | 688 | ||
| 692 | i2c_set_clientdata(i2c_client, cs4270); | 689 | i2c_set_clientdata(i2c_client, cs4270); |
| 693 | cs4270->control_data = i2c_client; | ||
| 694 | cs4270->control_type = SND_SOC_I2C; | 690 | cs4270->control_type = SND_SOC_I2C; |
| 695 | 691 | ||
| 696 | ret = snd_soc_register_codec(&i2c_client->dev, | 692 | ret = snd_soc_register_codec(&i2c_client->dev, |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 083aab96ca80..23d1bd5dadda 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
| @@ -156,7 +156,6 @@ static const u8 cs4271_dflt_reg[CS4271_NR_REGS] = { | |||
| 156 | struct cs4271_private { | 156 | struct cs4271_private { |
| 157 | /* SND_SOC_I2C or SND_SOC_SPI */ | 157 | /* SND_SOC_I2C or SND_SOC_SPI */ |
| 158 | enum snd_soc_control_type bus_type; | 158 | enum snd_soc_control_type bus_type; |
| 159 | void *control_data; | ||
| 160 | unsigned int mclk; | 159 | unsigned int mclk; |
| 161 | bool master; | 160 | bool master; |
| 162 | bool deemph; | 161 | bool deemph; |
| @@ -466,8 +465,6 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
| 466 | int ret; | 465 | int ret; |
| 467 | int gpio_nreset = -EINVAL; | 466 | int gpio_nreset = -EINVAL; |
| 468 | 467 | ||
| 469 | codec->control_data = cs4271->control_data; | ||
| 470 | |||
| 471 | if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) | 468 | if (cs4271plat && gpio_is_valid(cs4271plat->gpio_nreset)) |
| 472 | gpio_nreset = cs4271plat->gpio_nreset; | 469 | gpio_nreset = cs4271plat->gpio_nreset; |
| 473 | 470 | ||
| @@ -555,7 +552,6 @@ static int __devinit cs4271_spi_probe(struct spi_device *spi) | |||
| 555 | return -ENOMEM; | 552 | return -ENOMEM; |
| 556 | 553 | ||
| 557 | spi_set_drvdata(spi, cs4271); | 554 | spi_set_drvdata(spi, cs4271); |
| 558 | cs4271->control_data = spi; | ||
| 559 | cs4271->bus_type = SND_SOC_SPI; | 555 | cs4271->bus_type = SND_SOC_SPI; |
| 560 | 556 | ||
| 561 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, | 557 | return snd_soc_register_codec(&spi->dev, &soc_codec_dev_cs4271, |
| @@ -595,7 +591,6 @@ static int __devinit cs4271_i2c_probe(struct i2c_client *client, | |||
| 595 | return -ENOMEM; | 591 | return -ENOMEM; |
| 596 | 592 | ||
| 597 | i2c_set_clientdata(client, cs4271); | 593 | i2c_set_clientdata(client, cs4271); |
| 598 | cs4271->control_data = client; | ||
| 599 | cs4271->bus_type = SND_SOC_I2C; | 594 | cs4271->bus_type = SND_SOC_I2C; |
| 600 | 595 | ||
| 601 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, | 596 | return snd_soc_register_codec(&client->dev, &soc_codec_dev_cs4271, |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 8fb7070108dd..8c3c8205d19e 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
| @@ -42,7 +42,6 @@ enum master_slave_mode { | |||
| 42 | 42 | ||
| 43 | struct cs42l51_private { | 43 | struct cs42l51_private { |
| 44 | enum snd_soc_control_type control_type; | 44 | enum snd_soc_control_type control_type; |
| 45 | void *control_data; | ||
| 46 | unsigned int mclk; | 45 | unsigned int mclk; |
| 47 | unsigned int audio_mode; /* The mode (I2S or left-justified) */ | 46 | unsigned int audio_mode; /* The mode (I2S or left-justified) */ |
| 48 | enum master_slave_mode func; | 47 | enum master_slave_mode func; |
| @@ -57,7 +56,7 @@ struct cs42l51_private { | |||
| 57 | static int cs42l51_fill_cache(struct snd_soc_codec *codec) | 56 | static int cs42l51_fill_cache(struct snd_soc_codec *codec) |
| 58 | { | 57 | { |
| 59 | u8 *cache = codec->reg_cache + 1; | 58 | u8 *cache = codec->reg_cache + 1; |
| 60 | struct i2c_client *i2c_client = codec->control_data; | 59 | struct i2c_client *i2c_client = to_i2c_client(codec->dev); |
| 61 | s32 length; | 60 | s32 length; |
| 62 | 61 | ||
| 63 | length = i2c_smbus_read_i2c_block_data(i2c_client, | 62 | length = i2c_smbus_read_i2c_block_data(i2c_client, |
| @@ -289,7 +288,6 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 289 | { | 288 | { |
| 290 | struct snd_soc_codec *codec = codec_dai->codec; | 289 | struct snd_soc_codec *codec = codec_dai->codec; |
| 291 | struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); | 290 | struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); |
| 292 | int ret = 0; | ||
| 293 | 291 | ||
| 294 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { | 292 | switch (format & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 295 | case SND_SOC_DAIFMT_I2S: | 293 | case SND_SOC_DAIFMT_I2S: |
| @@ -299,7 +297,7 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 299 | break; | 297 | break; |
| 300 | default: | 298 | default: |
| 301 | dev_err(codec->dev, "invalid DAI format\n"); | 299 | dev_err(codec->dev, "invalid DAI format\n"); |
| 302 | ret = -EINVAL; | 300 | return -EINVAL; |
| 303 | } | 301 | } |
| 304 | 302 | ||
| 305 | switch (format & SND_SOC_DAIFMT_MASTER_MASK) { | 303 | switch (format & SND_SOC_DAIFMT_MASTER_MASK) { |
| @@ -310,11 +308,11 @@ static int cs42l51_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 310 | cs42l51->func = MODE_SLAVE_AUTO; | 308 | cs42l51->func = MODE_SLAVE_AUTO; |
| 311 | break; | 309 | break; |
| 312 | default: | 310 | default: |
| 313 | ret = -EINVAL; | 311 | dev_err(codec->dev, "Unknown master/slave configuration\n"); |
| 314 | break; | 312 | return -EINVAL; |
| 315 | } | 313 | } |
| 316 | 314 | ||
| 317 | return ret; | 315 | return 0; |
| 318 | } | 316 | } |
| 319 | 317 | ||
| 320 | struct cs42l51_ratios { | 318 | struct cs42l51_ratios { |
| @@ -520,8 +518,6 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
| 520 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 518 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 521 | int ret, reg; | 519 | int ret, reg; |
| 522 | 520 | ||
| 523 | codec->control_data = cs42l51->control_data; | ||
| 524 | |||
| 525 | ret = cs42l51_fill_cache(codec); | 521 | ret = cs42l51_fill_cache(codec); |
| 526 | if (ret < 0) { | 522 | if (ret < 0) { |
| 527 | dev_err(codec->dev, "failed to fill register cache\n"); | 523 | dev_err(codec->dev, "failed to fill register cache\n"); |
| @@ -593,7 +589,6 @@ static int cs42l51_i2c_probe(struct i2c_client *i2c_client, | |||
| 593 | } | 589 | } |
| 594 | 590 | ||
| 595 | i2c_set_clientdata(i2c_client, cs42l51); | 591 | i2c_set_clientdata(i2c_client, cs42l51); |
| 596 | cs42l51->control_data = i2c_client; | ||
| 597 | cs42l51->control_type = SND_SOC_I2C; | 592 | cs42l51->control_type = SND_SOC_I2C; |
| 598 | 593 | ||
| 599 | ret = snd_soc_register_codec(&i2c_client->dev, | 594 | ret = snd_soc_register_codec(&i2c_client->dev, |
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 92fd9d7a9221..0ebcbd534490 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c | |||
| @@ -26,23 +26,41 @@ | |||
| 26 | #include <sound/tlv.h> | 26 | #include <sound/tlv.h> |
| 27 | 27 | ||
| 28 | /* DA7210 register space */ | 28 | /* DA7210 register space */ |
| 29 | #define DA7210_CONTROL 0x01 | ||
| 29 | #define DA7210_STATUS 0x02 | 30 | #define DA7210_STATUS 0x02 |
| 30 | #define DA7210_STARTUP1 0x03 | 31 | #define DA7210_STARTUP1 0x03 |
| 32 | #define DA7210_STARTUP2 0x04 | ||
| 33 | #define DA7210_STARTUP3 0x05 | ||
| 31 | #define DA7210_MIC_L 0x07 | 34 | #define DA7210_MIC_L 0x07 |
| 32 | #define DA7210_MIC_R 0x08 | 35 | #define DA7210_MIC_R 0x08 |
| 36 | #define DA7210_AUX1_L 0x09 | ||
| 37 | #define DA7210_AUX1_R 0x0A | ||
| 38 | #define DA7210_AUX2 0x0B | ||
| 39 | #define DA7210_IN_GAIN 0x0C | ||
| 33 | #define DA7210_INMIX_L 0x0D | 40 | #define DA7210_INMIX_L 0x0D |
| 34 | #define DA7210_INMIX_R 0x0E | 41 | #define DA7210_INMIX_R 0x0E |
| 35 | #define DA7210_ADC_HPF 0x0F | 42 | #define DA7210_ADC_HPF 0x0F |
| 36 | #define DA7210_ADC 0x10 | 43 | #define DA7210_ADC 0x10 |
| 44 | #define DA7210_ADC_EQ1_2 0X11 | ||
| 45 | #define DA7210_ADC_EQ3_4 0x12 | ||
| 46 | #define DA7210_ADC_EQ5 0x13 | ||
| 37 | #define DA7210_DAC_HPF 0x14 | 47 | #define DA7210_DAC_HPF 0x14 |
| 38 | #define DA7210_DAC_L 0x15 | 48 | #define DA7210_DAC_L 0x15 |
| 39 | #define DA7210_DAC_R 0x16 | 49 | #define DA7210_DAC_R 0x16 |
| 40 | #define DA7210_DAC_SEL 0x17 | 50 | #define DA7210_DAC_SEL 0x17 |
| 51 | #define DA7210_SOFTMUTE 0x18 | ||
| 52 | #define DA7210_DAC_EQ1_2 0x19 | ||
| 53 | #define DA7210_DAC_EQ3_4 0x1A | ||
| 54 | #define DA7210_DAC_EQ5 0x1B | ||
| 41 | #define DA7210_OUTMIX_L 0x1C | 55 | #define DA7210_OUTMIX_L 0x1C |
| 42 | #define DA7210_OUTMIX_R 0x1D | 56 | #define DA7210_OUTMIX_R 0x1D |
| 57 | #define DA7210_OUT1_L 0x1E | ||
| 58 | #define DA7210_OUT1_R 0x1F | ||
| 59 | #define DA7210_OUT2 0x20 | ||
| 43 | #define DA7210_HP_L_VOL 0x21 | 60 | #define DA7210_HP_L_VOL 0x21 |
| 44 | #define DA7210_HP_R_VOL 0x22 | 61 | #define DA7210_HP_R_VOL 0x22 |
| 45 | #define DA7210_HP_CFG 0x23 | 62 | #define DA7210_HP_CFG 0x23 |
| 63 | #define DA7210_ZERO_CROSS 0x24 | ||
| 46 | #define DA7210_DAI_SRC_SEL 0x25 | 64 | #define DA7210_DAI_SRC_SEL 0x25 |
| 47 | #define DA7210_DAI_CFG1 0x26 | 65 | #define DA7210_DAI_CFG1 0x26 |
| 48 | #define DA7210_DAI_CFG3 0x28 | 66 | #define DA7210_DAI_CFG3 0x28 |
| @@ -50,6 +68,12 @@ | |||
| 50 | #define DA7210_PLL_DIV2 0x2A | 68 | #define DA7210_PLL_DIV2 0x2A |
| 51 | #define DA7210_PLL_DIV3 0x2B | 69 | #define DA7210_PLL_DIV3 0x2B |
| 52 | #define DA7210_PLL 0x2C | 70 | #define DA7210_PLL 0x2C |
| 71 | #define DA7210_ALC_MAX 0x83 | ||
| 72 | #define DA7210_ALC_MIN 0x84 | ||
| 73 | #define DA7210_ALC_NOIS 0x85 | ||
| 74 | #define DA7210_ALC_ATT 0x86 | ||
| 75 | #define DA7210_ALC_REL 0x87 | ||
| 76 | #define DA7210_ALC_DEL 0x88 | ||
| 53 | #define DA7210_A_HID_UNLOCK 0x8A | 77 | #define DA7210_A_HID_UNLOCK 0x8A |
| 54 | #define DA7210_A_TEST_UNLOCK 0x8B | 78 | #define DA7210_A_TEST_UNLOCK 0x8B |
| 55 | #define DA7210_A_PLL1 0x90 | 79 | #define DA7210_A_PLL1 0x90 |
| @@ -72,6 +96,7 @@ | |||
| 72 | #define DA7210_IN_R_EN (1 << 7) | 96 | #define DA7210_IN_R_EN (1 << 7) |
| 73 | 97 | ||
| 74 | /* ADC bit fields */ | 98 | /* ADC bit fields */ |
| 99 | #define DA7210_ADC_ALC_EN (1 << 0) | ||
| 75 | #define DA7210_ADC_L_EN (1 << 3) | 100 | #define DA7210_ADC_L_EN (1 << 3) |
| 76 | #define DA7210_ADC_R_EN (1 << 7) | 101 | #define DA7210_ADC_R_EN (1 << 7) |
| 77 | 102 | ||
| @@ -105,12 +130,17 @@ | |||
| 105 | 130 | ||
| 106 | /* DAI_CFG1 bit fields */ | 131 | /* DAI_CFG1 bit fields */ |
| 107 | #define DA7210_DAI_WORD_S16_LE (0 << 0) | 132 | #define DA7210_DAI_WORD_S16_LE (0 << 0) |
| 133 | #define DA7210_DAI_WORD_S20_3LE (1 << 0) | ||
| 108 | #define DA7210_DAI_WORD_S24_LE (2 << 0) | 134 | #define DA7210_DAI_WORD_S24_LE (2 << 0) |
| 135 | #define DA7210_DAI_WORD_S32_LE (3 << 0) | ||
| 109 | #define DA7210_DAI_FLEN_64BIT (1 << 2) | 136 | #define DA7210_DAI_FLEN_64BIT (1 << 2) |
| 137 | #define DA7210_DAI_MODE_SLAVE (0 << 7) | ||
| 110 | #define DA7210_DAI_MODE_MASTER (1 << 7) | 138 | #define DA7210_DAI_MODE_MASTER (1 << 7) |
| 111 | 139 | ||
| 112 | /* DAI_CFG3 bit fields */ | 140 | /* DAI_CFG3 bit fields */ |
| 113 | #define DA7210_DAI_FORMAT_I2SMODE (0 << 0) | 141 | #define DA7210_DAI_FORMAT_I2SMODE (0 << 0) |
| 142 | #define DA7210_DAI_FORMAT_LEFT_J (1 << 0) | ||
| 143 | #define DA7210_DAI_FORMAT_RIGHT_J (2 << 0) | ||
| 114 | #define DA7210_DAI_OE (1 << 3) | 144 | #define DA7210_DAI_OE (1 << 3) |
| 115 | #define DA7210_DAI_EN (1 << 7) | 145 | #define DA7210_DAI_EN (1 << 7) |
| 116 | 146 | ||
| @@ -133,6 +163,43 @@ | |||
| 133 | #define DA7210_PLL_FS_96000 (0xF << 0) | 163 | #define DA7210_PLL_FS_96000 (0xF << 0) |
| 134 | #define DA7210_PLL_EN (0x1 << 7) | 164 | #define DA7210_PLL_EN (0x1 << 7) |
| 135 | 165 | ||
| 166 | /* SOFTMUTE bit fields */ | ||
| 167 | #define DA7210_RAMP_EN (1 << 6) | ||
| 168 | |||
| 169 | /* CONTROL bit fields */ | ||
| 170 | #define DA7210_NOISE_SUP_EN (1 << 3) | ||
| 171 | |||
| 172 | /* IN_GAIN bit fields */ | ||
| 173 | #define DA7210_INPGA_L_VOL (0x0F << 0) | ||
| 174 | #define DA7210_INPGA_R_VOL (0xF0 << 0) | ||
| 175 | |||
| 176 | /* ZERO_CROSS bit fields */ | ||
| 177 | #define DA7210_AUX1_L_ZC (1 << 0) | ||
| 178 | #define DA7210_AUX1_R_ZC (1 << 1) | ||
| 179 | #define DA7210_HP_L_ZC (1 << 6) | ||
| 180 | #define DA7210_HP_R_ZC (1 << 7) | ||
| 181 | |||
| 182 | /* AUX1_L bit fields */ | ||
| 183 | #define DA7210_AUX1_L_VOL (0x3F << 0) | ||
| 184 | |||
| 185 | /* AUX1_R bit fields */ | ||
| 186 | #define DA7210_AUX1_R_VOL (0x3F << 0) | ||
| 187 | |||
| 188 | /* Minimum INPGA and AUX1 volume to enable noise suppression */ | ||
| 189 | #define DA7210_INPGA_MIN_VOL_NS 0x0A /* 10.5dB */ | ||
| 190 | #define DA7210_AUX1_MIN_VOL_NS 0x35 /* 6dB */ | ||
| 191 | |||
| 192 | /* OUT1_L bit fields */ | ||
| 193 | #define DA7210_OUT1_L_EN (1 << 7) | ||
| 194 | |||
| 195 | /* OUT1_R bit fields */ | ||
| 196 | #define DA7210_OUT1_R_EN (1 << 7) | ||
| 197 | |||
| 198 | /* OUT2 bit fields */ | ||
| 199 | #define DA7210_OUT2_OUTMIX_R (1 << 5) | ||
| 200 | #define DA7210_OUT2_OUTMIX_L (1 << 6) | ||
| 201 | #define DA7210_OUT2_EN (1 << 7) | ||
| 202 | |||
| 136 | #define DA7210_VERSION "0.0.1" | 203 | #define DA7210_VERSION "0.0.1" |
| 137 | 204 | ||
| 138 | /* | 205 | /* |
| @@ -144,24 +211,351 @@ | |||
| 144 | * mute : 0x10 | 211 | * mute : 0x10 |
| 145 | * reserved : 0x00 - 0x0F | 212 | * reserved : 0x00 - 0x0F |
| 146 | * | 213 | * |
| 147 | * ** FIXME ** | ||
| 148 | * | ||
| 149 | * Reserved area are considered as "mute". | 214 | * Reserved area are considered as "mute". |
| 150 | * -> min = -79.5 dB | ||
| 151 | */ | 215 | */ |
| 152 | static const DECLARE_TLV_DB_SCALE(hp_out_tlv, -7950, 150, 1); | 216 | static const unsigned int hp_out_tlv[] = { |
| 217 | TLV_DB_RANGE_HEAD(2), | ||
| 218 | 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), | ||
| 219 | /* -54 dB to +15 dB */ | ||
| 220 | 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0), | ||
| 221 | }; | ||
| 222 | |||
| 223 | static const unsigned int lineout_vol_tlv[] = { | ||
| 224 | TLV_DB_RANGE_HEAD(2), | ||
| 225 | 0x0, 0x10, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1), | ||
| 226 | /* -54dB to 15dB */ | ||
| 227 | 0x11, 0x3f, TLV_DB_SCALE_ITEM(-5400, 150, 0) | ||
| 228 | }; | ||
| 229 | |||
| 230 | static const unsigned int mono_vol_tlv[] = { | ||
| 231 | TLV_DB_RANGE_HEAD(2), | ||
| 232 | 0x0, 0x2, TLV_DB_SCALE_ITEM(-1800, 0, 1), | ||
| 233 | /* -18dB to 6dB */ | ||
| 234 | 0x3, 0x7, TLV_DB_SCALE_ITEM(-1800, 600, 0) | ||
| 235 | }; | ||
| 236 | |||
| 237 | static const DECLARE_TLV_DB_SCALE(eq_gain_tlv, -1050, 150, 0); | ||
| 238 | static const DECLARE_TLV_DB_SCALE(adc_eq_master_gain_tlv, -1800, 600, 1); | ||
| 239 | static const DECLARE_TLV_DB_SCALE(dac_gain_tlv, -7725, 75, 0); | ||
| 240 | |||
| 241 | /* ADC and DAC high pass filter f0 value */ | ||
| 242 | static const char const *da7210_hpf_cutoff_txt[] = { | ||
| 243 | "Fs/8192*pi", "Fs/4096*pi", "Fs/2048*pi", "Fs/1024*pi" | ||
| 244 | }; | ||
| 245 | |||
| 246 | static const struct soc_enum da7210_dac_hpf_cutoff = | ||
| 247 | SOC_ENUM_SINGLE(DA7210_DAC_HPF, 0, 4, da7210_hpf_cutoff_txt); | ||
| 248 | |||
| 249 | static const struct soc_enum da7210_adc_hpf_cutoff = | ||
| 250 | SOC_ENUM_SINGLE(DA7210_ADC_HPF, 0, 4, da7210_hpf_cutoff_txt); | ||
| 251 | |||
| 252 | /* ADC and DAC voice (8kHz) high pass cutoff value */ | ||
| 253 | static const char const *da7210_vf_cutoff_txt[] = { | ||
| 254 | "2.5Hz", "25Hz", "50Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz" | ||
| 255 | }; | ||
| 256 | |||
| 257 | static const struct soc_enum da7210_dac_vf_cutoff = | ||
| 258 | SOC_ENUM_SINGLE(DA7210_DAC_HPF, 4, 8, da7210_vf_cutoff_txt); | ||
| 259 | |||
| 260 | static const struct soc_enum da7210_adc_vf_cutoff = | ||
| 261 | SOC_ENUM_SINGLE(DA7210_ADC_HPF, 4, 8, da7210_vf_cutoff_txt); | ||
| 262 | |||
| 263 | static const char *da7210_hp_mode_txt[] = { | ||
| 264 | "Class H", "Class G" | ||
| 265 | }; | ||
| 266 | |||
| 267 | static const struct soc_enum da7210_hp_mode_sel = | ||
| 268 | SOC_ENUM_SINGLE(DA7210_HP_CFG, 0, 2, da7210_hp_mode_txt); | ||
| 269 | |||
| 270 | /* ALC can be enabled only if noise suppression is disabled */ | ||
| 271 | static int da7210_put_alc_sw(struct snd_kcontrol *kcontrol, | ||
| 272 | struct snd_ctl_elem_value *ucontrol) | ||
| 273 | { | ||
| 274 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 275 | |||
| 276 | if (ucontrol->value.integer.value[0]) { | ||
| 277 | /* Check if noise suppression is enabled */ | ||
| 278 | if (snd_soc_read(codec, DA7210_CONTROL) & DA7210_NOISE_SUP_EN) { | ||
| 279 | dev_dbg(codec->dev, | ||
| 280 | "Disable noise suppression to enable ALC\n"); | ||
| 281 | return -EINVAL; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | /* If all conditions are met or we are actually disabling ALC */ | ||
| 285 | return snd_soc_put_volsw(kcontrol, ucontrol); | ||
| 286 | } | ||
| 287 | |||
| 288 | /* Noise suppression can be enabled only if following conditions are met | ||
| 289 | * ALC disabled | ||
| 290 | * ZC enabled for HP and AUX1 PGA | ||
| 291 | * INPGA_L_VOL and INPGA_R_VOL >= 10.5 dB | ||
| 292 | * AUX1_L_VOL and AUX1_R_VOL >= 6 dB | ||
| 293 | */ | ||
| 294 | static int da7210_put_noise_sup_sw(struct snd_kcontrol *kcontrol, | ||
| 295 | struct snd_ctl_elem_value *ucontrol) | ||
| 296 | { | ||
| 297 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 298 | u8 val; | ||
| 299 | |||
| 300 | if (ucontrol->value.integer.value[0]) { | ||
| 301 | /* Check if ALC is enabled */ | ||
| 302 | if (snd_soc_read(codec, DA7210_ADC) & DA7210_ADC_ALC_EN) | ||
| 303 | goto err; | ||
| 304 | |||
| 305 | /* Check ZC for HP and AUX1 PGA */ | ||
| 306 | if ((snd_soc_read(codec, DA7210_ZERO_CROSS) & | ||
| 307 | (DA7210_AUX1_L_ZC | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | | ||
| 308 | DA7210_HP_R_ZC)) != (DA7210_AUX1_L_ZC | | ||
| 309 | DA7210_AUX1_R_ZC | DA7210_HP_L_ZC | DA7210_HP_R_ZC)) | ||
| 310 | goto err; | ||
| 311 | |||
| 312 | /* Check INPGA_L_VOL and INPGA_R_VOL */ | ||
| 313 | val = snd_soc_read(codec, DA7210_IN_GAIN); | ||
| 314 | if (((val & DA7210_INPGA_L_VOL) < DA7210_INPGA_MIN_VOL_NS) || | ||
| 315 | (((val & DA7210_INPGA_R_VOL) >> 4) < | ||
| 316 | DA7210_INPGA_MIN_VOL_NS)) | ||
| 317 | goto err; | ||
| 318 | |||
| 319 | /* Check AUX1_L_VOL and AUX1_R_VOL */ | ||
| 320 | if (((snd_soc_read(codec, DA7210_AUX1_L) & DA7210_AUX1_L_VOL) < | ||
| 321 | DA7210_AUX1_MIN_VOL_NS) || | ||
| 322 | ((snd_soc_read(codec, DA7210_AUX1_R) & DA7210_AUX1_R_VOL) < | ||
| 323 | DA7210_AUX1_MIN_VOL_NS)) | ||
| 324 | goto err; | ||
| 325 | } | ||
| 326 | /* If all conditions are met or we are actually disabling Noise sup */ | ||
| 327 | return snd_soc_put_volsw(kcontrol, ucontrol); | ||
| 328 | |||
| 329 | err: | ||
| 330 | return -EINVAL; | ||
| 331 | } | ||
| 153 | 332 | ||
| 154 | static const struct snd_kcontrol_new da7210_snd_controls[] = { | 333 | static const struct snd_kcontrol_new da7210_snd_controls[] = { |
| 155 | 334 | ||
| 156 | SOC_DOUBLE_R_TLV("HeadPhone Playback Volume", | 335 | SOC_DOUBLE_R_TLV("HeadPhone Playback Volume", |
| 157 | DA7210_HP_L_VOL, DA7210_HP_R_VOL, | 336 | DA7210_HP_L_VOL, DA7210_HP_R_VOL, |
| 158 | 0, 0x3F, 0, hp_out_tlv), | 337 | 0, 0x3F, 0, hp_out_tlv), |
| 338 | SOC_DOUBLE_R_TLV("Digital Playback Volume", | ||
| 339 | DA7210_DAC_L, DA7210_DAC_R, | ||
| 340 | 0, 0x77, 1, dac_gain_tlv), | ||
| 341 | SOC_DOUBLE_R_TLV("Lineout Playback Volume", | ||
| 342 | DA7210_OUT1_L, DA7210_OUT1_R, | ||
| 343 | 0, 0x3f, 0, lineout_vol_tlv), | ||
| 344 | SOC_SINGLE_TLV("Mono Playback Volume", DA7210_OUT2, 0, 0x7, 0, | ||
| 345 | mono_vol_tlv), | ||
| 346 | |||
| 347 | /* DAC Equalizer controls */ | ||
| 348 | SOC_SINGLE("DAC EQ Switch", DA7210_DAC_EQ5, 7, 1, 0), | ||
| 349 | SOC_SINGLE_TLV("DAC EQ1 Volume", DA7210_DAC_EQ1_2, 0, 0xf, 1, | ||
| 350 | eq_gain_tlv), | ||
| 351 | SOC_SINGLE_TLV("DAC EQ2 Volume", DA7210_DAC_EQ1_2, 4, 0xf, 1, | ||
| 352 | eq_gain_tlv), | ||
| 353 | SOC_SINGLE_TLV("DAC EQ3 Volume", DA7210_DAC_EQ3_4, 0, 0xf, 1, | ||
| 354 | eq_gain_tlv), | ||
| 355 | SOC_SINGLE_TLV("DAC EQ4 Volume", DA7210_DAC_EQ3_4, 4, 0xf, 1, | ||
| 356 | eq_gain_tlv), | ||
| 357 | SOC_SINGLE_TLV("DAC EQ5 Volume", DA7210_DAC_EQ5, 0, 0xf, 1, | ||
| 358 | eq_gain_tlv), | ||
| 359 | |||
| 360 | /* ADC Equalizer controls */ | ||
| 361 | SOC_SINGLE("ADC EQ Switch", DA7210_ADC_EQ5, 7, 1, 0), | ||
| 362 | SOC_SINGLE_TLV("ADC EQ Master Volume", DA7210_ADC_EQ5, 4, 0x3, | ||
| 363 | 1, adc_eq_master_gain_tlv), | ||
| 364 | SOC_SINGLE_TLV("ADC EQ1 Volume", DA7210_ADC_EQ1_2, 0, 0xf, 1, | ||
| 365 | eq_gain_tlv), | ||
| 366 | SOC_SINGLE_TLV("ADC EQ2 Volume", DA7210_ADC_EQ1_2, 4, 0xf, 1, | ||
| 367 | eq_gain_tlv), | ||
| 368 | SOC_SINGLE_TLV("ADC EQ3 Volume", DA7210_ADC_EQ3_4, 0, 0xf, 1, | ||
| 369 | eq_gain_tlv), | ||
| 370 | SOC_SINGLE_TLV("ADC EQ4 Volume", DA7210_ADC_EQ3_4, 4, 0xf, 1, | ||
| 371 | eq_gain_tlv), | ||
| 372 | SOC_SINGLE_TLV("ADC EQ5 Volume", DA7210_ADC_EQ5, 0, 0xf, 1, | ||
| 373 | eq_gain_tlv), | ||
| 374 | |||
| 375 | SOC_SINGLE("DAC HPF Switch", DA7210_DAC_HPF, 3, 1, 0), | ||
| 376 | SOC_ENUM("DAC HPF Cutoff", da7210_dac_hpf_cutoff), | ||
| 377 | SOC_SINGLE("DAC Voice Mode Switch", DA7210_DAC_HPF, 7, 1, 0), | ||
| 378 | SOC_ENUM("DAC Voice Cutoff", da7210_dac_vf_cutoff), | ||
| 379 | |||
| 380 | SOC_SINGLE("ADC HPF Switch", DA7210_ADC_HPF, 3, 1, 0), | ||
| 381 | SOC_ENUM("ADC HPF Cutoff", da7210_adc_hpf_cutoff), | ||
| 382 | SOC_SINGLE("ADC Voice Mode Switch", DA7210_ADC_HPF, 7, 1, 0), | ||
| 383 | SOC_ENUM("ADC Voice Cutoff", da7210_adc_vf_cutoff), | ||
| 384 | |||
| 385 | /* Mute controls */ | ||
| 386 | SOC_DOUBLE_R("Mic Capture Switch", DA7210_MIC_L, DA7210_MIC_R, 3, 1, 0), | ||
| 387 | SOC_SINGLE("Aux2 Capture Switch", DA7210_AUX2, 2, 1, 0), | ||
| 388 | SOC_DOUBLE("ADC Capture Switch", DA7210_ADC, 2, 6, 1, 0), | ||
| 389 | SOC_SINGLE("Digital Soft Mute Switch", DA7210_SOFTMUTE, 7, 1, 0), | ||
| 390 | SOC_SINGLE("Digital Soft Mute Rate", DA7210_SOFTMUTE, 0, 0x7, 0), | ||
| 391 | |||
| 392 | /* Zero cross controls */ | ||
| 393 | SOC_DOUBLE("Aux1 ZC Switch", DA7210_ZERO_CROSS, 0, 1, 1, 0), | ||
| 394 | SOC_DOUBLE("In PGA ZC Switch", DA7210_ZERO_CROSS, 2, 3, 1, 0), | ||
| 395 | SOC_DOUBLE("Lineout ZC Switch", DA7210_ZERO_CROSS, 4, 5, 1, 0), | ||
| 396 | SOC_DOUBLE("Headphone ZC Switch", DA7210_ZERO_CROSS, 6, 7, 1, 0), | ||
| 397 | |||
| 398 | SOC_ENUM("Headphone Class", da7210_hp_mode_sel), | ||
| 399 | |||
| 400 | /* ALC controls */ | ||
| 401 | SOC_SINGLE_EXT("ALC Enable Switch", DA7210_ADC, 0, 1, 0, | ||
| 402 | snd_soc_get_volsw, da7210_put_alc_sw), | ||
| 403 | SOC_SINGLE("ALC Capture Max Volume", DA7210_ALC_MAX, 0, 0x3F, 0), | ||
| 404 | SOC_SINGLE("ALC Capture Min Volume", DA7210_ALC_MIN, 0, 0x3F, 0), | ||
| 405 | SOC_SINGLE("ALC Capture Noise Volume", DA7210_ALC_NOIS, 0, 0x3F, 0), | ||
| 406 | SOC_SINGLE("ALC Capture Attack Rate", DA7210_ALC_ATT, 0, 0xFF, 0), | ||
| 407 | SOC_SINGLE("ALC Capture Release Rate", DA7210_ALC_REL, 0, 0xFF, 0), | ||
| 408 | SOC_SINGLE("ALC Capture Release Delay", DA7210_ALC_DEL, 0, 0xFF, 0), | ||
| 409 | |||
| 410 | SOC_SINGLE_EXT("Noise Suppression Enable Switch", DA7210_CONTROL, 3, 1, | ||
| 411 | 0, snd_soc_get_volsw, da7210_put_noise_sup_sw), | ||
| 412 | }; | ||
| 413 | |||
| 414 | /* | ||
| 415 | * DAPM Controls | ||
| 416 | * | ||
| 417 | * Current DAPM implementation covers almost all codec components e.g. IOs, | ||
| 418 | * mixers, PGAs,ADC and DAC. | ||
| 419 | */ | ||
| 420 | /* In Mixer Left */ | ||
| 421 | static const struct snd_kcontrol_new da7210_dapm_inmixl_controls[] = { | ||
| 422 | SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_L, 0, 1, 0), | ||
| 423 | SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_L, 1, 1, 0), | ||
| 424 | }; | ||
| 425 | |||
| 426 | /* In Mixer Right */ | ||
| 427 | static const struct snd_kcontrol_new da7210_dapm_inmixr_controls[] = { | ||
| 428 | SOC_DAPM_SINGLE("Mic Right Switch", DA7210_INMIX_R, 0, 1, 0), | ||
| 429 | SOC_DAPM_SINGLE("Mic Left Switch", DA7210_INMIX_R, 1, 1, 0), | ||
| 430 | }; | ||
| 431 | |||
| 432 | /* Out Mixer Left */ | ||
| 433 | static const struct snd_kcontrol_new da7210_dapm_outmixl_controls[] = { | ||
| 434 | SOC_DAPM_SINGLE("DAC Left Switch", DA7210_OUTMIX_L, 4, 1, 0), | ||
| 435 | }; | ||
| 436 | |||
| 437 | /* Out Mixer Right */ | ||
| 438 | static const struct snd_kcontrol_new da7210_dapm_outmixr_controls[] = { | ||
| 439 | SOC_DAPM_SINGLE("DAC Right Switch", DA7210_OUTMIX_R, 4, 1, 0), | ||
| 440 | }; | ||
| 441 | |||
| 442 | /* Mono Mixer */ | ||
| 443 | static const struct snd_kcontrol_new da7210_dapm_monomix_controls[] = { | ||
| 444 | SOC_DAPM_SINGLE("Outmix Right Switch", DA7210_OUT2, 5, 1, 0), | ||
| 445 | SOC_DAPM_SINGLE("Outmix Left Switch", DA7210_OUT2, 6, 1, 0), | ||
| 446 | }; | ||
| 447 | |||
| 448 | /* DAPM widgets */ | ||
| 449 | static const struct snd_soc_dapm_widget da7210_dapm_widgets[] = { | ||
| 450 | /* Input Side */ | ||
| 451 | /* Input Lines */ | ||
| 452 | SND_SOC_DAPM_INPUT("MICL"), | ||
| 453 | SND_SOC_DAPM_INPUT("MICR"), | ||
| 454 | |||
| 455 | /* Input PGAs */ | ||
| 456 | SND_SOC_DAPM_PGA("Mic Left", DA7210_STARTUP3, 0, 1, NULL, 0), | ||
| 457 | SND_SOC_DAPM_PGA("Mic Right", DA7210_STARTUP3, 1, 1, NULL, 0), | ||
| 458 | |||
| 459 | SND_SOC_DAPM_PGA("INPGA Left", DA7210_INMIX_L, 7, 0, NULL, 0), | ||
| 460 | SND_SOC_DAPM_PGA("INPGA Right", DA7210_INMIX_R, 7, 0, NULL, 0), | ||
| 461 | |||
| 462 | /* Input Mixers */ | ||
| 463 | SND_SOC_DAPM_MIXER("In Mixer Left", SND_SOC_NOPM, 0, 0, | ||
| 464 | &da7210_dapm_inmixl_controls[0], | ||
| 465 | ARRAY_SIZE(da7210_dapm_inmixl_controls)), | ||
| 466 | |||
| 467 | SND_SOC_DAPM_MIXER("In Mixer Right", SND_SOC_NOPM, 0, 0, | ||
| 468 | &da7210_dapm_inmixr_controls[0], | ||
| 469 | ARRAY_SIZE(da7210_dapm_inmixr_controls)), | ||
| 470 | |||
| 471 | /* ADCs */ | ||
| 472 | SND_SOC_DAPM_ADC("ADC Left", "Capture", DA7210_STARTUP3, 5, 1), | ||
| 473 | SND_SOC_DAPM_ADC("ADC Right", "Capture", DA7210_STARTUP3, 6, 1), | ||
| 474 | |||
| 475 | /* Output Side */ | ||
| 476 | /* DACs */ | ||
| 477 | SND_SOC_DAPM_DAC("DAC Left", "Playback", DA7210_STARTUP2, 5, 1), | ||
| 478 | SND_SOC_DAPM_DAC("DAC Right", "Playback", DA7210_STARTUP2, 6, 1), | ||
| 479 | |||
| 480 | /* Output Mixers */ | ||
| 481 | SND_SOC_DAPM_MIXER("Out Mixer Left", SND_SOC_NOPM, 0, 0, | ||
| 482 | &da7210_dapm_outmixl_controls[0], | ||
| 483 | ARRAY_SIZE(da7210_dapm_outmixl_controls)), | ||
| 484 | |||
| 485 | SND_SOC_DAPM_MIXER("Out Mixer Right", SND_SOC_NOPM, 0, 0, | ||
| 486 | &da7210_dapm_outmixr_controls[0], | ||
| 487 | ARRAY_SIZE(da7210_dapm_outmixr_controls)), | ||
| 488 | |||
| 489 | SND_SOC_DAPM_MIXER("Mono Mixer", SND_SOC_NOPM, 0, 0, | ||
| 490 | &da7210_dapm_monomix_controls[0], | ||
| 491 | ARRAY_SIZE(da7210_dapm_monomix_controls)), | ||
| 492 | |||
| 493 | /* Output PGAs */ | ||
| 494 | SND_SOC_DAPM_PGA("OUTPGA Left Enable", DA7210_OUTMIX_L, 7, 0, NULL, 0), | ||
| 495 | SND_SOC_DAPM_PGA("OUTPGA Right Enable", DA7210_OUTMIX_R, 7, 0, NULL, 0), | ||
| 496 | |||
| 497 | SND_SOC_DAPM_PGA("Out1 Left", DA7210_STARTUP2, 0, 1, NULL, 0), | ||
| 498 | SND_SOC_DAPM_PGA("Out1 Right", DA7210_STARTUP2, 1, 1, NULL, 0), | ||
| 499 | SND_SOC_DAPM_PGA("Out2 Mono", DA7210_STARTUP2, 2, 1, NULL, 0), | ||
| 500 | SND_SOC_DAPM_PGA("Headphone Left", DA7210_STARTUP2, 3, 1, NULL, 0), | ||
| 501 | SND_SOC_DAPM_PGA("Headphone Right", DA7210_STARTUP2, 4, 1, NULL, 0), | ||
| 502 | |||
| 503 | /* Output Lines */ | ||
| 504 | SND_SOC_DAPM_OUTPUT("OUT1L"), | ||
| 505 | SND_SOC_DAPM_OUTPUT("OUT1R"), | ||
| 506 | SND_SOC_DAPM_OUTPUT("HPL"), | ||
| 507 | SND_SOC_DAPM_OUTPUT("HPR"), | ||
| 508 | SND_SOC_DAPM_OUTPUT("OUT2"), | ||
| 509 | }; | ||
| 510 | |||
| 511 | /* DAPM audio route definition */ | ||
| 512 | static const struct snd_soc_dapm_route da7210_audio_map[] = { | ||
| 513 | /* Dest Connecting Widget source */ | ||
| 514 | /* Input path */ | ||
| 515 | {"Mic Left", NULL, "MICL"}, | ||
| 516 | {"Mic Right", NULL, "MICR"}, | ||
| 517 | |||
| 518 | {"In Mixer Left", "Mic Left Switch", "Mic Left"}, | ||
| 519 | {"In Mixer Left", "Mic Right Switch", "Mic Right"}, | ||
| 520 | |||
| 521 | {"In Mixer Right", "Mic Right Switch", "Mic Right"}, | ||
| 522 | {"In Mixer Right", "Mic Left Switch", "Mic Left"}, | ||
| 523 | |||
| 524 | {"INPGA Left", NULL, "In Mixer Left"}, | ||
| 525 | {"ADC Left", NULL, "INPGA Left"}, | ||
| 526 | |||
| 527 | {"INPGA Right", NULL, "In Mixer Right"}, | ||
| 528 | {"ADC Right", NULL, "INPGA Right"}, | ||
| 529 | |||
| 530 | /* Output path */ | ||
| 531 | {"Out Mixer Left", "DAC Left Switch", "DAC Left"}, | ||
| 532 | {"Out Mixer Right", "DAC Right Switch", "DAC Right"}, | ||
| 533 | |||
| 534 | {"Mono Mixer", "Outmix Right Switch", "Out Mixer Right"}, | ||
| 535 | {"Mono Mixer", "Outmix Left Switch", "Out Mixer Left"}, | ||
| 536 | |||
| 537 | {"OUTPGA Left Enable", NULL, "Out Mixer Left"}, | ||
| 538 | {"OUTPGA Right Enable", NULL, "Out Mixer Right"}, | ||
| 539 | |||
| 540 | {"Out1 Left", NULL, "OUTPGA Left Enable"}, | ||
| 541 | {"OUT1L", NULL, "Out1 Left"}, | ||
| 542 | |||
| 543 | {"Out1 Right", NULL, "OUTPGA Right Enable"}, | ||
| 544 | {"OUT1R", NULL, "Out1 Right"}, | ||
| 545 | |||
| 546 | {"Headphone Left", NULL, "OUTPGA Left Enable"}, | ||
| 547 | {"HPL", NULL, "Headphone Left"}, | ||
| 548 | |||
| 549 | {"Headphone Right", NULL, "OUTPGA Right Enable"}, | ||
| 550 | {"HPR", NULL, "Headphone Right"}, | ||
| 551 | |||
| 552 | {"Out2 Mono", NULL, "Mono Mixer"}, | ||
| 553 | {"OUT2", NULL, "Out2 Mono"}, | ||
| 159 | }; | 554 | }; |
| 160 | 555 | ||
| 161 | /* Codec private data */ | 556 | /* Codec private data */ |
| 162 | struct da7210_priv { | 557 | struct da7210_priv { |
| 163 | enum snd_soc_control_type control_type; | 558 | enum snd_soc_control_type control_type; |
| 164 | void *control_data; | ||
| 165 | }; | 559 | }; |
| 166 | 560 | ||
| 167 | /* | 561 | /* |
| @@ -188,72 +582,15 @@ static const u8 da7210_reg[] = { | |||
| 188 | 0x00, /* R88 */ | 582 | 0x00, /* R88 */ |
| 189 | }; | 583 | }; |
| 190 | 584 | ||
| 191 | /* | 585 | static int da7210_volatile_register(struct snd_soc_codec *codec, |
| 192 | * Read da7210 register cache | 586 | unsigned int reg) |
| 193 | */ | ||
| 194 | static inline u32 da7210_read_reg_cache(struct snd_soc_codec *codec, u32 reg) | ||
| 195 | { | ||
| 196 | u8 *cache = codec->reg_cache; | ||
| 197 | BUG_ON(reg >= ARRAY_SIZE(da7210_reg)); | ||
| 198 | return cache[reg]; | ||
| 199 | } | ||
| 200 | |||
| 201 | /* | ||
| 202 | * Write to the da7210 register space | ||
| 203 | */ | ||
| 204 | static int da7210_write(struct snd_soc_codec *codec, u32 reg, u32 value) | ||
| 205 | { | 587 | { |
| 206 | u8 *cache = codec->reg_cache; | 588 | switch (reg) { |
| 207 | u8 data[2]; | 589 | case DA7210_STATUS: |
| 208 | 590 | return 1; | |
| 209 | BUG_ON(codec->driver->volatile_register); | 591 | default: |
| 210 | 592 | return 0; | |
| 211 | data[0] = reg & 0xff; | ||
| 212 | data[1] = value & 0xff; | ||
| 213 | |||
| 214 | if (reg >= codec->driver->reg_cache_size) | ||
| 215 | return -EIO; | ||
| 216 | |||
| 217 | if (2 != codec->hw_write(codec->control_data, data, 2)) | ||
| 218 | return -EIO; | ||
| 219 | |||
| 220 | cache[reg] = value; | ||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Read from the da7210 register space. | ||
| 226 | */ | ||
| 227 | static inline u32 da7210_read(struct snd_soc_codec *codec, u32 reg) | ||
| 228 | { | ||
| 229 | if (DA7210_STATUS == reg) | ||
| 230 | return i2c_smbus_read_byte_data(codec->control_data, reg); | ||
| 231 | |||
| 232 | return da7210_read_reg_cache(codec, reg); | ||
| 233 | } | ||
| 234 | |||
| 235 | static int da7210_startup(struct snd_pcm_substream *substream, | ||
| 236 | struct snd_soc_dai *dai) | ||
| 237 | { | ||
| 238 | int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | ||
| 239 | struct snd_soc_codec *codec = dai->codec; | ||
| 240 | |||
| 241 | if (is_play) { | ||
| 242 | /* Enable Out */ | ||
| 243 | snd_soc_update_bits(codec, DA7210_OUTMIX_L, 0x1F, 0x10); | ||
| 244 | snd_soc_update_bits(codec, DA7210_OUTMIX_R, 0x1F, 0x10); | ||
| 245 | |||
| 246 | } else { | ||
| 247 | /* Volume 7 */ | ||
| 248 | snd_soc_update_bits(codec, DA7210_MIC_L, 0x7, 0x7); | ||
| 249 | snd_soc_update_bits(codec, DA7210_MIC_R, 0x7, 0x7); | ||
| 250 | |||
| 251 | /* Enable Mic */ | ||
| 252 | snd_soc_update_bits(codec, DA7210_INMIX_L, 0x1F, 0x1); | ||
| 253 | snd_soc_update_bits(codec, DA7210_INMIX_R, 0x1F, 0x1); | ||
| 254 | } | 593 | } |
| 255 | |||
| 256 | return 0; | ||
| 257 | } | 594 | } |
| 258 | 595 | ||
| 259 | /* | 596 | /* |
| @@ -266,93 +603,75 @@ static int da7210_hw_params(struct snd_pcm_substream *substream, | |||
| 266 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 603 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 267 | struct snd_soc_codec *codec = rtd->codec; | 604 | struct snd_soc_codec *codec = rtd->codec; |
| 268 | u32 dai_cfg1; | 605 | u32 dai_cfg1; |
| 269 | u32 hpf_reg, hpf_mask, hpf_value; | ||
| 270 | u32 fs, bypass; | 606 | u32 fs, bypass; |
| 271 | 607 | ||
| 272 | /* set DAI source to Left and Right ADC */ | 608 | /* set DAI source to Left and Right ADC */ |
| 273 | da7210_write(codec, DA7210_DAI_SRC_SEL, | 609 | snd_soc_write(codec, DA7210_DAI_SRC_SEL, |
| 274 | DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC); | 610 | DA7210_DAI_OUT_R_SRC | DA7210_DAI_OUT_L_SRC); |
| 275 | 611 | ||
| 276 | /* Enable DAI */ | 612 | /* Enable DAI */ |
| 277 | da7210_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN); | 613 | snd_soc_write(codec, DA7210_DAI_CFG3, DA7210_DAI_OE | DA7210_DAI_EN); |
| 278 | 614 | ||
| 279 | dai_cfg1 = 0xFC & da7210_read(codec, DA7210_DAI_CFG1); | 615 | dai_cfg1 = 0xFC & snd_soc_read(codec, DA7210_DAI_CFG1); |
| 280 | 616 | ||
| 281 | switch (params_format(params)) { | 617 | switch (params_format(params)) { |
| 282 | case SNDRV_PCM_FORMAT_S16_LE: | 618 | case SNDRV_PCM_FORMAT_S16_LE: |
| 283 | dai_cfg1 |= DA7210_DAI_WORD_S16_LE; | 619 | dai_cfg1 |= DA7210_DAI_WORD_S16_LE; |
| 284 | break; | 620 | break; |
| 621 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
| 622 | dai_cfg1 |= DA7210_DAI_WORD_S20_3LE; | ||
| 623 | break; | ||
| 285 | case SNDRV_PCM_FORMAT_S24_LE: | 624 | case SNDRV_PCM_FORMAT_S24_LE: |
| 286 | dai_cfg1 |= DA7210_DAI_WORD_S24_LE; | 625 | dai_cfg1 |= DA7210_DAI_WORD_S24_LE; |
| 287 | break; | 626 | break; |
| 627 | case SNDRV_PCM_FORMAT_S32_LE: | ||
| 628 | dai_cfg1 |= DA7210_DAI_WORD_S32_LE; | ||
| 629 | break; | ||
| 288 | default: | 630 | default: |
| 289 | return -EINVAL; | 631 | return -EINVAL; |
| 290 | } | 632 | } |
| 291 | 633 | ||
| 292 | da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); | 634 | snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1); |
| 293 | |||
| 294 | hpf_reg = (SNDRV_PCM_STREAM_PLAYBACK == substream->stream) ? | ||
| 295 | DA7210_DAC_HPF : DA7210_ADC_HPF; | ||
| 296 | 635 | ||
| 297 | switch (params_rate(params)) { | 636 | switch (params_rate(params)) { |
| 298 | case 8000: | 637 | case 8000: |
| 299 | fs = DA7210_PLL_FS_8000; | 638 | fs = DA7210_PLL_FS_8000; |
| 300 | hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN; | ||
| 301 | hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN; | ||
| 302 | bypass = DA7210_PLL_BYP; | 639 | bypass = DA7210_PLL_BYP; |
| 303 | break; | 640 | break; |
| 304 | case 11025: | 641 | case 11025: |
| 305 | fs = DA7210_PLL_FS_11025; | 642 | fs = DA7210_PLL_FS_11025; |
| 306 | hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN; | ||
| 307 | hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN; | ||
| 308 | bypass = 0; | 643 | bypass = 0; |
| 309 | break; | 644 | break; |
| 310 | case 12000: | 645 | case 12000: |
| 311 | fs = DA7210_PLL_FS_12000; | 646 | fs = DA7210_PLL_FS_12000; |
| 312 | hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN; | ||
| 313 | hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN; | ||
| 314 | bypass = DA7210_PLL_BYP; | 647 | bypass = DA7210_PLL_BYP; |
| 315 | break; | 648 | break; |
| 316 | case 16000: | 649 | case 16000: |
| 317 | fs = DA7210_PLL_FS_16000; | 650 | fs = DA7210_PLL_FS_16000; |
| 318 | hpf_mask = DA7210_VOICE_F0_MASK | DA7210_VOICE_EN; | ||
| 319 | hpf_value = DA7210_VOICE_F0_25 | DA7210_VOICE_EN; | ||
| 320 | bypass = DA7210_PLL_BYP; | 651 | bypass = DA7210_PLL_BYP; |
| 321 | break; | 652 | break; |
| 322 | case 22050: | 653 | case 22050: |
| 323 | fs = DA7210_PLL_FS_22050; | 654 | fs = DA7210_PLL_FS_22050; |
| 324 | hpf_mask = DA7210_VOICE_EN; | ||
| 325 | hpf_value = 0; | ||
| 326 | bypass = 0; | 655 | bypass = 0; |
| 327 | break; | 656 | break; |
| 328 | case 32000: | 657 | case 32000: |
| 329 | fs = DA7210_PLL_FS_32000; | 658 | fs = DA7210_PLL_FS_32000; |
| 330 | hpf_mask = DA7210_VOICE_EN; | ||
| 331 | hpf_value = 0; | ||
| 332 | bypass = DA7210_PLL_BYP; | 659 | bypass = DA7210_PLL_BYP; |
| 333 | break; | 660 | break; |
| 334 | case 44100: | 661 | case 44100: |
| 335 | fs = DA7210_PLL_FS_44100; | 662 | fs = DA7210_PLL_FS_44100; |
| 336 | hpf_mask = DA7210_VOICE_EN; | ||
| 337 | hpf_value = 0; | ||
| 338 | bypass = 0; | 663 | bypass = 0; |
| 339 | break; | 664 | break; |
| 340 | case 48000: | 665 | case 48000: |
| 341 | fs = DA7210_PLL_FS_48000; | 666 | fs = DA7210_PLL_FS_48000; |
| 342 | hpf_mask = DA7210_VOICE_EN; | ||
| 343 | hpf_value = 0; | ||
| 344 | bypass = DA7210_PLL_BYP; | 667 | bypass = DA7210_PLL_BYP; |
| 345 | break; | 668 | break; |
| 346 | case 88200: | 669 | case 88200: |
| 347 | fs = DA7210_PLL_FS_88200; | 670 | fs = DA7210_PLL_FS_88200; |
| 348 | hpf_mask = DA7210_VOICE_EN; | ||
| 349 | hpf_value = 0; | ||
| 350 | bypass = 0; | 671 | bypass = 0; |
| 351 | break; | 672 | break; |
| 352 | case 96000: | 673 | case 96000: |
| 353 | fs = DA7210_PLL_FS_96000; | 674 | fs = DA7210_PLL_FS_96000; |
| 354 | hpf_mask = DA7210_VOICE_EN; | ||
| 355 | hpf_value = 0; | ||
| 356 | bypass = DA7210_PLL_BYP; | 675 | bypass = DA7210_PLL_BYP; |
| 357 | break; | 676 | break; |
| 358 | default: | 677 | default: |
| @@ -362,7 +681,6 @@ static int da7210_hw_params(struct snd_pcm_substream *substream, | |||
| 362 | /* Disable active mode */ | 681 | /* Disable active mode */ |
| 363 | snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0); | 682 | snd_soc_update_bits(codec, DA7210_STARTUP1, DA7210_SC_MST_EN, 0); |
| 364 | 683 | ||
| 365 | snd_soc_update_bits(codec, hpf_reg, hpf_mask, hpf_value); | ||
| 366 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs); | 684 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_FS_MASK, fs); |
| 367 | snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass); | 685 | snd_soc_update_bits(codec, DA7210_PLL_DIV3, DA7210_PLL_BYP, bypass); |
| 368 | 686 | ||
| @@ -382,13 +700,16 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) | |||
| 382 | u32 dai_cfg1; | 700 | u32 dai_cfg1; |
| 383 | u32 dai_cfg3; | 701 | u32 dai_cfg3; |
| 384 | 702 | ||
| 385 | dai_cfg1 = 0x7f & da7210_read(codec, DA7210_DAI_CFG1); | 703 | dai_cfg1 = 0x7f & snd_soc_read(codec, DA7210_DAI_CFG1); |
| 386 | dai_cfg3 = 0xfc & da7210_read(codec, DA7210_DAI_CFG3); | 704 | dai_cfg3 = 0xfc & snd_soc_read(codec, DA7210_DAI_CFG3); |
| 387 | 705 | ||
| 388 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 706 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| 389 | case SND_SOC_DAIFMT_CBM_CFM: | 707 | case SND_SOC_DAIFMT_CBM_CFM: |
| 390 | dai_cfg1 |= DA7210_DAI_MODE_MASTER; | 708 | dai_cfg1 |= DA7210_DAI_MODE_MASTER; |
| 391 | break; | 709 | break; |
| 710 | case SND_SOC_DAIFMT_CBS_CFS: | ||
| 711 | dai_cfg1 |= DA7210_DAI_MODE_SLAVE; | ||
| 712 | break; | ||
| 392 | default: | 713 | default: |
| 393 | return -EINVAL; | 714 | return -EINVAL; |
| 394 | } | 715 | } |
| @@ -401,6 +722,12 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) | |||
| 401 | case SND_SOC_DAIFMT_I2S: | 722 | case SND_SOC_DAIFMT_I2S: |
| 402 | dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE; | 723 | dai_cfg3 |= DA7210_DAI_FORMAT_I2SMODE; |
| 403 | break; | 724 | break; |
| 725 | case SND_SOC_DAIFMT_LEFT_J: | ||
| 726 | dai_cfg3 |= DA7210_DAI_FORMAT_LEFT_J; | ||
| 727 | break; | ||
| 728 | case SND_SOC_DAIFMT_RIGHT_J: | ||
| 729 | dai_cfg3 |= DA7210_DAI_FORMAT_RIGHT_J; | ||
| 730 | break; | ||
| 404 | default: | 731 | default: |
| 405 | return -EINVAL; | 732 | return -EINVAL; |
| 406 | } | 733 | } |
| @@ -411,19 +738,32 @@ static int da7210_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) | |||
| 411 | */ | 738 | */ |
| 412 | dai_cfg1 |= DA7210_DAI_FLEN_64BIT; | 739 | dai_cfg1 |= DA7210_DAI_FLEN_64BIT; |
| 413 | 740 | ||
| 414 | da7210_write(codec, DA7210_DAI_CFG1, dai_cfg1); | 741 | snd_soc_write(codec, DA7210_DAI_CFG1, dai_cfg1); |
| 415 | da7210_write(codec, DA7210_DAI_CFG3, dai_cfg3); | 742 | snd_soc_write(codec, DA7210_DAI_CFG3, dai_cfg3); |
| 743 | |||
| 744 | return 0; | ||
| 745 | } | ||
| 746 | |||
| 747 | static int da7210_mute(struct snd_soc_dai *dai, int mute) | ||
| 748 | { | ||
| 749 | struct snd_soc_codec *codec = dai->codec; | ||
| 750 | u8 mute_reg = snd_soc_read(codec, DA7210_DAC_HPF) & 0xFB; | ||
| 416 | 751 | ||
| 752 | if (mute) | ||
| 753 | snd_soc_write(codec, DA7210_DAC_HPF, mute_reg | 0x4); | ||
| 754 | else | ||
| 755 | snd_soc_write(codec, DA7210_DAC_HPF, mute_reg); | ||
| 417 | return 0; | 756 | return 0; |
| 418 | } | 757 | } |
| 419 | 758 | ||
| 420 | #define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) | 759 | #define DA7210_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 760 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
| 421 | 761 | ||
| 422 | /* DAI operations */ | 762 | /* DAI operations */ |
| 423 | static struct snd_soc_dai_ops da7210_dai_ops = { | 763 | static struct snd_soc_dai_ops da7210_dai_ops = { |
| 424 | .startup = da7210_startup, | ||
| 425 | .hw_params = da7210_hw_params, | 764 | .hw_params = da7210_hw_params, |
| 426 | .set_fmt = da7210_set_dai_fmt, | 765 | .set_fmt = da7210_set_dai_fmt, |
| 766 | .digital_mute = da7210_mute, | ||
| 427 | }; | 767 | }; |
| 428 | 768 | ||
| 429 | static struct snd_soc_dai_driver da7210_dai = { | 769 | static struct snd_soc_dai_driver da7210_dai = { |
| @@ -451,11 +791,15 @@ static struct snd_soc_dai_driver da7210_dai = { | |||
| 451 | static int da7210_probe(struct snd_soc_codec *codec) | 791 | static int da7210_probe(struct snd_soc_codec *codec) |
| 452 | { | 792 | { |
| 453 | struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec); | 793 | struct da7210_priv *da7210 = snd_soc_codec_get_drvdata(codec); |
| 794 | int ret; | ||
| 454 | 795 | ||
| 455 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); | 796 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); |
| 456 | 797 | ||
| 457 | codec->control_data = da7210->control_data; | 798 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, da7210->control_type); |
| 458 | codec->hw_write = (hw_write_t)i2c_master_send; | 799 | if (ret < 0) { |
| 800 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
| 801 | return ret; | ||
| 802 | } | ||
| 459 | 803 | ||
| 460 | /* FIXME | 804 | /* FIXME |
| 461 | * | 805 | * |
| @@ -472,8 +816,8 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
| 472 | /* | 816 | /* |
| 473 | * make sure that DA7210 use bypass mode before start up | 817 | * make sure that DA7210 use bypass mode before start up |
| 474 | */ | 818 | */ |
| 475 | da7210_write(codec, DA7210_STARTUP1, 0); | 819 | snd_soc_write(codec, DA7210_STARTUP1, 0); |
| 476 | da7210_write(codec, DA7210_PLL_DIV3, | 820 | snd_soc_write(codec, DA7210_PLL_DIV3, |
| 477 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); | 821 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); |
| 478 | 822 | ||
| 479 | /* | 823 | /* |
| @@ -481,36 +825,70 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
| 481 | */ | 825 | */ |
| 482 | 826 | ||
| 483 | /* Enable Left & Right MIC PGA and Mic Bias */ | 827 | /* Enable Left & Right MIC PGA and Mic Bias */ |
| 484 | da7210_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN); | 828 | snd_soc_write(codec, DA7210_MIC_L, DA7210_MIC_L_EN | DA7210_MICBIAS_EN); |
| 485 | da7210_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN); | 829 | snd_soc_write(codec, DA7210_MIC_R, DA7210_MIC_R_EN); |
| 486 | 830 | ||
| 487 | /* Enable Left and Right input PGA */ | 831 | /* Enable Left and Right input PGA */ |
| 488 | da7210_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN); | 832 | snd_soc_write(codec, DA7210_INMIX_L, DA7210_IN_L_EN); |
| 489 | da7210_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN); | 833 | snd_soc_write(codec, DA7210_INMIX_R, DA7210_IN_R_EN); |
| 490 | 834 | ||
| 491 | /* Enable Left and Right ADC */ | 835 | /* Enable Left and Right ADC */ |
| 492 | da7210_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN); | 836 | snd_soc_write(codec, DA7210_ADC, DA7210_ADC_L_EN | DA7210_ADC_R_EN); |
| 493 | 837 | ||
| 494 | /* | 838 | /* |
| 495 | * DAC settings | 839 | * DAC settings |
| 496 | */ | 840 | */ |
| 497 | 841 | ||
| 498 | /* Enable Left and Right DAC */ | 842 | /* Enable Left and Right DAC */ |
| 499 | da7210_write(codec, DA7210_DAC_SEL, | 843 | snd_soc_write(codec, DA7210_DAC_SEL, |
| 500 | DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN | | 844 | DA7210_DAC_L_SRC_DAI_L | DA7210_DAC_L_EN | |
| 501 | DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN); | 845 | DA7210_DAC_R_SRC_DAI_R | DA7210_DAC_R_EN); |
| 502 | 846 | ||
| 503 | /* Enable Left and Right out PGA */ | 847 | /* Enable Left and Right out PGA */ |
| 504 | da7210_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN); | 848 | snd_soc_write(codec, DA7210_OUTMIX_L, DA7210_OUT_L_EN); |
| 505 | da7210_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN); | 849 | snd_soc_write(codec, DA7210_OUTMIX_R, DA7210_OUT_R_EN); |
| 506 | 850 | ||
| 507 | /* Enable Left and Right HeadPhone PGA */ | 851 | /* Enable Left and Right HeadPhone PGA */ |
| 508 | da7210_write(codec, DA7210_HP_CFG, | 852 | snd_soc_write(codec, DA7210_HP_CFG, |
| 509 | DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN | | 853 | DA7210_HP_2CAP_MODE | DA7210_HP_SENSE_EN | |
| 510 | DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN); | 854 | DA7210_HP_L_EN | DA7210_HP_MODE | DA7210_HP_R_EN); |
| 511 | 855 | ||
| 856 | /* Enable ramp mode for DAC gain update */ | ||
| 857 | snd_soc_write(codec, DA7210_SOFTMUTE, DA7210_RAMP_EN); | ||
| 858 | |||
| 859 | /* | ||
| 860 | * For DA7210 codec, there are two ways to enable/disable analog IOs | ||
| 861 | * and ADC/DAC, | ||
| 862 | * (1) Using "Enable Bit" of register associated with that IO | ||
| 863 | * (or ADC/DAC) | ||
| 864 | * e.g. Mic Left can be enabled using bit 7 of MIC_L(0x7) reg | ||
| 865 | * | ||
| 866 | * (2) Using "Standby Bit" of STARTUP2 or STARTUP3 register | ||
| 867 | * e.g. Mic left can be put to STANDBY using bit 0 of STARTUP3(0x5) | ||
| 868 | * | ||
| 869 | * Out of these two methods, the one using STANDBY bits is preferred | ||
| 870 | * way to enable/disable individual blocks. This is because STANDBY | ||
| 871 | * registers are part of system controller which allows system power | ||
| 872 | * up/down in a controlled, pop-free manner. Also, as per application | ||
| 873 | * note of DA7210, STANDBY register bits are only effective if a | ||
| 874 | * particular IO (or ADC/DAC) is already enabled using enable/disable | ||
| 875 | * register bits. Keeping these things in mind, current DAPM | ||
| 876 | * implementation manipulates only STANDBY bits. | ||
| 877 | * | ||
| 878 | * Overall implementation can be outlined as below, | ||
| 879 | * | ||
| 880 | * - "Enable bit" of an IO or ADC/DAC is used to enable it in probe() | ||
| 881 | * - "STANDBY bit" is controlled by DAPM | ||
| 882 | */ | ||
| 883 | |||
| 884 | /* Enable Line out amplifiers */ | ||
| 885 | snd_soc_write(codec, DA7210_OUT1_L, DA7210_OUT1_L_EN); | ||
| 886 | snd_soc_write(codec, DA7210_OUT1_R, DA7210_OUT1_R_EN); | ||
| 887 | snd_soc_write(codec, DA7210_OUT2, DA7210_OUT2_EN | | ||
| 888 | DA7210_OUT2_OUTMIX_L | DA7210_OUT2_OUTMIX_R); | ||
| 889 | |||
| 512 | /* Diable PLL and bypass it */ | 890 | /* Diable PLL and bypass it */ |
| 513 | da7210_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); | 891 | snd_soc_write(codec, DA7210_PLL, DA7210_PLL_FS_48000); |
| 514 | 892 | ||
| 515 | /* | 893 | /* |
| 516 | * If 48kHz sound came, it use bypass mode, | 894 | * If 48kHz sound came, it use bypass mode, |
| @@ -521,25 +899,22 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
| 521 | * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit. | 899 | * DA7210_PLL_DIV3 :: DA7210_PLL_BYP bit. |
| 522 | * see da7210_hw_params | 900 | * see da7210_hw_params |
| 523 | */ | 901 | */ |
| 524 | da7210_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */ | 902 | snd_soc_write(codec, DA7210_PLL_DIV1, 0xE5); /* MCLK = 12.288MHz */ |
| 525 | da7210_write(codec, DA7210_PLL_DIV2, 0x99); | 903 | snd_soc_write(codec, DA7210_PLL_DIV2, 0x99); |
| 526 | da7210_write(codec, DA7210_PLL_DIV3, 0x0A | | 904 | snd_soc_write(codec, DA7210_PLL_DIV3, 0x0A | |
| 527 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); | 905 | DA7210_MCLK_RANGE_10_20_MHZ | DA7210_PLL_BYP); |
| 528 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); | 906 | snd_soc_update_bits(codec, DA7210_PLL, DA7210_PLL_EN, DA7210_PLL_EN); |
| 529 | 907 | ||
| 530 | /* As suggested by Dialog */ | 908 | /* As suggested by Dialog */ |
| 531 | da7210_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ | 909 | snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x8B); /* unlock */ |
| 532 | da7210_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); | 910 | snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0xB4); |
| 533 | da7210_write(codec, DA7210_A_PLL1, 0x01); | 911 | snd_soc_write(codec, DA7210_A_PLL1, 0x01); |
| 534 | da7210_write(codec, DA7210_A_CP_MODE, 0x7C); | 912 | snd_soc_write(codec, DA7210_A_CP_MODE, 0x7C); |
| 535 | da7210_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ | 913 | snd_soc_write(codec, DA7210_A_HID_UNLOCK, 0x00); /* re-lock */ |
| 536 | da7210_write(codec, DA7210_A_TEST_UNLOCK, 0x00); | 914 | snd_soc_write(codec, DA7210_A_TEST_UNLOCK, 0x00); |
| 537 | 915 | ||
| 538 | /* Activate all enabled subsystem */ | 916 | /* Activate all enabled subsystem */ |
| 539 | da7210_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); | 917 | snd_soc_write(codec, DA7210_STARTUP1, DA7210_SC_MST_EN); |
| 540 | |||
| 541 | snd_soc_add_controls(codec, da7210_snd_controls, | ||
| 542 | ARRAY_SIZE(da7210_snd_controls)); | ||
| 543 | 918 | ||
| 544 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); | 919 | dev_info(codec->dev, "DA7210 Audio Codec %s\n", DA7210_VERSION); |
| 545 | 920 | ||
| @@ -548,11 +923,18 @@ static int da7210_probe(struct snd_soc_codec *codec) | |||
| 548 | 923 | ||
| 549 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { | 924 | static struct snd_soc_codec_driver soc_codec_dev_da7210 = { |
| 550 | .probe = da7210_probe, | 925 | .probe = da7210_probe, |
| 551 | .read = da7210_read, | ||
| 552 | .write = da7210_write, | ||
| 553 | .reg_cache_size = ARRAY_SIZE(da7210_reg), | 926 | .reg_cache_size = ARRAY_SIZE(da7210_reg), |
| 554 | .reg_word_size = sizeof(u8), | 927 | .reg_word_size = sizeof(u8), |
| 555 | .reg_cache_default = da7210_reg, | 928 | .reg_cache_default = da7210_reg, |
| 929 | .volatile_register = da7210_volatile_register, | ||
| 930 | |||
| 931 | .controls = da7210_snd_controls, | ||
| 932 | .num_controls = ARRAY_SIZE(da7210_snd_controls), | ||
| 933 | |||
| 934 | .dapm_widgets = da7210_dapm_widgets, | ||
| 935 | .num_dapm_widgets = ARRAY_SIZE(da7210_dapm_widgets), | ||
| 936 | .dapm_routes = da7210_audio_map, | ||
| 937 | .num_dapm_routes = ARRAY_SIZE(da7210_audio_map), | ||
| 556 | }; | 938 | }; |
| 557 | 939 | ||
| 558 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 940 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| @@ -567,7 +949,6 @@ static int __devinit da7210_i2c_probe(struct i2c_client *i2c, | |||
| 567 | return -ENOMEM; | 949 | return -ENOMEM; |
| 568 | 950 | ||
| 569 | i2c_set_clientdata(i2c, da7210); | 951 | i2c_set_clientdata(i2c, da7210); |
| 570 | da7210->control_data = i2c; | ||
| 571 | da7210->control_type = SND_SOC_I2C; | 952 | da7210->control_type = SND_SOC_I2C; |
| 572 | 953 | ||
| 573 | ret = snd_soc_register_codec(&i2c->dev, | 954 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/lm4857.c b/sound/soc/codecs/lm4857.c index 2c2a681da0d7..c387dafc6ab6 100644 --- a/sound/soc/codecs/lm4857.c +++ b/sound/soc/codecs/lm4857.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright 2007 Wolfson Microelectronics PLC. | 4 | * Copyright 2007 Wolfson Microelectronics PLC. |
| 5 | * Author: Graeme Gregory | 5 | * Author: Graeme Gregory |
| 6 | * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com | 6 | * graeme.gregory@wolfsonmicro.com |
| 7 | * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> | 7 | * Copyright 2011 Lars-Peter Clausen <lars@metafoo.de> |
| 8 | * | 8 | * |
| 9 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index ac65a2d36408..ebbf63c79c34 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
| @@ -40,7 +40,6 @@ struct max98088_cdata { | |||
| 40 | 40 | ||
| 41 | struct max98088_priv { | 41 | struct max98088_priv { |
| 42 | enum max98088_type devtype; | 42 | enum max98088_type devtype; |
| 43 | void *control_data; | ||
| 44 | struct max98088_pdata *pdata; | 43 | struct max98088_pdata *pdata; |
| 45 | unsigned int sysclk; | 44 | unsigned int sysclk; |
| 46 | struct max98088_cdata dai[2]; | 45 | struct max98088_cdata dai[2]; |
| @@ -1697,13 +1696,19 @@ static struct snd_soc_dai_driver max98088_dai[] = { | |||
| 1697 | } | 1696 | } |
| 1698 | }; | 1697 | }; |
| 1699 | 1698 | ||
| 1700 | static int max98088_get_channel(const char *name) | 1699 | static const char *eq_mode_name[] = {"EQ1 Mode", "EQ2 Mode"}; |
| 1700 | |||
| 1701 | static int max98088_get_channel(struct snd_soc_codec *codec, const char *name) | ||
| 1701 | { | 1702 | { |
| 1702 | if (strcmp(name, "EQ1 Mode") == 0) | 1703 | int i; |
| 1703 | return 0; | 1704 | |
| 1704 | if (strcmp(name, "EQ2 Mode") == 0) | 1705 | for (i = 0; i < ARRAY_SIZE(eq_mode_name); i++) |
| 1705 | return 1; | 1706 | if (strcmp(name, eq_mode_name[i]) == 0) |
| 1706 | return -EINVAL; | 1707 | return i; |
| 1708 | |||
| 1709 | /* Shouldn't happen */ | ||
| 1710 | dev_err(codec->dev, "Bad EQ channel name '%s'\n", name); | ||
| 1711 | return -EINVAL; | ||
| 1707 | } | 1712 | } |
| 1708 | 1713 | ||
| 1709 | static void max98088_setup_eq1(struct snd_soc_codec *codec) | 1714 | static void max98088_setup_eq1(struct snd_soc_codec *codec) |
| @@ -1807,10 +1812,13 @@ static int max98088_put_eq_enum(struct snd_kcontrol *kcontrol, | |||
| 1807 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1812 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 1808 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 1813 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
| 1809 | struct max98088_pdata *pdata = max98088->pdata; | 1814 | struct max98088_pdata *pdata = max98088->pdata; |
| 1810 | int channel = max98088_get_channel(kcontrol->id.name); | 1815 | int channel = max98088_get_channel(codec, kcontrol->id.name); |
| 1811 | struct max98088_cdata *cdata; | 1816 | struct max98088_cdata *cdata; |
| 1812 | int sel = ucontrol->value.integer.value[0]; | 1817 | int sel = ucontrol->value.integer.value[0]; |
| 1813 | 1818 | ||
| 1819 | if (channel < 0) | ||
| 1820 | return channel; | ||
| 1821 | |||
| 1814 | cdata = &max98088->dai[channel]; | 1822 | cdata = &max98088->dai[channel]; |
| 1815 | 1823 | ||
| 1816 | if (sel >= pdata->eq_cfgcnt) | 1824 | if (sel >= pdata->eq_cfgcnt) |
| @@ -1835,9 +1843,12 @@ static int max98088_get_eq_enum(struct snd_kcontrol *kcontrol, | |||
| 1835 | { | 1843 | { |
| 1836 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1844 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 1837 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 1845 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); |
| 1838 | int channel = max98088_get_channel(kcontrol->id.name); | 1846 | int channel = max98088_get_channel(codec, kcontrol->id.name); |
| 1839 | struct max98088_cdata *cdata; | 1847 | struct max98088_cdata *cdata; |
| 1840 | 1848 | ||
| 1849 | if (channel < 0) | ||
| 1850 | return channel; | ||
| 1851 | |||
| 1841 | cdata = &max98088->dai[channel]; | 1852 | cdata = &max98088->dai[channel]; |
| 1842 | ucontrol->value.enumerated.item[0] = cdata->eq_sel; | 1853 | ucontrol->value.enumerated.item[0] = cdata->eq_sel; |
| 1843 | return 0; | 1854 | return 0; |
| @@ -1852,17 +1863,17 @@ static void max98088_handle_eq_pdata(struct snd_soc_codec *codec) | |||
| 1852 | int i, j; | 1863 | int i, j; |
| 1853 | const char **t; | 1864 | const char **t; |
| 1854 | int ret; | 1865 | int ret; |
| 1855 | |||
| 1856 | struct snd_kcontrol_new controls[] = { | 1866 | struct snd_kcontrol_new controls[] = { |
| 1857 | SOC_ENUM_EXT("EQ1 Mode", | 1867 | SOC_ENUM_EXT((char *)eq_mode_name[0], |
| 1858 | max98088->eq_enum, | 1868 | max98088->eq_enum, |
| 1859 | max98088_get_eq_enum, | 1869 | max98088_get_eq_enum, |
| 1860 | max98088_put_eq_enum), | 1870 | max98088_put_eq_enum), |
| 1861 | SOC_ENUM_EXT("EQ2 Mode", | 1871 | SOC_ENUM_EXT((char *)eq_mode_name[1], |
| 1862 | max98088->eq_enum, | 1872 | max98088->eq_enum, |
| 1863 | max98088_get_eq_enum, | 1873 | max98088_get_eq_enum, |
| 1864 | max98088_put_eq_enum), | 1874 | max98088_put_eq_enum), |
| 1865 | }; | 1875 | }; |
| 1876 | BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(eq_mode_name)); | ||
| 1866 | 1877 | ||
| 1867 | cfg = pdata->eq_cfg; | 1878 | cfg = pdata->eq_cfg; |
| 1868 | cfgcnt = pdata->eq_cfgcnt; | 1879 | cfgcnt = pdata->eq_cfgcnt; |
| @@ -2066,7 +2077,6 @@ static int max98088_i2c_probe(struct i2c_client *i2c, | |||
| 2066 | max98088->devtype = id->driver_data; | 2077 | max98088->devtype = id->driver_data; |
| 2067 | 2078 | ||
| 2068 | i2c_set_clientdata(i2c, max98088); | 2079 | i2c_set_clientdata(i2c, max98088); |
| 2069 | max98088->control_data = i2c; | ||
| 2070 | max98088->pdata = i2c->dev.platform_data; | 2080 | max98088->pdata = i2c->dev.platform_data; |
| 2071 | 2081 | ||
| 2072 | ret = snd_soc_register_codec(&i2c->dev, | 2082 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c index 668434d44303..26d7b089fb9c 100644 --- a/sound/soc/codecs/max98095.c +++ b/sound/soc/codecs/max98095.c | |||
| @@ -40,7 +40,6 @@ struct max98095_cdata { | |||
| 40 | 40 | ||
| 41 | struct max98095_priv { | 41 | struct max98095_priv { |
| 42 | enum max98095_type devtype; | 42 | enum max98095_type devtype; |
| 43 | void *control_data; | ||
| 44 | struct max98095_pdata *pdata; | 43 | struct max98095_pdata *pdata; |
| 45 | unsigned int sysclk; | 44 | unsigned int sysclk; |
| 46 | struct max98095_cdata dai[3]; | 45 | struct max98095_cdata dai[3]; |
| @@ -618,14 +617,13 @@ static int max98095_volatile(struct snd_soc_codec *codec, unsigned int reg) | |||
| 618 | static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg, | 617 | static int max98095_hw_write(struct snd_soc_codec *codec, unsigned int reg, |
| 619 | unsigned int value) | 618 | unsigned int value) |
| 620 | { | 619 | { |
| 621 | u8 data[2]; | 620 | int ret; |
| 622 | 621 | ||
| 623 | data[0] = reg; | 622 | codec->cache_bypass = 1; |
| 624 | data[1] = value; | 623 | ret = snd_soc_write(codec, reg, value); |
| 625 | if (codec->hw_write(codec->control_data, data, 2) == 2) | 624 | codec->cache_bypass = 0; |
| 626 | return 0; | 625 | |
| 627 | else | 626 | return ret ? -EIO : 0; |
| 628 | return -EIO; | ||
| 629 | } | 627 | } |
| 630 | 628 | ||
| 631 | /* | 629 | /* |
| @@ -1992,12 +1990,19 @@ static void max98095_handle_eq_pdata(struct snd_soc_codec *codec) | |||
| 1992 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); | 1990 | dev_err(codec->dev, "Failed to add EQ control: %d\n", ret); |
| 1993 | } | 1991 | } |
| 1994 | 1992 | ||
| 1995 | static int max98095_get_bq_channel(const char *name) | 1993 | static const char *bq_mode_name[] = {"Biquad1 Mode", "Biquad2 Mode"}; |
| 1994 | |||
| 1995 | static int max98095_get_bq_channel(struct snd_soc_codec *codec, | ||
| 1996 | const char *name) | ||
| 1996 | { | 1997 | { |
| 1997 | if (strcmp(name, "Biquad1 Mode") == 0) | 1998 | int i; |
| 1998 | return 0; | 1999 | |
| 1999 | if (strcmp(name, "Biquad2 Mode") == 0) | 2000 | for (i = 0; i < ARRAY_SIZE(bq_mode_name); i++) |
| 2000 | return 1; | 2001 | if (strcmp(name, bq_mode_name[i]) == 0) |
| 2002 | return i; | ||
| 2003 | |||
| 2004 | /* Shouldn't happen */ | ||
| 2005 | dev_err(codec->dev, "Bad biquad channel name '%s'\n", name); | ||
| 2001 | return -EINVAL; | 2006 | return -EINVAL; |
| 2002 | } | 2007 | } |
| 2003 | 2008 | ||
| @@ -2007,14 +2012,15 @@ static int max98095_put_bq_enum(struct snd_kcontrol *kcontrol, | |||
| 2007 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2012 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 2008 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 2013 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
| 2009 | struct max98095_pdata *pdata = max98095->pdata; | 2014 | struct max98095_pdata *pdata = max98095->pdata; |
| 2010 | int channel = max98095_get_bq_channel(kcontrol->id.name); | 2015 | int channel = max98095_get_bq_channel(codec, kcontrol->id.name); |
| 2011 | struct max98095_cdata *cdata; | 2016 | struct max98095_cdata *cdata; |
| 2012 | int sel = ucontrol->value.integer.value[0]; | 2017 | int sel = ucontrol->value.integer.value[0]; |
| 2013 | struct max98095_biquad_cfg *coef_set; | 2018 | struct max98095_biquad_cfg *coef_set; |
| 2014 | int fs, best, best_val, i; | 2019 | int fs, best, best_val, i; |
| 2015 | int regmask, regsave; | 2020 | int regmask, regsave; |
| 2016 | 2021 | ||
| 2017 | BUG_ON(channel > 1); | 2022 | if (channel < 0) |
| 2023 | return channel; | ||
| 2018 | 2024 | ||
| 2019 | if (!pdata || !max98095->bq_textcnt) | 2025 | if (!pdata || !max98095->bq_textcnt) |
| 2020 | return 0; | 2026 | return 0; |
| @@ -2066,9 +2072,12 @@ static int max98095_get_bq_enum(struct snd_kcontrol *kcontrol, | |||
| 2066 | { | 2072 | { |
| 2067 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2073 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 2068 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); | 2074 | struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); |
| 2069 | int channel = max98095_get_bq_channel(kcontrol->id.name); | 2075 | int channel = max98095_get_bq_channel(codec, kcontrol->id.name); |
| 2070 | struct max98095_cdata *cdata; | 2076 | struct max98095_cdata *cdata; |
| 2071 | 2077 | ||
| 2078 | if (channel < 0) | ||
| 2079 | return channel; | ||
| 2080 | |||
| 2072 | cdata = &max98095->dai[channel]; | 2081 | cdata = &max98095->dai[channel]; |
| 2073 | ucontrol->value.enumerated.item[0] = cdata->bq_sel; | 2082 | ucontrol->value.enumerated.item[0] = cdata->bq_sel; |
| 2074 | 2083 | ||
| @@ -2086,15 +2095,16 @@ static void max98095_handle_bq_pdata(struct snd_soc_codec *codec) | |||
| 2086 | int ret; | 2095 | int ret; |
| 2087 | 2096 | ||
| 2088 | struct snd_kcontrol_new controls[] = { | 2097 | struct snd_kcontrol_new controls[] = { |
| 2089 | SOC_ENUM_EXT("Biquad1 Mode", | 2098 | SOC_ENUM_EXT((char *)bq_mode_name[0], |
| 2090 | max98095->bq_enum, | 2099 | max98095->bq_enum, |
| 2091 | max98095_get_bq_enum, | 2100 | max98095_get_bq_enum, |
| 2092 | max98095_put_bq_enum), | 2101 | max98095_put_bq_enum), |
| 2093 | SOC_ENUM_EXT("Biquad2 Mode", | 2102 | SOC_ENUM_EXT((char *)bq_mode_name[1], |
| 2094 | max98095->bq_enum, | 2103 | max98095->bq_enum, |
| 2095 | max98095_get_bq_enum, | 2104 | max98095_get_bq_enum, |
| 2096 | max98095_put_bq_enum), | 2105 | max98095_put_bq_enum), |
| 2097 | }; | 2106 | }; |
| 2107 | BUILD_BUG_ON(ARRAY_SIZE(controls) != ARRAY_SIZE(bq_mode_name)); | ||
| 2098 | 2108 | ||
| 2099 | cfg = pdata->bq_cfg; | 2109 | cfg = pdata->bq_cfg; |
| 2100 | cfgcnt = pdata->bq_cfgcnt; | 2110 | cfgcnt = pdata->bq_cfgcnt; |
| @@ -2337,7 +2347,6 @@ static int max98095_i2c_probe(struct i2c_client *i2c, | |||
| 2337 | 2347 | ||
| 2338 | max98095->devtype = id->driver_data; | 2348 | max98095->devtype = id->driver_data; |
| 2339 | i2c_set_clientdata(i2c, max98095); | 2349 | i2c_set_clientdata(i2c, max98095); |
| 2340 | max98095->control_data = i2c; | ||
| 2341 | max98095->pdata = i2c->dev.platform_data; | 2350 | max98095->pdata = i2c->dev.platform_data; |
| 2342 | 2351 | ||
| 2343 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095, | 2352 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98095, |
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c new file mode 100644 index 000000000000..27a078cbb6eb --- /dev/null +++ b/sound/soc/codecs/rt5631.c | |||
| @@ -0,0 +1,1773 @@ | |||
| 1 | /* | ||
| 2 | * rt5631.c -- RT5631 ALSA Soc Audio driver | ||
| 3 | * | ||
| 4 | * Copyright 2011 Realtek Microelectronics | ||
| 5 | * | ||
| 6 | * Author: flove <flove@realtek.com> | ||
| 7 | * | ||
| 8 | * Based on WM8753.c | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License version 2 as | ||
| 12 | * published by the Free Software Foundation. | ||
| 13 | * | ||
| 14 | */ | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/moduleparam.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/delay.h> | ||
| 19 | #include <linux/pm.h> | ||
| 20 | #include <linux/i2c.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/spi/spi.h> | ||
| 23 | #include <sound/core.h> | ||
| 24 | #include <sound/pcm.h> | ||
| 25 | #include <sound/pcm_params.h> | ||
| 26 | #include <sound/soc.h> | ||
| 27 | #include <sound/soc-dapm.h> | ||
| 28 | #include <sound/initval.h> | ||
| 29 | #include <sound/tlv.h> | ||
| 30 | |||
| 31 | #include "rt5631.h" | ||
| 32 | |||
| 33 | struct rt5631_priv { | ||
| 34 | int codec_version; | ||
| 35 | int master; | ||
| 36 | int sysclk; | ||
| 37 | int rx_rate; | ||
| 38 | int bclk_rate; | ||
| 39 | int dmic_used_flag; | ||
| 40 | }; | ||
| 41 | |||
| 42 | static const u16 rt5631_reg[RT5631_VENDOR_ID2 + 1] = { | ||
| 43 | [RT5631_SPK_OUT_VOL] = 0x8888, | ||
| 44 | [RT5631_HP_OUT_VOL] = 0x8080, | ||
| 45 | [RT5631_MONO_AXO_1_2_VOL] = 0xa080, | ||
| 46 | [RT5631_AUX_IN_VOL] = 0x0808, | ||
| 47 | [RT5631_ADC_REC_MIXER] = 0xf0f0, | ||
| 48 | [RT5631_VDAC_DIG_VOL] = 0x0010, | ||
| 49 | [RT5631_OUTMIXER_L_CTRL] = 0xffc0, | ||
| 50 | [RT5631_OUTMIXER_R_CTRL] = 0xffc0, | ||
| 51 | [RT5631_AXO1MIXER_CTRL] = 0x88c0, | ||
| 52 | [RT5631_AXO2MIXER_CTRL] = 0x88c0, | ||
| 53 | [RT5631_DIG_MIC_CTRL] = 0x3000, | ||
| 54 | [RT5631_MONO_INPUT_VOL] = 0x8808, | ||
| 55 | [RT5631_SPK_MIXER_CTRL] = 0xf8f8, | ||
| 56 | [RT5631_SPK_MONO_OUT_CTRL] = 0xfc00, | ||
| 57 | [RT5631_SPK_MONO_HP_OUT_CTRL] = 0x4440, | ||
| 58 | [RT5631_SDP_CTRL] = 0x8000, | ||
| 59 | [RT5631_MONO_SDP_CTRL] = 0x8000, | ||
| 60 | [RT5631_STEREO_AD_DA_CLK_CTRL] = 0x2010, | ||
| 61 | [RT5631_GEN_PUR_CTRL_REG] = 0x0e00, | ||
| 62 | [RT5631_INT_ST_IRQ_CTRL_2] = 0x071a, | ||
| 63 | [RT5631_MISC_CTRL] = 0x2040, | ||
| 64 | [RT5631_DEPOP_FUN_CTRL_2] = 0x8000, | ||
| 65 | [RT5631_SOFT_VOL_CTRL] = 0x07e0, | ||
| 66 | [RT5631_ALC_CTRL_1] = 0x0206, | ||
| 67 | [RT5631_ALC_CTRL_3] = 0x2000, | ||
| 68 | [RT5631_PSEUDO_SPATL_CTRL] = 0x0553, | ||
| 69 | }; | ||
| 70 | |||
| 71 | /** | ||
| 72 | * rt5631_write_index - write index register of 2nd layer | ||
| 73 | */ | ||
| 74 | static void rt5631_write_index(struct snd_soc_codec *codec, | ||
| 75 | unsigned int reg, unsigned int value) | ||
| 76 | { | ||
| 77 | snd_soc_write(codec, RT5631_INDEX_ADD, reg); | ||
| 78 | snd_soc_write(codec, RT5631_INDEX_DATA, value); | ||
| 79 | } | ||
| 80 | |||
| 81 | /** | ||
| 82 | * rt5631_read_index - read index register of 2nd layer | ||
| 83 | */ | ||
| 84 | static unsigned int rt5631_read_index(struct snd_soc_codec *codec, | ||
| 85 | unsigned int reg) | ||
| 86 | { | ||
| 87 | unsigned int value; | ||
| 88 | |||
| 89 | snd_soc_write(codec, RT5631_INDEX_ADD, reg); | ||
| 90 | value = snd_soc_read(codec, RT5631_INDEX_DATA); | ||
| 91 | |||
| 92 | return value; | ||
| 93 | } | ||
| 94 | |||
| 95 | static int rt5631_reset(struct snd_soc_codec *codec) | ||
| 96 | { | ||
| 97 | return snd_soc_write(codec, RT5631_RESET, 0); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int rt5631_volatile_register(struct snd_soc_codec *codec, | ||
| 101 | unsigned int reg) | ||
| 102 | { | ||
| 103 | switch (reg) { | ||
| 104 | case RT5631_RESET: | ||
| 105 | case RT5631_INT_ST_IRQ_CTRL_2: | ||
| 106 | case RT5631_INDEX_ADD: | ||
| 107 | case RT5631_INDEX_DATA: | ||
| 108 | case RT5631_EQ_CTRL: | ||
| 109 | return 1; | ||
| 110 | default: | ||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | static int rt5631_readable_register(struct snd_soc_codec *codec, | ||
| 116 | unsigned int reg) | ||
| 117 | { | ||
| 118 | switch (reg) { | ||
| 119 | case RT5631_RESET: | ||
| 120 | case RT5631_SPK_OUT_VOL: | ||
| 121 | case RT5631_HP_OUT_VOL: | ||
| 122 | case RT5631_MONO_AXO_1_2_VOL: | ||
| 123 | case RT5631_AUX_IN_VOL: | ||
| 124 | case RT5631_STEREO_DAC_VOL_1: | ||
| 125 | case RT5631_MIC_CTRL_1: | ||
| 126 | case RT5631_STEREO_DAC_VOL_2: | ||
| 127 | case RT5631_ADC_CTRL_1: | ||
| 128 | case RT5631_ADC_REC_MIXER: | ||
| 129 | case RT5631_ADC_CTRL_2: | ||
| 130 | case RT5631_VDAC_DIG_VOL: | ||
| 131 | case RT5631_OUTMIXER_L_CTRL: | ||
| 132 | case RT5631_OUTMIXER_R_CTRL: | ||
| 133 | case RT5631_AXO1MIXER_CTRL: | ||
| 134 | case RT5631_AXO2MIXER_CTRL: | ||
| 135 | case RT5631_MIC_CTRL_2: | ||
| 136 | case RT5631_DIG_MIC_CTRL: | ||
| 137 | case RT5631_MONO_INPUT_VOL: | ||
| 138 | case RT5631_SPK_MIXER_CTRL: | ||
| 139 | case RT5631_SPK_MONO_OUT_CTRL: | ||
| 140 | case RT5631_SPK_MONO_HP_OUT_CTRL: | ||
| 141 | case RT5631_SDP_CTRL: | ||
| 142 | case RT5631_MONO_SDP_CTRL: | ||
| 143 | case RT5631_STEREO_AD_DA_CLK_CTRL: | ||
| 144 | case RT5631_PWR_MANAG_ADD1: | ||
| 145 | case RT5631_PWR_MANAG_ADD2: | ||
| 146 | case RT5631_PWR_MANAG_ADD3: | ||
| 147 | case RT5631_PWR_MANAG_ADD4: | ||
| 148 | case RT5631_GEN_PUR_CTRL_REG: | ||
| 149 | case RT5631_GLOBAL_CLK_CTRL: | ||
| 150 | case RT5631_PLL_CTRL: | ||
| 151 | case RT5631_INT_ST_IRQ_CTRL_1: | ||
| 152 | case RT5631_INT_ST_IRQ_CTRL_2: | ||
| 153 | case RT5631_GPIO_CTRL: | ||
| 154 | case RT5631_MISC_CTRL: | ||
| 155 | case RT5631_DEPOP_FUN_CTRL_1: | ||
| 156 | case RT5631_DEPOP_FUN_CTRL_2: | ||
| 157 | case RT5631_JACK_DET_CTRL: | ||
| 158 | case RT5631_SOFT_VOL_CTRL: | ||
| 159 | case RT5631_ALC_CTRL_1: | ||
| 160 | case RT5631_ALC_CTRL_2: | ||
| 161 | case RT5631_ALC_CTRL_3: | ||
| 162 | case RT5631_PSEUDO_SPATL_CTRL: | ||
| 163 | case RT5631_INDEX_ADD: | ||
| 164 | case RT5631_INDEX_DATA: | ||
| 165 | case RT5631_EQ_CTRL: | ||
| 166 | case RT5631_VENDOR_ID: | ||
| 167 | case RT5631_VENDOR_ID1: | ||
| 168 | case RT5631_VENDOR_ID2: | ||
| 169 | return 1; | ||
| 170 | default: | ||
| 171 | return 0; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); | ||
| 176 | static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0); | ||
| 177 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | ||
| 178 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */ | ||
| 179 | static unsigned int mic_bst_tlv[] = { | ||
| 180 | TLV_DB_RANGE_HEAD(6), | ||
| 181 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | ||
| 182 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | ||
| 183 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | ||
| 184 | 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0), | ||
| 185 | 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0), | ||
| 186 | 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0), | ||
| 187 | 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), | ||
| 188 | }; | ||
| 189 | |||
| 190 | static int rt5631_dmic_get(struct snd_kcontrol *kcontrol, | ||
| 191 | struct snd_ctl_elem_value *ucontrol) | ||
| 192 | { | ||
| 193 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 194 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 195 | |||
| 196 | ucontrol->value.integer.value[0] = rt5631->dmic_used_flag; | ||
| 197 | |||
| 198 | return 0; | ||
| 199 | } | ||
| 200 | |||
| 201 | static int rt5631_dmic_put(struct snd_kcontrol *kcontrol, | ||
| 202 | struct snd_ctl_elem_value *ucontrol) | ||
| 203 | { | ||
| 204 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 205 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 206 | |||
| 207 | rt5631->dmic_used_flag = ucontrol->value.integer.value[0]; | ||
| 208 | return 0; | ||
| 209 | } | ||
| 210 | |||
| 211 | /* MIC Input Type */ | ||
| 212 | static const char *rt5631_input_mode[] = { | ||
| 213 | "Single ended", "Differential"}; | ||
| 214 | |||
| 215 | static const SOC_ENUM_SINGLE_DECL( | ||
| 216 | rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1, | ||
| 217 | RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
| 218 | |||
| 219 | static const SOC_ENUM_SINGLE_DECL( | ||
| 220 | rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1, | ||
| 221 | RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
| 222 | |||
| 223 | /* MONO Input Type */ | ||
| 224 | static const SOC_ENUM_SINGLE_DECL( | ||
| 225 | rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL, | ||
| 226 | RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode); | ||
| 227 | |||
| 228 | /* SPK Ratio Gain Control */ | ||
| 229 | static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x", | ||
| 230 | "1.56x", "1.68x", "1.99x", "2.34x"}; | ||
| 231 | |||
| 232 | static const SOC_ENUM_SINGLE_DECL( | ||
| 233 | rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG, | ||
| 234 | RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio); | ||
| 235 | |||
| 236 | static const struct snd_kcontrol_new rt5631_snd_controls[] = { | ||
| 237 | /* MIC */ | ||
| 238 | SOC_ENUM("MIC1 Mode Control", rt5631_mic1_mode_enum), | ||
| 239 | SOC_SINGLE_TLV("MIC1 Boost", RT5631_MIC_CTRL_2, | ||
| 240 | RT5631_MIC1_BOOST_SHIFT, 8, 0, mic_bst_tlv), | ||
| 241 | SOC_ENUM("MIC2 Mode Control", rt5631_mic2_mode_enum), | ||
| 242 | SOC_SINGLE_TLV("MIC2 Boost", RT5631_MIC_CTRL_2, | ||
| 243 | RT5631_MIC2_BOOST_SHIFT, 8, 0, mic_bst_tlv), | ||
| 244 | /* MONO IN */ | ||
| 245 | SOC_ENUM("MONOIN Mode Control", rt5631_monoin_mode_enum), | ||
| 246 | SOC_DOUBLE_TLV("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL, | ||
| 247 | RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, | ||
| 248 | RT5631_VOL_MASK, 1, in_vol_tlv), | ||
| 249 | /* AXI */ | ||
| 250 | SOC_DOUBLE_TLV("AXI Capture Volume", RT5631_AUX_IN_VOL, | ||
| 251 | RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, | ||
| 252 | RT5631_VOL_MASK, 1, in_vol_tlv), | ||
| 253 | /* DAC */ | ||
| 254 | SOC_DOUBLE_TLV("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2, | ||
| 255 | RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, | ||
| 256 | RT5631_DAC_VOL_MASK, 1, dac_vol_tlv), | ||
| 257 | SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1, | ||
| 258 | RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1), | ||
| 259 | /* AXO */ | ||
| 260 | SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL, | ||
| 261 | RT5631_L_MUTE_SHIFT, 1, 1), | ||
| 262 | SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL, | ||
| 263 | RT5631_R_VOL_SHIFT, 1, 1), | ||
| 264 | /* OUTVOL */ | ||
| 265 | SOC_DOUBLE("OUTVOL Channel Switch", RT5631_SPK_OUT_VOL, | ||
| 266 | RT5631_L_EN_SHIFT, RT5631_R_EN_SHIFT, 1, 0), | ||
| 267 | |||
| 268 | /* SPK */ | ||
| 269 | SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL, | ||
| 270 | RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1), | ||
| 271 | SOC_DOUBLE_TLV("Speaker Playback Volume", RT5631_SPK_OUT_VOL, | ||
| 272 | RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, 39, 1, out_vol_tlv), | ||
| 273 | /* MONO OUT */ | ||
| 274 | SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL, | ||
| 275 | RT5631_MUTE_MONO_SHIFT, 1, 1), | ||
| 276 | /* HP */ | ||
| 277 | SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL, | ||
| 278 | RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1), | ||
| 279 | SOC_DOUBLE_TLV("HP Playback Volume", RT5631_HP_OUT_VOL, | ||
| 280 | RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, | ||
| 281 | RT5631_VOL_MASK, 1, out_vol_tlv), | ||
| 282 | /* DMIC */ | ||
| 283 | SOC_SINGLE_EXT("DMIC Switch", 0, 0, 1, 0, | ||
| 284 | rt5631_dmic_get, rt5631_dmic_put), | ||
| 285 | SOC_DOUBLE("DMIC Capture Switch", RT5631_DIG_MIC_CTRL, | ||
| 286 | RT5631_DMIC_L_CH_MUTE_SHIFT, | ||
| 287 | RT5631_DMIC_R_CH_MUTE_SHIFT, 1, 1), | ||
| 288 | |||
| 289 | /* SPK Ratio Gain Control */ | ||
| 290 | SOC_ENUM("SPK Ratio Control", rt5631_spk_ratio_enum), | ||
| 291 | }; | ||
| 292 | |||
| 293 | static int check_sysclk1_source(struct snd_soc_dapm_widget *source, | ||
| 294 | struct snd_soc_dapm_widget *sink) | ||
| 295 | { | ||
| 296 | unsigned int reg; | ||
| 297 | |||
| 298 | reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL); | ||
| 299 | return reg & RT5631_SYSCLK_SOUR_SEL_PLL; | ||
| 300 | } | ||
| 301 | |||
| 302 | static int check_dmic_used(struct snd_soc_dapm_widget *source, | ||
| 303 | struct snd_soc_dapm_widget *sink) | ||
| 304 | { | ||
| 305 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec); | ||
| 306 | return rt5631->dmic_used_flag; | ||
| 307 | } | ||
| 308 | |||
| 309 | static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source, | ||
| 310 | struct snd_soc_dapm_widget *sink) | ||
| 311 | { | ||
| 312 | unsigned int reg; | ||
| 313 | |||
| 314 | reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL); | ||
| 315 | return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L); | ||
| 316 | } | ||
| 317 | |||
| 318 | static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source, | ||
| 319 | struct snd_soc_dapm_widget *sink) | ||
| 320 | { | ||
| 321 | unsigned int reg; | ||
| 322 | |||
| 323 | reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL); | ||
| 324 | return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R); | ||
| 325 | } | ||
| 326 | |||
| 327 | static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source, | ||
| 328 | struct snd_soc_dapm_widget *sink) | ||
| 329 | { | ||
| 330 | unsigned int reg; | ||
| 331 | |||
| 332 | reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL); | ||
| 333 | return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L); | ||
| 334 | } | ||
| 335 | |||
| 336 | static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source, | ||
| 337 | struct snd_soc_dapm_widget *sink) | ||
| 338 | { | ||
| 339 | unsigned int reg; | ||
| 340 | |||
| 341 | reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL); | ||
| 342 | return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R); | ||
| 343 | } | ||
| 344 | |||
| 345 | static int check_adcl_select(struct snd_soc_dapm_widget *source, | ||
| 346 | struct snd_soc_dapm_widget *sink) | ||
| 347 | { | ||
| 348 | unsigned int reg; | ||
| 349 | |||
| 350 | reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER); | ||
| 351 | return !(reg & RT5631_M_MIC1_TO_RECMIXER_L); | ||
| 352 | } | ||
| 353 | |||
| 354 | static int check_adcr_select(struct snd_soc_dapm_widget *source, | ||
| 355 | struct snd_soc_dapm_widget *sink) | ||
| 356 | { | ||
| 357 | unsigned int reg; | ||
| 358 | |||
| 359 | reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER); | ||
| 360 | return !(reg & RT5631_M_MIC2_TO_RECMIXER_R); | ||
| 361 | } | ||
| 362 | |||
| 363 | /** | ||
| 364 | * onebit_depop_power_stage - auto depop in power stage. | ||
| 365 | * @enable: power on/off | ||
| 366 | * | ||
| 367 | * When power on/off headphone, the depop sequence is done by hardware. | ||
| 368 | */ | ||
| 369 | static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable) | ||
| 370 | { | ||
| 371 | unsigned int soft_vol, hp_zc; | ||
| 372 | |||
| 373 | /* enable one-bit depop function */ | ||
| 374 | snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2, | ||
| 375 | RT5631_EN_ONE_BIT_DEPOP, 0); | ||
| 376 | |||
| 377 | /* keep soft volume and zero crossing setting */ | ||
| 378 | soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL); | ||
| 379 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0); | ||
| 380 | hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2); | ||
| 381 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff); | ||
| 382 | if (enable) { | ||
| 383 | /* config one-bit depop parameter */ | ||
| 384 | rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0); | ||
| 385 | rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f); | ||
| 386 | rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530); | ||
| 387 | /* power on capless block */ | ||
| 388 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, | ||
| 389 | RT5631_EN_CAP_FREE_DEPOP); | ||
| 390 | } else { | ||
| 391 | /* power off capless block */ | ||
| 392 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0); | ||
| 393 | msleep(100); | ||
| 394 | } | ||
| 395 | |||
| 396 | /* recover soft volume and zero crossing setting */ | ||
| 397 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol); | ||
| 398 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc); | ||
| 399 | } | ||
| 400 | |||
| 401 | /** | ||
| 402 | * onebit_depop_mute_stage - auto depop in mute stage. | ||
| 403 | * @enable: mute/unmute | ||
| 404 | * | ||
| 405 | * When mute/unmute headphone, the depop sequence is done by hardware. | ||
| 406 | */ | ||
| 407 | static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable) | ||
| 408 | { | ||
| 409 | unsigned int soft_vol, hp_zc; | ||
| 410 | |||
| 411 | /* enable one-bit depop function */ | ||
| 412 | snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2, | ||
| 413 | RT5631_EN_ONE_BIT_DEPOP, 0); | ||
| 414 | |||
| 415 | /* keep soft volume and zero crossing setting */ | ||
| 416 | soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL); | ||
| 417 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0); | ||
| 418 | hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2); | ||
| 419 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff); | ||
| 420 | if (enable) { | ||
| 421 | schedule_timeout_uninterruptible(msecs_to_jiffies(10)); | ||
| 422 | /* config one-bit depop parameter */ | ||
| 423 | rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f); | ||
| 424 | snd_soc_update_bits(codec, RT5631_HP_OUT_VOL, | ||
| 425 | RT5631_L_MUTE | RT5631_R_MUTE, 0); | ||
| 426 | msleep(300); | ||
| 427 | } else { | ||
| 428 | snd_soc_update_bits(codec, RT5631_HP_OUT_VOL, | ||
| 429 | RT5631_L_MUTE | RT5631_R_MUTE, | ||
| 430 | RT5631_L_MUTE | RT5631_R_MUTE); | ||
| 431 | msleep(100); | ||
| 432 | } | ||
| 433 | |||
| 434 | /* recover soft volume and zero crossing setting */ | ||
| 435 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol); | ||
| 436 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc); | ||
| 437 | } | ||
| 438 | |||
| 439 | /** | ||
| 440 | * onebit_depop_power_stage - step by step depop sequence in power stage. | ||
| 441 | * @enable: power on/off | ||
| 442 | * | ||
| 443 | * When power on/off headphone, the depop sequence is done in step by step. | ||
| 444 | */ | ||
| 445 | static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable) | ||
| 446 | { | ||
| 447 | unsigned int soft_vol, hp_zc; | ||
| 448 | |||
| 449 | /* depop control by register */ | ||
| 450 | snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2, | ||
| 451 | RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP); | ||
| 452 | |||
| 453 | /* keep soft volume and zero crossing setting */ | ||
| 454 | soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL); | ||
| 455 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0); | ||
| 456 | hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2); | ||
| 457 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff); | ||
| 458 | if (enable) { | ||
| 459 | /* config depop sequence parameter */ | ||
| 460 | rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e); | ||
| 461 | |||
| 462 | /* power on headphone and charge pump */ | ||
| 463 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 464 | RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP | | ||
| 465 | RT5631_PWR_HP_R_AMP, | ||
| 466 | RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP | | ||
| 467 | RT5631_PWR_HP_R_AMP); | ||
| 468 | |||
| 469 | /* power on soft generator and depop mode2 */ | ||
| 470 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 471 | RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP); | ||
| 472 | msleep(100); | ||
| 473 | |||
| 474 | /* stop depop mode */ | ||
| 475 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 476 | RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS); | ||
| 477 | } else { | ||
| 478 | /* config depop sequence parameter */ | ||
| 479 | rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F); | ||
| 480 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 481 | RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP | | ||
| 482 | RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP); | ||
| 483 | msleep(75); | ||
| 484 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 485 | RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP | | ||
| 486 | RT5631_PD_HPAMP_R_ST_UP); | ||
| 487 | |||
| 488 | /* start depop mode */ | ||
| 489 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 490 | RT5631_PWR_HP_DEPOP_DIS, 0); | ||
| 491 | |||
| 492 | /* config depop sequence parameter */ | ||
| 493 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 494 | RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP | | ||
| 495 | RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP); | ||
| 496 | msleep(80); | ||
| 497 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 498 | RT5631_POW_ON_SOFT_GEN); | ||
| 499 | |||
| 500 | /* power down headphone and charge pump */ | ||
| 501 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 502 | RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP | | ||
| 503 | RT5631_PWR_HP_R_AMP, 0); | ||
| 504 | } | ||
| 505 | |||
| 506 | /* recover soft volume and zero crossing setting */ | ||
| 507 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol); | ||
| 508 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc); | ||
| 509 | } | ||
| 510 | |||
| 511 | /** | ||
| 512 | * depop_seq_mute_stage - step by step depop sequence in mute stage. | ||
| 513 | * @enable: mute/unmute | ||
| 514 | * | ||
| 515 | * When mute/unmute headphone, the depop sequence is done in step by step. | ||
| 516 | */ | ||
| 517 | static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable) | ||
| 518 | { | ||
| 519 | unsigned int soft_vol, hp_zc; | ||
| 520 | |||
| 521 | /* depop control by register */ | ||
| 522 | snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2, | ||
| 523 | RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP); | ||
| 524 | |||
| 525 | /* keep soft volume and zero crossing setting */ | ||
| 526 | soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL); | ||
| 527 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0); | ||
| 528 | hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2); | ||
| 529 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff); | ||
| 530 | if (enable) { | ||
| 531 | schedule_timeout_uninterruptible(msecs_to_jiffies(10)); | ||
| 532 | |||
| 533 | /* config depop sequence parameter */ | ||
| 534 | rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f); | ||
| 535 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 536 | RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP | | ||
| 537 | RT5631_EN_HP_R_M_UN_MUTE_DEPOP | | ||
| 538 | RT5631_EN_HP_L_M_UN_MUTE_DEPOP); | ||
| 539 | |||
| 540 | snd_soc_update_bits(codec, RT5631_HP_OUT_VOL, | ||
| 541 | RT5631_L_MUTE | RT5631_R_MUTE, 0); | ||
| 542 | msleep(160); | ||
| 543 | } else { | ||
| 544 | /* config depop sequence parameter */ | ||
| 545 | rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f); | ||
| 546 | snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1, | ||
| 547 | RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP | | ||
| 548 | RT5631_EN_HP_R_M_UN_MUTE_DEPOP | | ||
| 549 | RT5631_EN_HP_L_M_UN_MUTE_DEPOP); | ||
| 550 | |||
| 551 | snd_soc_update_bits(codec, RT5631_HP_OUT_VOL, | ||
| 552 | RT5631_L_MUTE | RT5631_R_MUTE, | ||
| 553 | RT5631_L_MUTE | RT5631_R_MUTE); | ||
| 554 | msleep(150); | ||
| 555 | } | ||
| 556 | |||
| 557 | /* recover soft volume and zero crossing setting */ | ||
| 558 | snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol); | ||
| 559 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc); | ||
| 560 | } | ||
| 561 | |||
| 562 | static int hp_event(struct snd_soc_dapm_widget *w, | ||
| 563 | struct snd_kcontrol *kcontrol, int event) | ||
| 564 | { | ||
| 565 | struct snd_soc_codec *codec = w->codec; | ||
| 566 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 567 | |||
| 568 | switch (event) { | ||
| 569 | case SND_SOC_DAPM_PRE_PMD: | ||
| 570 | if (rt5631->codec_version) { | ||
| 571 | onebit_depop_mute_stage(codec, 0); | ||
| 572 | onebit_depop_power_stage(codec, 0); | ||
| 573 | } else { | ||
| 574 | depop_seq_mute_stage(codec, 0); | ||
| 575 | depop_seq_power_stage(codec, 0); | ||
| 576 | } | ||
| 577 | break; | ||
| 578 | |||
| 579 | case SND_SOC_DAPM_POST_PMU: | ||
| 580 | if (rt5631->codec_version) { | ||
| 581 | onebit_depop_power_stage(codec, 1); | ||
| 582 | onebit_depop_mute_stage(codec, 1); | ||
| 583 | } else { | ||
| 584 | depop_seq_power_stage(codec, 1); | ||
| 585 | depop_seq_mute_stage(codec, 1); | ||
| 586 | } | ||
| 587 | break; | ||
| 588 | |||
| 589 | default: | ||
| 590 | break; | ||
| 591 | } | ||
| 592 | |||
| 593 | return 0; | ||
| 594 | } | ||
| 595 | |||
| 596 | static int set_dmic_params(struct snd_soc_dapm_widget *w, | ||
| 597 | struct snd_kcontrol *kcontrol, int event) | ||
| 598 | { | ||
| 599 | struct snd_soc_codec *codec = w->codec; | ||
| 600 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 601 | |||
| 602 | switch (rt5631->rx_rate) { | ||
| 603 | case 44100: | ||
| 604 | case 48000: | ||
| 605 | snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL, | ||
| 606 | RT5631_DMIC_CLK_CTRL_MASK, | ||
| 607 | RT5631_DMIC_CLK_CTRL_TO_32FS); | ||
| 608 | break; | ||
| 609 | |||
| 610 | case 32000: | ||
| 611 | case 22050: | ||
| 612 | snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL, | ||
| 613 | RT5631_DMIC_CLK_CTRL_MASK, | ||
| 614 | RT5631_DMIC_CLK_CTRL_TO_64FS); | ||
| 615 | break; | ||
| 616 | |||
| 617 | case 16000: | ||
| 618 | case 11025: | ||
| 619 | case 8000: | ||
| 620 | snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL, | ||
| 621 | RT5631_DMIC_CLK_CTRL_MASK, | ||
| 622 | RT5631_DMIC_CLK_CTRL_TO_128FS); | ||
| 623 | break; | ||
| 624 | |||
| 625 | default: | ||
| 626 | return -EINVAL; | ||
| 627 | } | ||
| 628 | |||
| 629 | return 0; | ||
| 630 | } | ||
| 631 | |||
| 632 | static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = { | ||
| 633 | SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 634 | RT5631_M_OUTMIXL_RECMIXL_BIT, 1, 1), | ||
| 635 | SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 636 | RT5631_M_MIC1_RECMIXL_BIT, 1, 1), | ||
| 637 | SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 638 | RT5631_M_AXIL_RECMIXL_BIT, 1, 1), | ||
| 639 | SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 640 | RT5631_M_MONO_IN_RECMIXL_BIT, 1, 1), | ||
| 641 | }; | ||
| 642 | |||
| 643 | static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = { | ||
| 644 | SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 645 | RT5631_M_MONO_IN_RECMIXR_BIT, 1, 1), | ||
| 646 | SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 647 | RT5631_M_AXIR_RECMIXR_BIT, 1, 1), | ||
| 648 | SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 649 | RT5631_M_MIC2_RECMIXR_BIT, 1, 1), | ||
| 650 | SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER, | ||
| 651 | RT5631_M_OUTMIXR_RECMIXR_BIT, 1, 1), | ||
| 652 | }; | ||
| 653 | |||
| 654 | static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = { | ||
| 655 | SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 656 | RT5631_M_RECMIXL_SPKMIXL_BIT, 1, 1), | ||
| 657 | SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 658 | RT5631_M_MIC1P_SPKMIXL_BIT, 1, 1), | ||
| 659 | SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 660 | RT5631_M_DACL_SPKMIXL_BIT, 1, 1), | ||
| 661 | SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 662 | RT5631_M_OUTMIXL_SPKMIXL_BIT, 1, 1), | ||
| 663 | }; | ||
| 664 | |||
| 665 | static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = { | ||
| 666 | SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 667 | RT5631_M_OUTMIXR_SPKMIXR_BIT, 1, 1), | ||
| 668 | SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 669 | RT5631_M_DACR_SPKMIXR_BIT, 1, 1), | ||
| 670 | SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 671 | RT5631_M_MIC2P_SPKMIXR_BIT, 1, 1), | ||
| 672 | SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL, | ||
| 673 | RT5631_M_RECMIXR_SPKMIXR_BIT, 1, 1), | ||
| 674 | }; | ||
| 675 | |||
| 676 | static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = { | ||
| 677 | SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 678 | RT5631_M_RECMIXL_OUTMIXL_BIT, 1, 1), | ||
| 679 | SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 680 | RT5631_M_RECMIXR_OUTMIXL_BIT, 1, 1), | ||
| 681 | SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 682 | RT5631_M_DACL_OUTMIXL_BIT, 1, 1), | ||
| 683 | SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 684 | RT5631_M_MIC1_OUTMIXL_BIT, 1, 1), | ||
| 685 | SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 686 | RT5631_M_MIC2_OUTMIXL_BIT, 1, 1), | ||
| 687 | SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 688 | RT5631_M_MONO_INP_OUTMIXL_BIT, 1, 1), | ||
| 689 | SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 690 | RT5631_M_AXIL_OUTMIXL_BIT, 1, 1), | ||
| 691 | SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 692 | RT5631_M_AXIR_OUTMIXL_BIT, 1, 1), | ||
| 693 | SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL, | ||
| 694 | RT5631_M_VDAC_OUTMIXL_BIT, 1, 1), | ||
| 695 | }; | ||
| 696 | |||
| 697 | static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = { | ||
| 698 | SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 699 | RT5631_M_VDAC_OUTMIXR_BIT, 1, 1), | ||
| 700 | SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 701 | RT5631_M_AXIR_OUTMIXR_BIT, 1, 1), | ||
| 702 | SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 703 | RT5631_M_AXIL_OUTMIXR_BIT, 1, 1), | ||
| 704 | SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 705 | RT5631_M_MONO_INN_OUTMIXR_BIT, 1, 1), | ||
| 706 | SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 707 | RT5631_M_MIC2_OUTMIXR_BIT, 1, 1), | ||
| 708 | SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 709 | RT5631_M_MIC1_OUTMIXR_BIT, 1, 1), | ||
| 710 | SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 711 | RT5631_M_DACR_OUTMIXR_BIT, 1, 1), | ||
| 712 | SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 713 | RT5631_M_RECMIXR_OUTMIXR_BIT, 1, 1), | ||
| 714 | SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL, | ||
| 715 | RT5631_M_RECMIXL_OUTMIXR_BIT, 1, 1), | ||
| 716 | }; | ||
| 717 | |||
| 718 | static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = { | ||
| 719 | SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL, | ||
| 720 | RT5631_M_MIC1_AXO1MIX_BIT , 1, 1), | ||
| 721 | SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL, | ||
| 722 | RT5631_M_MIC2_AXO1MIX_BIT, 1, 1), | ||
| 723 | SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL, | ||
| 724 | RT5631_M_OUTMIXL_AXO1MIX_BIT , 1 , 1), | ||
| 725 | SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL, | ||
| 726 | RT5631_M_OUTMIXR_AXO1MIX_BIT, 1, 1), | ||
| 727 | }; | ||
| 728 | |||
| 729 | static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = { | ||
| 730 | SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL, | ||
| 731 | RT5631_M_MIC1_AXO2MIX_BIT, 1, 1), | ||
| 732 | SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL, | ||
| 733 | RT5631_M_MIC2_AXO2MIX_BIT, 1, 1), | ||
| 734 | SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL, | ||
| 735 | RT5631_M_OUTMIXL_AXO2MIX_BIT, 1, 1), | ||
| 736 | SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL, | ||
| 737 | RT5631_M_OUTMIXR_AXO2MIX_BIT, 1 , 1), | ||
| 738 | }; | ||
| 739 | |||
| 740 | static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = { | ||
| 741 | SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, | ||
| 742 | RT5631_M_SPKVOLL_SPOLMIX_BIT, 1, 1), | ||
| 743 | SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, | ||
| 744 | RT5631_M_SPKVOLR_SPOLMIX_BIT, 1, 1), | ||
| 745 | }; | ||
| 746 | |||
| 747 | static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = { | ||
| 748 | SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, | ||
| 749 | RT5631_M_SPKVOLL_SPORMIX_BIT, 1, 1), | ||
| 750 | SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, | ||
| 751 | RT5631_M_SPKVOLR_SPORMIX_BIT, 1, 1), | ||
| 752 | }; | ||
| 753 | |||
| 754 | static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = { | ||
| 755 | SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, | ||
| 756 | RT5631_M_OUTVOLL_MONOMIX_BIT, 1, 1), | ||
| 757 | SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, | ||
| 758 | RT5631_M_OUTVOLR_MONOMIX_BIT, 1, 1), | ||
| 759 | }; | ||
| 760 | |||
| 761 | /* Left SPK Volume Input */ | ||
| 762 | static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"}; | ||
| 763 | |||
| 764 | static const SOC_ENUM_SINGLE_DECL( | ||
| 765 | rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL, | ||
| 766 | RT5631_L_EN_SHIFT, rt5631_spkvoll_sel); | ||
| 767 | |||
| 768 | static const struct snd_kcontrol_new rt5631_spkvoll_mux_control = | ||
| 769 | SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum); | ||
| 770 | |||
| 771 | /* Left HP Volume Input */ | ||
| 772 | static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"}; | ||
| 773 | |||
| 774 | static const SOC_ENUM_SINGLE_DECL( | ||
| 775 | rt5631_hpvoll_enum, RT5631_HP_OUT_VOL, | ||
| 776 | RT5631_L_EN_SHIFT, rt5631_hpvoll_sel); | ||
| 777 | |||
| 778 | static const struct snd_kcontrol_new rt5631_hpvoll_mux_control = | ||
| 779 | SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum); | ||
| 780 | |||
| 781 | /* Left Out Volume Input */ | ||
| 782 | static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"}; | ||
| 783 | |||
| 784 | static const SOC_ENUM_SINGLE_DECL( | ||
| 785 | rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL, | ||
| 786 | RT5631_L_EN_SHIFT, rt5631_outvoll_sel); | ||
| 787 | |||
| 788 | static const struct snd_kcontrol_new rt5631_outvoll_mux_control = | ||
| 789 | SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum); | ||
| 790 | |||
| 791 | /* Right Out Volume Input */ | ||
| 792 | static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"}; | ||
| 793 | |||
| 794 | static const SOC_ENUM_SINGLE_DECL( | ||
| 795 | rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL, | ||
| 796 | RT5631_R_EN_SHIFT, rt5631_outvolr_sel); | ||
| 797 | |||
| 798 | static const struct snd_kcontrol_new rt5631_outvolr_mux_control = | ||
| 799 | SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum); | ||
| 800 | |||
| 801 | /* Right HP Volume Input */ | ||
| 802 | static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"}; | ||
| 803 | |||
| 804 | static const SOC_ENUM_SINGLE_DECL( | ||
| 805 | rt5631_hpvolr_enum, RT5631_HP_OUT_VOL, | ||
| 806 | RT5631_R_EN_SHIFT, rt5631_hpvolr_sel); | ||
| 807 | |||
| 808 | static const struct snd_kcontrol_new rt5631_hpvolr_mux_control = | ||
| 809 | SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum); | ||
| 810 | |||
| 811 | /* Right SPK Volume Input */ | ||
| 812 | static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"}; | ||
| 813 | |||
| 814 | static const SOC_ENUM_SINGLE_DECL( | ||
| 815 | rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL, | ||
| 816 | RT5631_R_EN_SHIFT, rt5631_spkvolr_sel); | ||
| 817 | |||
| 818 | static const struct snd_kcontrol_new rt5631_spkvolr_mux_control = | ||
| 819 | SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum); | ||
| 820 | |||
| 821 | /* SPO Left Channel Input */ | ||
| 822 | static const char *rt5631_spol_src_sel[] = { | ||
| 823 | "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"}; | ||
| 824 | |||
| 825 | static const SOC_ENUM_SINGLE_DECL( | ||
| 826 | rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | ||
| 827 | RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel); | ||
| 828 | |||
| 829 | static const struct snd_kcontrol_new rt5631_spol_mux_control = | ||
| 830 | SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum); | ||
| 831 | |||
| 832 | /* SPO Right Channel Input */ | ||
| 833 | static const char *rt5631_spor_src_sel[] = { | ||
| 834 | "SPORMIX", "MONOIN_RX", "VDAC", "DACR"}; | ||
| 835 | |||
| 836 | static const SOC_ENUM_SINGLE_DECL( | ||
| 837 | rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | ||
| 838 | RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel); | ||
| 839 | |||
| 840 | static const struct snd_kcontrol_new rt5631_spor_mux_control = | ||
| 841 | SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum); | ||
| 842 | |||
| 843 | /* MONO Input */ | ||
| 844 | static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"}; | ||
| 845 | |||
| 846 | static const SOC_ENUM_SINGLE_DECL( | ||
| 847 | rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | ||
| 848 | RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel); | ||
| 849 | |||
| 850 | static const struct snd_kcontrol_new rt5631_mono_mux_control = | ||
| 851 | SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum); | ||
| 852 | |||
| 853 | /* Left HPO Input */ | ||
| 854 | static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"}; | ||
| 855 | |||
| 856 | static const SOC_ENUM_SINGLE_DECL( | ||
| 857 | rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | ||
| 858 | RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel); | ||
| 859 | |||
| 860 | static const struct snd_kcontrol_new rt5631_hpl_mux_control = | ||
| 861 | SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum); | ||
| 862 | |||
| 863 | /* Right HPO Input */ | ||
| 864 | static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"}; | ||
| 865 | |||
| 866 | static const SOC_ENUM_SINGLE_DECL( | ||
| 867 | rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL, | ||
| 868 | RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel); | ||
| 869 | |||
| 870 | static const struct snd_kcontrol_new rt5631_hpr_mux_control = | ||
| 871 | SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum); | ||
| 872 | |||
| 873 | static const struct snd_soc_dapm_widget rt5631_dapm_widgets[] = { | ||
| 874 | /* Vmid */ | ||
| 875 | SND_SOC_DAPM_VMID("Vmid"), | ||
| 876 | /* PLL1 */ | ||
| 877 | SND_SOC_DAPM_SUPPLY("PLL1", RT5631_PWR_MANAG_ADD2, | ||
| 878 | RT5631_PWR_PLL1_BIT, 0, NULL, 0), | ||
| 879 | |||
| 880 | /* Input Side */ | ||
| 881 | /* Input Lines */ | ||
| 882 | SND_SOC_DAPM_INPUT("MIC1"), | ||
| 883 | SND_SOC_DAPM_INPUT("MIC2"), | ||
| 884 | SND_SOC_DAPM_INPUT("AXIL"), | ||
| 885 | SND_SOC_DAPM_INPUT("AXIR"), | ||
| 886 | SND_SOC_DAPM_INPUT("MONOIN_RXN"), | ||
| 887 | SND_SOC_DAPM_INPUT("MONOIN_RXP"), | ||
| 888 | SND_SOC_DAPM_INPUT("DMIC"), | ||
| 889 | |||
| 890 | /* MICBIAS */ | ||
| 891 | SND_SOC_DAPM_MICBIAS("MIC Bias1", RT5631_PWR_MANAG_ADD2, | ||
| 892 | RT5631_PWR_MICBIAS1_VOL_BIT, 0), | ||
| 893 | SND_SOC_DAPM_MICBIAS("MIC Bias2", RT5631_PWR_MANAG_ADD2, | ||
| 894 | RT5631_PWR_MICBIAS2_VOL_BIT, 0), | ||
| 895 | |||
| 896 | /* Boost */ | ||
| 897 | SND_SOC_DAPM_PGA("MIC1 Boost", RT5631_PWR_MANAG_ADD2, | ||
| 898 | RT5631_PWR_MIC1_BOOT_GAIN_BIT, 0, NULL, 0), | ||
| 899 | SND_SOC_DAPM_PGA("MIC2 Boost", RT5631_PWR_MANAG_ADD2, | ||
| 900 | RT5631_PWR_MIC2_BOOT_GAIN_BIT, 0, NULL, 0), | ||
| 901 | SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4, | ||
| 902 | RT5631_PWR_MONO_IN_P_VOL_BIT, 0, NULL, 0), | ||
| 903 | SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4, | ||
| 904 | RT5631_PWR_MONO_IN_N_VOL_BIT, 0, NULL, 0), | ||
| 905 | SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4, | ||
| 906 | RT5631_PWR_AXIL_IN_VOL_BIT, 0, NULL, 0), | ||
| 907 | SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4, | ||
| 908 | RT5631_PWR_AXIR_IN_VOL_BIT, 0, NULL, 0), | ||
| 909 | |||
| 910 | /* MONO In */ | ||
| 911 | SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 912 | |||
| 913 | /* REC Mixer */ | ||
| 914 | SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2, | ||
| 915 | RT5631_PWR_RECMIXER_L_BIT, 0, | ||
| 916 | &rt5631_recmixl_mixer_controls[0], | ||
| 917 | ARRAY_SIZE(rt5631_recmixl_mixer_controls)), | ||
| 918 | SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2, | ||
| 919 | RT5631_PWR_RECMIXER_R_BIT, 0, | ||
| 920 | &rt5631_recmixr_mixer_controls[0], | ||
| 921 | ARRAY_SIZE(rt5631_recmixr_mixer_controls)), | ||
| 922 | /* Because of record duplication for L/R channel, | ||
| 923 | * L/R ADCs need power up at the same time */ | ||
| 924 | SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 925 | |||
| 926 | /* DMIC */ | ||
| 927 | SND_SOC_DAPM_SUPPLY("DMIC Supply", RT5631_DIG_MIC_CTRL, | ||
| 928 | RT5631_DMIC_ENA_SHIFT, 0, | ||
| 929 | set_dmic_params, SND_SOC_DAPM_PRE_PMU), | ||
| 930 | /* ADC Data Srouce */ | ||
| 931 | SND_SOC_DAPM_SUPPLY("Left ADC Select", RT5631_INT_ST_IRQ_CTRL_2, | ||
| 932 | RT5631_ADC_DATA_SEL_MIC1_SHIFT, 0, NULL, 0), | ||
| 933 | SND_SOC_DAPM_SUPPLY("Right ADC Select", RT5631_INT_ST_IRQ_CTRL_2, | ||
| 934 | RT5631_ADC_DATA_SEL_MIC2_SHIFT, 0, NULL, 0), | ||
| 935 | |||
| 936 | /* ADCs */ | ||
| 937 | SND_SOC_DAPM_ADC("Left ADC", "HIFI Capture", | ||
| 938 | RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_L_CLK_BIT, 0), | ||
| 939 | SND_SOC_DAPM_ADC("Right ADC", "HIFI Capture", | ||
| 940 | RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_R_CLK_BIT, 0), | ||
| 941 | |||
| 942 | /* DAC and ADC supply power */ | ||
| 943 | SND_SOC_DAPM_SUPPLY("I2S", RT5631_PWR_MANAG_ADD1, | ||
| 944 | RT5631_PWR_MAIN_I2S_BIT, 0, NULL, 0), | ||
| 945 | SND_SOC_DAPM_SUPPLY("DAC REF", RT5631_PWR_MANAG_ADD1, | ||
| 946 | RT5631_PWR_DAC_REF_BIT, 0, NULL, 0), | ||
| 947 | |||
| 948 | /* Output Side */ | ||
| 949 | /* DACs */ | ||
| 950 | SND_SOC_DAPM_DAC("Left DAC", "HIFI Playback", | ||
| 951 | RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_L_CLK_BIT, 0), | ||
| 952 | SND_SOC_DAPM_DAC("Right DAC", "HIFI Playback", | ||
| 953 | RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_R_CLK_BIT, 0), | ||
| 954 | SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback", | ||
| 955 | SND_SOC_NOPM, 0, 0), | ||
| 956 | SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 957 | /* DAC supply power */ | ||
| 958 | SND_SOC_DAPM_SUPPLY("Left DAC To Mixer", RT5631_PWR_MANAG_ADD1, | ||
| 959 | RT5631_PWR_DAC_L_TO_MIXER_BIT, 0, NULL, 0), | ||
| 960 | SND_SOC_DAPM_SUPPLY("Right DAC To Mixer", RT5631_PWR_MANAG_ADD1, | ||
| 961 | RT5631_PWR_DAC_R_TO_MIXER_BIT, 0, NULL, 0), | ||
| 962 | |||
| 963 | /* Left SPK Mixer */ | ||
| 964 | SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2, | ||
| 965 | RT5631_PWR_SPKMIXER_L_BIT, 0, | ||
| 966 | &rt5631_spkmixl_mixer_controls[0], | ||
| 967 | ARRAY_SIZE(rt5631_spkmixl_mixer_controls)), | ||
| 968 | /* Left Out Mixer */ | ||
| 969 | SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2, | ||
| 970 | RT5631_PWR_OUTMIXER_L_BIT, 0, | ||
| 971 | &rt5631_outmixl_mixer_controls[0], | ||
| 972 | ARRAY_SIZE(rt5631_outmixl_mixer_controls)), | ||
| 973 | /* Right Out Mixer */ | ||
| 974 | SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2, | ||
| 975 | RT5631_PWR_OUTMIXER_R_BIT, 0, | ||
| 976 | &rt5631_outmixr_mixer_controls[0], | ||
| 977 | ARRAY_SIZE(rt5631_outmixr_mixer_controls)), | ||
| 978 | /* Right SPK Mixer */ | ||
| 979 | SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2, | ||
| 980 | RT5631_PWR_SPKMIXER_R_BIT, 0, | ||
| 981 | &rt5631_spkmixr_mixer_controls[0], | ||
| 982 | ARRAY_SIZE(rt5631_spkmixr_mixer_controls)), | ||
| 983 | |||
| 984 | /* Volume Mux */ | ||
| 985 | SND_SOC_DAPM_MUX("Left SPKVOL Mux", RT5631_PWR_MANAG_ADD4, | ||
| 986 | RT5631_PWR_SPK_L_VOL_BIT, 0, | ||
| 987 | &rt5631_spkvoll_mux_control), | ||
| 988 | SND_SOC_DAPM_MUX("Left HPVOL Mux", RT5631_PWR_MANAG_ADD4, | ||
| 989 | RT5631_PWR_HP_L_OUT_VOL_BIT, 0, | ||
| 990 | &rt5631_hpvoll_mux_control), | ||
| 991 | SND_SOC_DAPM_MUX("Left OUTVOL Mux", RT5631_PWR_MANAG_ADD4, | ||
| 992 | RT5631_PWR_LOUT_VOL_BIT, 0, | ||
| 993 | &rt5631_outvoll_mux_control), | ||
| 994 | SND_SOC_DAPM_MUX("Right OUTVOL Mux", RT5631_PWR_MANAG_ADD4, | ||
| 995 | RT5631_PWR_ROUT_VOL_BIT, 0, | ||
| 996 | &rt5631_outvolr_mux_control), | ||
| 997 | SND_SOC_DAPM_MUX("Right HPVOL Mux", RT5631_PWR_MANAG_ADD4, | ||
| 998 | RT5631_PWR_HP_R_OUT_VOL_BIT, 0, | ||
| 999 | &rt5631_hpvolr_mux_control), | ||
| 1000 | SND_SOC_DAPM_MUX("Right SPKVOL Mux", RT5631_PWR_MANAG_ADD4, | ||
| 1001 | RT5631_PWR_SPK_R_VOL_BIT, 0, | ||
| 1002 | &rt5631_spkvolr_mux_control), | ||
| 1003 | |||
| 1004 | /* DAC To HP */ | ||
| 1005 | SND_SOC_DAPM_PGA_S("Left DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 1006 | SND_SOC_DAPM_PGA_S("Right DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 1007 | |||
| 1008 | /* HP Depop */ | ||
| 1009 | SND_SOC_DAPM_PGA_S("HP Depop", 1, SND_SOC_NOPM, 0, 0, | ||
| 1010 | hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), | ||
| 1011 | |||
| 1012 | /* AXO1 Mixer */ | ||
| 1013 | SND_SOC_DAPM_MIXER("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3, | ||
| 1014 | RT5631_PWR_AXO1MIXER_BIT, 0, | ||
| 1015 | &rt5631_AXO1MIX_mixer_controls[0], | ||
| 1016 | ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls)), | ||
| 1017 | /* SPOL Mixer */ | ||
| 1018 | SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0, | ||
| 1019 | &rt5631_spolmix_mixer_controls[0], | ||
| 1020 | ARRAY_SIZE(rt5631_spolmix_mixer_controls)), | ||
| 1021 | /* MONO Mixer */ | ||
| 1022 | SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3, | ||
| 1023 | RT5631_PWR_MONOMIXER_BIT, 0, | ||
| 1024 | &rt5631_monomix_mixer_controls[0], | ||
| 1025 | ARRAY_SIZE(rt5631_monomix_mixer_controls)), | ||
| 1026 | /* SPOR Mixer */ | ||
| 1027 | SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0, | ||
| 1028 | &rt5631_spormix_mixer_controls[0], | ||
| 1029 | ARRAY_SIZE(rt5631_spormix_mixer_controls)), | ||
| 1030 | /* AXO2 Mixer */ | ||
| 1031 | SND_SOC_DAPM_MIXER("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3, | ||
| 1032 | RT5631_PWR_AXO2MIXER_BIT, 0, | ||
| 1033 | &rt5631_AXO2MIX_mixer_controls[0], | ||
| 1034 | ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls)), | ||
| 1035 | |||
| 1036 | /* Mux */ | ||
| 1037 | SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0, | ||
| 1038 | &rt5631_spol_mux_control), | ||
| 1039 | SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0, | ||
| 1040 | &rt5631_spor_mux_control), | ||
| 1041 | SND_SOC_DAPM_MUX("MONO Mux", SND_SOC_NOPM, 0, 0, | ||
| 1042 | &rt5631_mono_mux_control), | ||
| 1043 | SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, | ||
| 1044 | &rt5631_hpl_mux_control), | ||
| 1045 | SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, | ||
| 1046 | &rt5631_hpr_mux_control), | ||
| 1047 | |||
| 1048 | /* AMP supply */ | ||
| 1049 | SND_SOC_DAPM_SUPPLY("MONO Depop", RT5631_PWR_MANAG_ADD3, | ||
| 1050 | RT5631_PWR_MONO_DEPOP_DIS_BIT, 0, NULL, 0), | ||
| 1051 | SND_SOC_DAPM_SUPPLY("Class D", RT5631_PWR_MANAG_ADD1, | ||
| 1052 | RT5631_PWR_CLASS_D_BIT, 0, NULL, 0), | ||
| 1053 | |||
| 1054 | /* Output Lines */ | ||
| 1055 | SND_SOC_DAPM_OUTPUT("AUXO1"), | ||
| 1056 | SND_SOC_DAPM_OUTPUT("AUXO2"), | ||
| 1057 | SND_SOC_DAPM_OUTPUT("SPOL"), | ||
| 1058 | SND_SOC_DAPM_OUTPUT("SPOR"), | ||
| 1059 | SND_SOC_DAPM_OUTPUT("HPOL"), | ||
| 1060 | SND_SOC_DAPM_OUTPUT("HPOR"), | ||
| 1061 | SND_SOC_DAPM_OUTPUT("MONO"), | ||
| 1062 | }; | ||
| 1063 | |||
| 1064 | static const struct snd_soc_dapm_route rt5631_dapm_routes[] = { | ||
| 1065 | {"MIC1 Boost", NULL, "MIC1"}, | ||
| 1066 | {"MIC2 Boost", NULL, "MIC2"}, | ||
| 1067 | {"MONOIN_RXP Boost", NULL, "MONOIN_RXP"}, | ||
| 1068 | {"MONOIN_RXN Boost", NULL, "MONOIN_RXN"}, | ||
| 1069 | {"AXIL Boost", NULL, "AXIL"}, | ||
| 1070 | {"AXIR Boost", NULL, "AXIR"}, | ||
| 1071 | |||
| 1072 | {"MONO_IN", NULL, "MONOIN_RXP Boost"}, | ||
| 1073 | {"MONO_IN", NULL, "MONOIN_RXN Boost"}, | ||
| 1074 | |||
| 1075 | {"RECMIXL Mixer", "OUTMIXL Capture Switch", "OUTMIXL Mixer"}, | ||
| 1076 | {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "MIC1 Boost"}, | ||
| 1077 | {"RECMIXL Mixer", "AXILVOL Capture Switch", "AXIL Boost"}, | ||
| 1078 | {"RECMIXL Mixer", "MONOIN_RX Capture Switch", "MONO_IN"}, | ||
| 1079 | |||
| 1080 | {"RECMIXR Mixer", "OUTMIXR Capture Switch", "OUTMIXR Mixer"}, | ||
| 1081 | {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "MIC2 Boost"}, | ||
| 1082 | {"RECMIXR Mixer", "AXIRVOL Capture Switch", "AXIR Boost"}, | ||
| 1083 | {"RECMIXR Mixer", "MONOIN_RX Capture Switch", "MONO_IN"}, | ||
| 1084 | |||
| 1085 | {"ADC Mixer", NULL, "RECMIXL Mixer"}, | ||
| 1086 | {"ADC Mixer", NULL, "RECMIXR Mixer"}, | ||
| 1087 | |||
| 1088 | {"Left ADC", NULL, "ADC Mixer"}, | ||
| 1089 | {"Left ADC", NULL, "Left ADC Select", check_adcl_select}, | ||
| 1090 | {"Left ADC", NULL, "PLL1", check_sysclk1_source}, | ||
| 1091 | {"Left ADC", NULL, "I2S"}, | ||
| 1092 | {"Left ADC", NULL, "DAC REF"}, | ||
| 1093 | |||
| 1094 | {"Right ADC", NULL, "ADC Mixer"}, | ||
| 1095 | {"Right ADC", NULL, "Right ADC Select", check_adcr_select}, | ||
| 1096 | {"Right ADC", NULL, "PLL1", check_sysclk1_source}, | ||
| 1097 | {"Right ADC", NULL, "I2S"}, | ||
| 1098 | {"Right ADC", NULL, "DAC REF"}, | ||
| 1099 | |||
| 1100 | {"DMIC", NULL, "DMIC Supply", check_dmic_used}, | ||
| 1101 | {"Left ADC", NULL, "DMIC"}, | ||
| 1102 | {"Right ADC", NULL, "DMIC"}, | ||
| 1103 | |||
| 1104 | {"Left DAC", NULL, "PLL1", check_sysclk1_source}, | ||
| 1105 | {"Left DAC", NULL, "I2S"}, | ||
| 1106 | {"Left DAC", NULL, "DAC REF"}, | ||
| 1107 | {"Right DAC", NULL, "PLL1", check_sysclk1_source}, | ||
| 1108 | {"Right DAC", NULL, "I2S"}, | ||
| 1109 | {"Right DAC", NULL, "DAC REF"}, | ||
| 1110 | |||
| 1111 | {"Voice DAC Boost", NULL, "Voice DAC"}, | ||
| 1112 | |||
| 1113 | {"SPKMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_spkmixl}, | ||
| 1114 | {"SPKMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"}, | ||
| 1115 | {"SPKMIXL Mixer", "MIC1_P Playback Switch", "MIC1"}, | ||
| 1116 | {"SPKMIXL Mixer", "DACL Playback Switch", "Left DAC"}, | ||
| 1117 | {"SPKMIXL Mixer", "OUTMIXL Playback Switch", "OUTMIXL Mixer"}, | ||
| 1118 | |||
| 1119 | {"SPKMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_spkmixr}, | ||
| 1120 | {"SPKMIXR Mixer", "OUTMIXR Playback Switch", "OUTMIXR Mixer"}, | ||
| 1121 | {"SPKMIXR Mixer", "DACR Playback Switch", "Right DAC"}, | ||
| 1122 | {"SPKMIXR Mixer", "MIC2_P Playback Switch", "MIC2"}, | ||
| 1123 | {"SPKMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"}, | ||
| 1124 | |||
| 1125 | {"OUTMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_outmixl}, | ||
| 1126 | {"OUTMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"}, | ||
| 1127 | {"OUTMIXL Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"}, | ||
| 1128 | {"OUTMIXL Mixer", "DACL Playback Switch", "Left DAC"}, | ||
| 1129 | {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"}, | ||
| 1130 | {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"}, | ||
| 1131 | {"OUTMIXL Mixer", "MONOIN_RXP Playback Switch", "MONOIN_RXP Boost"}, | ||
| 1132 | {"OUTMIXL Mixer", "AXILVOL Playback Switch", "AXIL Boost"}, | ||
| 1133 | {"OUTMIXL Mixer", "AXIRVOL Playback Switch", "AXIR Boost"}, | ||
| 1134 | {"OUTMIXL Mixer", "VDAC Playback Switch", "Voice DAC Boost"}, | ||
| 1135 | |||
| 1136 | {"OUTMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_outmixr}, | ||
| 1137 | {"OUTMIXR Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"}, | ||
| 1138 | {"OUTMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"}, | ||
| 1139 | {"OUTMIXR Mixer", "DACR Playback Switch", "Right DAC"}, | ||
| 1140 | {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"}, | ||
| 1141 | {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"}, | ||
| 1142 | {"OUTMIXR Mixer", "MONOIN_RXN Playback Switch", "MONOIN_RXN Boost"}, | ||
| 1143 | {"OUTMIXR Mixer", "AXILVOL Playback Switch", "AXIL Boost"}, | ||
| 1144 | {"OUTMIXR Mixer", "AXIRVOL Playback Switch", "AXIR Boost"}, | ||
| 1145 | {"OUTMIXR Mixer", "VDAC Playback Switch", "Voice DAC Boost"}, | ||
| 1146 | |||
| 1147 | {"Left SPKVOL Mux", "SPKMIXL", "SPKMIXL Mixer"}, | ||
| 1148 | {"Left SPKVOL Mux", "Vmid", "Vmid"}, | ||
| 1149 | {"Left HPVOL Mux", "OUTMIXL", "OUTMIXL Mixer"}, | ||
| 1150 | {"Left HPVOL Mux", "Vmid", "Vmid"}, | ||
| 1151 | {"Left OUTVOL Mux", "OUTMIXL", "OUTMIXL Mixer"}, | ||
| 1152 | {"Left OUTVOL Mux", "Vmid", "Vmid"}, | ||
| 1153 | {"Right OUTVOL Mux", "OUTMIXR", "OUTMIXR Mixer"}, | ||
| 1154 | {"Right OUTVOL Mux", "Vmid", "Vmid"}, | ||
| 1155 | {"Right HPVOL Mux", "OUTMIXR", "OUTMIXR Mixer"}, | ||
| 1156 | {"Right HPVOL Mux", "Vmid", "Vmid"}, | ||
| 1157 | {"Right SPKVOL Mux", "SPKMIXR", "SPKMIXR Mixer"}, | ||
| 1158 | {"Right SPKVOL Mux", "Vmid", "Vmid"}, | ||
| 1159 | |||
| 1160 | {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"}, | ||
| 1161 | {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"}, | ||
| 1162 | {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"}, | ||
| 1163 | {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"}, | ||
| 1164 | |||
| 1165 | {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"}, | ||
| 1166 | {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"}, | ||
| 1167 | {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"}, | ||
| 1168 | {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"}, | ||
| 1169 | |||
| 1170 | {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"}, | ||
| 1171 | {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"}, | ||
| 1172 | |||
| 1173 | {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"}, | ||
| 1174 | {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"}, | ||
| 1175 | |||
| 1176 | {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"}, | ||
| 1177 | {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"}, | ||
| 1178 | |||
| 1179 | {"SPOL Mux", "SPOLMIX", "SPOLMIX Mixer"}, | ||
| 1180 | {"SPOL Mux", "MONOIN_RX", "MONO_IN"}, | ||
| 1181 | {"SPOL Mux", "VDAC", "Voice DAC Boost"}, | ||
| 1182 | {"SPOL Mux", "DACL", "Left DAC"}, | ||
| 1183 | |||
| 1184 | {"SPOR Mux", "SPORMIX", "SPORMIX Mixer"}, | ||
| 1185 | {"SPOR Mux", "MONOIN_RX", "MONO_IN"}, | ||
| 1186 | {"SPOR Mux", "VDAC", "Voice DAC Boost"}, | ||
| 1187 | {"SPOR Mux", "DACR", "Right DAC"}, | ||
| 1188 | |||
| 1189 | {"MONO Mux", "MONOMIX", "MONOMIX Mixer"}, | ||
| 1190 | {"MONO Mux", "MONOIN_RX", "MONO_IN"}, | ||
| 1191 | {"MONO Mux", "VDAC", "Voice DAC Boost"}, | ||
| 1192 | |||
| 1193 | {"Right DAC_HP", NULL, "Right DAC"}, | ||
| 1194 | {"Left DAC_HP", NULL, "Left DAC"}, | ||
| 1195 | |||
| 1196 | {"HPL Mux", "Left HPVOL", "Left HPVOL Mux"}, | ||
| 1197 | {"HPL Mux", "Left DAC", "Left DAC_HP"}, | ||
| 1198 | {"HPR Mux", "Right HPVOL", "Right HPVOL Mux"}, | ||
| 1199 | {"HPR Mux", "Right DAC", "Right DAC_HP"}, | ||
| 1200 | |||
| 1201 | {"HP Depop", NULL, "HPL Mux"}, | ||
| 1202 | {"HP Depop", NULL, "HPR Mux"}, | ||
| 1203 | |||
| 1204 | {"AUXO1", NULL, "AXO1MIX Mixer"}, | ||
| 1205 | {"AUXO2", NULL, "AXO2MIX Mixer"}, | ||
| 1206 | |||
| 1207 | {"SPOL", NULL, "Class D"}, | ||
| 1208 | {"SPOL", NULL, "SPOL Mux"}, | ||
| 1209 | {"SPOR", NULL, "Class D"}, | ||
| 1210 | {"SPOR", NULL, "SPOR Mux"}, | ||
| 1211 | |||
| 1212 | {"HPOL", NULL, "HP Depop"}, | ||
| 1213 | {"HPOR", NULL, "HP Depop"}, | ||
| 1214 | |||
| 1215 | {"MONO", NULL, "MONO Depop"}, | ||
| 1216 | {"MONO", NULL, "MONO Mux"}, | ||
| 1217 | }; | ||
| 1218 | |||
| 1219 | struct coeff_clk_div { | ||
| 1220 | u32 mclk; | ||
| 1221 | u32 bclk; | ||
| 1222 | u32 rate; | ||
| 1223 | u16 reg_val; | ||
| 1224 | }; | ||
| 1225 | |||
| 1226 | /* PLL divisors */ | ||
| 1227 | struct pll_div { | ||
| 1228 | u32 pll_in; | ||
| 1229 | u32 pll_out; | ||
| 1230 | u16 reg_val; | ||
| 1231 | }; | ||
| 1232 | |||
| 1233 | static const struct pll_div codec_master_pll_div[] = { | ||
| 1234 | {2048000, 8192000, 0x0ea0}, | ||
| 1235 | {3686400, 8192000, 0x4e27}, | ||
| 1236 | {12000000, 8192000, 0x456b}, | ||
| 1237 | {13000000, 8192000, 0x495f}, | ||
| 1238 | {13100000, 8192000, 0x0320}, | ||
| 1239 | {2048000, 11289600, 0xf637}, | ||
| 1240 | {3686400, 11289600, 0x2f22}, | ||
| 1241 | {12000000, 11289600, 0x3e2f}, | ||
| 1242 | {13000000, 11289600, 0x4d5b}, | ||
| 1243 | {13100000, 11289600, 0x363b}, | ||
| 1244 | {2048000, 16384000, 0x1ea0}, | ||
| 1245 | {3686400, 16384000, 0x9e27}, | ||
| 1246 | {12000000, 16384000, 0x452b}, | ||
| 1247 | {13000000, 16384000, 0x542f}, | ||
| 1248 | {13100000, 16384000, 0x03a0}, | ||
| 1249 | {2048000, 16934400, 0xe625}, | ||
| 1250 | {3686400, 16934400, 0x9126}, | ||
| 1251 | {12000000, 16934400, 0x4d2c}, | ||
| 1252 | {13000000, 16934400, 0x742f}, | ||
| 1253 | {13100000, 16934400, 0x3c27}, | ||
| 1254 | {2048000, 22579200, 0x2aa0}, | ||
| 1255 | {3686400, 22579200, 0x2f20}, | ||
| 1256 | {12000000, 22579200, 0x7e2f}, | ||
| 1257 | {13000000, 22579200, 0x742f}, | ||
| 1258 | {13100000, 22579200, 0x3c27}, | ||
| 1259 | {2048000, 24576000, 0x2ea0}, | ||
| 1260 | {3686400, 24576000, 0xee27}, | ||
| 1261 | {12000000, 24576000, 0x2915}, | ||
| 1262 | {13000000, 24576000, 0x772e}, | ||
| 1263 | {13100000, 24576000, 0x0d20}, | ||
| 1264 | {26000000, 24576000, 0x2027}, | ||
| 1265 | {26000000, 22579200, 0x392f}, | ||
| 1266 | {24576000, 22579200, 0x0921}, | ||
| 1267 | {24576000, 24576000, 0x02a0}, | ||
| 1268 | }; | ||
| 1269 | |||
| 1270 | static const struct pll_div codec_slave_pll_div[] = { | ||
| 1271 | {256000, 2048000, 0x46f0}, | ||
| 1272 | {256000, 4096000, 0x3ea0}, | ||
| 1273 | {352800, 5644800, 0x3ea0}, | ||
| 1274 | {512000, 8192000, 0x3ea0}, | ||
| 1275 | {1024000, 8192000, 0x46f0}, | ||
| 1276 | {705600, 11289600, 0x3ea0}, | ||
| 1277 | {1024000, 16384000, 0x3ea0}, | ||
| 1278 | {1411200, 22579200, 0x3ea0}, | ||
| 1279 | {1536000, 24576000, 0x3ea0}, | ||
| 1280 | {2048000, 16384000, 0x1ea0}, | ||
| 1281 | {2822400, 22579200, 0x1ea0}, | ||
| 1282 | {2822400, 45158400, 0x5ec0}, | ||
| 1283 | {5644800, 45158400, 0x46f0}, | ||
| 1284 | {3072000, 24576000, 0x1ea0}, | ||
| 1285 | {3072000, 49152000, 0x5ec0}, | ||
| 1286 | {6144000, 49152000, 0x46f0}, | ||
| 1287 | {705600, 11289600, 0x3ea0}, | ||
| 1288 | {705600, 8467200, 0x3ab0}, | ||
| 1289 | {24576000, 24576000, 0x02a0}, | ||
| 1290 | {1411200, 11289600, 0x1690}, | ||
| 1291 | {2822400, 11289600, 0x0a90}, | ||
| 1292 | {1536000, 12288000, 0x1690}, | ||
| 1293 | {3072000, 12288000, 0x0a90}, | ||
| 1294 | }; | ||
| 1295 | |||
| 1296 | static struct coeff_clk_div coeff_div[] = { | ||
| 1297 | /* sysclk is 256fs */ | ||
| 1298 | {2048000, 8000 * 32, 8000, 0x1000}, | ||
| 1299 | {2048000, 8000 * 64, 8000, 0x0000}, | ||
| 1300 | {2822400, 11025 * 32, 11025, 0x1000}, | ||
| 1301 | {2822400, 11025 * 64, 11025, 0x0000}, | ||
| 1302 | {4096000, 16000 * 32, 16000, 0x1000}, | ||
| 1303 | {4096000, 16000 * 64, 16000, 0x0000}, | ||
| 1304 | {5644800, 22050 * 32, 22050, 0x1000}, | ||
| 1305 | {5644800, 22050 * 64, 22050, 0x0000}, | ||
| 1306 | {8192000, 32000 * 32, 32000, 0x1000}, | ||
| 1307 | {8192000, 32000 * 64, 32000, 0x0000}, | ||
| 1308 | {11289600, 44100 * 32, 44100, 0x1000}, | ||
| 1309 | {11289600, 44100 * 64, 44100, 0x0000}, | ||
| 1310 | {12288000, 48000 * 32, 48000, 0x1000}, | ||
| 1311 | {12288000, 48000 * 64, 48000, 0x0000}, | ||
| 1312 | {22579200, 88200 * 32, 88200, 0x1000}, | ||
| 1313 | {22579200, 88200 * 64, 88200, 0x0000}, | ||
| 1314 | {24576000, 96000 * 32, 96000, 0x1000}, | ||
| 1315 | {24576000, 96000 * 64, 96000, 0x0000}, | ||
| 1316 | /* sysclk is 512fs */ | ||
| 1317 | {4096000, 8000 * 32, 8000, 0x3000}, | ||
| 1318 | {4096000, 8000 * 64, 8000, 0x2000}, | ||
| 1319 | {5644800, 11025 * 32, 11025, 0x3000}, | ||
| 1320 | {5644800, 11025 * 64, 11025, 0x2000}, | ||
| 1321 | {8192000, 16000 * 32, 16000, 0x3000}, | ||
| 1322 | {8192000, 16000 * 64, 16000, 0x2000}, | ||
| 1323 | {11289600, 22050 * 32, 22050, 0x3000}, | ||
| 1324 | {11289600, 22050 * 64, 22050, 0x2000}, | ||
| 1325 | {16384000, 32000 * 32, 32000, 0x3000}, | ||
| 1326 | {16384000, 32000 * 64, 32000, 0x2000}, | ||
| 1327 | {22579200, 44100 * 32, 44100, 0x3000}, | ||
| 1328 | {22579200, 44100 * 64, 44100, 0x2000}, | ||
| 1329 | {24576000, 48000 * 32, 48000, 0x3000}, | ||
| 1330 | {24576000, 48000 * 64, 48000, 0x2000}, | ||
| 1331 | {45158400, 88200 * 32, 88200, 0x3000}, | ||
| 1332 | {45158400, 88200 * 64, 88200, 0x2000}, | ||
| 1333 | {49152000, 96000 * 32, 96000, 0x3000}, | ||
| 1334 | {49152000, 96000 * 64, 96000, 0x2000}, | ||
| 1335 | /* sysclk is 24.576Mhz or 22.5792Mhz */ | ||
| 1336 | {24576000, 8000 * 32, 8000, 0x7080}, | ||
| 1337 | {24576000, 8000 * 64, 8000, 0x6080}, | ||
| 1338 | {24576000, 16000 * 32, 16000, 0x5080}, | ||
| 1339 | {24576000, 16000 * 64, 16000, 0x4080}, | ||
| 1340 | {24576000, 24000 * 32, 24000, 0x5000}, | ||
| 1341 | {24576000, 24000 * 64, 24000, 0x4000}, | ||
| 1342 | {24576000, 32000 * 32, 32000, 0x3080}, | ||
| 1343 | {24576000, 32000 * 64, 32000, 0x2080}, | ||
| 1344 | {22579200, 11025 * 32, 11025, 0x7000}, | ||
| 1345 | {22579200, 11025 * 64, 11025, 0x6000}, | ||
| 1346 | {22579200, 22050 * 32, 22050, 0x5000}, | ||
| 1347 | {22579200, 22050 * 64, 22050, 0x4000}, | ||
| 1348 | }; | ||
| 1349 | |||
| 1350 | static int get_coeff(int mclk, int rate, int timesofbclk) | ||
| 1351 | { | ||
| 1352 | int i; | ||
| 1353 | |||
| 1354 | for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { | ||
| 1355 | if (coeff_div[i].mclk == mclk && coeff_div[i].rate == rate && | ||
| 1356 | (coeff_div[i].bclk / coeff_div[i].rate) == timesofbclk) | ||
| 1357 | return i; | ||
| 1358 | } | ||
| 1359 | return -EINVAL; | ||
| 1360 | } | ||
| 1361 | |||
| 1362 | static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream, | ||
| 1363 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | ||
| 1364 | { | ||
| 1365 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 1366 | struct snd_soc_codec *codec = rtd->codec; | ||
| 1367 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 1368 | int timesofbclk = 32, coeff; | ||
| 1369 | unsigned int iface = 0; | ||
| 1370 | |||
| 1371 | dev_dbg(codec->dev, "enter %s\n", __func__); | ||
| 1372 | |||
| 1373 | rt5631->bclk_rate = snd_soc_params_to_bclk(params); | ||
| 1374 | if (rt5631->bclk_rate < 0) { | ||
| 1375 | dev_err(codec->dev, "Fail to get BCLK rate\n"); | ||
| 1376 | return rt5631->bclk_rate; | ||
| 1377 | } | ||
| 1378 | rt5631->rx_rate = params_rate(params); | ||
| 1379 | |||
| 1380 | if (rt5631->master) | ||
| 1381 | coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate, | ||
| 1382 | rt5631->bclk_rate / rt5631->rx_rate); | ||
| 1383 | else | ||
| 1384 | coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate, | ||
| 1385 | timesofbclk); | ||
| 1386 | if (coeff < 0) { | ||
| 1387 | dev_err(codec->dev, "Fail to get coeff\n"); | ||
| 1388 | return -EINVAL; | ||
| 1389 | } | ||
| 1390 | |||
| 1391 | switch (params_format(params)) { | ||
| 1392 | case SNDRV_PCM_FORMAT_S16_LE: | ||
| 1393 | break; | ||
| 1394 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
| 1395 | iface |= RT5631_SDP_I2S_DL_20; | ||
| 1396 | break; | ||
| 1397 | case SNDRV_PCM_FORMAT_S24_LE: | ||
| 1398 | iface |= RT5631_SDP_I2S_DL_24; | ||
| 1399 | break; | ||
| 1400 | case SNDRV_PCM_FORMAT_S8: | ||
| 1401 | iface |= RT5631_SDP_I2S_DL_8; | ||
| 1402 | break; | ||
| 1403 | default: | ||
| 1404 | return -EINVAL; | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | snd_soc_update_bits(codec, RT5631_SDP_CTRL, | ||
| 1408 | RT5631_SDP_I2S_DL_MASK, iface); | ||
| 1409 | snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL, | ||
| 1410 | coeff_div[coeff].reg_val); | ||
| 1411 | |||
| 1412 | return 0; | ||
| 1413 | } | ||
| 1414 | |||
| 1415 | static int rt5631_hifi_codec_set_dai_fmt(struct snd_soc_dai *codec_dai, | ||
| 1416 | unsigned int fmt) | ||
| 1417 | { | ||
| 1418 | struct snd_soc_codec *codec = codec_dai->codec; | ||
| 1419 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 1420 | unsigned int iface = 0; | ||
| 1421 | |||
| 1422 | dev_dbg(codec->dev, "enter %s\n", __func__); | ||
| 1423 | |||
| 1424 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 1425 | case SND_SOC_DAIFMT_CBM_CFM: | ||
| 1426 | rt5631->master = 1; | ||
| 1427 | break; | ||
| 1428 | case SND_SOC_DAIFMT_CBS_CFS: | ||
| 1429 | iface |= RT5631_SDP_MODE_SEL_SLAVE; | ||
| 1430 | rt5631->master = 0; | ||
| 1431 | break; | ||
| 1432 | default: | ||
| 1433 | return -EINVAL; | ||
| 1434 | } | ||
| 1435 | |||
| 1436 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 1437 | case SND_SOC_DAIFMT_I2S: | ||
| 1438 | break; | ||
| 1439 | case SND_SOC_DAIFMT_LEFT_J: | ||
| 1440 | iface |= RT5631_SDP_I2S_DF_LEFT; | ||
| 1441 | break; | ||
| 1442 | case SND_SOC_DAIFMT_DSP_A: | ||
| 1443 | iface |= RT5631_SDP_I2S_DF_PCM_A; | ||
| 1444 | break; | ||
| 1445 | case SND_SOC_DAIFMT_DSP_B: | ||
| 1446 | iface |= RT5631_SDP_I2S_DF_PCM_B; | ||
| 1447 | break; | ||
| 1448 | default: | ||
| 1449 | return -EINVAL; | ||
| 1450 | } | ||
| 1451 | |||
| 1452 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
| 1453 | case SND_SOC_DAIFMT_NB_NF: | ||
| 1454 | break; | ||
| 1455 | case SND_SOC_DAIFMT_IB_NF: | ||
| 1456 | iface |= RT5631_SDP_I2S_BCLK_POL_CTRL; | ||
| 1457 | break; | ||
| 1458 | default: | ||
| 1459 | return -EINVAL; | ||
| 1460 | } | ||
| 1461 | |||
| 1462 | snd_soc_write(codec, RT5631_SDP_CTRL, iface); | ||
| 1463 | |||
| 1464 | return 0; | ||
| 1465 | } | ||
| 1466 | |||
| 1467 | static int rt5631_hifi_codec_set_dai_sysclk(struct snd_soc_dai *codec_dai, | ||
| 1468 | int clk_id, unsigned int freq, int dir) | ||
| 1469 | { | ||
| 1470 | struct snd_soc_codec *codec = codec_dai->codec; | ||
| 1471 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 1472 | |||
| 1473 | dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq); | ||
| 1474 | |||
| 1475 | if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) { | ||
| 1476 | rt5631->sysclk = freq; | ||
| 1477 | return 0; | ||
| 1478 | } | ||
| 1479 | |||
| 1480 | return -EINVAL; | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | ||
| 1484 | int source, unsigned int freq_in, unsigned int freq_out) | ||
| 1485 | { | ||
| 1486 | struct snd_soc_codec *codec = codec_dai->codec; | ||
| 1487 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 1488 | int i, ret = -EINVAL; | ||
| 1489 | |||
| 1490 | dev_dbg(codec->dev, "enter %s\n", __func__); | ||
| 1491 | |||
| 1492 | if (!freq_in || !freq_out) { | ||
| 1493 | dev_dbg(codec->dev, "PLL disabled\n"); | ||
| 1494 | |||
| 1495 | snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL, | ||
| 1496 | RT5631_SYSCLK_SOUR_SEL_MASK, | ||
| 1497 | RT5631_SYSCLK_SOUR_SEL_MCLK); | ||
| 1498 | |||
| 1499 | return 0; | ||
| 1500 | } | ||
| 1501 | |||
| 1502 | if (rt5631->master) { | ||
| 1503 | for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) | ||
| 1504 | if (freq_in == codec_master_pll_div[i].pll_in && | ||
| 1505 | freq_out == codec_master_pll_div[i].pll_out) { | ||
| 1506 | dev_info(codec->dev, | ||
| 1507 | "change PLL in master mode\n"); | ||
| 1508 | snd_soc_write(codec, RT5631_PLL_CTRL, | ||
| 1509 | codec_master_pll_div[i].reg_val); | ||
| 1510 | schedule_timeout_uninterruptible( | ||
| 1511 | msecs_to_jiffies(20)); | ||
| 1512 | snd_soc_update_bits(codec, | ||
| 1513 | RT5631_GLOBAL_CLK_CTRL, | ||
| 1514 | RT5631_SYSCLK_SOUR_SEL_MASK | | ||
| 1515 | RT5631_PLLCLK_SOUR_SEL_MASK, | ||
| 1516 | RT5631_SYSCLK_SOUR_SEL_PLL | | ||
| 1517 | RT5631_PLLCLK_SOUR_SEL_MCLK); | ||
| 1518 | ret = 0; | ||
| 1519 | break; | ||
| 1520 | } | ||
| 1521 | } else { | ||
| 1522 | for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) | ||
| 1523 | if (freq_in == codec_slave_pll_div[i].pll_in && | ||
| 1524 | freq_out == codec_slave_pll_div[i].pll_out) { | ||
| 1525 | dev_info(codec->dev, | ||
| 1526 | "change PLL in slave mode\n"); | ||
| 1527 | snd_soc_write(codec, RT5631_PLL_CTRL, | ||
| 1528 | codec_slave_pll_div[i].reg_val); | ||
| 1529 | schedule_timeout_uninterruptible( | ||
| 1530 | msecs_to_jiffies(20)); | ||
| 1531 | snd_soc_update_bits(codec, | ||
| 1532 | RT5631_GLOBAL_CLK_CTRL, | ||
| 1533 | RT5631_SYSCLK_SOUR_SEL_MASK | | ||
| 1534 | RT5631_PLLCLK_SOUR_SEL_MASK, | ||
| 1535 | RT5631_SYSCLK_SOUR_SEL_PLL | | ||
| 1536 | RT5631_PLLCLK_SOUR_SEL_BCLK); | ||
| 1537 | ret = 0; | ||
| 1538 | break; | ||
| 1539 | } | ||
| 1540 | } | ||
| 1541 | |||
| 1542 | return ret; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | static int rt5631_set_bias_level(struct snd_soc_codec *codec, | ||
| 1546 | enum snd_soc_bias_level level) | ||
| 1547 | { | ||
| 1548 | switch (level) { | ||
| 1549 | case SND_SOC_BIAS_ON: | ||
| 1550 | case SND_SOC_BIAS_PREPARE: | ||
| 1551 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2, | ||
| 1552 | RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL, | ||
| 1553 | RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL); | ||
| 1554 | break; | ||
| 1555 | |||
| 1556 | case SND_SOC_BIAS_STANDBY: | ||
| 1557 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
| 1558 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 1559 | RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS, | ||
| 1560 | RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS); | ||
| 1561 | msleep(80); | ||
| 1562 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 1563 | RT5631_PWR_FAST_VREF_CTRL, | ||
| 1564 | RT5631_PWR_FAST_VREF_CTRL); | ||
| 1565 | codec->cache_only = false; | ||
| 1566 | snd_soc_cache_sync(codec); | ||
| 1567 | } | ||
| 1568 | break; | ||
| 1569 | |||
| 1570 | case SND_SOC_BIAS_OFF: | ||
| 1571 | snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000); | ||
| 1572 | snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000); | ||
| 1573 | snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000); | ||
| 1574 | snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000); | ||
| 1575 | break; | ||
| 1576 | |||
| 1577 | default: | ||
| 1578 | break; | ||
| 1579 | } | ||
| 1580 | codec->dapm.bias_level = level; | ||
| 1581 | |||
| 1582 | return 0; | ||
| 1583 | } | ||
| 1584 | |||
| 1585 | static int rt5631_probe(struct snd_soc_codec *codec) | ||
| 1586 | { | ||
| 1587 | struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec); | ||
| 1588 | unsigned int val; | ||
| 1589 | int ret; | ||
| 1590 | |||
| 1591 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | ||
| 1592 | if (ret != 0) { | ||
| 1593 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
| 1594 | return ret; | ||
| 1595 | } | ||
| 1596 | |||
| 1597 | val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3); | ||
| 1598 | if (val & 0x0002) | ||
| 1599 | rt5631->codec_version = 1; | ||
| 1600 | else | ||
| 1601 | rt5631->codec_version = 0; | ||
| 1602 | |||
| 1603 | rt5631_reset(codec); | ||
| 1604 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 1605 | RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS, | ||
| 1606 | RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS); | ||
| 1607 | msleep(80); | ||
| 1608 | snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3, | ||
| 1609 | RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL); | ||
| 1610 | /* enable HP zero cross */ | ||
| 1611 | snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18); | ||
| 1612 | /* power off ClassD auto Recovery */ | ||
| 1613 | if (rt5631->codec_version) | ||
| 1614 | snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2, | ||
| 1615 | 0x2000, 0x2000); | ||
| 1616 | else | ||
| 1617 | snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2, | ||
| 1618 | 0x2000, 0); | ||
| 1619 | /* DMIC */ | ||
| 1620 | if (rt5631->dmic_used_flag) { | ||
| 1621 | snd_soc_update_bits(codec, RT5631_GPIO_CTRL, | ||
| 1622 | RT5631_GPIO_PIN_FUN_SEL_MASK | | ||
| 1623 | RT5631_GPIO_DMIC_FUN_SEL_MASK, | ||
| 1624 | RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC | | ||
| 1625 | RT5631_GPIO_DMIC_FUN_SEL_DIMC); | ||
| 1626 | snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL, | ||
| 1627 | RT5631_DMIC_L_CH_LATCH_MASK | | ||
| 1628 | RT5631_DMIC_R_CH_LATCH_MASK, | ||
| 1629 | RT5631_DMIC_L_CH_LATCH_FALLING | | ||
| 1630 | RT5631_DMIC_R_CH_LATCH_RISING); | ||
| 1631 | } | ||
| 1632 | |||
| 1633 | codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; | ||
| 1634 | |||
| 1635 | return 0; | ||
| 1636 | } | ||
| 1637 | |||
| 1638 | static int rt5631_remove(struct snd_soc_codec *codec) | ||
| 1639 | { | ||
| 1640 | rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 1641 | return 0; | ||
| 1642 | } | ||
| 1643 | |||
| 1644 | #ifdef CONFIG_PM | ||
| 1645 | static int rt5631_suspend(struct snd_soc_codec *codec, pm_message_t state) | ||
| 1646 | { | ||
| 1647 | rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 1648 | return 0; | ||
| 1649 | } | ||
| 1650 | |||
| 1651 | static int rt5631_resume(struct snd_soc_codec *codec) | ||
| 1652 | { | ||
| 1653 | rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
| 1654 | return 0; | ||
| 1655 | } | ||
| 1656 | #else | ||
| 1657 | #define rt5631_suspend NULL | ||
| 1658 | #define rt5631_resume NULL | ||
| 1659 | #endif | ||
| 1660 | |||
| 1661 | #define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000 | ||
| 1662 | #define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \ | ||
| 1663 | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
| 1664 | SNDRV_PCM_FMTBIT_S24_LE | \ | ||
| 1665 | SNDRV_PCM_FMTBIT_S8) | ||
| 1666 | |||
| 1667 | static struct snd_soc_dai_ops rt5631_ops = { | ||
| 1668 | .hw_params = rt5631_hifi_pcm_params, | ||
| 1669 | .set_fmt = rt5631_hifi_codec_set_dai_fmt, | ||
| 1670 | .set_sysclk = rt5631_hifi_codec_set_dai_sysclk, | ||
| 1671 | .set_pll = rt5631_codec_set_dai_pll, | ||
| 1672 | }; | ||
| 1673 | |||
| 1674 | static struct snd_soc_dai_driver rt5631_dai[] = { | ||
| 1675 | { | ||
| 1676 | .name = "rt5631-hifi", | ||
| 1677 | .id = 1, | ||
| 1678 | .playback = { | ||
| 1679 | .stream_name = "HIFI Playback", | ||
| 1680 | .channels_min = 1, | ||
| 1681 | .channels_max = 2, | ||
| 1682 | .rates = RT5631_STEREO_RATES, | ||
| 1683 | .formats = RT5631_FORMAT, | ||
| 1684 | }, | ||
| 1685 | .capture = { | ||
| 1686 | .stream_name = "HIFI Capture", | ||
| 1687 | .channels_min = 1, | ||
| 1688 | .channels_max = 2, | ||
| 1689 | .rates = RT5631_STEREO_RATES, | ||
| 1690 | .formats = RT5631_FORMAT, | ||
| 1691 | }, | ||
| 1692 | .ops = &rt5631_ops, | ||
| 1693 | }, | ||
| 1694 | }; | ||
| 1695 | |||
| 1696 | static struct snd_soc_codec_driver soc_codec_dev_rt5631 = { | ||
| 1697 | .probe = rt5631_probe, | ||
| 1698 | .remove = rt5631_remove, | ||
| 1699 | .suspend = rt5631_suspend, | ||
| 1700 | .resume = rt5631_resume, | ||
| 1701 | .set_bias_level = rt5631_set_bias_level, | ||
| 1702 | .reg_cache_size = RT5631_VENDOR_ID2 + 1, | ||
| 1703 | .reg_word_size = sizeof(u16), | ||
| 1704 | .reg_cache_default = rt5631_reg, | ||
| 1705 | .volatile_register = rt5631_volatile_register, | ||
| 1706 | .readable_register = rt5631_readable_register, | ||
| 1707 | .reg_cache_step = 1, | ||
| 1708 | .controls = rt5631_snd_controls, | ||
| 1709 | .num_controls = ARRAY_SIZE(rt5631_snd_controls), | ||
| 1710 | .dapm_widgets = rt5631_dapm_widgets, | ||
| 1711 | .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets), | ||
| 1712 | .dapm_routes = rt5631_dapm_routes, | ||
| 1713 | .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes), | ||
| 1714 | }; | ||
| 1715 | |||
| 1716 | static const struct i2c_device_id rt5631_i2c_id[] = { | ||
| 1717 | { "rt5631", 0 }, | ||
| 1718 | { } | ||
| 1719 | }; | ||
| 1720 | MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id); | ||
| 1721 | |||
| 1722 | static int rt5631_i2c_probe(struct i2c_client *i2c, | ||
| 1723 | const struct i2c_device_id *id) | ||
| 1724 | { | ||
| 1725 | struct rt5631_priv *rt5631; | ||
| 1726 | int ret; | ||
| 1727 | |||
| 1728 | rt5631 = kzalloc(sizeof(struct rt5631_priv), GFP_KERNEL); | ||
| 1729 | if (NULL == rt5631) | ||
| 1730 | return -ENOMEM; | ||
| 1731 | |||
| 1732 | i2c_set_clientdata(i2c, rt5631); | ||
| 1733 | |||
| 1734 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631, | ||
| 1735 | rt5631_dai, ARRAY_SIZE(rt5631_dai)); | ||
| 1736 | if (ret < 0) | ||
| 1737 | kfree(rt5631); | ||
| 1738 | |||
| 1739 | return ret; | ||
| 1740 | } | ||
| 1741 | |||
| 1742 | static __devexit int rt5631_i2c_remove(struct i2c_client *client) | ||
| 1743 | { | ||
| 1744 | snd_soc_unregister_codec(&client->dev); | ||
| 1745 | kfree(i2c_get_clientdata(client)); | ||
| 1746 | return 0; | ||
| 1747 | } | ||
| 1748 | |||
| 1749 | static struct i2c_driver rt5631_i2c_driver = { | ||
| 1750 | .driver = { | ||
| 1751 | .name = "rt5631", | ||
| 1752 | .owner = THIS_MODULE, | ||
| 1753 | }, | ||
| 1754 | .probe = rt5631_i2c_probe, | ||
| 1755 | .remove = __devexit_p(rt5631_i2c_remove), | ||
| 1756 | .id_table = rt5631_i2c_id, | ||
| 1757 | }; | ||
| 1758 | |||
| 1759 | static int __init rt5631_modinit(void) | ||
| 1760 | { | ||
| 1761 | return i2c_add_driver(&rt5631_i2c_driver); | ||
| 1762 | } | ||
| 1763 | module_init(rt5631_modinit); | ||
| 1764 | |||
| 1765 | static void __exit rt5631_modexit(void) | ||
| 1766 | { | ||
| 1767 | i2c_del_driver(&rt5631_i2c_driver); | ||
| 1768 | } | ||
| 1769 | module_exit(rt5631_modexit); | ||
| 1770 | |||
| 1771 | MODULE_DESCRIPTION("ASoC RT5631 driver"); | ||
| 1772 | MODULE_AUTHOR("flove <flove@realtek.com>"); | ||
| 1773 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/rt5631.h b/sound/soc/codecs/rt5631.h new file mode 100644 index 000000000000..13401581b0df --- /dev/null +++ b/sound/soc/codecs/rt5631.h | |||
| @@ -0,0 +1,701 @@ | |||
| 1 | #ifndef __RTCODEC5631_H__ | ||
| 2 | #define __RTCODEC5631_H__ | ||
| 3 | |||
| 4 | |||
| 5 | #define RT5631_RESET 0x00 | ||
| 6 | #define RT5631_SPK_OUT_VOL 0x02 | ||
| 7 | #define RT5631_HP_OUT_VOL 0x04 | ||
| 8 | #define RT5631_MONO_AXO_1_2_VOL 0x06 | ||
| 9 | #define RT5631_AUX_IN_VOL 0x0A | ||
| 10 | #define RT5631_STEREO_DAC_VOL_1 0x0C | ||
| 11 | #define RT5631_MIC_CTRL_1 0x0E | ||
| 12 | #define RT5631_STEREO_DAC_VOL_2 0x10 | ||
| 13 | #define RT5631_ADC_CTRL_1 0x12 | ||
| 14 | #define RT5631_ADC_REC_MIXER 0x14 | ||
| 15 | #define RT5631_ADC_CTRL_2 0x16 | ||
| 16 | #define RT5631_VDAC_DIG_VOL 0x18 | ||
| 17 | #define RT5631_OUTMIXER_L_CTRL 0x1A | ||
| 18 | #define RT5631_OUTMIXER_R_CTRL 0x1C | ||
| 19 | #define RT5631_AXO1MIXER_CTRL 0x1E | ||
| 20 | #define RT5631_AXO2MIXER_CTRL 0x20 | ||
| 21 | #define RT5631_MIC_CTRL_2 0x22 | ||
| 22 | #define RT5631_DIG_MIC_CTRL 0x24 | ||
| 23 | #define RT5631_MONO_INPUT_VOL 0x26 | ||
| 24 | #define RT5631_SPK_MIXER_CTRL 0x28 | ||
| 25 | #define RT5631_SPK_MONO_OUT_CTRL 0x2A | ||
| 26 | #define RT5631_SPK_MONO_HP_OUT_CTRL 0x2C | ||
| 27 | #define RT5631_SDP_CTRL 0x34 | ||
| 28 | #define RT5631_MONO_SDP_CTRL 0x36 | ||
| 29 | #define RT5631_STEREO_AD_DA_CLK_CTRL 0x38 | ||
| 30 | #define RT5631_PWR_MANAG_ADD1 0x3A | ||
| 31 | #define RT5631_PWR_MANAG_ADD2 0x3B | ||
| 32 | #define RT5631_PWR_MANAG_ADD3 0x3C | ||
| 33 | #define RT5631_PWR_MANAG_ADD4 0x3E | ||
| 34 | #define RT5631_GEN_PUR_CTRL_REG 0x40 | ||
| 35 | #define RT5631_GLOBAL_CLK_CTRL 0x42 | ||
| 36 | #define RT5631_PLL_CTRL 0x44 | ||
| 37 | #define RT5631_INT_ST_IRQ_CTRL_1 0x48 | ||
| 38 | #define RT5631_INT_ST_IRQ_CTRL_2 0x4A | ||
| 39 | #define RT5631_GPIO_CTRL 0x4C | ||
| 40 | #define RT5631_MISC_CTRL 0x52 | ||
| 41 | #define RT5631_DEPOP_FUN_CTRL_1 0x54 | ||
| 42 | #define RT5631_DEPOP_FUN_CTRL_2 0x56 | ||
| 43 | #define RT5631_JACK_DET_CTRL 0x5A | ||
| 44 | #define RT5631_SOFT_VOL_CTRL 0x5C | ||
| 45 | #define RT5631_ALC_CTRL_1 0x64 | ||
| 46 | #define RT5631_ALC_CTRL_2 0x65 | ||
| 47 | #define RT5631_ALC_CTRL_3 0x66 | ||
| 48 | #define RT5631_PSEUDO_SPATL_CTRL 0x68 | ||
| 49 | #define RT5631_INDEX_ADD 0x6A | ||
| 50 | #define RT5631_INDEX_DATA 0x6C | ||
| 51 | #define RT5631_EQ_CTRL 0x6E | ||
| 52 | #define RT5631_VENDOR_ID 0x7A | ||
| 53 | #define RT5631_VENDOR_ID1 0x7C | ||
| 54 | #define RT5631_VENDOR_ID2 0x7E | ||
| 55 | |||
| 56 | /* Index of Codec Private Register definition */ | ||
| 57 | #define RT5631_EQ_BW_LOP 0x00 | ||
| 58 | #define RT5631_EQ_GAIN_LOP 0x01 | ||
| 59 | #define RT5631_EQ_FC_BP1 0x02 | ||
| 60 | #define RT5631_EQ_BW_BP1 0x03 | ||
| 61 | #define RT5631_EQ_GAIN_BP1 0x04 | ||
| 62 | #define RT5631_EQ_FC_BP2 0x05 | ||
| 63 | #define RT5631_EQ_BW_BP2 0x06 | ||
| 64 | #define RT5631_EQ_GAIN_BP2 0x07 | ||
| 65 | #define RT5631_EQ_FC_BP3 0x08 | ||
| 66 | #define RT5631_EQ_BW_BP3 0x09 | ||
| 67 | #define RT5631_EQ_GAIN_BP3 0x0a | ||
| 68 | #define RT5631_EQ_BW_HIP 0x0b | ||
| 69 | #define RT5631_EQ_GAIN_HIP 0x0c | ||
| 70 | #define RT5631_EQ_HPF_A1 0x0d | ||
| 71 | #define RT5631_EQ_HPF_A2 0x0e | ||
| 72 | #define RT5631_EQ_HPF_GAIN 0x0f | ||
| 73 | #define RT5631_EQ_PRE_VOL_CTRL 0x11 | ||
| 74 | #define RT5631_EQ_POST_VOL_CTRL 0x12 | ||
| 75 | #define RT5631_TEST_MODE_CTRL 0x39 | ||
| 76 | #define RT5631_CP_INTL_REG2 0x45 | ||
| 77 | #define RT5631_ADDA_MIXER_INTL_REG3 0x52 | ||
| 78 | #define RT5631_SPK_INTL_CTRL 0x56 | ||
| 79 | |||
| 80 | |||
| 81 | /* global definition */ | ||
| 82 | #define RT5631_L_MUTE (0x1 << 15) | ||
| 83 | #define RT5631_L_MUTE_SHIFT 15 | ||
| 84 | #define RT5631_L_EN (0x1 << 14) | ||
| 85 | #define RT5631_L_EN_SHIFT 14 | ||
| 86 | #define RT5631_R_MUTE (0x1 << 7) | ||
| 87 | #define RT5631_R_MUTE_SHIFT 7 | ||
| 88 | #define RT5631_R_EN (0x1 << 6) | ||
| 89 | #define RT5631_R_EN_SHIFT 6 | ||
| 90 | #define RT5631_VOL_MASK 0x1f | ||
| 91 | #define RT5631_L_VOL_SHIFT 8 | ||
| 92 | #define RT5631_R_VOL_SHIFT 0 | ||
| 93 | |||
| 94 | /* Speaker Output Control(0x02) */ | ||
| 95 | #define RT5631_SPK_L_VOL_SEL_MASK (0x1 << 14) | ||
| 96 | #define RT5631_SPK_L_VOL_SEL_VMID (0x0 << 14) | ||
| 97 | #define RT5631_SPK_L_VOL_SEL_SPKMIX_L (0x1 << 14) | ||
| 98 | #define RT5631_SPK_R_VOL_SEL_MASK (0x1 << 6) | ||
| 99 | #define RT5631_SPK_R_VOL_SEL_VMID (0x0 << 6) | ||
| 100 | #define RT5631_SPK_R_VOL_SEL_SPKMIX_R (0x1 << 6) | ||
| 101 | |||
| 102 | /* Headphone Output Control(0x04) */ | ||
| 103 | #define RT5631_HP_L_VOL_SEL_MASK (0x1 << 14) | ||
| 104 | #define RT5631_HP_L_VOL_SEL_VMID (0x0 << 14) | ||
| 105 | #define RT5631_HP_L_VOL_SEL_OUTMIX_L (0x1 << 14) | ||
| 106 | #define RT5631_HP_R_VOL_SEL_MASK (0x1 << 6) | ||
| 107 | #define RT5631_HP_R_VOL_SEL_VMID (0x0 << 6) | ||
| 108 | #define RT5631_HP_R_VOL_SEL_OUTMIX_R (0x1 << 6) | ||
| 109 | |||
| 110 | /* Output Control for AUXOUT/MONO(0x06) */ | ||
| 111 | #define RT5631_AUXOUT_1_VOL_SEL_MASK (0x1 << 14) | ||
| 112 | #define RT5631_AUXOUT_1_VOL_SEL_VMID (0x0 << 14) | ||
| 113 | #define RT5631_AUXOUT_1_VOL_SEL_OUTMIX_L (0x1 << 14) | ||
| 114 | #define RT5631_MUTE_MONO (0x1 << 13) | ||
| 115 | #define RT5631_MUTE_MONO_SHIFT 13 | ||
| 116 | #define RT5631_AUXOUT_2_VOL_SEL_MASK (0x1 << 6) | ||
| 117 | #define RT5631_AUXOUT_2_VOL_SEL_VMID (0x0 << 6) | ||
| 118 | #define RT5631_AUXOUT_2_VOL_SEL_OUTMIX_R (0x1 << 6) | ||
| 119 | |||
| 120 | /* Microphone Input Control 1(0x0E) */ | ||
| 121 | #define RT5631_MIC1_DIFF_INPUT_CTRL (0x1 << 15) | ||
| 122 | #define RT5631_MIC1_DIFF_INPUT_SHIFT 15 | ||
| 123 | #define RT5631_MIC2_DIFF_INPUT_CTRL (0x1 << 7) | ||
| 124 | #define RT5631_MIC2_DIFF_INPUT_SHIFT 7 | ||
| 125 | |||
| 126 | /* Stereo DAC Digital Volume2(0x10) */ | ||
| 127 | #define RT5631_DAC_VOL_MASK 0xff | ||
| 128 | |||
| 129 | /* ADC Recording Mixer Control(0x14) */ | ||
| 130 | #define RT5631_M_OUTMIXER_L_TO_RECMIXER_L (0x1 << 15) | ||
| 131 | #define RT5631_M_OUTMIXL_RECMIXL_BIT 15 | ||
| 132 | #define RT5631_M_MIC1_TO_RECMIXER_L (0x1 << 14) | ||
| 133 | #define RT5631_M_MIC1_RECMIXL_BIT 14 | ||
| 134 | #define RT5631_M_AXIL_TO_RECMIXER_L (0x1 << 13) | ||
| 135 | #define RT5631_M_AXIL_RECMIXL_BIT 13 | ||
| 136 | #define RT5631_M_MONO_IN_TO_RECMIXER_L (0x1 << 12) | ||
| 137 | #define RT5631_M_MONO_IN_RECMIXL_BIT 12 | ||
| 138 | #define RT5631_M_OUTMIXER_R_TO_RECMIXER_R (0x1 << 7) | ||
| 139 | #define RT5631_M_OUTMIXR_RECMIXR_BIT 7 | ||
| 140 | #define RT5631_M_MIC2_TO_RECMIXER_R (0x1 << 6) | ||
| 141 | #define RT5631_M_MIC2_RECMIXR_BIT 6 | ||
| 142 | #define RT5631_M_AXIR_TO_RECMIXER_R (0x1 << 5) | ||
| 143 | #define RT5631_M_AXIR_RECMIXR_BIT 5 | ||
| 144 | #define RT5631_M_MONO_IN_TO_RECMIXER_R (0x1 << 4) | ||
| 145 | #define RT5631_M_MONO_IN_RECMIXR_BIT 4 | ||
| 146 | |||
| 147 | /* Left Output Mixer Control(0x1A) */ | ||
| 148 | #define RT5631_M_RECMIXER_L_TO_OUTMIXER_L (0x1 << 15) | ||
| 149 | #define RT5631_M_RECMIXL_OUTMIXL_BIT 15 | ||
| 150 | #define RT5631_M_RECMIXER_R_TO_OUTMIXER_L (0x1 << 14) | ||
| 151 | #define RT5631_M_RECMIXR_OUTMIXL_BIT 14 | ||
| 152 | #define RT5631_M_DAC_L_TO_OUTMIXER_L (0x1 << 13) | ||
| 153 | #define RT5631_M_DACL_OUTMIXL_BIT 13 | ||
| 154 | #define RT5631_M_MIC1_TO_OUTMIXER_L (0x1 << 12) | ||
| 155 | #define RT5631_M_MIC1_OUTMIXL_BIT 12 | ||
| 156 | #define RT5631_M_MIC2_TO_OUTMIXER_L (0x1 << 11) | ||
| 157 | #define RT5631_M_MIC2_OUTMIXL_BIT 11 | ||
| 158 | #define RT5631_M_MONO_IN_P_TO_OUTMIXER_L (0x1 << 10) | ||
| 159 | #define RT5631_M_MONO_INP_OUTMIXL_BIT 10 | ||
| 160 | #define RT5631_M_AXIL_TO_OUTMIXER_L (0x1 << 9) | ||
| 161 | #define RT5631_M_AXIL_OUTMIXL_BIT 9 | ||
| 162 | #define RT5631_M_AXIR_TO_OUTMIXER_L (0x1 << 8) | ||
| 163 | #define RT5631_M_AXIR_OUTMIXL_BIT 8 | ||
| 164 | #define RT5631_M_VDAC_TO_OUTMIXER_L (0x1 << 7) | ||
| 165 | #define RT5631_M_VDAC_OUTMIXL_BIT 7 | ||
| 166 | |||
| 167 | /* Right Output Mixer Control(0x1C) */ | ||
| 168 | #define RT5631_M_RECMIXER_L_TO_OUTMIXER_R (0x1 << 15) | ||
| 169 | #define RT5631_M_RECMIXL_OUTMIXR_BIT 15 | ||
| 170 | #define RT5631_M_RECMIXER_R_TO_OUTMIXER_R (0x1 << 14) | ||
| 171 | #define RT5631_M_RECMIXR_OUTMIXR_BIT 14 | ||
| 172 | #define RT5631_M_DAC_R_TO_OUTMIXER_R (0x1 << 13) | ||
| 173 | #define RT5631_M_DACR_OUTMIXR_BIT 13 | ||
| 174 | #define RT5631_M_MIC1_TO_OUTMIXER_R (0x1 << 12) | ||
| 175 | #define RT5631_M_MIC1_OUTMIXR_BIT 12 | ||
| 176 | #define RT5631_M_MIC2_TO_OUTMIXER_R (0x1 << 11) | ||
| 177 | #define RT5631_M_MIC2_OUTMIXR_BIT 11 | ||
| 178 | #define RT5631_M_MONO_IN_N_TO_OUTMIXER_R (0x1 << 10) | ||
| 179 | #define RT5631_M_MONO_INN_OUTMIXR_BIT 10 | ||
| 180 | #define RT5631_M_AXIL_TO_OUTMIXER_R (0x1 << 9) | ||
| 181 | #define RT5631_M_AXIL_OUTMIXR_BIT 9 | ||
| 182 | #define RT5631_M_AXIR_TO_OUTMIXER_R (0x1 << 8) | ||
| 183 | #define RT5631_M_AXIR_OUTMIXR_BIT 8 | ||
| 184 | #define RT5631_M_VDAC_TO_OUTMIXER_R (0x1 << 7) | ||
| 185 | #define RT5631_M_VDAC_OUTMIXR_BIT 7 | ||
| 186 | |||
| 187 | /* Lout Mixer Control(0x1E) */ | ||
| 188 | #define RT5631_M_MIC1_TO_AXO1MIXER (0x1 << 15) | ||
| 189 | #define RT5631_M_MIC1_AXO1MIX_BIT 15 | ||
| 190 | #define RT5631_M_MIC2_TO_AXO1MIXER (0x1 << 11) | ||
| 191 | #define RT5631_M_MIC2_AXO1MIX_BIT 11 | ||
| 192 | #define RT5631_M_OUTMIXER_L_TO_AXO1MIXER (0x1 << 7) | ||
| 193 | #define RT5631_M_OUTMIXL_AXO1MIX_BIT 7 | ||
| 194 | #define RT5631_M_OUTMIXER_R_TO_AXO1MIXER (0x1 << 6) | ||
| 195 | #define RT5631_M_OUTMIXR_AXO1MIX_BIT 6 | ||
| 196 | |||
| 197 | /* Rout Mixer Control(0x20) */ | ||
| 198 | #define RT5631_M_MIC1_TO_AXO2MIXER (0x1 << 15) | ||
| 199 | #define RT5631_M_MIC1_AXO2MIX_BIT 15 | ||
| 200 | #define RT5631_M_MIC2_TO_AXO2MIXER (0x1 << 11) | ||
| 201 | #define RT5631_M_MIC2_AXO2MIX_BIT 11 | ||
| 202 | #define RT5631_M_OUTMIXER_L_TO_AXO2MIXER (0x1 << 7) | ||
| 203 | #define RT5631_M_OUTMIXL_AXO2MIX_BIT 7 | ||
| 204 | #define RT5631_M_OUTMIXER_R_TO_AXO2MIXER (0x1 << 6) | ||
| 205 | #define RT5631_M_OUTMIXR_AXO2MIX_BIT 6 | ||
| 206 | |||
| 207 | /* Micphone Input Control 2(0x22) */ | ||
| 208 | #define RT5631_MIC_BIAS_90_PRECNET_AVDD 1 | ||
| 209 | #define RT5631_MIC_BIAS_75_PRECNET_AVDD 2 | ||
| 210 | |||
| 211 | #define RT5631_MIC1_BOOST_CTRL_MASK (0xf << 12) | ||
| 212 | #define RT5631_MIC1_BOOST_CTRL_BYPASS (0x0 << 12) | ||
| 213 | #define RT5631_MIC1_BOOST_CTRL_20DB (0x1 << 12) | ||
| 214 | #define RT5631_MIC1_BOOST_CTRL_24DB (0x2 << 12) | ||
| 215 | #define RT5631_MIC1_BOOST_CTRL_30DB (0x3 << 12) | ||
| 216 | #define RT5631_MIC1_BOOST_CTRL_35DB (0x4 << 12) | ||
| 217 | #define RT5631_MIC1_BOOST_CTRL_40DB (0x5 << 12) | ||
| 218 | #define RT5631_MIC1_BOOST_CTRL_34DB (0x6 << 12) | ||
| 219 | #define RT5631_MIC1_BOOST_CTRL_50DB (0x7 << 12) | ||
| 220 | #define RT5631_MIC1_BOOST_CTRL_52DB (0x8 << 12) | ||
| 221 | #define RT5631_MIC1_BOOST_SHIFT 12 | ||
| 222 | |||
| 223 | #define RT5631_MIC2_BOOST_CTRL_MASK (0xf << 8) | ||
| 224 | #define RT5631_MIC2_BOOST_CTRL_BYPASS (0x0 << 8) | ||
| 225 | #define RT5631_MIC2_BOOST_CTRL_20DB (0x1 << 8) | ||
| 226 | #define RT5631_MIC2_BOOST_CTRL_24DB (0x2 << 8) | ||
| 227 | #define RT5631_MIC2_BOOST_CTRL_30DB (0x3 << 8) | ||
| 228 | #define RT5631_MIC2_BOOST_CTRL_35DB (0x4 << 8) | ||
| 229 | #define RT5631_MIC2_BOOST_CTRL_40DB (0x5 << 8) | ||
| 230 | #define RT5631_MIC2_BOOST_CTRL_34DB (0x6 << 8) | ||
| 231 | #define RT5631_MIC2_BOOST_CTRL_50DB (0x7 << 8) | ||
| 232 | #define RT5631_MIC2_BOOST_CTRL_52DB (0x8 << 8) | ||
| 233 | #define RT5631_MIC2_BOOST_SHIFT 8 | ||
| 234 | |||
| 235 | #define RT5631_MICBIAS1_VOLT_CTRL_MASK (0x1 << 7) | ||
| 236 | #define RT5631_MICBIAS1_VOLT_CTRL_90P (0x0 << 7) | ||
| 237 | #define RT5631_MICBIAS1_VOLT_CTRL_75P (0x1 << 7) | ||
| 238 | |||
| 239 | #define RT5631_MICBIAS1_S_C_DET_MASK (0x1 << 6) | ||
| 240 | #define RT5631_MICBIAS1_S_C_DET_DIS (0x0 << 6) | ||
| 241 | #define RT5631_MICBIAS1_S_C_DET_ENA (0x1 << 6) | ||
| 242 | |||
| 243 | #define RT5631_MICBIAS1_SHORT_CURR_DET_MASK (0x3 << 4) | ||
| 244 | #define RT5631_MICBIAS1_SHORT_CURR_DET_600UA (0x0 << 4) | ||
| 245 | #define RT5631_MICBIAS1_SHORT_CURR_DET_1500UA (0x1 << 4) | ||
| 246 | #define RT5631_MICBIAS1_SHORT_CURR_DET_2000UA (0x2 << 4) | ||
| 247 | |||
| 248 | #define RT5631_MICBIAS2_VOLT_CTRL_MASK (0x1 << 3) | ||
| 249 | #define RT5631_MICBIAS2_VOLT_CTRL_90P (0x0 << 3) | ||
| 250 | #define RT5631_MICBIAS2_VOLT_CTRL_75P (0x1 << 3) | ||
| 251 | |||
| 252 | #define RT5631_MICBIAS2_S_C_DET_MASK (0x1 << 2) | ||
| 253 | #define RT5631_MICBIAS2_S_C_DET_DIS (0x0 << 2) | ||
| 254 | #define RT5631_MICBIAS2_S_C_DET_ENA (0x1 << 2) | ||
| 255 | |||
| 256 | #define RT5631_MICBIAS2_SHORT_CURR_DET_MASK (0x3) | ||
| 257 | #define RT5631_MICBIAS2_SHORT_CURR_DET_600UA (0x0) | ||
| 258 | #define RT5631_MICBIAS2_SHORT_CURR_DET_1500UA (0x1) | ||
| 259 | #define RT5631_MICBIAS2_SHORT_CURR_DET_2000UA (0x2) | ||
| 260 | |||
| 261 | |||
| 262 | /* Digital Microphone Control(0x24) */ | ||
| 263 | #define RT5631_DMIC_ENA_MASK (0x1 << 15) | ||
| 264 | #define RT5631_DMIC_ENA_SHIFT 15 | ||
| 265 | /* DMIC_ENA: DMIC to ADC Digital filter */ | ||
| 266 | #define RT5631_DMIC_ENA (0x1 << 15) | ||
| 267 | /* DMIC_DIS: ADC mixer to ADC Digital filter */ | ||
| 268 | #define RT5631_DMIC_DIS (0x0 << 15) | ||
| 269 | #define RT5631_DMIC_L_CH_MUTE (0x1 << 13) | ||
| 270 | #define RT5631_DMIC_L_CH_MUTE_SHIFT 13 | ||
| 271 | #define RT5631_DMIC_R_CH_MUTE (0x1 << 12) | ||
| 272 | #define RT5631_DMIC_R_CH_MUTE_SHIFT 12 | ||
| 273 | #define RT5631_DMIC_L_CH_LATCH_MASK (0x1 << 9) | ||
| 274 | #define RT5631_DMIC_L_CH_LATCH_RISING (0x1 << 9) | ||
| 275 | #define RT5631_DMIC_L_CH_LATCH_FALLING (0x0 << 9) | ||
| 276 | #define RT5631_DMIC_R_CH_LATCH_MASK (0x1 << 8) | ||
| 277 | #define RT5631_DMIC_R_CH_LATCH_RISING (0x1 << 8) | ||
| 278 | #define RT5631_DMIC_R_CH_LATCH_FALLING (0x0 << 8) | ||
| 279 | #define RT5631_DMIC_CLK_CTRL_MASK (0x3 << 4) | ||
| 280 | #define RT5631_DMIC_CLK_CTRL_TO_128FS (0x0 << 4) | ||
| 281 | #define RT5631_DMIC_CLK_CTRL_TO_64FS (0x1 << 4) | ||
| 282 | #define RT5631_DMIC_CLK_CTRL_TO_32FS (0x2 << 4) | ||
| 283 | |||
| 284 | /* Microphone Input Volume(0x26) */ | ||
| 285 | #define RT5631_MONO_DIFF_INPUT_SHIFT 15 | ||
| 286 | |||
| 287 | /* Speaker Mixer Control(0x28) */ | ||
| 288 | #define RT5631_M_RECMIXER_L_TO_SPKMIXER_L (0x1 << 15) | ||
| 289 | #define RT5631_M_RECMIXL_SPKMIXL_BIT 15 | ||
| 290 | #define RT5631_M_MIC1_P_TO_SPKMIXER_L (0x1 << 14) | ||
| 291 | #define RT5631_M_MIC1P_SPKMIXL_BIT 14 | ||
| 292 | #define RT5631_M_DAC_L_TO_SPKMIXER_L (0x1 << 13) | ||
| 293 | #define RT5631_M_DACL_SPKMIXL_BIT 13 | ||
| 294 | #define RT5631_M_OUTMIXER_L_TO_SPKMIXER_L (0x1 << 12) | ||
| 295 | #define RT5631_M_OUTMIXL_SPKMIXL_BIT 12 | ||
| 296 | |||
| 297 | #define RT5631_M_RECMIXER_R_TO_SPKMIXER_R (0x1 << 7) | ||
| 298 | #define RT5631_M_RECMIXR_SPKMIXR_BIT 7 | ||
| 299 | #define RT5631_M_MIC2_P_TO_SPKMIXER_R (0x1 << 6) | ||
| 300 | #define RT5631_M_MIC2P_SPKMIXR_BIT 6 | ||
| 301 | #define RT5631_M_DAC_R_TO_SPKMIXER_R (0x1 << 5) | ||
| 302 | #define RT5631_M_DACR_SPKMIXR_BIT 5 | ||
| 303 | #define RT5631_M_OUTMIXER_R_TO_SPKMIXER_R (0x1 << 4) | ||
| 304 | #define RT5631_M_OUTMIXR_SPKMIXR_BIT 4 | ||
| 305 | |||
| 306 | /* Speaker/Mono Output Control(0x2A) */ | ||
| 307 | #define RT5631_M_SPKVOL_L_TO_SPOL_MIXER (0x1 << 15) | ||
| 308 | #define RT5631_M_SPKVOLL_SPOLMIX_BIT 15 | ||
| 309 | #define RT5631_M_SPKVOL_R_TO_SPOL_MIXER (0x1 << 14) | ||
| 310 | #define RT5631_M_SPKVOLR_SPOLMIX_BIT 14 | ||
| 311 | #define RT5631_M_SPKVOL_L_TO_SPOR_MIXER (0x1 << 13) | ||
| 312 | #define RT5631_M_SPKVOLL_SPORMIX_BIT 13 | ||
| 313 | #define RT5631_M_SPKVOL_R_TO_SPOR_MIXER (0x1 << 12) | ||
| 314 | #define RT5631_M_SPKVOLR_SPORMIX_BIT 12 | ||
| 315 | #define RT5631_M_OUTVOL_L_TO_MONOMIXER (0x1 << 11) | ||
| 316 | #define RT5631_M_OUTVOLL_MONOMIX_BIT 11 | ||
| 317 | #define RT5631_M_OUTVOL_R_TO_MONOMIXER (0x1 << 10) | ||
| 318 | #define RT5631_M_OUTVOLR_MONOMIX_BIT 10 | ||
| 319 | |||
| 320 | /* Speaker/Mono/HP Output Control(0x2C) */ | ||
| 321 | #define RT5631_SPK_L_MUX_SEL_MASK (0x3 << 14) | ||
| 322 | #define RT5631_SPK_L_MUX_SEL_SPKMIXER_L (0x0 << 14) | ||
| 323 | #define RT5631_SPK_L_MUX_SEL_MONO_IN (0x1 << 14) | ||
| 324 | #define RT5631_SPK_L_MUX_SEL_DAC_L (0x3 << 14) | ||
| 325 | #define RT5631_SPK_L_MUX_SEL_SHIFT 14 | ||
| 326 | |||
| 327 | #define RT5631_SPK_R_MUX_SEL_MASK (0x3 << 10) | ||
| 328 | #define RT5631_SPK_R_MUX_SEL_SPKMIXER_R (0x0 << 10) | ||
| 329 | #define RT5631_SPK_R_MUX_SEL_MONO_IN (0x1 << 10) | ||
| 330 | #define RT5631_SPK_R_MUX_SEL_DAC_R (0x3 << 10) | ||
| 331 | #define RT5631_SPK_R_MUX_SEL_SHIFT 10 | ||
| 332 | |||
| 333 | #define RT5631_MONO_MUX_SEL_MASK (0x3 << 6) | ||
| 334 | #define RT5631_MONO_MUX_SEL_MONOMIXER (0x0 << 6) | ||
| 335 | #define RT5631_MONO_MUX_SEL_MONO_IN (0x1 << 6) | ||
| 336 | #define RT5631_MONO_MUX_SEL_SHIFT 6 | ||
| 337 | |||
| 338 | #define RT5631_HP_L_MUX_SEL_MASK (0x1 << 3) | ||
| 339 | #define RT5631_HP_L_MUX_SEL_HPVOL_L (0x0 << 3) | ||
| 340 | #define RT5631_HP_L_MUX_SEL_DAC_L (0x1 << 3) | ||
| 341 | #define RT5631_HP_L_MUX_SEL_SHIFT 3 | ||
| 342 | |||
| 343 | #define RT5631_HP_R_MUX_SEL_MASK (0x1 << 2) | ||
| 344 | #define RT5631_HP_R_MUX_SEL_HPVOL_R (0x0 << 2) | ||
| 345 | #define RT5631_HP_R_MUX_SEL_DAC_R (0x1 << 2) | ||
| 346 | #define RT5631_HP_R_MUX_SEL_SHIFT 2 | ||
| 347 | |||
| 348 | /* Stereo I2S Serial Data Port Control(0x34) */ | ||
| 349 | #define RT5631_SDP_MODE_SEL_MASK (0x1 << 15) | ||
| 350 | #define RT5631_SDP_MODE_SEL_MASTER (0x0 << 15) | ||
| 351 | #define RT5631_SDP_MODE_SEL_SLAVE (0x1 << 15) | ||
| 352 | |||
| 353 | #define RT5631_SDP_ADC_CPS_SEL_MASK (0x3 << 10) | ||
| 354 | #define RT5631_SDP_ADC_CPS_SEL_OFF (0x0 << 10) | ||
| 355 | #define RT5631_SDP_ADC_CPS_SEL_U_LAW (0x1 << 10) | ||
| 356 | #define RT5631_SDP_ADC_CPS_SEL_A_LAW (0x2 << 10) | ||
| 357 | |||
| 358 | #define RT5631_SDP_DAC_CPS_SEL_MASK (0x3 << 8) | ||
| 359 | #define RT5631_SDP_DAC_CPS_SEL_OFF (0x0 << 8) | ||
| 360 | #define RT5631_SDP_DAC_CPS_SEL_U_LAW (0x1 << 8) | ||
| 361 | #define RT5631_SDP_DAC_CPS_SEL_A_LAW (0x2 << 8) | ||
| 362 | /* 0:Normal 1:Invert */ | ||
| 363 | #define RT5631_SDP_I2S_BCLK_POL_CTRL (0x1 << 7) | ||
| 364 | /* 0:Normal 1:Invert */ | ||
| 365 | #define RT5631_SDP_DAC_R_INV (0x1 << 6) | ||
| 366 | /* 0:ADC data appear at left phase of LRCK | ||
| 367 | * 1:ADC data appear at right phase of LRCK | ||
| 368 | */ | ||
| 369 | #define RT5631_SDP_ADC_DATA_L_R_SWAP (0x1 << 5) | ||
| 370 | /* 0:DAC data appear at left phase of LRCK | ||
| 371 | * 1:DAC data appear at right phase of LRCK | ||
| 372 | */ | ||
| 373 | #define RT5631_SDP_DAC_DATA_L_R_SWAP (0x1 << 4) | ||
| 374 | |||
| 375 | /* Data Length Slection */ | ||
| 376 | #define RT5631_SDP_I2S_DL_MASK (0x3 << 2) | ||
| 377 | #define RT5631_SDP_I2S_DL_16 (0x0 << 2) | ||
| 378 | #define RT5631_SDP_I2S_DL_20 (0x1 << 2) | ||
| 379 | #define RT5631_SDP_I2S_DL_24 (0x2 << 2) | ||
| 380 | #define RT5631_SDP_I2S_DL_8 (0x3 << 2) | ||
| 381 | |||
| 382 | /* PCM Data Format Selection */ | ||
| 383 | #define RT5631_SDP_I2S_DF_MASK (0x3) | ||
| 384 | #define RT5631_SDP_I2S_DF_I2S (0x0) | ||
| 385 | #define RT5631_SDP_I2S_DF_LEFT (0x1) | ||
| 386 | #define RT5631_SDP_I2S_DF_PCM_A (0x2) | ||
| 387 | #define RT5631_SDP_I2S_DF_PCM_B (0x3) | ||
| 388 | |||
| 389 | /* Stereo AD/DA Clock Control(0x38h) */ | ||
| 390 | #define RT5631_I2S_PRE_DIV_MASK (0x7 << 13) | ||
| 391 | #define RT5631_I2S_PRE_DIV_1 (0x0 << 13) | ||
| 392 | #define RT5631_I2S_PRE_DIV_2 (0x1 << 13) | ||
| 393 | #define RT5631_I2S_PRE_DIV_4 (0x2 << 13) | ||
| 394 | #define RT5631_I2S_PRE_DIV_8 (0x3 << 13) | ||
| 395 | #define RT5631_I2S_PRE_DIV_16 (0x4 << 13) | ||
| 396 | #define RT5631_I2S_PRE_DIV_32 (0x5 << 13) | ||
| 397 | /* CLOCK RELATIVE OF BCLK AND LCRK */ | ||
| 398 | #define RT5631_I2S_LRCK_SEL_N_BCLK_MASK (0x1 << 12) | ||
| 399 | #define RT5631_I2S_LRCK_SEL_64_BCLK (0x0 << 12) /* 64FS */ | ||
| 400 | #define RT5631_I2S_LRCK_SEL_32_BCLK (0x1 << 12) /* 32FS */ | ||
| 401 | |||
| 402 | #define RT5631_DAC_OSR_SEL_MASK (0x3 << 10) | ||
| 403 | #define RT5631_DAC_OSR_SEL_128FS (0x3 << 10) | ||
| 404 | #define RT5631_DAC_OSR_SEL_64FS (0x3 << 10) | ||
| 405 | #define RT5631_DAC_OSR_SEL_32FS (0x3 << 10) | ||
| 406 | #define RT5631_DAC_OSR_SEL_16FS (0x3 << 10) | ||
| 407 | |||
| 408 | #define RT5631_ADC_OSR_SEL_MASK (0x3 << 8) | ||
| 409 | #define RT5631_ADC_OSR_SEL_128FS (0x3 << 8) | ||
| 410 | #define RT5631_ADC_OSR_SEL_64FS (0x3 << 8) | ||
| 411 | #define RT5631_ADC_OSR_SEL_32FS (0x3 << 8) | ||
| 412 | #define RT5631_ADC_OSR_SEL_16FS (0x3 << 8) | ||
| 413 | |||
| 414 | #define RT5631_ADDA_FILTER_CLK_SEL_256FS (0 << 7) /* 256FS */ | ||
| 415 | #define RT5631_ADDA_FILTER_CLK_SEL_384FS (1 << 7) /* 384FS */ | ||
| 416 | |||
| 417 | /* Power managment addition 1 (0x3A) */ | ||
| 418 | #define RT5631_PWR_MAIN_I2S_EN (0x1 << 15) | ||
| 419 | #define RT5631_PWR_MAIN_I2S_BIT 15 | ||
| 420 | #define RT5631_PWR_CLASS_D (0x1 << 12) | ||
| 421 | #define RT5631_PWR_CLASS_D_BIT 12 | ||
| 422 | #define RT5631_PWR_ADC_L_CLK (0x1 << 11) | ||
| 423 | #define RT5631_PWR_ADC_L_CLK_BIT 11 | ||
| 424 | #define RT5631_PWR_ADC_R_CLK (0x1 << 10) | ||
| 425 | #define RT5631_PWR_ADC_R_CLK_BIT 10 | ||
| 426 | #define RT5631_PWR_DAC_L_CLK (0x1 << 9) | ||
| 427 | #define RT5631_PWR_DAC_L_CLK_BIT 9 | ||
| 428 | #define RT5631_PWR_DAC_R_CLK (0x1 << 8) | ||
| 429 | #define RT5631_PWR_DAC_R_CLK_BIT 8 | ||
| 430 | #define RT5631_PWR_DAC_REF (0x1 << 7) | ||
| 431 | #define RT5631_PWR_DAC_REF_BIT 7 | ||
| 432 | #define RT5631_PWR_DAC_L_TO_MIXER (0x1 << 6) | ||
| 433 | #define RT5631_PWR_DAC_L_TO_MIXER_BIT 6 | ||
| 434 | #define RT5631_PWR_DAC_R_TO_MIXER (0x1 << 5) | ||
| 435 | #define RT5631_PWR_DAC_R_TO_MIXER_BIT 5 | ||
| 436 | |||
| 437 | /* Power managment addition 2 (0x3B) */ | ||
| 438 | #define RT5631_PWR_OUTMIXER_L (0x1 << 15) | ||
| 439 | #define RT5631_PWR_OUTMIXER_L_BIT 15 | ||
| 440 | #define RT5631_PWR_OUTMIXER_R (0x1 << 14) | ||
| 441 | #define RT5631_PWR_OUTMIXER_R_BIT 14 | ||
| 442 | #define RT5631_PWR_SPKMIXER_L (0x1 << 13) | ||
| 443 | #define RT5631_PWR_SPKMIXER_L_BIT 13 | ||
| 444 | #define RT5631_PWR_SPKMIXER_R (0x1 << 12) | ||
| 445 | #define RT5631_PWR_SPKMIXER_R_BIT 12 | ||
| 446 | #define RT5631_PWR_RECMIXER_L (0x1 << 11) | ||
| 447 | #define RT5631_PWR_RECMIXER_L_BIT 11 | ||
| 448 | #define RT5631_PWR_RECMIXER_R (0x1 << 10) | ||
| 449 | #define RT5631_PWR_RECMIXER_R_BIT 10 | ||
| 450 | #define RT5631_PWR_MIC1_BOOT_GAIN (0x1 << 5) | ||
| 451 | #define RT5631_PWR_MIC1_BOOT_GAIN_BIT 5 | ||
| 452 | #define RT5631_PWR_MIC2_BOOT_GAIN (0x1 << 4) | ||
| 453 | #define RT5631_PWR_MIC2_BOOT_GAIN_BIT 4 | ||
| 454 | #define RT5631_PWR_MICBIAS1_VOL (0x1 << 3) | ||
| 455 | #define RT5631_PWR_MICBIAS1_VOL_BIT 3 | ||
| 456 | #define RT5631_PWR_MICBIAS2_VOL (0x1 << 2) | ||
| 457 | #define RT5631_PWR_MICBIAS2_VOL_BIT 2 | ||
| 458 | #define RT5631_PWR_PLL1 (0x1 << 1) | ||
| 459 | #define RT5631_PWR_PLL1_BIT 1 | ||
| 460 | #define RT5631_PWR_PLL2 (0x1 << 0) | ||
| 461 | #define RT5631_PWR_PLL2_BIT 0 | ||
| 462 | |||
| 463 | /* Power managment addition 3(0x3C) */ | ||
| 464 | #define RT5631_PWR_VREF (0x1 << 15) | ||
| 465 | #define RT5631_PWR_VREF_BIT 15 | ||
| 466 | #define RT5631_PWR_FAST_VREF_CTRL (0x1 << 14) | ||
| 467 | #define RT5631_PWR_FAST_VREF_CTRL_BIT 14 | ||
| 468 | #define RT5631_PWR_MAIN_BIAS (0x1 << 13) | ||
| 469 | #define RT5631_PWR_MAIN_BIAS_BIT 13 | ||
| 470 | #define RT5631_PWR_AXO1MIXER (0x1 << 11) | ||
| 471 | #define RT5631_PWR_AXO1MIXER_BIT 11 | ||
| 472 | #define RT5631_PWR_AXO2MIXER (0x1 << 10) | ||
| 473 | #define RT5631_PWR_AXO2MIXER_BIT 10 | ||
| 474 | #define RT5631_PWR_MONOMIXER (0x1 << 9) | ||
| 475 | #define RT5631_PWR_MONOMIXER_BIT 9 | ||
| 476 | #define RT5631_PWR_MONO_DEPOP_DIS (0x1 << 8) | ||
| 477 | #define RT5631_PWR_MONO_DEPOP_DIS_BIT 8 | ||
| 478 | #define RT5631_PWR_MONO_AMP_EN (0x1 << 7) | ||
| 479 | #define RT5631_PWR_MONO_AMP_EN_BIT 7 | ||
| 480 | #define RT5631_PWR_CHARGE_PUMP (0x1 << 4) | ||
| 481 | #define RT5631_PWR_CHARGE_PUMP_BIT 4 | ||
| 482 | #define RT5631_PWR_HP_L_AMP (0x1 << 3) | ||
| 483 | #define RT5631_PWR_HP_L_AMP_BIT 3 | ||
| 484 | #define RT5631_PWR_HP_R_AMP (0x1 << 2) | ||
| 485 | #define RT5631_PWR_HP_R_AMP_BIT 2 | ||
| 486 | #define RT5631_PWR_HP_DEPOP_DIS (0x1 << 1) | ||
| 487 | #define RT5631_PWR_HP_DEPOP_DIS_BIT 1 | ||
| 488 | #define RT5631_PWR_HP_AMP_DRIVING (0x1 << 0) | ||
| 489 | #define RT5631_PWR_HP_AMP_DRIVING_BIT 0 | ||
| 490 | |||
| 491 | /* Power managment addition 4(0x3E) */ | ||
| 492 | #define RT5631_PWR_SPK_L_VOL (0x1 << 15) | ||
| 493 | #define RT5631_PWR_SPK_L_VOL_BIT 15 | ||
| 494 | #define RT5631_PWR_SPK_R_VOL (0x1 << 14) | ||
| 495 | #define RT5631_PWR_SPK_R_VOL_BIT 14 | ||
| 496 | #define RT5631_PWR_LOUT_VOL (0x1 << 13) | ||
| 497 | #define RT5631_PWR_LOUT_VOL_BIT 13 | ||
| 498 | #define RT5631_PWR_ROUT_VOL (0x1 << 12) | ||
| 499 | #define RT5631_PWR_ROUT_VOL_BIT 12 | ||
| 500 | #define RT5631_PWR_HP_L_OUT_VOL (0x1 << 11) | ||
| 501 | #define RT5631_PWR_HP_L_OUT_VOL_BIT 11 | ||
| 502 | #define RT5631_PWR_HP_R_OUT_VOL (0x1 << 10) | ||
| 503 | #define RT5631_PWR_HP_R_OUT_VOL_BIT 10 | ||
| 504 | #define RT5631_PWR_AXIL_IN_VOL (0x1 << 9) | ||
| 505 | #define RT5631_PWR_AXIL_IN_VOL_BIT 9 | ||
| 506 | #define RT5631_PWR_AXIR_IN_VOL (0x1 << 8) | ||
| 507 | #define RT5631_PWR_AXIR_IN_VOL_BIT 8 | ||
| 508 | #define RT5631_PWR_MONO_IN_P_VOL (0x1 << 7) | ||
| 509 | #define RT5631_PWR_MONO_IN_P_VOL_BIT 7 | ||
| 510 | #define RT5631_PWR_MONO_IN_N_VOL (0x1 << 6) | ||
| 511 | #define RT5631_PWR_MONO_IN_N_VOL_BIT 6 | ||
| 512 | |||
| 513 | /* General Purpose Control Register(0x40) */ | ||
| 514 | #define RT5631_SPK_AMP_AUTO_RATIO_EN (0x1 << 15) | ||
| 515 | |||
| 516 | #define RT5631_SPK_AMP_RATIO_CTRL_MASK (0x7 << 12) | ||
| 517 | #define RT5631_SPK_AMP_RATIO_CTRL_2_34 (0x0 << 12) /* 7.40DB */ | ||
| 518 | #define RT5631_SPK_AMP_RATIO_CTRL_1_99 (0x1 << 12) /* 5.99DB */ | ||
| 519 | #define RT5631_SPK_AMP_RATIO_CTRL_1_68 (0x2 << 12) /* 4.50DB */ | ||
| 520 | #define RT5631_SPK_AMP_RATIO_CTRL_1_56 (0x3 << 12) /* 3.86DB */ | ||
| 521 | #define RT5631_SPK_AMP_RATIO_CTRL_1_44 (0x4 << 12) /* 3.16DB */ | ||
| 522 | #define RT5631_SPK_AMP_RATIO_CTRL_1_27 (0x5 << 12) /* 2.10DB */ | ||
| 523 | #define RT5631_SPK_AMP_RATIO_CTRL_1_09 (0x6 << 12) /* 0.80DB */ | ||
| 524 | #define RT5631_SPK_AMP_RATIO_CTRL_1_00 (0x7 << 12) /* 0.00DB */ | ||
| 525 | #define RT5631_SPK_AMP_RATIO_CTRL_SHIFT 12 | ||
| 526 | |||
| 527 | #define RT5631_STEREO_DAC_HI_PASS_FILT_EN (0x1 << 11) | ||
| 528 | #define RT5631_STEREO_ADC_HI_PASS_FILT_EN (0x1 << 10) | ||
| 529 | /* Select ADC Wind Filter Clock type */ | ||
| 530 | #define RT5631_ADC_WIND_FILT_MASK (0x3 << 4) | ||
| 531 | #define RT5631_ADC_WIND_FILT_8_16_32K (0x0 << 4) /*8/16/32k*/ | ||
| 532 | #define RT5631_ADC_WIND_FILT_11_22_44K (0x1 << 4) /*11/22/44k*/ | ||
| 533 | #define RT5631_ADC_WIND_FILT_12_24_48K (0x2 << 4) /*12/24/48k*/ | ||
| 534 | #define RT5631_ADC_WIND_FILT_EN (0x1 << 3) | ||
| 535 | /* SelectADC Wind Filter Corner Frequency */ | ||
| 536 | #define RT5631_ADC_WIND_CNR_FREQ_MASK (0x7 << 0) | ||
| 537 | #define RT5631_ADC_WIND_CNR_FREQ_82_113_122 (0x0 << 0) /* 82/113/122 Hz */ | ||
| 538 | #define RT5631_ADC_WIND_CNR_FREQ_102_141_153 (0x1 << 0) /* 102/141/153 Hz */ | ||
| 539 | #define RT5631_ADC_WIND_CNR_FREQ_131_180_156 (0x2 << 0) /* 131/180/156 Hz */ | ||
| 540 | #define RT5631_ADC_WIND_CNR_FREQ_163_225_245 (0x3 << 0) /* 163/225/245 Hz */ | ||
| 541 | #define RT5631_ADC_WIND_CNR_FREQ_204_281_306 (0x4 << 0) /* 204/281/306 Hz */ | ||
| 542 | #define RT5631_ADC_WIND_CNR_FREQ_261_360_392 (0x5 << 0) /* 261/360/392 Hz */ | ||
| 543 | #define RT5631_ADC_WIND_CNR_FREQ_327_450_490 (0x6 << 0) /* 327/450/490 Hz */ | ||
| 544 | #define RT5631_ADC_WIND_CNR_FREQ_408_563_612 (0x7 << 0) /* 408/563/612 Hz */ | ||
| 545 | |||
| 546 | /* Global Clock Control Register(0x42) */ | ||
| 547 | #define RT5631_SYSCLK_SOUR_SEL_MASK (0x3 << 14) | ||
| 548 | #define RT5631_SYSCLK_SOUR_SEL_MCLK (0x0 << 14) | ||
| 549 | #define RT5631_SYSCLK_SOUR_SEL_PLL (0x1 << 14) | ||
| 550 | #define RT5631_SYSCLK_SOUR_SEL_PLL_TCK (0x2 << 14) | ||
| 551 | |||
| 552 | #define RT5631_PLLCLK_SOUR_SEL_MASK (0x3 << 12) | ||
| 553 | #define RT5631_PLLCLK_SOUR_SEL_MCLK (0x0 << 12) | ||
| 554 | #define RT5631_PLLCLK_SOUR_SEL_BCLK (0x1 << 12) | ||
| 555 | #define RT5631_PLLCLK_SOUR_SEL_VBCLK (0x2 << 12) | ||
| 556 | |||
| 557 | #define RT5631_PLLCLK_PRE_DIV1 (0x0 << 11) | ||
| 558 | #define RT5631_PLLCLK_PRE_DIV2 (0x1 << 11) | ||
| 559 | |||
| 560 | /* PLL Control(0x44) */ | ||
| 561 | #define RT5631_PLL_CTRL_M_VAL(m) ((m)&0xf) | ||
| 562 | #define RT5631_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4) | ||
| 563 | #define RT5631_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8) | ||
| 564 | |||
| 565 | /* Internal Status and IRQ Control2(0x4A) */ | ||
| 566 | #define RT5631_ADC_DATA_SEL_MASK (0x3 << 14) | ||
| 567 | #define RT5631_ADC_DATA_SEL_Disable (0x0 << 14) | ||
| 568 | #define RT5631_ADC_DATA_SEL_MIC1 (0x1 << 14) | ||
| 569 | #define RT5631_ADC_DATA_SEL_MIC1_SHIFT 14 | ||
| 570 | #define RT5631_ADC_DATA_SEL_MIC2 (0x2 << 14) | ||
| 571 | #define RT5631_ADC_DATA_SEL_MIC2_SHIFT 15 | ||
| 572 | #define RT5631_ADC_DATA_SEL_STO (0x3 << 14) | ||
| 573 | #define RT5631_ADC_DATA_SEL_SHIFT 14 | ||
| 574 | |||
| 575 | /* GPIO Pin Configuration(0x4C) */ | ||
| 576 | #define RT5631_GPIO_PIN_FUN_SEL_MASK (0x1 << 15) | ||
| 577 | #define RT5631_GPIO_PIN_FUN_SEL_IRQ (0x1 << 15) | ||
| 578 | #define RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC (0x0 << 15) | ||
| 579 | |||
| 580 | #define RT5631_GPIO_DMIC_FUN_SEL_MASK (0x1 << 3) | ||
| 581 | #define RT5631_GPIO_DMIC_FUN_SEL_DIMC (0x1 << 3) | ||
| 582 | #define RT5631_GPIO_DMIC_FUN_SEL_GPIO (0x0 << 3) | ||
| 583 | |||
| 584 | #define RT5631_GPIO_PIN_CON_MASK (0x1 << 2) | ||
| 585 | #define RT5631_GPIO_PIN_SET_INPUT (0x0 << 2) | ||
| 586 | #define RT5631_GPIO_PIN_SET_OUTPUT (0x1 << 2) | ||
| 587 | |||
| 588 | /* De-POP function Control 1(0x54) */ | ||
| 589 | #define RT5631_POW_ON_SOFT_GEN (0x1 << 15) | ||
| 590 | #define RT5631_EN_MUTE_UNMUTE_DEPOP (0x1 << 14) | ||
| 591 | #define RT5631_EN_DEPOP2_FOR_HP (0x1 << 7) | ||
| 592 | /* Power Down HPAMP_L Starts Up Signal */ | ||
| 593 | #define RT5631_PD_HPAMP_L_ST_UP (0x1 << 5) | ||
| 594 | /* Power Down HPAMP_R Starts Up Signal */ | ||
| 595 | #define RT5631_PD_HPAMP_R_ST_UP (0x1 << 4) | ||
| 596 | /* Enable left HP mute/unmute depop */ | ||
| 597 | #define RT5631_EN_HP_L_M_UN_MUTE_DEPOP (0x1 << 1) | ||
| 598 | /* Enable right HP mute/unmute depop */ | ||
| 599 | #define RT5631_EN_HP_R_M_UN_MUTE_DEPOP (0x1 << 0) | ||
| 600 | |||
| 601 | /* De-POP Fnction Control(0x56) */ | ||
| 602 | #define RT5631_EN_ONE_BIT_DEPOP (0x1 << 15) | ||
| 603 | #define RT5631_EN_CAP_FREE_DEPOP (0x1 << 14) | ||
| 604 | |||
| 605 | /* Jack Detect Control Register(0x5A) */ | ||
| 606 | #define RT5631_JD_USE_MASK (0x3 << 14) | ||
| 607 | #define RT5631_JD_USE_JD2 (0x3 << 14) | ||
| 608 | #define RT5631_JD_USE_JD1 (0x2 << 14) | ||
| 609 | #define RT5631_JD_USE_GPIO (0x1 << 14) | ||
| 610 | #define RT5631_JD_OFF (0x0 << 14) | ||
| 611 | /* JD trigger enable for HP */ | ||
| 612 | #define RT5631_JD_HP_EN (0x1 << 11) | ||
| 613 | #define RT5631_JD_HP_TRI_MASK (0x1 << 10) | ||
| 614 | #define RT5631_JD_HP_TRI_HI (0x1 << 10) | ||
| 615 | #define RT5631_JD_HP_TRI_LO (0x1 << 10) | ||
| 616 | /* JD trigger enable for speaker LP/LN */ | ||
| 617 | #define RT5631_JD_SPK_L_EN (0x1 << 9) | ||
| 618 | #define RT5631_JD_SPK_L_TRI_MASK (0x1 << 8) | ||
| 619 | #define RT5631_JD_SPK_L_TRI_HI (0x1 << 8) | ||
| 620 | #define RT5631_JD_SPK_L_TRI_LO (0x0 << 8) | ||
| 621 | /* JD trigger enable for speaker RP/RN */ | ||
| 622 | #define RT5631_JD_SPK_R_EN (0x1 << 7) | ||
| 623 | #define RT5631_JD_SPK_R_TRI_MASK (0x1 << 6) | ||
| 624 | #define RT5631_JD_SPK_R_TRI_HI (0x1 << 6) | ||
| 625 | #define RT5631_JD_SPK_R_TRI_LO (0x0 << 6) | ||
| 626 | /* JD trigger enable for monoout */ | ||
| 627 | #define RT5631_JD_MONO_EN (0x1 << 5) | ||
| 628 | #define RT5631_JD_MONO_TRI_MASK (0x1 << 4) | ||
| 629 | #define RT5631_JD_MONO_TRI_HI (0x1 << 4) | ||
| 630 | #define RT5631_JD_MONO_TRI_LO (0x0 << 4) | ||
| 631 | /* JD trigger enable for Lout */ | ||
| 632 | #define RT5631_JD_AUX_1_EN (0x1 << 3) | ||
| 633 | #define RT5631_JD_AUX_1_MASK (0x1 << 2) | ||
| 634 | #define RT5631_JD_AUX_1_TRI_HI (0x1 << 2) | ||
| 635 | #define RT5631_JD_AUX_1_TRI_LO (0x0 << 2) | ||
| 636 | /* JD trigger enable for Rout */ | ||
| 637 | #define RT5631_JD_AUX_2_EN (0x1 << 1) | ||
| 638 | #define RT5631_JD_AUX_2_MASK (0x1 << 0) | ||
| 639 | #define RT5631_JD_AUX_2_TRI_HI (0x1 << 0) | ||
| 640 | #define RT5631_JD_AUX_2_TRI_LO (0x0 << 0) | ||
| 641 | |||
| 642 | /* ALC CONTROL 1(0x64) */ | ||
| 643 | #define RT5631_ALC_ATTACK_RATE_MASK (0x1F << 8) | ||
| 644 | #define RT5631_ALC_RECOVERY_RATE_MASK (0x1F << 0) | ||
| 645 | |||
| 646 | /* ALC CONTROL 2(0x65) */ | ||
| 647 | /* select Compensation gain for Noise gate function */ | ||
| 648 | #define RT5631_ALC_COM_NOISE_GATE_MASK (0xF << 0) | ||
| 649 | |||
| 650 | /* ALC CONTROL 3(0x66) */ | ||
| 651 | #define RT5631_ALC_FUN_MASK (0x3 << 14) | ||
| 652 | #define RT5631_ALC_FUN_DIS (0x0 << 14) | ||
| 653 | #define RT5631_ALC_ENA_DAC_PATH (0x1 << 14) | ||
| 654 | #define RT5631_ALC_ENA_ADC_PATH (0x3 << 14) | ||
| 655 | #define RT5631_ALC_PARA_UPDATE (0x1 << 13) | ||
| 656 | #define RT5631_ALC_LIMIT_LEVEL_MASK (0x1F << 8) | ||
| 657 | #define RT5631_ALC_NOISE_GATE_FUN_MASK (0x1 << 7) | ||
| 658 | #define RT5631_ALC_NOISE_GATE_FUN_DIS (0x0 << 7) | ||
| 659 | #define RT5631_ALC_NOISE_GATE_FUN_ENA (0x1 << 7) | ||
| 660 | /* ALC noise gate hold data function */ | ||
| 661 | #define RT5631_ALC_NOISE_GATE_H_D_MASK (0x1 << 6) | ||
| 662 | #define RT5631_ALC_NOISE_GATE_H_D_DIS (0x0 << 6) | ||
| 663 | #define RT5631_ALC_NOISE_GATE_H_D_ENA (0x1 << 6) | ||
| 664 | |||
| 665 | /* Psedueo Stereo & Spatial Effect Block Control(0x68) */ | ||
| 666 | #define RT5631_SPATIAL_CTRL_EN (0x1 << 15) | ||
| 667 | #define RT5631_ALL_PASS_FILTER_EN (0x1 << 14) | ||
| 668 | #define RT5631_PSEUDO_STEREO_EN (0x1 << 13) | ||
| 669 | #define RT5631_STEREO_EXPENSION_EN (0x1 << 12) | ||
| 670 | /* 3D gain parameter */ | ||
| 671 | #define RT5631_GAIN_3D_PARA_MASK (0x3 << 6) | ||
| 672 | #define RT5631_GAIN_3D_PARA_1_00 (0x0 << 6) /* 3D gain 1.0 */ | ||
| 673 | #define RT5631_GAIN_3D_PARA_1_50 (0x1 << 6) /* 3D gain 1.5 */ | ||
| 674 | #define RT5631_GAIN_3D_PARA_2_00 (0x2 << 6) /* 3D gain 2.0 */ | ||
| 675 | /* 3D ratio parameter */ | ||
| 676 | #define RT5631_RATIO_3D_MASK (0x3 << 4) | ||
| 677 | #define RT5631_RATIO_3D_0_0 (0x0 << 4) /* 3D ratio 0.0 */ | ||
| 678 | #define RT5631_RATIO_3D_0_66 (0x1 << 4) /* 3D ratio 0.66 */ | ||
| 679 | #define RT5631_RATIO_3D_1_0 (0x2 << 4) /* 3D ratio 1.0 */ | ||
| 680 | /* select samplerate for all pass filter */ | ||
| 681 | #define RT5631_APF_FUN_SLE_MASK (0x3 << 0) | ||
| 682 | #define RT5631_APF_FUN_SEL_48K (0x3 << 0) | ||
| 683 | #define RT5631_APF_FUN_SEL_44_1K (0x2 << 0) | ||
| 684 | #define RT5631_APF_FUN_SEL_32K (0x1 << 0) | ||
| 685 | #define RT5631_APF_FUN_DIS (0x0 << 0) | ||
| 686 | |||
| 687 | /* EQ CONTROL 1(0x6E) */ | ||
| 688 | #define RT5631_HW_EQ_PATH_SEL_MASK (0x1 << 15) | ||
| 689 | #define RT5631_HW_EQ_PATH_SEL_DAC (0x0 << 15) | ||
| 690 | #define RT5631_HW_EQ_PATH_SEL_ADC (0x1 << 15) | ||
| 691 | #define RT5631_HW_EQ_UPDATE_CTRL (0x1 << 14) | ||
| 692 | |||
| 693 | #define RT5631_EN_HW_EQ_HPF2 (0x1 << 5) | ||
| 694 | #define RT5631_EN_HW_EQ_HPF1 (0x1 << 4) | ||
| 695 | #define RT5631_EN_HW_EQ_BP3 (0x1 << 3) | ||
| 696 | #define RT5631_EN_HW_EQ_BP2 (0x1 << 2) | ||
| 697 | #define RT5631_EN_HW_EQ_BP1 (0x1 << 1) | ||
| 698 | #define RT5631_EN_HW_EQ_LPF (0x1 << 0) | ||
| 699 | |||
| 700 | |||
| 701 | #endif /* __RTCODEC5631_H__ */ | ||
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 7e4066e131e6..d15695d1c273 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/regulator/driver.h> | 20 | #include <linux/regulator/driver.h> |
| 21 | #include <linux/regulator/machine.h> | 21 | #include <linux/regulator/machine.h> |
| 22 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
| 23 | #include <linux/of_device.h> | ||
| 23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
| 24 | #include <sound/tlv.h> | 25 | #include <sound/tlv.h> |
| 25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
| @@ -130,16 +131,13 @@ static int mic_bias_event(struct snd_soc_dapm_widget *w, | |||
| 130 | case SND_SOC_DAPM_POST_PMU: | 131 | case SND_SOC_DAPM_POST_PMU: |
| 131 | /* change mic bias resistor to 4Kohm */ | 132 | /* change mic bias resistor to 4Kohm */ |
| 132 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, | 133 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, |
| 133 | SGTL5000_BIAS_R_4k, SGTL5000_BIAS_R_4k); | 134 | SGTL5000_BIAS_R_MASK, |
| 135 | SGTL5000_BIAS_R_4k << SGTL5000_BIAS_R_SHIFT); | ||
| 134 | break; | 136 | break; |
| 135 | 137 | ||
| 136 | case SND_SOC_DAPM_PRE_PMD: | 138 | case SND_SOC_DAPM_PRE_PMD: |
| 137 | /* | ||
| 138 | * SGTL5000_BIAS_R_8k as mask to clean the two bits | ||
| 139 | * of mic bias and output impedance | ||
| 140 | */ | ||
| 141 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, | 139 | snd_soc_update_bits(w->codec, SGTL5000_CHIP_MIC_CTRL, |
| 142 | SGTL5000_BIAS_R_8k, 0); | 140 | SGTL5000_BIAS_R_MASK, 0); |
| 143 | break; | 141 | break; |
| 144 | } | 142 | } |
| 145 | return 0; | 143 | return 0; |
| @@ -725,7 +723,9 @@ static int sgtl5000_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 725 | return -EINVAL; | 723 | return -EINVAL; |
| 726 | } | 724 | } |
| 727 | 725 | ||
| 728 | snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, i2s_ctl, i2s_ctl); | 726 | snd_soc_update_bits(codec, SGTL5000_CHIP_I2S_CTRL, |
| 727 | SGTL5000_I2S_DLEN_MASK | SGTL5000_I2S_SCLKFREQ_MASK, | ||
| 728 | i2s_ctl); | ||
| 729 | 729 | ||
| 730 | return 0; | 730 | return 0; |
| 731 | } | 731 | } |
| @@ -756,7 +756,7 @@ static int ldo_regulator_enable(struct regulator_dev *dev) | |||
| 756 | 756 | ||
| 757 | /* set voltage to register */ | 757 | /* set voltage to register */ |
| 758 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, | 758 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, |
| 759 | (0x1 << 4) - 1, reg); | 759 | SGTL5000_LINREG_VDDD_MASK, reg); |
| 760 | 760 | ||
| 761 | snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, | 761 | snd_soc_update_bits(codec, SGTL5000_CHIP_ANA_POWER, |
| 762 | SGTL5000_LINEREG_D_POWERUP, | 762 | SGTL5000_LINEREG_D_POWERUP, |
| @@ -782,7 +782,7 @@ static int ldo_regulator_disable(struct regulator_dev *dev) | |||
| 782 | 782 | ||
| 783 | /* clear voltage info */ | 783 | /* clear voltage info */ |
| 784 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, | 784 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, |
| 785 | (0x1 << 4) - 1, 0); | 785 | SGTL5000_LINREG_VDDD_MASK, 0); |
| 786 | 786 | ||
| 787 | ldo->enabled = 0; | 787 | ldo->enabled = 0; |
| 788 | 788 | ||
| @@ -808,6 +808,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, | |||
| 808 | int voltage) | 808 | int voltage) |
| 809 | { | 809 | { |
| 810 | struct ldo_regulator *ldo; | 810 | struct ldo_regulator *ldo; |
| 811 | struct sgtl5000_priv *sgtl5000 = snd_soc_codec_get_drvdata(codec); | ||
| 811 | 812 | ||
| 812 | ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL); | 813 | ldo = kzalloc(sizeof(struct ldo_regulator), GFP_KERNEL); |
| 813 | 814 | ||
| @@ -842,6 +843,7 @@ static int ldo_regulator_register(struct snd_soc_codec *codec, | |||
| 842 | 843 | ||
| 843 | return ret; | 844 | return ret; |
| 844 | } | 845 | } |
| 846 | sgtl5000->ldo = ldo; | ||
| 845 | 847 | ||
| 846 | return 0; | 848 | return 0; |
| 847 | } | 849 | } |
| @@ -1115,7 +1117,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) | |||
| 1115 | 1117 | ||
| 1116 | /* set voltage to register */ | 1118 | /* set voltage to register */ |
| 1117 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, | 1119 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINREG_CTRL, |
| 1118 | (0x1 << 4) - 1, 0x8); | 1120 | SGTL5000_LINREG_VDDD_MASK, 0x8); |
| 1119 | 1121 | ||
| 1120 | /* | 1122 | /* |
| 1121 | * if vddd linear reg has been enabled, | 1123 | * if vddd linear reg has been enabled, |
| @@ -1146,8 +1148,7 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) | |||
| 1146 | vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP; | 1148 | vag = (vag - SGTL5000_ANA_GND_BASE) / SGTL5000_ANA_GND_STP; |
| 1147 | 1149 | ||
| 1148 | snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL, | 1150 | snd_soc_update_bits(codec, SGTL5000_CHIP_REF_CTRL, |
| 1149 | vag << SGTL5000_ANA_GND_SHIFT, | 1151 | SGTL5000_ANA_GND_MASK, vag << SGTL5000_ANA_GND_SHIFT); |
| 1150 | vag << SGTL5000_ANA_GND_SHIFT); | ||
| 1151 | 1152 | ||
| 1152 | /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */ | 1153 | /* set line out VAG to vddio / 2, in range (0.8v, 1.675v) */ |
| 1153 | vag = vddio / 2; | 1154 | vag = vddio / 2; |
| @@ -1161,9 +1162,8 @@ static int sgtl5000_set_power_regs(struct snd_soc_codec *codec) | |||
| 1161 | SGTL5000_LINE_OUT_GND_STP; | 1162 | SGTL5000_LINE_OUT_GND_STP; |
| 1162 | 1163 | ||
| 1163 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL, | 1164 | snd_soc_update_bits(codec, SGTL5000_CHIP_LINE_OUT_CTRL, |
| 1164 | vag << SGTL5000_LINE_OUT_GND_SHIFT | | 1165 | SGTL5000_LINE_OUT_CURRENT_MASK | |
| 1165 | SGTL5000_LINE_OUT_CURRENT_360u << | 1166 | SGTL5000_LINE_OUT_GND_MASK, |
| 1166 | SGTL5000_LINE_OUT_CURRENT_SHIFT, | ||
| 1167 | vag << SGTL5000_LINE_OUT_GND_SHIFT | | 1167 | vag << SGTL5000_LINE_OUT_GND_SHIFT | |
| 1168 | SGTL5000_LINE_OUT_CURRENT_360u << | 1168 | SGTL5000_LINE_OUT_CURRENT_360u << |
| 1169 | SGTL5000_LINE_OUT_CURRENT_SHIFT); | 1169 | SGTL5000_LINE_OUT_CURRENT_SHIFT); |
| @@ -1436,10 +1436,17 @@ static const struct i2c_device_id sgtl5000_id[] = { | |||
| 1436 | 1436 | ||
| 1437 | MODULE_DEVICE_TABLE(i2c, sgtl5000_id); | 1437 | MODULE_DEVICE_TABLE(i2c, sgtl5000_id); |
| 1438 | 1438 | ||
| 1439 | static const struct of_device_id sgtl5000_dt_ids[] = { | ||
| 1440 | { .compatible = "fsl,sgtl5000", }, | ||
| 1441 | { /* sentinel */ } | ||
| 1442 | }; | ||
| 1443 | MODULE_DEVICE_TABLE(of, sgtl5000_dt_ids); | ||
| 1444 | |||
| 1439 | static struct i2c_driver sgtl5000_i2c_driver = { | 1445 | static struct i2c_driver sgtl5000_i2c_driver = { |
| 1440 | .driver = { | 1446 | .driver = { |
| 1441 | .name = "sgtl5000", | 1447 | .name = "sgtl5000", |
| 1442 | .owner = THIS_MODULE, | 1448 | .owner = THIS_MODULE, |
| 1449 | .of_match_table = sgtl5000_dt_ids, | ||
| 1443 | }, | 1450 | }, |
| 1444 | .probe = sgtl5000_i2c_probe, | 1451 | .probe = sgtl5000_i2c_probe, |
| 1445 | .remove = __devexit_p(sgtl5000_i2c_remove), | 1452 | .remove = __devexit_p(sgtl5000_i2c_remove), |
diff --git a/sound/soc/codecs/sgtl5000.h b/sound/soc/codecs/sgtl5000.h index eec3ab368f39..8a9f43534b79 100644 --- a/sound/soc/codecs/sgtl5000.h +++ b/sound/soc/codecs/sgtl5000.h | |||
| @@ -280,7 +280,7 @@ | |||
| 280 | /* | 280 | /* |
| 281 | * SGTL5000_CHIP_MIC_CTRL | 281 | * SGTL5000_CHIP_MIC_CTRL |
| 282 | */ | 282 | */ |
| 283 | #define SGTL5000_BIAS_R_MASK 0x0200 | 283 | #define SGTL5000_BIAS_R_MASK 0x0300 |
| 284 | #define SGTL5000_BIAS_R_SHIFT 8 | 284 | #define SGTL5000_BIAS_R_SHIFT 8 |
| 285 | #define SGTL5000_BIAS_R_WIDTH 2 | 285 | #define SGTL5000_BIAS_R_WIDTH 2 |
| 286 | #define SGTL5000_BIAS_R_off 0x0 | 286 | #define SGTL5000_BIAS_R_off 0x0 |
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c index 84ffdebb8a8b..f681e41fc12e 100644 --- a/sound/soc/codecs/sn95031.c +++ b/sound/soc/codecs/sn95031.c | |||
| @@ -79,7 +79,7 @@ static void configure_adc(struct snd_soc_codec *sn95031_codec, int val) | |||
| 79 | */ | 79 | */ |
| 80 | static int find_free_channel(struct snd_soc_codec *sn95031_codec) | 80 | static int find_free_channel(struct snd_soc_codec *sn95031_codec) |
| 81 | { | 81 | { |
| 82 | int ret = 0, i, value; | 82 | int i, value; |
| 83 | 83 | ||
| 84 | /* check whether ADC is enabled */ | 84 | /* check whether ADC is enabled */ |
| 85 | value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); | 85 | value = snd_soc_read(sn95031_codec, SN95031_ADC1CNTL1); |
| @@ -91,12 +91,10 @@ static int find_free_channel(struct snd_soc_codec *sn95031_codec) | |||
| 91 | for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { | 91 | for (i = 0; i < SN95031_ADC_CHANLS_MAX; i++) { |
| 92 | value = snd_soc_read(sn95031_codec, | 92 | value = snd_soc_read(sn95031_codec, |
| 93 | SN95031_ADC_CHNL_START_ADDR + i); | 93 | SN95031_ADC_CHNL_START_ADDR + i); |
| 94 | if (value & SN95031_STOPBIT_MASK) { | 94 | if (value & SN95031_STOPBIT_MASK) |
| 95 | ret = i; | ||
| 96 | break; | 95 | break; |
| 97 | } | ||
| 98 | } | 96 | } |
| 99 | return (ret > SN95031_ADC_LOOP_MAX) ? (-EINVAL) : ret; | 97 | return (i == SN95031_ADC_CHANLS_MAX) ? (-EINVAL) : i; |
| 100 | } | 98 | } |
| 101 | 99 | ||
| 102 | /* Initialize the ADC for reading micbias values. Can sleep. */ | 100 | /* Initialize the ADC for reading micbias values. Can sleep. */ |
| @@ -104,7 +102,7 @@ static int sn95031_initialize_adc(struct snd_soc_codec *sn95031_codec) | |||
| 104 | { | 102 | { |
| 105 | int base_addr, chnl_addr; | 103 | int base_addr, chnl_addr; |
| 106 | int value; | 104 | int value; |
| 107 | static int channel_index; | 105 | int channel_index; |
| 108 | 106 | ||
| 109 | /* Index of the first channel in which the stop bit is set */ | 107 | /* Index of the first channel in which the stop bit is set */ |
| 110 | channel_index = find_free_channel(sn95031_codec); | 108 | channel_index = find_free_channel(sn95031_codec); |
| @@ -163,7 +161,6 @@ static unsigned int sn95031_get_mic_bias(struct snd_soc_codec *codec) | |||
| 163 | pr_debug("mic bias = %dmV\n", mic_bias); | 161 | pr_debug("mic bias = %dmV\n", mic_bias); |
| 164 | return mic_bias; | 162 | return mic_bias; |
| 165 | } | 163 | } |
| 166 | EXPORT_SYMBOL_GPL(sn95031_get_mic_bias); | ||
| 167 | /*end - adc helper functions */ | 164 | /*end - adc helper functions */ |
| 168 | 165 | ||
| 169 | static inline unsigned int sn95031_read(struct snd_soc_codec *codec, | 166 | static inline unsigned int sn95031_read(struct snd_soc_codec *codec, |
| @@ -660,7 +657,7 @@ static int sn95031_pcm_spkr_mute(struct snd_soc_dai *dai, int mute) | |||
| 660 | return 0; | 657 | return 0; |
| 661 | } | 658 | } |
| 662 | 659 | ||
| 663 | int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, | 660 | static int sn95031_pcm_hw_params(struct snd_pcm_substream *substream, |
| 664 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) | 661 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
| 665 | { | 662 | { |
| 666 | unsigned int format, rate; | 663 | unsigned int format, rate; |
| @@ -718,7 +715,7 @@ static struct snd_soc_dai_ops sn95031_vib2_dai_ops = { | |||
| 718 | .hw_params = sn95031_pcm_hw_params, | 715 | .hw_params = sn95031_pcm_hw_params, |
| 719 | }; | 716 | }; |
| 720 | 717 | ||
| 721 | struct snd_soc_dai_driver sn95031_dais[] = { | 718 | static struct snd_soc_dai_driver sn95031_dais[] = { |
| 722 | { | 719 | { |
| 723 | .name = "SN95031 Headset", | 720 | .name = "SN95031 Headset", |
| 724 | .playback = { | 721 | .playback = { |
| @@ -829,7 +826,6 @@ static int sn95031_codec_probe(struct snd_soc_codec *codec) | |||
| 829 | { | 826 | { |
| 830 | pr_debug("codec_probe called\n"); | 827 | pr_debug("codec_probe called\n"); |
| 831 | 828 | ||
| 832 | codec->dapm.bias_level = SND_SOC_BIAS_OFF; | ||
| 833 | codec->dapm.idle_bias_off = 1; | 829 | codec->dapm.idle_bias_off = 1; |
| 834 | 830 | ||
| 835 | /* PCM interface config | 831 | /* PCM interface config |
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 9801cd7cfcb5..3cb3271c5fe2 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c | |||
| @@ -59,6 +59,7 @@ struct ssm2602_priv { | |||
| 59 | struct snd_pcm_substream *slave_substream; | 59 | struct snd_pcm_substream *slave_substream; |
| 60 | 60 | ||
| 61 | enum ssm2602_type type; | 61 | enum ssm2602_type type; |
| 62 | unsigned int clk_out_pwr; | ||
| 62 | }; | 63 | }; |
| 63 | 64 | ||
| 64 | /* | 65 | /* |
| @@ -294,7 +295,6 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, | |||
| 294 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 295 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 295 | struct snd_soc_codec *codec = rtd->codec; | 296 | struct snd_soc_codec *codec = rtd->codec; |
| 296 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); | 297 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
| 297 | struct i2c_client *i2c = codec->control_data; | ||
| 298 | struct snd_pcm_runtime *master_runtime; | 298 | struct snd_pcm_runtime *master_runtime; |
| 299 | 299 | ||
| 300 | /* The DAI has shared clocks so if we already have a playback or | 300 | /* The DAI has shared clocks so if we already have a playback or |
| @@ -303,7 +303,7 @@ static int ssm2602_startup(struct snd_pcm_substream *substream, | |||
| 303 | */ | 303 | */ |
| 304 | if (ssm2602->master_substream) { | 304 | if (ssm2602->master_substream) { |
| 305 | master_runtime = ssm2602->master_substream->runtime; | 305 | master_runtime = ssm2602->master_substream->runtime; |
| 306 | dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n", | 306 | dev_dbg(codec->dev, "Constraining to %d bits at %dHz\n", |
| 307 | master_runtime->sample_bits, | 307 | master_runtime->sample_bits, |
| 308 | master_runtime->rate); | 308 | master_runtime->rate); |
| 309 | 309 | ||
| @@ -343,12 +343,14 @@ static void ssm2602_shutdown(struct snd_pcm_substream *substream, | |||
| 343 | static int ssm2602_mute(struct snd_soc_dai *dai, int mute) | 343 | static int ssm2602_mute(struct snd_soc_dai *dai, int mute) |
| 344 | { | 344 | { |
| 345 | struct snd_soc_codec *codec = dai->codec; | 345 | struct snd_soc_codec *codec = dai->codec; |
| 346 | u16 mute_reg = snd_soc_read(codec, SSM2602_APDIGI) & ~APDIGI_ENABLE_DAC_MUTE; | 346 | |
| 347 | if (mute) | 347 | if (mute) |
| 348 | snd_soc_write(codec, SSM2602_APDIGI, | 348 | snd_soc_update_bits(codec, SSM2602_APDIGI, |
| 349 | mute_reg | APDIGI_ENABLE_DAC_MUTE); | 349 | APDIGI_ENABLE_DAC_MUTE, |
| 350 | APDIGI_ENABLE_DAC_MUTE); | ||
| 350 | else | 351 | else |
| 351 | snd_soc_write(codec, SSM2602_APDIGI, mute_reg); | 352 | snd_soc_update_bits(codec, SSM2602_APDIGI, |
| 353 | APDIGI_ENABLE_DAC_MUTE, 0); | ||
| 352 | return 0; | 354 | return 0; |
| 353 | } | 355 | } |
| 354 | 356 | ||
| @@ -357,16 +359,46 @@ static int ssm2602_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
| 357 | { | 359 | { |
| 358 | struct snd_soc_codec *codec = codec_dai->codec; | 360 | struct snd_soc_codec *codec = codec_dai->codec; |
| 359 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); | 361 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
| 360 | switch (freq) { | 362 | |
| 361 | case 11289600: | 363 | if (dir == SND_SOC_CLOCK_IN) { |
| 362 | case 12000000: | 364 | if (clk_id != SSM2602_SYSCLK) |
| 363 | case 12288000: | 365 | return -EINVAL; |
| 364 | case 16934400: | 366 | |
| 365 | case 18432000: | 367 | switch (freq) { |
| 366 | ssm2602->sysclk = freq; | 368 | case 11289600: |
| 367 | return 0; | 369 | case 12000000: |
| 370 | case 12288000: | ||
| 371 | case 16934400: | ||
| 372 | case 18432000: | ||
| 373 | ssm2602->sysclk = freq; | ||
| 374 | break; | ||
| 375 | default: | ||
| 376 | return -EINVAL; | ||
| 377 | } | ||
| 378 | } else { | ||
| 379 | unsigned int mask; | ||
| 380 | |||
| 381 | switch (clk_id) { | ||
| 382 | case SSM2602_CLK_CLKOUT: | ||
| 383 | mask = PWR_CLK_OUT_PDN; | ||
| 384 | break; | ||
| 385 | case SSM2602_CLK_XTO: | ||
| 386 | mask = PWR_OSC_PDN; | ||
| 387 | break; | ||
| 388 | default: | ||
| 389 | return -EINVAL; | ||
| 390 | } | ||
| 391 | |||
| 392 | if (freq == 0) | ||
| 393 | ssm2602->clk_out_pwr |= mask; | ||
| 394 | else | ||
| 395 | ssm2602->clk_out_pwr &= ~mask; | ||
| 396 | |||
| 397 | snd_soc_update_bits(codec, SSM2602_PWR, | ||
| 398 | PWR_CLK_OUT_PDN | PWR_OSC_PDN, ssm2602->clk_out_pwr); | ||
| 368 | } | 399 | } |
| 369 | return -EINVAL; | 400 | |
| 401 | return 0; | ||
| 370 | } | 402 | } |
| 371 | 403 | ||
| 372 | static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, | 404 | static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, |
| @@ -431,23 +463,27 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 431 | static int ssm2602_set_bias_level(struct snd_soc_codec *codec, | 463 | static int ssm2602_set_bias_level(struct snd_soc_codec *codec, |
| 432 | enum snd_soc_bias_level level) | 464 | enum snd_soc_bias_level level) |
| 433 | { | 465 | { |
| 434 | u16 reg = snd_soc_read(codec, SSM2602_PWR); | 466 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
| 435 | reg &= ~(PWR_POWER_OFF | PWR_OSC_PDN); | ||
| 436 | 467 | ||
| 437 | switch (level) { | 468 | switch (level) { |
| 438 | case SND_SOC_BIAS_ON: | 469 | case SND_SOC_BIAS_ON: |
| 439 | /* vref/mid, osc on, dac unmute */ | 470 | /* vref/mid on, osc and clkout on if enabled */ |
| 440 | snd_soc_write(codec, SSM2602_PWR, reg); | 471 | snd_soc_update_bits(codec, SSM2602_PWR, |
| 472 | PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN, | ||
| 473 | ssm2602->clk_out_pwr); | ||
| 441 | break; | 474 | break; |
| 442 | case SND_SOC_BIAS_PREPARE: | 475 | case SND_SOC_BIAS_PREPARE: |
| 443 | break; | 476 | break; |
| 444 | case SND_SOC_BIAS_STANDBY: | 477 | case SND_SOC_BIAS_STANDBY: |
| 445 | /* everything off except vref/vmid, */ | 478 | /* everything off except vref/vmid, */ |
| 446 | snd_soc_write(codec, SSM2602_PWR, reg | PWR_CLK_OUT_PDN); | 479 | snd_soc_update_bits(codec, SSM2602_PWR, |
| 480 | PWR_POWER_OFF | PWR_CLK_OUT_PDN | PWR_OSC_PDN, | ||
| 481 | PWR_CLK_OUT_PDN | PWR_OSC_PDN); | ||
| 447 | break; | 482 | break; |
| 448 | case SND_SOC_BIAS_OFF: | 483 | case SND_SOC_BIAS_OFF: |
| 449 | /* everything off, dac mute, inactive */ | 484 | /* everything off */ |
| 450 | snd_soc_write(codec, SSM2602_PWR, 0xffff); | 485 | snd_soc_update_bits(codec, SSM2602_PWR, |
| 486 | PWR_POWER_OFF, PWR_POWER_OFF); | ||
| 451 | break; | 487 | break; |
| 452 | 488 | ||
| 453 | } | 489 | } |
| @@ -506,12 +542,12 @@ static int ssm2602_resume(struct snd_soc_codec *codec) | |||
| 506 | static int ssm2602_probe(struct snd_soc_codec *codec) | 542 | static int ssm2602_probe(struct snd_soc_codec *codec) |
| 507 | { | 543 | { |
| 508 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 544 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 509 | int ret, reg; | 545 | int ret; |
| 510 | 546 | ||
| 511 | reg = snd_soc_read(codec, SSM2602_LOUT1V); | 547 | snd_soc_update_bits(codec, SSM2602_LOUT1V, |
| 512 | snd_soc_write(codec, SSM2602_LOUT1V, reg | LOUT1V_LRHP_BOTH); | 548 | LOUT1V_LRHP_BOTH, LOUT1V_LRHP_BOTH); |
| 513 | reg = snd_soc_read(codec, SSM2602_ROUT1V); | 549 | snd_soc_update_bits(codec, SSM2602_ROUT1V, |
| 514 | snd_soc_write(codec, SSM2602_ROUT1V, reg | ROUT1V_RLHP_BOTH); | 550 | ROUT1V_RLHP_BOTH, ROUT1V_RLHP_BOTH); |
| 515 | 551 | ||
| 516 | ret = snd_soc_add_controls(codec, ssm2602_snd_controls, | 552 | ret = snd_soc_add_controls(codec, ssm2602_snd_controls, |
| 517 | ARRAY_SIZE(ssm2602_snd_controls)); | 553 | ARRAY_SIZE(ssm2602_snd_controls)); |
| @@ -544,7 +580,7 @@ static int ssm2604_probe(struct snd_soc_codec *codec) | |||
| 544 | static int ssm260x_probe(struct snd_soc_codec *codec) | 580 | static int ssm260x_probe(struct snd_soc_codec *codec) |
| 545 | { | 581 | { |
| 546 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); | 582 | struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec); |
| 547 | int ret, reg; | 583 | int ret; |
| 548 | 584 | ||
| 549 | pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); | 585 | pr_info("ssm2602 Audio Codec %s", SSM2602_VERSION); |
| 550 | 586 | ||
| @@ -561,10 +597,10 @@ static int ssm260x_probe(struct snd_soc_codec *codec) | |||
| 561 | } | 597 | } |
| 562 | 598 | ||
| 563 | /* set the update bits */ | 599 | /* set the update bits */ |
| 564 | reg = snd_soc_read(codec, SSM2602_LINVOL); | 600 | snd_soc_update_bits(codec, SSM2602_LINVOL, |
| 565 | snd_soc_write(codec, SSM2602_LINVOL, reg | LINVOL_LRIN_BOTH); | 601 | LINVOL_LRIN_BOTH, LINVOL_LRIN_BOTH); |
| 566 | reg = snd_soc_read(codec, SSM2602_RINVOL); | 602 | snd_soc_update_bits(codec, SSM2602_RINVOL, |
| 567 | snd_soc_write(codec, SSM2602_RINVOL, reg | RINVOL_RLIN_BOTH); | 603 | RINVOL_RLIN_BOTH, RINVOL_RLIN_BOTH); |
| 568 | /*select Line in as default input*/ | 604 | /*select Line in as default input*/ |
| 569 | snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC | | 605 | snd_soc_write(codec, SSM2602_APANA, APANA_SELECT_DAC | |
| 570 | APANA_ENABLE_MIC_BOOST); | 606 | APANA_ENABLE_MIC_BOOST); |
| @@ -578,7 +614,12 @@ static int ssm260x_probe(struct snd_soc_codec *codec) | |||
| 578 | break; | 614 | break; |
| 579 | } | 615 | } |
| 580 | 616 | ||
| 581 | return ret; | 617 | if (ret) |
| 618 | return ret; | ||
| 619 | |||
| 620 | ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
| 621 | |||
| 622 | return 0; | ||
| 582 | } | 623 | } |
| 583 | 624 | ||
| 584 | /* remove everything here */ | 625 | /* remove everything here */ |
diff --git a/sound/soc/codecs/ssm2602.h b/sound/soc/codecs/ssm2602.h index b98c69168036..fbd07d7b73ca 100644 --- a/sound/soc/codecs/ssm2602.h +++ b/sound/soc/codecs/ssm2602.h | |||
| @@ -116,6 +116,10 @@ | |||
| 116 | 116 | ||
| 117 | #define SSM2602_CACHEREGNUM 10 | 117 | #define SSM2602_CACHEREGNUM 10 |
| 118 | 118 | ||
| 119 | #define SSM2602_SYSCLK 0 | 119 | enum ssm2602_clk { |
| 120 | SSM2602_SYSCLK, | ||
| 121 | SSM2602_CLK_CLKOUT, | ||
| 122 | SSM2602_CLK_XTO | ||
| 123 | }; | ||
| 120 | 124 | ||
| 121 | #endif | 125 | #endif |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index fbd7eb9e61ce..bb82408ab8e1 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
| @@ -524,13 +524,17 @@ static int sta32x_hw_params(struct snd_pcm_substream *substream, | |||
| 524 | rate = params_rate(params); | 524 | rate = params_rate(params); |
| 525 | pr_debug("rate: %u\n", rate); | 525 | pr_debug("rate: %u\n", rate); |
| 526 | for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) | 526 | for (i = 0; i < ARRAY_SIZE(interpolation_ratios); i++) |
| 527 | if (interpolation_ratios[i].fs == rate) | 527 | if (interpolation_ratios[i].fs == rate) { |
| 528 | ir = interpolation_ratios[i].ir; | 528 | ir = interpolation_ratios[i].ir; |
| 529 | break; | ||
| 530 | } | ||
| 529 | if (ir < 0) | 531 | if (ir < 0) |
| 530 | return -EINVAL; | 532 | return -EINVAL; |
| 531 | for (i = 0; mclk_ratios[ir][i].ratio; i++) | 533 | for (i = 0; mclk_ratios[ir][i].ratio; i++) |
| 532 | if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) | 534 | if (mclk_ratios[ir][i].ratio * rate == sta32x->mclk) { |
| 533 | mcs = mclk_ratios[ir][i].mcs; | 535 | mcs = mclk_ratios[ir][i].mcs; |
| 536 | break; | ||
| 537 | } | ||
| 534 | if (mcs < 0) | 538 | if (mcs < 0) |
| 535 | return -EINVAL; | 539 | return -EINVAL; |
| 536 | 540 | ||
| @@ -752,25 +756,19 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
| 752 | return ret; | 756 | return ret; |
| 753 | } | 757 | } |
| 754 | 758 | ||
| 755 | /* read reg reset values into cache */ | 759 | /* Chip documentation explicitly requires that the reset values |
| 756 | for (i = 0; i < STA32X_REGISTER_COUNT; i++) | 760 | * of reserved register bits are left untouched. |
| 757 | snd_soc_cache_write(codec, i, sta32x_regs[i]); | 761 | * Write the register default value to cache for reserved registers, |
| 758 | 762 | * so the write to the these registers are suppressed by the cache | |
| 759 | /* preserve reset values of reserved register bits */ | 763 | * restore code when it skips writes of default registers. |
| 760 | snd_soc_cache_write(codec, STA32X_CONFC, | 764 | */ |
| 761 | codec->hw_read(codec, STA32X_CONFC)); | 765 | snd_soc_cache_write(codec, STA32X_CONFC, 0xc2); |
| 762 | snd_soc_cache_write(codec, STA32X_CONFE, | 766 | snd_soc_cache_write(codec, STA32X_CONFE, 0xc2); |
| 763 | codec->hw_read(codec, STA32X_CONFE)); | 767 | snd_soc_cache_write(codec, STA32X_CONFF, 0x5c); |
| 764 | snd_soc_cache_write(codec, STA32X_CONFF, | 768 | snd_soc_cache_write(codec, STA32X_MMUTE, 0x10); |
| 765 | codec->hw_read(codec, STA32X_CONFF)); | 769 | snd_soc_cache_write(codec, STA32X_AUTO1, 0x60); |
| 766 | snd_soc_cache_write(codec, STA32X_MMUTE, | 770 | snd_soc_cache_write(codec, STA32X_AUTO3, 0x00); |
| 767 | codec->hw_read(codec, STA32X_MMUTE)); | 771 | snd_soc_cache_write(codec, STA32X_C3CFG, 0x40); |
| 768 | snd_soc_cache_write(codec, STA32X_AUTO1, | ||
| 769 | codec->hw_read(codec, STA32X_AUTO1)); | ||
| 770 | snd_soc_cache_write(codec, STA32X_AUTO3, | ||
| 771 | codec->hw_read(codec, STA32X_AUTO3)); | ||
| 772 | snd_soc_cache_write(codec, STA32X_C3CFG, | ||
| 773 | codec->hw_read(codec, STA32X_C3CFG)); | ||
| 774 | 772 | ||
| 775 | /* FIXME enable thermal warning adjustment and recovery */ | 773 | /* FIXME enable thermal warning adjustment and recovery */ |
| 776 | snd_soc_update_bits(codec, STA32X_CONFA, | 774 | snd_soc_update_bits(codec, STA32X_CONFA, |
| @@ -808,6 +806,7 @@ static int sta32x_remove(struct snd_soc_codec *codec) | |||
| 808 | { | 806 | { |
| 809 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | 807 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); |
| 810 | 808 | ||
| 809 | sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 811 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | 810 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); |
| 812 | regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | 811 | regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); |
| 813 | 812 | ||
| @@ -832,6 +831,7 @@ static const struct snd_soc_codec_driver sta32x_codec = { | |||
| 832 | .resume = sta32x_resume, | 831 | .resume = sta32x_resume, |
| 833 | .reg_cache_size = STA32X_REGISTER_COUNT, | 832 | .reg_cache_size = STA32X_REGISTER_COUNT, |
| 834 | .reg_word_size = sizeof(u8), | 833 | .reg_word_size = sizeof(u8), |
| 834 | .reg_cache_default = sta32x_regs, | ||
| 835 | .volatile_register = sta32x_reg_is_volatile, | 835 | .volatile_register = sta32x_reg_is_volatile, |
| 836 | .set_bias_level = sta32x_set_bias_level, | 836 | .set_bias_level = sta32x_set_bias_level, |
| 837 | .controls = sta32x_snd_controls, | 837 | .controls = sta32x_snd_controls, |
| @@ -867,18 +867,8 @@ static __devinit int sta32x_i2c_probe(struct i2c_client *i2c, | |||
| 867 | static __devexit int sta32x_i2c_remove(struct i2c_client *client) | 867 | static __devexit int sta32x_i2c_remove(struct i2c_client *client) |
| 868 | { | 868 | { |
| 869 | struct sta32x_priv *sta32x = i2c_get_clientdata(client); | 869 | struct sta32x_priv *sta32x = i2c_get_clientdata(client); |
| 870 | struct snd_soc_codec *codec = sta32x->codec; | ||
| 871 | |||
| 872 | if (codec) | ||
| 873 | sta32x_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 874 | |||
| 875 | regulator_bulk_free(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | ||
| 876 | |||
| 877 | if (codec) { | ||
| 878 | snd_soc_unregister_codec(&client->dev); | ||
| 879 | snd_soc_codec_set_drvdata(codec, NULL); | ||
| 880 | } | ||
| 881 | 870 | ||
| 871 | snd_soc_unregister_codec(&client->dev); | ||
| 882 | kfree(sta32x); | 872 | kfree(sta32x); |
| 883 | return 0; | 873 | return 0; |
| 884 | } | 874 | } |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 33bb52f3f683..ab27dbcd1262 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
| @@ -47,63 +47,6 @@ static const u16 tlv320aic23_reg[] = { | |||
| 47 | 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ | 47 | 0x0000, 0x0000, 0x0000, 0x0000, /* 12 */ |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | /* | ||
| 51 | * read tlv320aic23 register cache | ||
| 52 | */ | ||
| 53 | static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec | ||
| 54 | *codec, unsigned int reg) | ||
| 55 | { | ||
| 56 | u16 *cache = codec->reg_cache; | ||
| 57 | if (reg >= ARRAY_SIZE(tlv320aic23_reg)) | ||
| 58 | return -1; | ||
| 59 | return cache[reg]; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* | ||
| 63 | * write tlv320aic23 register cache | ||
| 64 | */ | ||
| 65 | static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec, | ||
| 66 | u8 reg, u16 value) | ||
| 67 | { | ||
| 68 | u16 *cache = codec->reg_cache; | ||
| 69 | if (reg >= ARRAY_SIZE(tlv320aic23_reg)) | ||
| 70 | return; | ||
| 71 | cache[reg] = value; | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * write to the tlv320aic23 register space | ||
| 76 | */ | ||
| 77 | static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 78 | unsigned int value) | ||
| 79 | { | ||
| 80 | |||
| 81 | u8 data[2]; | ||
| 82 | |||
| 83 | /* TLV320AIC23 has 7 bit address and 9 bits of data | ||
| 84 | * so we need to switch one data bit into reg and rest | ||
| 85 | * of data into val | ||
| 86 | */ | ||
| 87 | |||
| 88 | if (reg > 9 && reg != 15) { | ||
| 89 | printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg); | ||
| 90 | return -1; | ||
| 91 | } | ||
| 92 | |||
| 93 | data[0] = (reg << 1) | (value >> 8 & 0x01); | ||
| 94 | data[1] = value & 0xff; | ||
| 95 | |||
| 96 | tlv320aic23_write_reg_cache(codec, reg, value); | ||
| 97 | |||
| 98 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
| 99 | return 0; | ||
| 100 | |||
| 101 | printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__, | ||
| 102 | value, reg); | ||
| 103 | |||
| 104 | return -EIO; | ||
| 105 | } | ||
| 106 | |||
| 107 | static const char *rec_src_text[] = { "Line", "Mic" }; | 50 | static const char *rec_src_text[] = { "Line", "Mic" }; |
| 108 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | 51 | static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"}; |
| 109 | 52 | ||
| @@ -139,8 +82,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 139 | */ | 82 | */ |
| 140 | val = (val >= 4) ? 4 : (3 - val); | 83 | val = (val >= 4) ? 4 : (3 - val); |
| 141 | 84 | ||
| 142 | reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0); | 85 | reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0); |
| 143 | tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6)); | 86 | snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6)); |
| 144 | 87 | ||
| 145 | return 0; | 88 | return 0; |
| 146 | } | 89 | } |
| @@ -151,7 +94,7 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, | |||
| 151 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 94 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 152 | u16 val; | 95 | u16 val; |
| 153 | 96 | ||
| 154 | val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0); | 97 | val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0); |
| 155 | val = val >> 6; | 98 | val = val >> 6; |
| 156 | val = (val >= 4) ? 4 : (3 - val); | 99 | val = (val >= 4) ? 4 : (3 - val); |
| 157 | ucontrol->value.integer.value[0] = val; | 100 | ucontrol->value.integer.value[0] = val; |
| @@ -159,15 +102,6 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol, | |||
| 159 | 102 | ||
| 160 | } | 103 | } |
| 161 | 104 | ||
| 162 | #define SOC_TLV320AIC23_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ | ||
| 163 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
| 164 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
| 165 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | ||
| 166 | .tlv.p = (tlv_array), \ | ||
| 167 | .info = snd_soc_info_volsw, .get = snd_soc_tlv320aic23_get_volsw,\ | ||
| 168 | .put = snd_soc_tlv320aic23_put_volsw, \ | ||
| 169 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | ||
| 170 | |||
| 171 | static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { | 105 | static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { |
| 172 | SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, | 106 | SOC_DOUBLE_R_TLV("Digital Playback Volume", TLV320AIC23_LCHNVOL, |
| 173 | TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv), | 107 | TLV320AIC23_RCHNVOL, 0, 127, 0, out_gain_tlv), |
| @@ -178,8 +112,9 @@ static const struct snd_kcontrol_new tlv320aic23_snd_controls[] = { | |||
| 178 | TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), | 112 | TLV320AIC23_RINVOL, 0, 31, 0, input_gain_tlv), |
| 179 | SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), | 113 | SOC_SINGLE("Mic Input Switch", TLV320AIC23_ANLG, 1, 1, 1), |
| 180 | SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), | 114 | SOC_SINGLE("Mic Booster Switch", TLV320AIC23_ANLG, 0, 1, 0), |
| 181 | SOC_TLV320AIC23_SINGLE_TLV("Sidetone Volume", TLV320AIC23_ANLG, | 115 | SOC_SINGLE_EXT_TLV("Sidetone Volume", TLV320AIC23_ANLG, 6, 4, 0, |
| 182 | 6, 4, 0, sidetone_vol_tlv), | 116 | snd_soc_tlv320aic23_get_volsw, |
| 117 | snd_soc_tlv320aic23_put_volsw, sidetone_vol_tlv), | ||
| 183 | SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), | 118 | SOC_ENUM("Playback De-emphasis", tlv320aic23_deemph), |
| 184 | }; | 119 | }; |
| 185 | 120 | ||
| @@ -240,7 +175,6 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = { | |||
| 240 | /* AIC23 driver data */ | 175 | /* AIC23 driver data */ |
| 241 | struct aic23 { | 176 | struct aic23 { |
| 242 | enum snd_soc_control_type control_type; | 177 | enum snd_soc_control_type control_type; |
| 243 | void *control_data; | ||
| 244 | int mclk; | 178 | int mclk; |
| 245 | int requested_adc; | 179 | int requested_adc; |
| 246 | int requested_dac; | 180 | int requested_dac; |
| @@ -352,7 +286,7 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac) | |||
| 352 | static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk, | 286 | static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk, |
| 353 | u32 *sample_rate_adc, u32 *sample_rate_dac) | 287 | u32 *sample_rate_adc, u32 *sample_rate_dac) |
| 354 | { | 288 | { |
| 355 | int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE); | 289 | int src = snd_soc_read(codec, TLV320AIC23_SRATE); |
| 356 | int sr = (src >> 2) & 0x0f; | 290 | int sr = (src >> 2) & 0x0f; |
| 357 | int val = (mclk / bosr_usb_divisor_table[src & 3]); | 291 | int val = (mclk / bosr_usb_divisor_table[src & 3]); |
| 358 | int adc = (val * sr_adc_mult_table[sr]) / SR_MULT; | 292 | int adc = (val * sr_adc_mult_table[sr]) / SR_MULT; |
| @@ -376,7 +310,7 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk, | |||
| 376 | __func__, sample_rate_adc, sample_rate_dac); | 310 | __func__, sample_rate_adc, sample_rate_dac); |
| 377 | return -EINVAL; | 311 | return -EINVAL; |
| 378 | } | 312 | } |
| 379 | tlv320aic23_write(codec, TLV320AIC23_SRATE, data); | 313 | snd_soc_write(codec, TLV320AIC23_SRATE, data); |
| 380 | #ifdef DEBUG | 314 | #ifdef DEBUG |
| 381 | { | 315 | { |
| 382 | u32 adc, dac; | 316 | u32 adc, dac; |
| @@ -415,9 +349,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, | |||
| 415 | if (ret < 0) | 349 | if (ret < 0) |
| 416 | return ret; | 350 | return ret; |
| 417 | 351 | ||
| 418 | iface_reg = | 352 | iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2); |
| 419 | tlv320aic23_read_reg_cache(codec, | 353 | |
| 420 | TLV320AIC23_DIGT_FMT) & ~(0x03 << 2); | ||
| 421 | switch (params_format(params)) { | 354 | switch (params_format(params)) { |
| 422 | case SNDRV_PCM_FORMAT_S16_LE: | 355 | case SNDRV_PCM_FORMAT_S16_LE: |
| 423 | break; | 356 | break; |
| @@ -431,7 +364,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, | |||
| 431 | iface_reg |= (0x03 << 2); | 364 | iface_reg |= (0x03 << 2); |
| 432 | break; | 365 | break; |
| 433 | } | 366 | } |
| 434 | tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); | 367 | snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); |
| 435 | 368 | ||
| 436 | return 0; | 369 | return 0; |
| 437 | } | 370 | } |
| @@ -443,7 +376,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream, | |||
| 443 | struct snd_soc_codec *codec = rtd->codec; | 376 | struct snd_soc_codec *codec = rtd->codec; |
| 444 | 377 | ||
| 445 | /* set active */ | 378 | /* set active */ |
| 446 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001); | 379 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001); |
| 447 | 380 | ||
| 448 | return 0; | 381 | return 0; |
| 449 | } | 382 | } |
| @@ -458,7 +391,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream, | |||
| 458 | /* deactivate */ | 391 | /* deactivate */ |
| 459 | if (!codec->active) { | 392 | if (!codec->active) { |
| 460 | udelay(50); | 393 | udelay(50); |
| 461 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); | 394 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); |
| 462 | } | 395 | } |
| 463 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 396 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 464 | aic23->requested_dac = 0; | 397 | aic23->requested_dac = 0; |
| @@ -471,14 +404,14 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute) | |||
| 471 | struct snd_soc_codec *codec = dai->codec; | 404 | struct snd_soc_codec *codec = dai->codec; |
| 472 | u16 reg; | 405 | u16 reg; |
| 473 | 406 | ||
| 474 | reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT); | 407 | reg = snd_soc_read(codec, TLV320AIC23_DIGT); |
| 475 | if (mute) | 408 | if (mute) |
| 476 | reg |= TLV320AIC23_DACM_MUTE; | 409 | reg |= TLV320AIC23_DACM_MUTE; |
| 477 | 410 | ||
| 478 | else | 411 | else |
| 479 | reg &= ~TLV320AIC23_DACM_MUTE; | 412 | reg &= ~TLV320AIC23_DACM_MUTE; |
| 480 | 413 | ||
| 481 | tlv320aic23_write(codec, TLV320AIC23_DIGT, reg); | 414 | snd_soc_write(codec, TLV320AIC23_DIGT, reg); |
| 482 | 415 | ||
| 483 | return 0; | 416 | return 0; |
| 484 | } | 417 | } |
| @@ -489,8 +422,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 489 | struct snd_soc_codec *codec = codec_dai->codec; | 422 | struct snd_soc_codec *codec = codec_dai->codec; |
| 490 | u16 iface_reg; | 423 | u16 iface_reg; |
| 491 | 424 | ||
| 492 | iface_reg = | 425 | iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03); |
| 493 | tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03); | ||
| 494 | 426 | ||
| 495 | /* set master/slave audio interface */ | 427 | /* set master/slave audio interface */ |
| 496 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 428 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
| @@ -524,7 +456,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 524 | 456 | ||
| 525 | } | 457 | } |
| 526 | 458 | ||
| 527 | tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); | 459 | snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg); |
| 528 | 460 | ||
| 529 | return 0; | 461 | return 0; |
| 530 | } | 462 | } |
| @@ -540,26 +472,26 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai, | |||
| 540 | static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, | 472 | static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, |
| 541 | enum snd_soc_bias_level level) | 473 | enum snd_soc_bias_level level) |
| 542 | { | 474 | { |
| 543 | u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f; | 475 | u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f; |
| 544 | 476 | ||
| 545 | switch (level) { | 477 | switch (level) { |
| 546 | case SND_SOC_BIAS_ON: | 478 | case SND_SOC_BIAS_ON: |
| 547 | /* vref/mid, osc on, dac unmute */ | 479 | /* vref/mid, osc on, dac unmute */ |
| 548 | reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \ | 480 | reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \ |
| 549 | TLV320AIC23_DAC_OFF); | 481 | TLV320AIC23_DAC_OFF); |
| 550 | tlv320aic23_write(codec, TLV320AIC23_PWR, reg); | 482 | snd_soc_write(codec, TLV320AIC23_PWR, reg); |
| 551 | break; | 483 | break; |
| 552 | case SND_SOC_BIAS_PREPARE: | 484 | case SND_SOC_BIAS_PREPARE: |
| 553 | break; | 485 | break; |
| 554 | case SND_SOC_BIAS_STANDBY: | 486 | case SND_SOC_BIAS_STANDBY: |
| 555 | /* everything off except vref/vmid, */ | 487 | /* everything off except vref/vmid, */ |
| 556 | tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \ | 488 | snd_soc_write(codec, TLV320AIC23_PWR, |
| 557 | TLV320AIC23_CLK_OFF); | 489 | reg | TLV320AIC23_CLK_OFF); |
| 558 | break; | 490 | break; |
| 559 | case SND_SOC_BIAS_OFF: | 491 | case SND_SOC_BIAS_OFF: |
| 560 | /* everything off, dac mute, inactive */ | 492 | /* everything off, dac mute, inactive */ |
| 561 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); | 493 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0); |
| 562 | tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); | 494 | snd_soc_write(codec, TLV320AIC23_PWR, 0xffff); |
| 563 | break; | 495 | break; |
| 564 | } | 496 | } |
| 565 | codec->dapm.bias_level = level; | 497 | codec->dapm.bias_level = level; |
| @@ -606,13 +538,7 @@ static int tlv320aic23_suspend(struct snd_soc_codec *codec, | |||
| 606 | 538 | ||
| 607 | static int tlv320aic23_resume(struct snd_soc_codec *codec) | 539 | static int tlv320aic23_resume(struct snd_soc_codec *codec) |
| 608 | { | 540 | { |
| 609 | u16 reg; | 541 | snd_soc_cache_sync(codec); |
| 610 | |||
| 611 | /* Sync reg_cache with the hardware */ | ||
| 612 | for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) { | ||
| 613 | u16 val = tlv320aic23_read_reg_cache(codec, reg); | ||
| 614 | tlv320aic23_write(codec, reg, val); | ||
| 615 | } | ||
| 616 | tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 542 | tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 617 | 543 | ||
| 618 | return 0; | 544 | return 0; |
| @@ -621,46 +547,52 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec) | |||
| 621 | static int tlv320aic23_probe(struct snd_soc_codec *codec) | 547 | static int tlv320aic23_probe(struct snd_soc_codec *codec) |
| 622 | { | 548 | { |
| 623 | struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); | 549 | struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec); |
| 624 | int reg; | 550 | int ret; |
| 625 | 551 | ||
| 626 | printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); | 552 | printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); |
| 627 | codec->control_data = aic23->control_data; | 553 | |
| 628 | codec->hw_write = (hw_write_t)i2c_master_send; | 554 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type); |
| 629 | codec->hw_read = NULL; | 555 | if (ret < 0) { |
| 556 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
| 557 | return ret; | ||
| 558 | } | ||
| 630 | 559 | ||
| 631 | /* Reset codec */ | 560 | /* Reset codec */ |
| 632 | tlv320aic23_write(codec, TLV320AIC23_RESET, 0); | 561 | snd_soc_write(codec, TLV320AIC23_RESET, 0); |
| 562 | |||
| 563 | /* Write the register default value to cache for reserved registers, | ||
| 564 | * so the write to the these registers are suppressed by the cache | ||
| 565 | * restore code when it skips writes of default registers. | ||
| 566 | */ | ||
| 567 | snd_soc_cache_write(codec, 0x0A, 0); | ||
| 568 | snd_soc_cache_write(codec, 0x0B, 0); | ||
| 569 | snd_soc_cache_write(codec, 0x0C, 0); | ||
| 570 | snd_soc_cache_write(codec, 0x0D, 0); | ||
| 571 | snd_soc_cache_write(codec, 0x0E, 0); | ||
| 633 | 572 | ||
| 634 | /* power on device */ | 573 | /* power on device */ |
| 635 | tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 574 | tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 636 | 575 | ||
| 637 | tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K); | 576 | snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K); |
| 638 | 577 | ||
| 639 | /* Unmute input */ | 578 | /* Unmute input */ |
| 640 | reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL); | 579 | snd_soc_update_bits(codec, TLV320AIC23_LINVOL, |
| 641 | tlv320aic23_write(codec, TLV320AIC23_LINVOL, | 580 | TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED); |
| 642 | (reg & (~TLV320AIC23_LIM_MUTED)) | | ||
| 643 | (TLV320AIC23_LRS_ENABLED)); | ||
| 644 | 581 | ||
| 645 | reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL); | 582 | snd_soc_update_bits(codec, TLV320AIC23_RINVOL, |
| 646 | tlv320aic23_write(codec, TLV320AIC23_RINVOL, | 583 | TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED); |
| 647 | (reg & (~TLV320AIC23_LIM_MUTED)) | | ||
| 648 | TLV320AIC23_LRS_ENABLED); | ||
| 649 | 584 | ||
| 650 | reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG); | 585 | snd_soc_update_bits(codec, TLV320AIC23_ANLG, |
| 651 | tlv320aic23_write(codec, TLV320AIC23_ANLG, | 586 | TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED, |
| 652 | (reg) & (~TLV320AIC23_BYPASS_ON) & | 587 | 0); |
| 653 | (~TLV320AIC23_MICM_MUTED)); | ||
| 654 | 588 | ||
| 655 | /* Default output volume */ | 589 | /* Default output volume */ |
| 656 | tlv320aic23_write(codec, TLV320AIC23_LCHNVOL, | 590 | snd_soc_write(codec, TLV320AIC23_LCHNVOL, |
| 657 | TLV320AIC23_DEFAULT_OUT_VOL & | 591 | TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK); |
| 658 | TLV320AIC23_OUT_VOL_MASK); | 592 | snd_soc_write(codec, TLV320AIC23_RCHNVOL, |
| 659 | tlv320aic23_write(codec, TLV320AIC23_RCHNVOL, | 593 | TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK); |
| 660 | TLV320AIC23_DEFAULT_OUT_VOL & | ||
| 661 | TLV320AIC23_OUT_VOL_MASK); | ||
| 662 | 594 | ||
| 663 | tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1); | 595 | snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1); |
| 664 | 596 | ||
| 665 | snd_soc_add_controls(codec, tlv320aic23_snd_controls, | 597 | snd_soc_add_controls(codec, tlv320aic23_snd_controls, |
| 666 | ARRAY_SIZE(tlv320aic23_snd_controls)); | 598 | ARRAY_SIZE(tlv320aic23_snd_controls)); |
| @@ -682,8 +614,6 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = { | |||
| 682 | .remove = tlv320aic23_remove, | 614 | .remove = tlv320aic23_remove, |
| 683 | .suspend = tlv320aic23_suspend, | 615 | .suspend = tlv320aic23_suspend, |
| 684 | .resume = tlv320aic23_resume, | 616 | .resume = tlv320aic23_resume, |
| 685 | .read = tlv320aic23_read_reg_cache, | ||
| 686 | .write = tlv320aic23_write, | ||
| 687 | .set_bias_level = tlv320aic23_set_bias_level, | 617 | .set_bias_level = tlv320aic23_set_bias_level, |
| 688 | .dapm_widgets = tlv320aic23_dapm_widgets, | 618 | .dapm_widgets = tlv320aic23_dapm_widgets, |
| 689 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), | 619 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), |
| @@ -710,7 +640,6 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c, | |||
| 710 | return -ENOMEM; | 640 | return -ENOMEM; |
| 711 | 641 | ||
| 712 | i2c_set_clientdata(i2c, aic23); | 642 | i2c_set_clientdata(i2c, aic23); |
| 713 | aic23->control_data = i2c; | ||
| 714 | aic23->control_type = SND_SOC_I2C; | 643 | aic23->control_type = SND_SOC_I2C; |
| 715 | 644 | ||
| 716 | ret = snd_soc_register_codec(&i2c->dev, | 645 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c index e93b9d1ae1dd..b21c610051c0 100644 --- a/sound/soc/codecs/tlv320aic32x4.c +++ b/sound/soc/codecs/tlv320aic32x4.c | |||
| @@ -528,40 +528,33 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | |||
| 528 | enum snd_soc_bias_level level) | 528 | enum snd_soc_bias_level level) |
| 529 | { | 529 | { |
| 530 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); | 530 | struct aic32x4_priv *aic32x4 = snd_soc_codec_get_drvdata(codec); |
| 531 | u8 value; | ||
| 532 | 531 | ||
| 533 | switch (level) { | 532 | switch (level) { |
| 534 | case SND_SOC_BIAS_ON: | 533 | case SND_SOC_BIAS_ON: |
| 535 | if (aic32x4->master) { | 534 | if (aic32x4->master) { |
| 536 | /* Switch on PLL */ | 535 | /* Switch on PLL */ |
| 537 | value = snd_soc_read(codec, AIC32X4_PLLPR); | 536 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
| 538 | snd_soc_write(codec, AIC32X4_PLLPR, | 537 | AIC32X4_PLLEN, AIC32X4_PLLEN); |
| 539 | (value | AIC32X4_PLLEN)); | ||
| 540 | 538 | ||
| 541 | /* Switch on NDAC Divider */ | 539 | /* Switch on NDAC Divider */ |
| 542 | value = snd_soc_read(codec, AIC32X4_NDAC); | 540 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
| 543 | snd_soc_write(codec, AIC32X4_NDAC, | 541 | AIC32X4_NDACEN, AIC32X4_NDACEN); |
| 544 | value | AIC32X4_NDACEN); | ||
| 545 | 542 | ||
| 546 | /* Switch on MDAC Divider */ | 543 | /* Switch on MDAC Divider */ |
| 547 | value = snd_soc_read(codec, AIC32X4_MDAC); | 544 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
| 548 | snd_soc_write(codec, AIC32X4_MDAC, | 545 | AIC32X4_MDACEN, AIC32X4_MDACEN); |
| 549 | value | AIC32X4_MDACEN); | ||
| 550 | 546 | ||
| 551 | /* Switch on NADC Divider */ | 547 | /* Switch on NADC Divider */ |
| 552 | value = snd_soc_read(codec, AIC32X4_NADC); | 548 | snd_soc_update_bits(codec, AIC32X4_NADC, |
| 553 | snd_soc_write(codec, AIC32X4_NADC, | 549 | AIC32X4_NADCEN, AIC32X4_NADCEN); |
| 554 | value | AIC32X4_MDACEN); | ||
| 555 | 550 | ||
| 556 | /* Switch on MADC Divider */ | 551 | /* Switch on MADC Divider */ |
| 557 | value = snd_soc_read(codec, AIC32X4_MADC); | 552 | snd_soc_update_bits(codec, AIC32X4_MADC, |
| 558 | snd_soc_write(codec, AIC32X4_MADC, | 553 | AIC32X4_MADCEN, AIC32X4_MADCEN); |
| 559 | value | AIC32X4_MDACEN); | ||
| 560 | 554 | ||
| 561 | /* Switch on BCLK_N Divider */ | 555 | /* Switch on BCLK_N Divider */ |
| 562 | value = snd_soc_read(codec, AIC32X4_BCLKN); | 556 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
| 563 | snd_soc_write(codec, AIC32X4_BCLKN, | 557 | AIC32X4_BCLKEN, AIC32X4_BCLKEN); |
| 564 | value | AIC32X4_BCLKEN); | ||
| 565 | } | 558 | } |
| 566 | break; | 559 | break; |
| 567 | case SND_SOC_BIAS_PREPARE: | 560 | case SND_SOC_BIAS_PREPARE: |
| @@ -569,34 +562,28 @@ static int aic32x4_set_bias_level(struct snd_soc_codec *codec, | |||
| 569 | case SND_SOC_BIAS_STANDBY: | 562 | case SND_SOC_BIAS_STANDBY: |
| 570 | if (aic32x4->master) { | 563 | if (aic32x4->master) { |
| 571 | /* Switch off PLL */ | 564 | /* Switch off PLL */ |
| 572 | value = snd_soc_read(codec, AIC32X4_PLLPR); | 565 | snd_soc_update_bits(codec, AIC32X4_PLLPR, |
| 573 | snd_soc_write(codec, AIC32X4_PLLPR, | 566 | AIC32X4_PLLEN, 0); |
| 574 | (value & ~AIC32X4_PLLEN)); | ||
| 575 | 567 | ||
| 576 | /* Switch off NDAC Divider */ | 568 | /* Switch off NDAC Divider */ |
| 577 | value = snd_soc_read(codec, AIC32X4_NDAC); | 569 | snd_soc_update_bits(codec, AIC32X4_NDAC, |
| 578 | snd_soc_write(codec, AIC32X4_NDAC, | 570 | AIC32X4_NDACEN, 0); |
| 579 | value & ~AIC32X4_NDACEN); | ||
| 580 | 571 | ||
| 581 | /* Switch off MDAC Divider */ | 572 | /* Switch off MDAC Divider */ |
| 582 | value = snd_soc_read(codec, AIC32X4_MDAC); | 573 | snd_soc_update_bits(codec, AIC32X4_MDAC, |
| 583 | snd_soc_write(codec, AIC32X4_MDAC, | 574 | AIC32X4_MDACEN, 0); |
| 584 | value & ~AIC32X4_MDACEN); | ||
| 585 | 575 | ||
| 586 | /* Switch off NADC Divider */ | 576 | /* Switch off NADC Divider */ |
| 587 | value = snd_soc_read(codec, AIC32X4_NADC); | 577 | snd_soc_update_bits(codec, AIC32X4_NADC, |
| 588 | snd_soc_write(codec, AIC32X4_NADC, | 578 | AIC32X4_NADCEN, 0); |
| 589 | value & ~AIC32X4_NDACEN); | ||
| 590 | 579 | ||
| 591 | /* Switch off MADC Divider */ | 580 | /* Switch off MADC Divider */ |
| 592 | value = snd_soc_read(codec, AIC32X4_MADC); | 581 | snd_soc_update_bits(codec, AIC32X4_MADC, |
| 593 | snd_soc_write(codec, AIC32X4_MADC, | 582 | AIC32X4_MADCEN, 0); |
| 594 | value & ~AIC32X4_MDACEN); | ||
| 595 | value = snd_soc_read(codec, AIC32X4_BCLKN); | ||
| 596 | 583 | ||
| 597 | /* Switch off BCLK_N Divider */ | 584 | /* Switch off BCLK_N Divider */ |
| 598 | snd_soc_write(codec, AIC32X4_BCLKN, | 585 | snd_soc_update_bits(codec, AIC32X4_BCLKN, |
| 599 | value & ~AIC32X4_BCLKEN); | 586 | AIC32X4_BCLKEN, 0); |
| 600 | } | 587 | } |
| 601 | break; | 588 | break; |
| 602 | case SND_SOC_BIAS_OFF: | 589 | case SND_SOC_BIAS_OFF: |
| @@ -685,10 +672,10 @@ static int aic32x4_probe(struct snd_soc_codec *codec) | |||
| 685 | } | 672 | } |
| 686 | 673 | ||
| 687 | /* Mic PGA routing */ | 674 | /* Mic PGA routing */ |
| 688 | if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) { | 675 | if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_LMIC_IN2R_10K) { |
| 689 | snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K); | 676 | snd_soc_write(codec, AIC32X4_LMICPGANIN, AIC32X4_LMICPGANIN_IN2R_10K); |
| 690 | } | 677 | } |
| 691 | if (aic32x4->micpga_routing | AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) { | 678 | if (aic32x4->micpga_routing & AIC32X4_MICPGA_ROUTE_RMIC_IN1L_10K) { |
| 692 | snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K); | 679 | snd_soc_write(codec, AIC32X4_RMICPGANIN, AIC32X4_RMICPGANIN_IN1L_10K); |
| 693 | } | 680 | } |
| 694 | 681 | ||
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 0963c4c7a83f..7a49390bc30d 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
| @@ -76,7 +76,6 @@ struct aic3x_priv { | |||
| 76 | struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; | 76 | struct aic3x_disable_nb disable_nb[AIC3X_NUM_SUPPLIES]; |
| 77 | enum snd_soc_control_type control_type; | 77 | enum snd_soc_control_type control_type; |
| 78 | struct aic3x_setup_data *setup; | 78 | struct aic3x_setup_data *setup; |
| 79 | void *control_data; | ||
| 80 | unsigned int sysclk; | 79 | unsigned int sysclk; |
| 81 | struct list_head list; | 80 | struct list_head list; |
| 82 | int master; | 81 | int master; |
| @@ -138,7 +137,10 @@ static int aic3x_read(struct snd_soc_codec *codec, unsigned int reg, | |||
| 138 | if (reg >= AIC3X_CACHEREGNUM) | 137 | if (reg >= AIC3X_CACHEREGNUM) |
| 139 | return -1; | 138 | return -1; |
| 140 | 139 | ||
| 141 | *value = codec->hw_read(codec, reg); | 140 | codec->cache_bypass = 1; |
| 141 | *value = snd_soc_read(codec, reg); | ||
| 142 | codec->cache_bypass = 0; | ||
| 143 | |||
| 142 | cache[reg] = *value; | 144 | cache[reg] = *value; |
| 143 | 145 | ||
| 144 | return 0; | 146 | return 0; |
| @@ -198,6 +200,10 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, | |||
| 198 | else | 200 | else |
| 199 | /* old connection must be powered down */ | 201 | /* old connection must be powered down */ |
| 200 | path->connect = invert ? 1 : 0; | 202 | path->connect = invert ? 1 : 0; |
| 203 | |||
| 204 | dapm_mark_dirty(path->source, "tlv320aic3x source"); | ||
| 205 | dapm_mark_dirty(path->sink, "tlv320aic3x sink"); | ||
| 206 | |||
| 201 | break; | 207 | break; |
| 202 | } | 208 | } |
| 203 | 209 | ||
| @@ -1383,7 +1389,6 @@ static int aic3x_probe(struct snd_soc_codec *codec) | |||
| 1383 | int ret, i; | 1389 | int ret, i; |
| 1384 | 1390 | ||
| 1385 | INIT_LIST_HEAD(&aic3x->list); | 1391 | INIT_LIST_HEAD(&aic3x->list); |
| 1386 | codec->control_data = aic3x->control_data; | ||
| 1387 | aic3x->codec = codec; | 1392 | aic3x->codec = codec; |
| 1388 | codec->dapm.idle_bias_off = 1; | 1393 | codec->dapm.idle_bias_off = 1; |
| 1389 | 1394 | ||
| @@ -1495,9 +1500,9 @@ static struct snd_soc_codec_driver soc_codec_dev_aic3x = { | |||
| 1495 | */ | 1500 | */ |
| 1496 | 1501 | ||
| 1497 | static const struct i2c_device_id aic3x_i2c_id[] = { | 1502 | static const struct i2c_device_id aic3x_i2c_id[] = { |
| 1498 | [AIC3X_MODEL_3X] = { "tlv320aic3x", 0 }, | 1503 | { "tlv320aic3x", AIC3X_MODEL_3X }, |
| 1499 | [AIC3X_MODEL_33] = { "tlv320aic33", 0 }, | 1504 | { "tlv320aic33", AIC3X_MODEL_33 }, |
| 1500 | [AIC3X_MODEL_3007] = { "tlv320aic3007", 0 }, | 1505 | { "tlv320aic3007", AIC3X_MODEL_3007 }, |
| 1501 | { } | 1506 | { } |
| 1502 | }; | 1507 | }; |
| 1503 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); | 1508 | MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id); |
| @@ -1512,7 +1517,6 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
| 1512 | struct aic3x_pdata *pdata = i2c->dev.platform_data; | 1517 | struct aic3x_pdata *pdata = i2c->dev.platform_data; |
| 1513 | struct aic3x_priv *aic3x; | 1518 | struct aic3x_priv *aic3x; |
| 1514 | int ret; | 1519 | int ret; |
| 1515 | const struct i2c_device_id *tbl; | ||
| 1516 | 1520 | ||
| 1517 | aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); | 1521 | aic3x = kzalloc(sizeof(struct aic3x_priv), GFP_KERNEL); |
| 1518 | if (aic3x == NULL) { | 1522 | if (aic3x == NULL) { |
| @@ -1520,7 +1524,6 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
| 1520 | return -ENOMEM; | 1524 | return -ENOMEM; |
| 1521 | } | 1525 | } |
| 1522 | 1526 | ||
| 1523 | aic3x->control_data = i2c; | ||
| 1524 | aic3x->control_type = SND_SOC_I2C; | 1527 | aic3x->control_type = SND_SOC_I2C; |
| 1525 | 1528 | ||
| 1526 | i2c_set_clientdata(i2c, aic3x); | 1529 | i2c_set_clientdata(i2c, aic3x); |
| @@ -1531,11 +1534,7 @@ static int aic3x_i2c_probe(struct i2c_client *i2c, | |||
| 1531 | aic3x->gpio_reset = -1; | 1534 | aic3x->gpio_reset = -1; |
| 1532 | } | 1535 | } |
| 1533 | 1536 | ||
| 1534 | for (tbl = aic3x_i2c_id; tbl->name[0]; tbl++) { | 1537 | aic3x->model = id->driver_data; |
| 1535 | if (!strcmp(tbl->name, id->name)) | ||
| 1536 | break; | ||
| 1537 | } | ||
| 1538 | aic3x->model = tbl - aic3x_i2c_id; | ||
| 1539 | 1538 | ||
| 1540 | ret = snd_soc_register_codec(&i2c->dev, | 1539 | ret = snd_soc_register_codec(&i2c->dev, |
| 1541 | &soc_codec_dev_aic3x, &aic3x_dai, 1); | 1540 | &soc_codec_dev_aic3x, &aic3x_dai, 1); |
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index faa5e9fb1471..dc8a2b2bdc1c 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c | |||
| @@ -55,13 +55,13 @@ | |||
| 55 | #define BURST_BASEFREQ_HZ 49152000 | 55 | #define BURST_BASEFREQ_HZ 49152000 |
| 56 | 56 | ||
| 57 | #define SAMPLES_TO_US(rate, samples) \ | 57 | #define SAMPLES_TO_US(rate, samples) \ |
| 58 | (1000000000 / ((rate * 1000) / samples)) | 58 | (1000000000 / (((rate) * 1000) / (samples))) |
| 59 | 59 | ||
| 60 | #define US_TO_SAMPLES(rate, us) \ | 60 | #define US_TO_SAMPLES(rate, us) \ |
| 61 | (rate / (1000000 / (us < 1000000 ? us : 1000000))) | 61 | ((rate) / (1000000 / ((us) < 1000000 ? (us) : 1000000))) |
| 62 | 62 | ||
| 63 | #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ | 63 | #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ |
| 64 | ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) | 64 | (((samples)*5000) / (((burstrate)*5000) / ((burstrate) - (playrate)))) |
| 65 | 65 | ||
| 66 | static void dac33_calculate_times(struct snd_pcm_substream *substream); | 66 | static void dac33_calculate_times(struct snd_pcm_substream *substream); |
| 67 | static int dac33_prepare_chip(struct snd_pcm_substream *substream); | 67 | static int dac33_prepare_chip(struct snd_pcm_substream *substream); |
| @@ -627,18 +627,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 627 | {"RIGHT_LO", NULL, "Codec Power"}, | 627 | {"RIGHT_LO", NULL, "Codec Power"}, |
| 628 | }; | 628 | }; |
| 629 | 629 | ||
| 630 | static int dac33_add_widgets(struct snd_soc_codec *codec) | ||
| 631 | { | ||
| 632 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 633 | |||
| 634 | snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets, | ||
| 635 | ARRAY_SIZE(dac33_dapm_widgets)); | ||
| 636 | /* set up audio path interconnects */ | ||
| 637 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 638 | |||
| 639 | return 0; | ||
| 640 | } | ||
| 641 | |||
| 642 | static int dac33_set_bias_level(struct snd_soc_codec *codec, | 630 | static int dac33_set_bias_level(struct snd_soc_codec *codec, |
| 643 | enum snd_soc_bias_level level) | 631 | enum snd_soc_bias_level level) |
| 644 | { | 632 | { |
| @@ -1431,7 +1419,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
| 1431 | /* Check if the IRQ number is valid and request it */ | 1419 | /* Check if the IRQ number is valid and request it */ |
| 1432 | if (dac33->irq >= 0) { | 1420 | if (dac33->irq >= 0) { |
| 1433 | ret = request_irq(dac33->irq, dac33_interrupt_handler, | 1421 | ret = request_irq(dac33->irq, dac33_interrupt_handler, |
| 1434 | IRQF_TRIGGER_RISING | IRQF_DISABLED, | 1422 | IRQF_TRIGGER_RISING, |
| 1435 | codec->name, codec); | 1423 | codec->name, codec); |
| 1436 | if (ret < 0) { | 1424 | if (ret < 0) { |
| 1437 | dev_err(codec->dev, "Could not request IRQ%d (%d)\n", | 1425 | dev_err(codec->dev, "Could not request IRQ%d (%d)\n", |
| @@ -1451,15 +1439,11 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) | |||
| 1451 | } | 1439 | } |
| 1452 | } | 1440 | } |
| 1453 | 1441 | ||
| 1454 | snd_soc_add_controls(codec, dac33_snd_controls, | ||
| 1455 | ARRAY_SIZE(dac33_snd_controls)); | ||
| 1456 | /* Only add the FIFO controls, if we have valid IRQ number */ | 1442 | /* Only add the FIFO controls, if we have valid IRQ number */ |
| 1457 | if (dac33->irq >= 0) | 1443 | if (dac33->irq >= 0) |
| 1458 | snd_soc_add_controls(codec, dac33_mode_snd_controls, | 1444 | snd_soc_add_controls(codec, dac33_mode_snd_controls, |
| 1459 | ARRAY_SIZE(dac33_mode_snd_controls)); | 1445 | ARRAY_SIZE(dac33_mode_snd_controls)); |
| 1460 | 1446 | ||
| 1461 | dac33_add_widgets(codec); | ||
| 1462 | |||
| 1463 | err_power: | 1447 | err_power: |
| 1464 | return ret; | 1448 | return ret; |
| 1465 | } | 1449 | } |
| @@ -1502,6 +1486,13 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { | |||
| 1502 | .remove = dac33_soc_remove, | 1486 | .remove = dac33_soc_remove, |
| 1503 | .suspend = dac33_soc_suspend, | 1487 | .suspend = dac33_soc_suspend, |
| 1504 | .resume = dac33_soc_resume, | 1488 | .resume = dac33_soc_resume, |
| 1489 | |||
| 1490 | .controls = dac33_snd_controls, | ||
| 1491 | .num_controls = ARRAY_SIZE(dac33_snd_controls), | ||
| 1492 | .dapm_widgets = dac33_dapm_widgets, | ||
| 1493 | .num_dapm_widgets = ARRAY_SIZE(dac33_dapm_widgets), | ||
| 1494 | .dapm_routes = audio_map, | ||
| 1495 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 1505 | }; | 1496 | }; |
| 1506 | 1497 | ||
| 1507 | #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ | 1498 | #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ |
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 239e0c461068..7eeca79d7387 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c | |||
| @@ -33,6 +33,11 @@ | |||
| 33 | 33 | ||
| 34 | #include "tpa6130a2.h" | 34 | #include "tpa6130a2.h" |
| 35 | 35 | ||
| 36 | enum tpa_model { | ||
| 37 | TPA6130A2, | ||
| 38 | TPA6140A2, | ||
| 39 | }; | ||
| 40 | |||
| 36 | static struct i2c_client *tpa6130a2_client; | 41 | static struct i2c_client *tpa6130a2_client; |
| 37 | 42 | ||
| 38 | /* This struct is used to save the context */ | 43 | /* This struct is used to save the context */ |
| @@ -383,7 +388,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client, | |||
| 383 | 388 | ||
| 384 | pdata = client->dev.platform_data; | 389 | pdata = client->dev.platform_data; |
| 385 | data->power_gpio = pdata->power_gpio; | 390 | data->power_gpio = pdata->power_gpio; |
| 386 | data->id = pdata->id; | 391 | data->id = id->driver_data; |
| 387 | 392 | ||
| 388 | mutex_init(&data->mutex); | 393 | mutex_init(&data->mutex); |
| 389 | 394 | ||
| @@ -405,7 +410,7 @@ static int __devinit tpa6130a2_probe(struct i2c_client *client, | |||
| 405 | switch (data->id) { | 410 | switch (data->id) { |
| 406 | default: | 411 | default: |
| 407 | dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", | 412 | dev_warn(dev, "Unknown TPA model (%d). Assuming 6130A2\n", |
| 408 | pdata->id); | 413 | data->id); |
| 409 | case TPA6130A2: | 414 | case TPA6130A2: |
| 410 | regulator = "Vdd"; | 415 | regulator = "Vdd"; |
| 411 | break; | 416 | break; |
| @@ -446,7 +451,6 @@ err_regulator: | |||
| 446 | gpio_free(data->power_gpio); | 451 | gpio_free(data->power_gpio); |
| 447 | err_gpio: | 452 | err_gpio: |
| 448 | kfree(data); | 453 | kfree(data); |
| 449 | i2c_set_clientdata(tpa6130a2_client, NULL); | ||
| 450 | tpa6130a2_client = NULL; | 454 | tpa6130a2_client = NULL; |
| 451 | 455 | ||
| 452 | return ret; | 456 | return ret; |
| @@ -470,7 +474,8 @@ static int __devexit tpa6130a2_remove(struct i2c_client *client) | |||
| 470 | } | 474 | } |
| 471 | 475 | ||
| 472 | static const struct i2c_device_id tpa6130a2_id[] = { | 476 | static const struct i2c_device_id tpa6130a2_id[] = { |
| 473 | { "tpa6130a2", 0 }, | 477 | { "tpa6130a2", TPA6130A2 }, |
| 478 | { "tpa6140a2", TPA6140A2 }, | ||
| 474 | { } | 479 | { } |
| 475 | }; | 480 | }; |
| 476 | MODULE_DEVICE_TABLE(i2c, tpa6130a2_id); | 481 | MODULE_DEVICE_TABLE(i2c, tpa6130a2_id); |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 71674bec9604..f798247ac1b2 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
| @@ -863,34 +863,6 @@ static int digimic_event(struct snd_soc_dapm_widget *w, | |||
| 863 | * Inverting not going to help with these. | 863 | * Inverting not going to help with these. |
| 864 | * Custom volsw and volsw_2r get/put functions to handle these gain bits. | 864 | * Custom volsw and volsw_2r get/put functions to handle these gain bits. |
| 865 | */ | 865 | */ |
| 866 | #define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\ | ||
| 867 | xinvert, tlv_array) \ | ||
| 868 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | ||
| 869 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
| 870 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | ||
| 871 | .tlv.p = (tlv_array), \ | ||
| 872 | .info = snd_soc_info_volsw, \ | ||
| 873 | .get = snd_soc_get_volsw_twl4030, \ | ||
| 874 | .put = snd_soc_put_volsw_twl4030, \ | ||
| 875 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
| 876 | {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ | ||
| 877 | .max = xmax, .invert = xinvert} } | ||
| 878 | #define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\ | ||
| 879 | xinvert, tlv_array) \ | ||
| 880 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | ||
| 881 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
| 882 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | ||
| 883 | .tlv.p = (tlv_array), \ | ||
| 884 | .info = snd_soc_info_volsw_2r, \ | ||
| 885 | .get = snd_soc_get_volsw_r2_twl4030,\ | ||
| 886 | .put = snd_soc_put_volsw_r2_twl4030, \ | ||
| 887 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
| 888 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | ||
| 889 | .rshift = xshift, .max = xmax, .invert = xinvert} } | ||
| 890 | #define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \ | ||
| 891 | SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \ | ||
| 892 | xinvert, tlv_array) | ||
| 893 | |||
| 894 | static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, | 866 | static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol, |
| 895 | struct snd_ctl_elem_value *ucontrol) | 867 | struct snd_ctl_elem_value *ucontrol) |
| 896 | { | 868 | { |
| @@ -1197,19 +1169,23 @@ static const struct snd_kcontrol_new twl4030_snd_controls[] = { | |||
| 1197 | TWL4030_REG_VDL_APGA_CTL, 1, 1, 0), | 1169 | TWL4030_REG_VDL_APGA_CTL, 1, 1, 0), |
| 1198 | 1170 | ||
| 1199 | /* Separate output gain controls */ | 1171 | /* Separate output gain controls */ |
| 1200 | SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume", | 1172 | SOC_DOUBLE_R_EXT_TLV("PreDriv Playback Volume", |
| 1201 | TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, | 1173 | TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL, |
| 1202 | 4, 3, 0, output_tvl), | 1174 | 4, 3, 0, snd_soc_get_volsw_r2_twl4030, |
| 1175 | snd_soc_put_volsw_r2_twl4030, output_tvl), | ||
| 1203 | 1176 | ||
| 1204 | SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume", | 1177 | SOC_DOUBLE_EXT_TLV("Headset Playback Volume", |
| 1205 | TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl), | 1178 | TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, snd_soc_get_volsw_twl4030, |
| 1179 | snd_soc_put_volsw_twl4030, output_tvl), | ||
| 1206 | 1180 | ||
| 1207 | SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume", | 1181 | SOC_DOUBLE_R_EXT_TLV("Carkit Playback Volume", |
| 1208 | TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL, | 1182 | TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL, |
| 1209 | 4, 3, 0, output_tvl), | 1183 | 4, 3, 0, snd_soc_get_volsw_r2_twl4030, |
| 1184 | snd_soc_put_volsw_r2_twl4030, output_tvl), | ||
| 1210 | 1185 | ||
| 1211 | SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume", | 1186 | SOC_SINGLE_EXT_TLV("Earpiece Playback Volume", |
| 1212 | TWL4030_REG_EAR_CTL, 4, 3, 0, output_ear_tvl), | 1187 | TWL4030_REG_EAR_CTL, 4, 3, 0, snd_soc_get_volsw_twl4030, |
| 1188 | snd_soc_put_volsw_twl4030, output_ear_tvl), | ||
| 1213 | 1189 | ||
| 1214 | /* Common capture gain controls */ | 1190 | /* Common capture gain controls */ |
| 1215 | SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume", | 1191 | SOC_DOUBLE_R_TLV("TX1 Digital Capture Volume", |
| @@ -1633,17 +1609,6 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
| 1633 | 1609 | ||
| 1634 | }; | 1610 | }; |
| 1635 | 1611 | ||
| 1636 | static int twl4030_add_widgets(struct snd_soc_codec *codec) | ||
| 1637 | { | ||
| 1638 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 1639 | |||
| 1640 | snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets, | ||
| 1641 | ARRAY_SIZE(twl4030_dapm_widgets)); | ||
| 1642 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | ||
| 1643 | |||
| 1644 | return 0; | ||
| 1645 | } | ||
| 1646 | |||
| 1647 | static int twl4030_set_bias_level(struct snd_soc_codec *codec, | 1612 | static int twl4030_set_bias_level(struct snd_soc_codec *codec, |
| 1648 | enum snd_soc_bias_level level) | 1613 | enum snd_soc_bias_level level) |
| 1649 | { | 1614 | { |
| @@ -2265,9 +2230,6 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) | |||
| 2265 | 2230 | ||
| 2266 | twl4030_init_chip(codec); | 2231 | twl4030_init_chip(codec); |
| 2267 | 2232 | ||
| 2268 | snd_soc_add_controls(codec, twl4030_snd_controls, | ||
| 2269 | ARRAY_SIZE(twl4030_snd_controls)); | ||
| 2270 | twl4030_add_widgets(codec); | ||
| 2271 | return 0; | 2233 | return 0; |
| 2272 | } | 2234 | } |
| 2273 | 2235 | ||
| @@ -2293,6 +2255,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
| 2293 | .reg_cache_size = sizeof(twl4030_reg), | 2255 | .reg_cache_size = sizeof(twl4030_reg), |
| 2294 | .reg_word_size = sizeof(u8), | 2256 | .reg_word_size = sizeof(u8), |
| 2295 | .reg_cache_default = twl4030_reg, | 2257 | .reg_cache_default = twl4030_reg, |
| 2258 | |||
| 2259 | .controls = twl4030_snd_controls, | ||
| 2260 | .num_controls = ARRAY_SIZE(twl4030_snd_controls), | ||
| 2261 | .dapm_widgets = twl4030_dapm_widgets, | ||
| 2262 | .num_dapm_widgets = ARRAY_SIZE(twl4030_dapm_widgets), | ||
| 2263 | .dapm_routes = intercon, | ||
| 2264 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
| 2296 | }; | 2265 | }; |
| 2297 | 2266 | ||
| 2298 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) | 2267 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 443032b3b329..73e11f022ded 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c | |||
| @@ -57,6 +57,13 @@ | |||
| 57 | #define TWL6040_HF_VOL_MASK 0x1F | 57 | #define TWL6040_HF_VOL_MASK 0x1F |
| 58 | #define TWL6040_HF_VOL_SHIFT 0 | 58 | #define TWL6040_HF_VOL_SHIFT 0 |
| 59 | 59 | ||
| 60 | /* Shadow register used by the driver */ | ||
| 61 | #define TWL6040_REG_SW_SHADOW 0x2F | ||
| 62 | #define TWL6040_CACHEREGNUM (TWL6040_REG_SW_SHADOW + 1) | ||
| 63 | |||
| 64 | /* TWL6040_REG_SW_SHADOW (0x2F) fields */ | ||
| 65 | #define TWL6040_EAR_PATH_ENABLE 0x01 | ||
| 66 | |||
| 60 | struct twl6040_output { | 67 | struct twl6040_output { |
| 61 | u16 active; | 68 | u16 active; |
| 62 | u16 left_vol; | 69 | u16 left_vol; |
| @@ -65,12 +72,13 @@ struct twl6040_output { | |||
| 65 | u16 right_step; | 72 | u16 right_step; |
| 66 | unsigned int step_delay; | 73 | unsigned int step_delay; |
| 67 | u16 ramp; | 74 | u16 ramp; |
| 68 | u16 mute; | 75 | struct delayed_work work; |
| 69 | struct completion ramp_done; | 76 | struct completion ramp_done; |
| 70 | }; | 77 | }; |
| 71 | 78 | ||
| 72 | struct twl6040_jack_data { | 79 | struct twl6040_jack_data { |
| 73 | struct snd_soc_jack *jack; | 80 | struct snd_soc_jack *jack; |
| 81 | struct delayed_work work; | ||
| 74 | int report; | 82 | int report; |
| 75 | }; | 83 | }; |
| 76 | 84 | ||
| @@ -79,7 +87,6 @@ struct twl6040_data { | |||
| 79 | int plug_irq; | 87 | int plug_irq; |
| 80 | int codec_powered; | 88 | int codec_powered; |
| 81 | int pll; | 89 | int pll; |
| 82 | int non_lp; | ||
| 83 | int pll_power_mode; | 90 | int pll_power_mode; |
| 84 | int hs_power_mode; | 91 | int hs_power_mode; |
| 85 | int hs_power_mode_locked; | 92 | int hs_power_mode_locked; |
| @@ -92,104 +99,68 @@ struct twl6040_data { | |||
| 92 | struct twl6040_jack_data hs_jack; | 99 | struct twl6040_jack_data hs_jack; |
| 93 | struct snd_soc_codec *codec; | 100 | struct snd_soc_codec *codec; |
| 94 | struct workqueue_struct *workqueue; | 101 | struct workqueue_struct *workqueue; |
| 95 | struct delayed_work delayed_work; | ||
| 96 | struct mutex mutex; | 102 | struct mutex mutex; |
| 97 | struct twl6040_output headset; | 103 | struct twl6040_output headset; |
| 98 | struct twl6040_output handsfree; | 104 | struct twl6040_output handsfree; |
| 99 | struct workqueue_struct *hf_workqueue; | ||
| 100 | struct workqueue_struct *hs_workqueue; | ||
| 101 | struct delayed_work hs_delayed_work; | ||
| 102 | struct delayed_work hf_delayed_work; | ||
| 103 | }; | 105 | }; |
| 104 | 106 | ||
| 105 | /* | 107 | /* |
| 106 | * twl6040 register cache & default register settings | 108 | * twl6040 register cache & default register settings |
| 107 | */ | 109 | */ |
| 108 | static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { | 110 | static const u8 twl6040_reg[TWL6040_CACHEREGNUM] = { |
| 109 | 0x00, /* not used 0x00 */ | 111 | 0x00, /* not used 0x00 */ |
| 110 | 0x4B, /* TWL6040_ASICID (ro) 0x01 */ | 112 | 0x4B, /* REG_ASICID 0x01 (ro) */ |
| 111 | 0x00, /* TWL6040_ASICREV (ro) 0x02 */ | 113 | 0x00, /* REG_ASICREV 0x02 (ro) */ |
| 112 | 0x00, /* TWL6040_INTID 0x03 */ | 114 | 0x00, /* REG_INTID 0x03 */ |
| 113 | 0x00, /* TWL6040_INTMR 0x04 */ | 115 | 0x00, /* REG_INTMR 0x04 */ |
| 114 | 0x00, /* TWL6040_NCPCTRL 0x05 */ | 116 | 0x00, /* REG_NCPCTRL 0x05 */ |
| 115 | 0x00, /* TWL6040_LDOCTL 0x06 */ | 117 | 0x00, /* REG_LDOCTL 0x06 */ |
| 116 | 0x60, /* TWL6040_HPPLLCTL 0x07 */ | 118 | 0x60, /* REG_HPPLLCTL 0x07 */ |
| 117 | 0x00, /* TWL6040_LPPLLCTL 0x08 */ | 119 | 0x00, /* REG_LPPLLCTL 0x08 */ |
| 118 | 0x4A, /* TWL6040_LPPLLDIV 0x09 */ | 120 | 0x4A, /* REG_LPPLLDIV 0x09 */ |
| 119 | 0x00, /* TWL6040_AMICBCTL 0x0A */ | 121 | 0x00, /* REG_AMICBCTL 0x0A */ |
| 120 | 0x00, /* TWL6040_DMICBCTL 0x0B */ | 122 | 0x00, /* REG_DMICBCTL 0x0B */ |
| 121 | 0x18, /* TWL6040_MICLCTL 0x0C - No input selected on Left Mic */ | 123 | 0x00, /* REG_MICLCTL 0x0C */ |
| 122 | 0x18, /* TWL6040_MICRCTL 0x0D - No input selected on Right Mic */ | 124 | 0x00, /* REG_MICRCTL 0x0D */ |
| 123 | 0x00, /* TWL6040_MICGAIN 0x0E */ | 125 | 0x00, /* REG_MICGAIN 0x0E */ |
| 124 | 0x1B, /* TWL6040_LINEGAIN 0x0F */ | 126 | 0x1B, /* REG_LINEGAIN 0x0F */ |
| 125 | 0x00, /* TWL6040_HSLCTL 0x10 */ | 127 | 0x00, /* REG_HSLCTL 0x10 */ |
| 126 | 0x00, /* TWL6040_HSRCTL 0x11 */ | 128 | 0x00, /* REG_HSRCTL 0x11 */ |
| 127 | 0x00, /* TWL6040_HSGAIN 0x12 */ | 129 | 0x00, /* REG_HSGAIN 0x12 */ |
| 128 | 0x00, /* TWL6040_EARCTL 0x13 */ | 130 | 0x00, /* REG_EARCTL 0x13 */ |
| 129 | 0x00, /* TWL6040_HFLCTL 0x14 */ | 131 | 0x00, /* REG_HFLCTL 0x14 */ |
| 130 | 0x00, /* TWL6040_HFLGAIN 0x15 */ | 132 | 0x00, /* REG_HFLGAIN 0x15 */ |
| 131 | 0x00, /* TWL6040_HFRCTL 0x16 */ | 133 | 0x00, /* REG_HFRCTL 0x16 */ |
| 132 | 0x00, /* TWL6040_HFRGAIN 0x17 */ | 134 | 0x00, /* REG_HFRGAIN 0x17 */ |
| 133 | 0x00, /* TWL6040_VIBCTLL 0x18 */ | 135 | 0x00, /* REG_VIBCTLL 0x18 */ |
| 134 | 0x00, /* TWL6040_VIBDATL 0x19 */ | 136 | 0x00, /* REG_VIBDATL 0x19 */ |
| 135 | 0x00, /* TWL6040_VIBCTLR 0x1A */ | 137 | 0x00, /* REG_VIBCTLR 0x1A */ |
| 136 | 0x00, /* TWL6040_VIBDATR 0x1B */ | 138 | 0x00, /* REG_VIBDATR 0x1B */ |
| 137 | 0x00, /* TWL6040_HKCTL1 0x1C */ | 139 | 0x00, /* REG_HKCTL1 0x1C */ |
| 138 | 0x00, /* TWL6040_HKCTL2 0x1D */ | 140 | 0x00, /* REG_HKCTL2 0x1D */ |
| 139 | 0x00, /* TWL6040_GPOCTL 0x1E */ | 141 | 0x00, /* REG_GPOCTL 0x1E */ |
| 140 | 0x00, /* TWL6040_ALB 0x1F */ | 142 | 0x00, /* REG_ALB 0x1F */ |
| 141 | 0x00, /* TWL6040_DLB 0x20 */ | 143 | 0x00, /* REG_DLB 0x20 */ |
| 142 | 0x00, /* not used 0x21 */ | 144 | 0x00, /* not used 0x21 */ |
| 143 | 0x00, /* not used 0x22 */ | 145 | 0x00, /* not used 0x22 */ |
| 144 | 0x00, /* not used 0x23 */ | 146 | 0x00, /* not used 0x23 */ |
| 145 | 0x00, /* not used 0x24 */ | 147 | 0x00, /* not used 0x24 */ |
| 146 | 0x00, /* not used 0x25 */ | 148 | 0x00, /* not used 0x25 */ |
| 147 | 0x00, /* not used 0x26 */ | 149 | 0x00, /* not used 0x26 */ |
| 148 | 0x00, /* not used 0x27 */ | 150 | 0x00, /* not used 0x27 */ |
| 149 | 0x00, /* TWL6040_TRIM1 0x28 */ | 151 | 0x00, /* REG_TRIM1 0x28 */ |
| 150 | 0x00, /* TWL6040_TRIM2 0x29 */ | 152 | 0x00, /* REG_TRIM2 0x29 */ |
| 151 | 0x00, /* TWL6040_TRIM3 0x2A */ | 153 | 0x00, /* REG_TRIM3 0x2A */ |
| 152 | 0x00, /* TWL6040_HSOTRIM 0x2B */ | 154 | 0x00, /* REG_HSOTRIM 0x2B */ |
| 153 | 0x00, /* TWL6040_HFOTRIM 0x2C */ | 155 | 0x00, /* REG_HFOTRIM 0x2C */ |
| 154 | 0x09, /* TWL6040_ACCCTL 0x2D */ | 156 | 0x09, /* REG_ACCCTL 0x2D */ |
| 155 | 0x00, /* TWL6040_STATUS (ro) 0x2E */ | 157 | 0x00, /* REG_STATUS 0x2E (ro) */ |
| 156 | }; | 158 | |
| 157 | 159 | 0x00, /* REG_SW_SHADOW 0x2F - Shadow, non HW register */ | |
| 158 | /* | ||
| 159 | * twl6040 vio/gnd registers: | ||
| 160 | * registers under vio/gnd supply can be accessed | ||
| 161 | * before the power-up sequence, after NRESPWRON goes high | ||
| 162 | */ | ||
| 163 | static const int twl6040_vio_reg[TWL6040_VIOREGNUM] = { | ||
| 164 | TWL6040_REG_ASICID, | ||
| 165 | TWL6040_REG_ASICREV, | ||
| 166 | TWL6040_REG_INTID, | ||
| 167 | TWL6040_REG_INTMR, | ||
| 168 | TWL6040_REG_NCPCTL, | ||
| 169 | TWL6040_REG_LDOCTL, | ||
| 170 | TWL6040_REG_AMICBCTL, | ||
| 171 | TWL6040_REG_DMICBCTL, | ||
| 172 | TWL6040_REG_HKCTL1, | ||
| 173 | TWL6040_REG_HKCTL2, | ||
| 174 | TWL6040_REG_GPOCTL, | ||
| 175 | TWL6040_REG_TRIM1, | ||
| 176 | TWL6040_REG_TRIM2, | ||
| 177 | TWL6040_REG_TRIM3, | ||
| 178 | TWL6040_REG_HSOTRIM, | ||
| 179 | TWL6040_REG_HFOTRIM, | ||
| 180 | TWL6040_REG_ACCCTL, | ||
| 181 | TWL6040_REG_STATUS, | ||
| 182 | }; | 160 | }; |
| 183 | 161 | ||
| 184 | /* | 162 | /* List of registers to be restored after power up */ |
| 185 | * twl6040 vdd/vss registers: | 163 | static const int twl6040_restore_list[] = { |
| 186 | * registers under vdd/vss supplies can only be accessed | ||
| 187 | * after the power-up sequence | ||
| 188 | */ | ||
| 189 | static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = { | ||
| 190 | TWL6040_REG_HPPLLCTL, | ||
| 191 | TWL6040_REG_LPPLLCTL, | ||
| 192 | TWL6040_REG_LPPLLDIV, | ||
| 193 | TWL6040_REG_MICLCTL, | 164 | TWL6040_REG_MICLCTL, |
| 194 | TWL6040_REG_MICRCTL, | 165 | TWL6040_REG_MICRCTL, |
| 195 | TWL6040_REG_MICGAIN, | 166 | TWL6040_REG_MICGAIN, |
| @@ -202,12 +173,6 @@ static const int twl6040_vdd_reg[TWL6040_VDDREGNUM] = { | |||
| 202 | TWL6040_REG_HFLGAIN, | 173 | TWL6040_REG_HFLGAIN, |
| 203 | TWL6040_REG_HFRCTL, | 174 | TWL6040_REG_HFRCTL, |
| 204 | TWL6040_REG_HFRGAIN, | 175 | TWL6040_REG_HFRGAIN, |
| 205 | TWL6040_REG_VIBCTLL, | ||
| 206 | TWL6040_REG_VIBDATL, | ||
| 207 | TWL6040_REG_VIBCTLR, | ||
| 208 | TWL6040_REG_VIBDATR, | ||
| 209 | TWL6040_REG_ALB, | ||
| 210 | TWL6040_REG_DLB, | ||
| 211 | }; | 176 | }; |
| 212 | 177 | ||
| 213 | /* set of rates for each pll: low-power and high-performance */ | 178 | /* set of rates for each pll: low-power and high-performance */ |
| @@ -275,8 +240,12 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec, | |||
| 275 | if (reg >= TWL6040_CACHEREGNUM) | 240 | if (reg >= TWL6040_CACHEREGNUM) |
| 276 | return -EIO; | 241 | return -EIO; |
| 277 | 242 | ||
| 278 | value = twl6040_reg_read(twl6040, reg); | 243 | if (likely(reg < TWL6040_REG_SW_SHADOW)) { |
| 279 | twl6040_write_reg_cache(codec, reg, value); | 244 | value = twl6040_reg_read(twl6040, reg); |
| 245 | twl6040_write_reg_cache(codec, reg, value); | ||
| 246 | } else { | ||
| 247 | value = twl6040_read_reg_cache(codec, reg); | ||
| 248 | } | ||
| 280 | 249 | ||
| 281 | return value; | 250 | return value; |
| 282 | } | 251 | } |
| @@ -293,59 +262,51 @@ static int twl6040_write(struct snd_soc_codec *codec, | |||
| 293 | return -EIO; | 262 | return -EIO; |
| 294 | 263 | ||
| 295 | twl6040_write_reg_cache(codec, reg, value); | 264 | twl6040_write_reg_cache(codec, reg, value); |
| 296 | return twl6040_reg_write(twl6040, reg, value); | 265 | if (likely(reg < TWL6040_REG_SW_SHADOW)) |
| 266 | return twl6040_reg_write(twl6040, reg, value); | ||
| 267 | else | ||
| 268 | return 0; | ||
| 297 | } | 269 | } |
| 298 | 270 | ||
| 299 | static void twl6040_init_vio_regs(struct snd_soc_codec *codec) | 271 | static void twl6040_init_chip(struct snd_soc_codec *codec) |
| 300 | { | 272 | { |
| 301 | u8 *cache = codec->reg_cache; | 273 | struct twl6040 *twl6040 = codec->control_data; |
| 302 | int reg, i; | 274 | u8 val; |
| 303 | 275 | ||
| 304 | for (i = 0; i < TWL6040_VIOREGNUM; i++) { | 276 | /* Update reg_cache: ASICREV, and TRIM values */ |
| 305 | reg = twl6040_vio_reg[i]; | 277 | val = twl6040_get_revid(twl6040); |
| 306 | /* | 278 | twl6040_write_reg_cache(codec, TWL6040_REG_ASICREV, val); |
| 307 | * skip read-only registers (ASICID, ASICREV, STATUS) | 279 | |
| 308 | * and registers shared among MFD children | 280 | twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM1); |
| 309 | */ | 281 | twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM2); |
| 310 | switch (reg) { | 282 | twl6040_read_reg_volatile(codec, TWL6040_REG_TRIM3); |
| 311 | case TWL6040_REG_ASICID: | 283 | twl6040_read_reg_volatile(codec, TWL6040_REG_HSOTRIM); |
| 312 | case TWL6040_REG_ASICREV: | 284 | twl6040_read_reg_volatile(codec, TWL6040_REG_HFOTRIM); |
| 313 | case TWL6040_REG_INTID: | 285 | |
| 314 | case TWL6040_REG_INTMR: | 286 | /* Change chip defaults */ |
| 315 | case TWL6040_REG_NCPCTL: | 287 | /* No imput selected for microphone amplifiers */ |
| 316 | case TWL6040_REG_LDOCTL: | 288 | twl6040_write_reg_cache(codec, TWL6040_REG_MICLCTL, 0x18); |
| 317 | case TWL6040_REG_GPOCTL: | 289 | twl6040_write_reg_cache(codec, TWL6040_REG_MICRCTL, 0x18); |
| 318 | case TWL6040_REG_ACCCTL: | 290 | |
| 319 | case TWL6040_REG_STATUS: | 291 | /* |
| 320 | continue; | 292 | * We need to lower the default gain values, so the ramp code |
| 321 | default: | 293 | * can work correctly for the first playback. |
| 322 | break; | 294 | * This reduces the pop noise heard at the first playback. |
| 323 | } | 295 | */ |
| 324 | twl6040_write(codec, reg, cache[reg]); | 296 | twl6040_write_reg_cache(codec, TWL6040_REG_HSGAIN, 0xff); |
| 325 | } | 297 | twl6040_write_reg_cache(codec, TWL6040_REG_EARCTL, 0x1e); |
| 298 | twl6040_write_reg_cache(codec, TWL6040_REG_HFLGAIN, 0x1d); | ||
| 299 | twl6040_write_reg_cache(codec, TWL6040_REG_HFRGAIN, 0x1d); | ||
| 300 | twl6040_write_reg_cache(codec, TWL6040_REG_LINEGAIN, 0); | ||
| 326 | } | 301 | } |
| 327 | 302 | ||
| 328 | static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) | 303 | static void twl6040_restore_regs(struct snd_soc_codec *codec) |
| 329 | { | 304 | { |
| 330 | u8 *cache = codec->reg_cache; | 305 | u8 *cache = codec->reg_cache; |
| 331 | int reg, i; | 306 | int reg, i; |
| 332 | 307 | ||
| 333 | for (i = 0; i < TWL6040_VDDREGNUM; i++) { | 308 | for (i = 0; i < ARRAY_SIZE(twl6040_restore_list); i++) { |
| 334 | reg = twl6040_vdd_reg[i]; | 309 | reg = twl6040_restore_list[i]; |
| 335 | /* skip vibra and PLL registers */ | ||
| 336 | switch (reg) { | ||
| 337 | case TWL6040_REG_VIBCTLL: | ||
| 338 | case TWL6040_REG_VIBDATL: | ||
| 339 | case TWL6040_REG_VIBCTLR: | ||
| 340 | case TWL6040_REG_VIBDATR: | ||
| 341 | case TWL6040_REG_HPPLLCTL: | ||
| 342 | case TWL6040_REG_LPPLLCTL: | ||
| 343 | case TWL6040_REG_LPPLLDIV: | ||
| 344 | continue; | ||
| 345 | default: | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | |||
| 349 | twl6040_write(codec, reg, cache[reg]); | 310 | twl6040_write(codec, reg, cache[reg]); |
| 350 | } | 311 | } |
| 351 | } | 312 | } |
| @@ -524,18 +485,17 @@ static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec, | |||
| 524 | static void twl6040_pga_hs_work(struct work_struct *work) | 485 | static void twl6040_pga_hs_work(struct work_struct *work) |
| 525 | { | 486 | { |
| 526 | struct twl6040_data *priv = | 487 | struct twl6040_data *priv = |
| 527 | container_of(work, struct twl6040_data, hs_delayed_work.work); | 488 | container_of(work, struct twl6040_data, headset.work.work); |
| 528 | struct snd_soc_codec *codec = priv->codec; | 489 | struct snd_soc_codec *codec = priv->codec; |
| 529 | struct twl6040_output *headset = &priv->headset; | 490 | struct twl6040_output *headset = &priv->headset; |
| 530 | unsigned int delay = headset->step_delay; | ||
| 531 | int i, headset_complete; | 491 | int i, headset_complete; |
| 532 | 492 | ||
| 533 | /* do we need to ramp at all ? */ | 493 | /* do we need to ramp at all ? */ |
| 534 | if (headset->ramp == TWL6040_RAMP_NONE) | 494 | if (headset->ramp == TWL6040_RAMP_NONE) |
| 535 | return; | 495 | return; |
| 536 | 496 | ||
| 537 | /* HS PGA volumes have 4 bits of resolution to ramp */ | 497 | /* HS PGA gain range: 0x0 - 0xf (0 - 15) */ |
| 538 | for (i = 0; i <= 16; i++) { | 498 | for (i = 0; i < 16; i++) { |
| 539 | headset_complete = twl6040_hs_ramp_step(codec, | 499 | headset_complete = twl6040_hs_ramp_step(codec, |
| 540 | headset->left_step, | 500 | headset->left_step, |
| 541 | headset->right_step); | 501 | headset->right_step); |
| @@ -544,15 +504,8 @@ static void twl6040_pga_hs_work(struct work_struct *work) | |||
| 544 | if (headset_complete) | 504 | if (headset_complete) |
| 545 | break; | 505 | break; |
| 546 | 506 | ||
| 547 | /* | 507 | schedule_timeout_interruptible( |
| 548 | * TODO: tune: delay is longer over 0dB | 508 | msecs_to_jiffies(headset->step_delay)); |
| 549 | * as increases are larger. | ||
| 550 | */ | ||
| 551 | if (i >= 8) | ||
| 552 | schedule_timeout_interruptible(msecs_to_jiffies(delay + | ||
| 553 | (delay >> 1))); | ||
| 554 | else | ||
| 555 | schedule_timeout_interruptible(msecs_to_jiffies(delay)); | ||
| 556 | } | 509 | } |
| 557 | 510 | ||
| 558 | if (headset->ramp == TWL6040_RAMP_DOWN) { | 511 | if (headset->ramp == TWL6040_RAMP_DOWN) { |
| @@ -567,18 +520,18 @@ static void twl6040_pga_hs_work(struct work_struct *work) | |||
| 567 | static void twl6040_pga_hf_work(struct work_struct *work) | 520 | static void twl6040_pga_hf_work(struct work_struct *work) |
| 568 | { | 521 | { |
| 569 | struct twl6040_data *priv = | 522 | struct twl6040_data *priv = |
| 570 | container_of(work, struct twl6040_data, hf_delayed_work.work); | 523 | container_of(work, struct twl6040_data, handsfree.work.work); |
| 571 | struct snd_soc_codec *codec = priv->codec; | 524 | struct snd_soc_codec *codec = priv->codec; |
| 572 | struct twl6040_output *handsfree = &priv->handsfree; | 525 | struct twl6040_output *handsfree = &priv->handsfree; |
| 573 | unsigned int delay = handsfree->step_delay; | ||
| 574 | int i, handsfree_complete; | 526 | int i, handsfree_complete; |
| 575 | 527 | ||
| 576 | /* do we need to ramp at all ? */ | 528 | /* do we need to ramp at all ? */ |
| 577 | if (handsfree->ramp == TWL6040_RAMP_NONE) | 529 | if (handsfree->ramp == TWL6040_RAMP_NONE) |
| 578 | return; | 530 | return; |
| 579 | 531 | ||
| 580 | /* HF PGA volumes have 5 bits of resolution to ramp */ | 532 | /* |
| 581 | for (i = 0; i <= 32; i++) { | 533 | * HF PGA gain range: 0x00 - 0x1d (0 - 29) */ |
| 534 | for (i = 0; i < 30; i++) { | ||
| 582 | handsfree_complete = twl6040_hf_ramp_step(codec, | 535 | handsfree_complete = twl6040_hf_ramp_step(codec, |
| 583 | handsfree->left_step, | 536 | handsfree->left_step, |
| 584 | handsfree->right_step); | 537 | handsfree->right_step); |
| @@ -587,15 +540,8 @@ static void twl6040_pga_hf_work(struct work_struct *work) | |||
| 587 | if (handsfree_complete) | 540 | if (handsfree_complete) |
| 588 | break; | 541 | break; |
| 589 | 542 | ||
| 590 | /* | 543 | schedule_timeout_interruptible( |
| 591 | * TODO: tune: delay is longer over 0dB | 544 | msecs_to_jiffies(handsfree->step_delay)); |
| 592 | * as increases are larger. | ||
| 593 | */ | ||
| 594 | if (i >= 16) | ||
| 595 | schedule_timeout_interruptible(msecs_to_jiffies(delay + | ||
| 596 | (delay >> 1))); | ||
| 597 | else | ||
| 598 | schedule_timeout_interruptible(msecs_to_jiffies(delay)); | ||
| 599 | } | 545 | } |
| 600 | 546 | ||
| 601 | 547 | ||
| @@ -607,36 +553,40 @@ static void twl6040_pga_hf_work(struct work_struct *work) | |||
| 607 | handsfree->ramp = TWL6040_RAMP_NONE; | 553 | handsfree->ramp = TWL6040_RAMP_NONE; |
| 608 | } | 554 | } |
| 609 | 555 | ||
| 610 | static int pga_event(struct snd_soc_dapm_widget *w, | 556 | static int out_drv_event(struct snd_soc_dapm_widget *w, |
| 611 | struct snd_kcontrol *kcontrol, int event) | 557 | struct snd_kcontrol *kcontrol, int event) |
| 612 | { | 558 | { |
| 613 | struct snd_soc_codec *codec = w->codec; | 559 | struct snd_soc_codec *codec = w->codec; |
| 614 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 560 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
| 615 | struct twl6040_output *out; | 561 | struct twl6040_output *out; |
| 616 | struct delayed_work *work; | 562 | struct delayed_work *work; |
| 617 | struct workqueue_struct *queue; | ||
| 618 | 563 | ||
| 619 | switch (w->shift) { | 564 | switch (w->shift) { |
| 620 | case 2: | 565 | case 2: /* Headset output driver */ |
| 621 | case 3: | ||
| 622 | out = &priv->headset; | 566 | out = &priv->headset; |
| 623 | work = &priv->hs_delayed_work; | 567 | work = &out->work; |
| 624 | queue = priv->hs_workqueue; | 568 | /* |
| 569 | * Make sure, that we do not mess up variables for already | ||
| 570 | * executing work. | ||
| 571 | */ | ||
| 572 | cancel_delayed_work_sync(work); | ||
| 573 | |||
| 625 | out->left_step = priv->hs_left_step; | 574 | out->left_step = priv->hs_left_step; |
| 626 | out->right_step = priv->hs_right_step; | 575 | out->right_step = priv->hs_right_step; |
| 627 | out->step_delay = 5; /* 5 ms between volume ramp steps */ | 576 | out->step_delay = 5; /* 5 ms between volume ramp steps */ |
| 628 | break; | 577 | break; |
| 629 | case 4: | 578 | case 4: /* Handsfree output driver */ |
| 630 | out = &priv->handsfree; | 579 | out = &priv->handsfree; |
| 631 | work = &priv->hf_delayed_work; | 580 | work = &out->work; |
| 632 | queue = priv->hf_workqueue; | 581 | /* |
| 582 | * Make sure, that we do not mess up variables for already | ||
| 583 | * executing work. | ||
| 584 | */ | ||
| 585 | cancel_delayed_work_sync(work); | ||
| 586 | |||
| 633 | out->left_step = priv->hf_left_step; | 587 | out->left_step = priv->hf_left_step; |
| 634 | out->right_step = priv->hf_right_step; | 588 | out->right_step = priv->hf_right_step; |
| 635 | out->step_delay = 5; /* 5 ms between volume ramp steps */ | 589 | out->step_delay = 5; /* 5 ms between volume ramp steps */ |
| 636 | if (SND_SOC_DAPM_EVENT_ON(event)) | ||
| 637 | priv->non_lp++; | ||
| 638 | else | ||
| 639 | priv->non_lp--; | ||
| 640 | break; | 590 | break; |
| 641 | default: | 591 | default: |
| 642 | return -1; | 592 | return -1; |
| @@ -648,31 +598,25 @@ static int pga_event(struct snd_soc_dapm_widget *w, | |||
| 648 | break; | 598 | break; |
| 649 | 599 | ||
| 650 | /* don't use volume ramp for power-up */ | 600 | /* don't use volume ramp for power-up */ |
| 601 | out->ramp = TWL6040_RAMP_UP; | ||
| 651 | out->left_step = out->left_vol; | 602 | out->left_step = out->left_vol; |
| 652 | out->right_step = out->right_vol; | 603 | out->right_step = out->right_vol; |
| 653 | 604 | ||
| 654 | if (!delayed_work_pending(work)) { | 605 | queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1)); |
| 655 | out->ramp = TWL6040_RAMP_UP; | ||
| 656 | queue_delayed_work(queue, work, | ||
| 657 | msecs_to_jiffies(1)); | ||
| 658 | } | ||
| 659 | break; | 606 | break; |
| 660 | 607 | ||
| 661 | case SND_SOC_DAPM_PRE_PMD: | 608 | case SND_SOC_DAPM_PRE_PMD: |
| 662 | if (!out->active) | 609 | if (!out->active) |
| 663 | break; | 610 | break; |
| 664 | 611 | ||
| 665 | if (!delayed_work_pending(work)) { | 612 | /* use volume ramp for power-down */ |
| 666 | /* use volume ramp for power-down */ | 613 | out->ramp = TWL6040_RAMP_DOWN; |
| 667 | out->ramp = TWL6040_RAMP_DOWN; | 614 | INIT_COMPLETION(out->ramp_done); |
| 668 | INIT_COMPLETION(out->ramp_done); | ||
| 669 | 615 | ||
| 670 | queue_delayed_work(queue, work, | 616 | queue_delayed_work(priv->workqueue, work, msecs_to_jiffies(1)); |
| 671 | msecs_to_jiffies(1)); | ||
| 672 | 617 | ||
| 673 | wait_for_completion_timeout(&out->ramp_done, | 618 | wait_for_completion_timeout(&out->ramp_done, |
| 674 | msecs_to_jiffies(2000)); | 619 | msecs_to_jiffies(2000)); |
| 675 | } | ||
| 676 | break; | 620 | break; |
| 677 | } | 621 | } |
| 678 | 622 | ||
| @@ -683,7 +627,7 @@ static int pga_event(struct snd_soc_dapm_widget *w, | |||
| 683 | static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) | 627 | static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) |
| 684 | { | 628 | { |
| 685 | int hslctl, hsrctl; | 629 | int hslctl, hsrctl; |
| 686 | int mask = TWL6040_HSDRVMODEL | TWL6040_HSDACMODEL; | 630 | int mask = TWL6040_HSDRVMODE | TWL6040_HSDACMODE; |
| 687 | 631 | ||
| 688 | hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); | 632 | hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); |
| 689 | hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); | 633 | hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); |
| @@ -705,11 +649,31 @@ static int headset_power_mode(struct snd_soc_codec *codec, int high_perf) | |||
| 705 | static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, | 649 | static int twl6040_hs_dac_event(struct snd_soc_dapm_widget *w, |
| 706 | struct snd_kcontrol *kcontrol, int event) | 650 | struct snd_kcontrol *kcontrol, int event) |
| 707 | { | 651 | { |
| 652 | struct snd_soc_codec *codec = w->codec; | ||
| 653 | u8 hslctl, hsrctl; | ||
| 654 | |||
| 655 | /* | ||
| 656 | * Workaround for Headset DC offset caused pop noise: | ||
| 657 | * Both HS DAC need to be turned on (before the HS driver) and off at | ||
| 658 | * the same time. | ||
| 659 | */ | ||
| 660 | hslctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSLCTL); | ||
| 661 | hsrctl = twl6040_read_reg_cache(codec, TWL6040_REG_HSRCTL); | ||
| 662 | if (SND_SOC_DAPM_EVENT_ON(event)) { | ||
| 663 | hslctl |= TWL6040_HSDACENA; | ||
| 664 | hsrctl |= TWL6040_HSDACENA; | ||
| 665 | } else { | ||
| 666 | hslctl &= ~TWL6040_HSDACENA; | ||
| 667 | hsrctl &= ~TWL6040_HSDACENA; | ||
| 668 | } | ||
| 669 | twl6040_write(codec, TWL6040_REG_HSLCTL, hslctl); | ||
| 670 | twl6040_write(codec, TWL6040_REG_HSRCTL, hsrctl); | ||
| 671 | |||
| 708 | msleep(1); | 672 | msleep(1); |
| 709 | return 0; | 673 | return 0; |
| 710 | } | 674 | } |
| 711 | 675 | ||
| 712 | static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, | 676 | static int twl6040_ep_drv_event(struct snd_soc_dapm_widget *w, |
| 713 | struct snd_kcontrol *kcontrol, int event) | 677 | struct snd_kcontrol *kcontrol, int event) |
| 714 | { | 678 | { |
| 715 | struct snd_soc_codec *codec = w->codec; | 679 | struct snd_soc_codec *codec = w->codec; |
| @@ -717,18 +681,12 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, | |||
| 717 | int ret = 0; | 681 | int ret = 0; |
| 718 | 682 | ||
| 719 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 683 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
| 720 | priv->non_lp++; | 684 | /* Earphone doesn't support low power mode */ |
| 721 | if (!strcmp(w->name, "Earphone Driver")) { | 685 | priv->hs_power_mode_locked = 1; |
| 722 | /* Earphone doesn't support low power mode */ | 686 | ret = headset_power_mode(codec, 1); |
| 723 | priv->hs_power_mode_locked = 1; | ||
| 724 | ret = headset_power_mode(codec, 1); | ||
| 725 | } | ||
| 726 | } else { | 687 | } else { |
| 727 | priv->non_lp--; | 688 | priv->hs_power_mode_locked = 0; |
| 728 | if (!strcmp(w->name, "Earphone Driver")) { | 689 | ret = headset_power_mode(codec, priv->hs_power_mode); |
| 729 | priv->hs_power_mode_locked = 0; | ||
| 730 | ret = headset_power_mode(codec, priv->hs_power_mode); | ||
| 731 | } | ||
| 732 | } | 690 | } |
| 733 | 691 | ||
| 734 | msleep(1); | 692 | msleep(1); |
| @@ -770,7 +728,7 @@ EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect); | |||
| 770 | static void twl6040_accessory_work(struct work_struct *work) | 728 | static void twl6040_accessory_work(struct work_struct *work) |
| 771 | { | 729 | { |
| 772 | struct twl6040_data *priv = container_of(work, | 730 | struct twl6040_data *priv = container_of(work, |
| 773 | struct twl6040_data, delayed_work.work); | 731 | struct twl6040_data, hs_jack.work.work); |
| 774 | struct snd_soc_codec *codec = priv->codec; | 732 | struct snd_soc_codec *codec = priv->codec; |
| 775 | struct twl6040_jack_data *hs_jack = &priv->hs_jack; | 733 | struct twl6040_jack_data *hs_jack = &priv->hs_jack; |
| 776 | 734 | ||
| @@ -781,15 +739,10 @@ static void twl6040_accessory_work(struct work_struct *work) | |||
| 781 | static irqreturn_t twl6040_audio_handler(int irq, void *data) | 739 | static irqreturn_t twl6040_audio_handler(int irq, void *data) |
| 782 | { | 740 | { |
| 783 | struct snd_soc_codec *codec = data; | 741 | struct snd_soc_codec *codec = data; |
| 784 | struct twl6040 *twl6040 = codec->control_data; | ||
| 785 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); | 742 | struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); |
| 786 | u8 intid; | ||
| 787 | |||
| 788 | intid = twl6040_reg_read(twl6040, TWL6040_REG_INTID); | ||
| 789 | 743 | ||
| 790 | if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT)) | 744 | queue_delayed_work(priv->workqueue, &priv->hs_jack.work, |
| 791 | queue_delayed_work(priv->workqueue, &priv->delayed_work, | 745 | msecs_to_jiffies(200)); |
| 792 | msecs_to_jiffies(200)); | ||
| 793 | 746 | ||
| 794 | return IRQ_HANDLED; | 747 | return IRQ_HANDLED; |
| 795 | } | 748 | } |
| @@ -803,25 +756,27 @@ static int twl6040_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 803 | struct soc_mixer_control *mc = | 756 | struct soc_mixer_control *mc = |
| 804 | (struct soc_mixer_control *)kcontrol->private_value; | 757 | (struct soc_mixer_control *)kcontrol->private_value; |
| 805 | int ret; | 758 | int ret; |
| 806 | unsigned int reg = mc->reg; | ||
| 807 | 759 | ||
| 808 | /* For HS and HF we shadow the values and only actually write | 760 | /* For HS and HF we shadow the values and only actually write |
| 809 | * them out when active in order to ensure the amplifier comes on | 761 | * them out when active in order to ensure the amplifier comes on |
| 810 | * as quietly as possible. */ | 762 | * as quietly as possible. */ |
| 811 | switch (reg) { | 763 | switch (mc->reg) { |
| 812 | case TWL6040_REG_HSGAIN: | 764 | case TWL6040_REG_HSGAIN: |
| 813 | out = &twl6040_priv->headset; | 765 | out = &twl6040_priv->headset; |
| 814 | break; | 766 | break; |
| 815 | default: | 767 | case TWL6040_REG_HFLGAIN: |
| 768 | out = &twl6040_priv->handsfree; | ||
| 816 | break; | 769 | break; |
| 770 | default: | ||
| 771 | dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n", | ||
| 772 | __func__, mc->reg); | ||
| 773 | return -EINVAL; | ||
| 817 | } | 774 | } |
| 818 | 775 | ||
| 819 | if (out) { | 776 | out->left_vol = ucontrol->value.integer.value[0]; |
| 820 | out->left_vol = ucontrol->value.integer.value[0]; | 777 | out->right_vol = ucontrol->value.integer.value[1]; |
| 821 | out->right_vol = ucontrol->value.integer.value[1]; | 778 | if (!out->active) |
| 822 | if (!out->active) | 779 | return 1; |
| 823 | return 1; | ||
| 824 | } | ||
| 825 | 780 | ||
| 826 | ret = snd_soc_put_volsw(kcontrol, ucontrol); | 781 | ret = snd_soc_put_volsw(kcontrol, ucontrol); |
| 827 | if (ret < 0) | 782 | if (ret < 0) |
| @@ -838,112 +793,42 @@ static int twl6040_get_volsw(struct snd_kcontrol *kcontrol, | |||
| 838 | struct twl6040_output *out = &twl6040_priv->headset; | 793 | struct twl6040_output *out = &twl6040_priv->headset; |
| 839 | struct soc_mixer_control *mc = | 794 | struct soc_mixer_control *mc = |
| 840 | (struct soc_mixer_control *)kcontrol->private_value; | 795 | (struct soc_mixer_control *)kcontrol->private_value; |
| 841 | unsigned int reg = mc->reg; | ||
| 842 | 796 | ||
| 843 | switch (reg) { | 797 | switch (mc->reg) { |
| 844 | case TWL6040_REG_HSGAIN: | 798 | case TWL6040_REG_HSGAIN: |
| 845 | out = &twl6040_priv->headset; | 799 | out = &twl6040_priv->headset; |
| 846 | ucontrol->value.integer.value[0] = out->left_vol; | ||
| 847 | ucontrol->value.integer.value[1] = out->right_vol; | ||
| 848 | return 0; | ||
| 849 | |||
| 850 | default: | ||
| 851 | break; | 800 | break; |
| 852 | } | ||
| 853 | |||
| 854 | return snd_soc_get_volsw(kcontrol, ucontrol); | ||
| 855 | } | ||
| 856 | |||
| 857 | static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, | ||
| 858 | struct snd_ctl_elem_value *ucontrol) | ||
| 859 | { | ||
| 860 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 861 | struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); | ||
| 862 | struct twl6040_output *out = NULL; | ||
| 863 | struct soc_mixer_control *mc = | ||
| 864 | (struct soc_mixer_control *)kcontrol->private_value; | ||
| 865 | int ret; | ||
| 866 | unsigned int reg = mc->reg; | ||
| 867 | |||
| 868 | /* For HS and HF we shadow the values and only actually write | ||
| 869 | * them out when active in order to ensure the amplifier comes on | ||
| 870 | * as quietly as possible. */ | ||
| 871 | switch (reg) { | ||
| 872 | case TWL6040_REG_HFLGAIN: | 801 | case TWL6040_REG_HFLGAIN: |
| 873 | case TWL6040_REG_HFRGAIN: | ||
| 874 | out = &twl6040_priv->handsfree; | 802 | out = &twl6040_priv->handsfree; |
| 875 | break; | 803 | break; |
| 876 | default: | 804 | default: |
| 877 | break; | 805 | dev_warn(codec->dev, "%s: Unexpected register: 0x%02x\n", |
| 878 | } | 806 | __func__, mc->reg); |
| 879 | 807 | return -EINVAL; | |
| 880 | if (out) { | ||
| 881 | out->left_vol = ucontrol->value.integer.value[0]; | ||
| 882 | out->right_vol = ucontrol->value.integer.value[1]; | ||
| 883 | if (!out->active) | ||
| 884 | return 1; | ||
| 885 | } | 808 | } |
| 886 | 809 | ||
| 887 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); | 810 | ucontrol->value.integer.value[0] = out->left_vol; |
| 888 | if (ret < 0) | 811 | ucontrol->value.integer.value[1] = out->right_vol; |
| 889 | return ret; | 812 | return 0; |
| 890 | |||
| 891 | return 1; | ||
| 892 | } | 813 | } |
| 893 | 814 | ||
| 894 | static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol, | 815 | static int twl6040_soc_dapm_put_vibra_enum(struct snd_kcontrol *kcontrol, |
| 895 | struct snd_ctl_elem_value *ucontrol) | 816 | struct snd_ctl_elem_value *ucontrol) |
| 896 | { | 817 | { |
| 897 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 818 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
| 898 | struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); | 819 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; |
| 899 | struct twl6040_output *out = &twl6040_priv->handsfree; | 820 | struct snd_soc_codec *codec = widget->codec; |
| 900 | struct soc_mixer_control *mc = | 821 | struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; |
| 901 | (struct soc_mixer_control *)kcontrol->private_value; | 822 | unsigned int val; |
| 902 | unsigned int reg = mc->reg; | 823 | |
| 903 | 824 | /* Do not allow changes while Input/FF efect is running */ | |
| 904 | /* If these are cached registers use the cache */ | 825 | val = twl6040_read_reg_volatile(codec, e->reg); |
| 905 | switch (reg) { | 826 | if (val & TWL6040_VIBENA && !(val & TWL6040_VIBSEL)) |
| 906 | case TWL6040_REG_HFLGAIN: | 827 | return -EBUSY; |
| 907 | case TWL6040_REG_HFRGAIN: | 828 | |
| 908 | out = &twl6040_priv->handsfree; | 829 | return snd_soc_dapm_put_enum_double(kcontrol, ucontrol); |
| 909 | ucontrol->value.integer.value[0] = out->left_vol; | ||
| 910 | ucontrol->value.integer.value[1] = out->right_vol; | ||
| 911 | return 0; | ||
| 912 | |||
| 913 | default: | ||
| 914 | break; | ||
| 915 | } | ||
| 916 | |||
| 917 | return snd_soc_get_volsw_2r(kcontrol, ucontrol); | ||
| 918 | } | 830 | } |
| 919 | 831 | ||
| 920 | /* double control with volume update */ | ||
| 921 | #define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\ | ||
| 922 | xinvert, tlv_array)\ | ||
| 923 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | ||
| 924 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
| 925 | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ | ||
| 926 | .tlv.p = (tlv_array), \ | ||
| 927 | .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \ | ||
| 928 | .put = twl6040_put_volsw, \ | ||
| 929 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
| 930 | {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ | ||
| 931 | .max = xmax, .platform_max = xmax, .invert = xinvert} } | ||
| 932 | |||
| 933 | /* double control with volume update */ | ||
| 934 | #define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\ | ||
| 935 | xinvert, tlv_array)\ | ||
| 936 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ | ||
| 937 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | ||
| 938 | SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | ||
| 939 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
| 940 | .tlv.p = (tlv_array), \ | ||
| 941 | .info = snd_soc_info_volsw_2r, \ | ||
| 942 | .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \ | ||
| 943 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
| 944 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | ||
| 945 | .rshift = xshift, .max = xmax, .invert = xinvert}, } | ||
| 946 | |||
| 947 | /* | 832 | /* |
| 948 | * MICATT volume control: | 833 | * MICATT volume control: |
| 949 | * from -6 to 0 dB in 6 dB steps | 834 | * from -6 to 0 dB in 6 dB steps |
| @@ -1015,6 +900,19 @@ static const struct soc_enum twl6040_hf_enum[] = { | |||
| 1015 | twl6040_hf_texts), | 900 | twl6040_hf_texts), |
| 1016 | }; | 901 | }; |
| 1017 | 902 | ||
| 903 | static const char *twl6040_vibrapath_texts[] = { | ||
| 904 | "Input FF", "Audio PDM" | ||
| 905 | }; | ||
| 906 | |||
| 907 | static const struct soc_enum twl6040_vibra_enum[] = { | ||
| 908 | SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLL, 1, | ||
| 909 | ARRAY_SIZE(twl6040_vibrapath_texts), | ||
| 910 | twl6040_vibrapath_texts), | ||
| 911 | SOC_ENUM_SINGLE(TWL6040_REG_VIBCTLR, 1, | ||
| 912 | ARRAY_SIZE(twl6040_vibrapath_texts), | ||
| 913 | twl6040_vibrapath_texts), | ||
| 914 | }; | ||
| 915 | |||
| 1018 | static const struct snd_kcontrol_new amicl_control = | 916 | static const struct snd_kcontrol_new amicl_control = |
| 1019 | SOC_DAPM_ENUM("Route", twl6040_enum[0]); | 917 | SOC_DAPM_ENUM("Route", twl6040_enum[0]); |
| 1020 | 918 | ||
| @@ -1035,8 +933,25 @@ static const struct snd_kcontrol_new hfl_mux_controls = | |||
| 1035 | static const struct snd_kcontrol_new hfr_mux_controls = | 933 | static const struct snd_kcontrol_new hfr_mux_controls = |
| 1036 | SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]); | 934 | SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]); |
| 1037 | 935 | ||
| 1038 | static const struct snd_kcontrol_new ep_driver_switch_controls = | 936 | static const struct snd_kcontrol_new ep_path_enable_control = |
| 1039 | SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); | 937 | SOC_DAPM_SINGLE("Switch", TWL6040_REG_SW_SHADOW, 0, 1, 0); |
| 938 | |||
| 939 | static const struct snd_kcontrol_new auxl_switch_control = | ||
| 940 | SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 6, 1, 0); | ||
| 941 | |||
| 942 | static const struct snd_kcontrol_new auxr_switch_control = | ||
| 943 | SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 6, 1, 0); | ||
| 944 | |||
| 945 | /* Vibra playback switches */ | ||
| 946 | static const struct snd_kcontrol_new vibral_mux_controls = | ||
| 947 | SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[0], | ||
| 948 | snd_soc_dapm_get_enum_double, | ||
| 949 | twl6040_soc_dapm_put_vibra_enum); | ||
| 950 | |||
| 951 | static const struct snd_kcontrol_new vibrar_mux_controls = | ||
| 952 | SOC_DAPM_ENUM_EXT("Route", twl6040_vibra_enum[1], | ||
| 953 | snd_soc_dapm_get_enum_double, | ||
| 954 | twl6040_soc_dapm_put_vibra_enum); | ||
| 1040 | 955 | ||
| 1041 | /* Headset power mode */ | 956 | /* Headset power mode */ |
| 1042 | static const char *twl6040_power_mode_texts[] = { | 957 | static const char *twl6040_power_mode_texts[] = { |
| @@ -1105,6 +1020,15 @@ int twl6040_get_clk_id(struct snd_soc_codec *codec) | |||
| 1105 | } | 1020 | } |
| 1106 | EXPORT_SYMBOL_GPL(twl6040_get_clk_id); | 1021 | EXPORT_SYMBOL_GPL(twl6040_get_clk_id); |
| 1107 | 1022 | ||
| 1023 | int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim) | ||
| 1024 | { | ||
| 1025 | if (unlikely(trim >= TWL6040_TRIM_INVAL)) | ||
| 1026 | return -EINVAL; | ||
| 1027 | |||
| 1028 | return twl6040_read_reg_cache(codec, TWL6040_REG_TRIM1 + trim); | ||
| 1029 | } | ||
| 1030 | EXPORT_SYMBOL_GPL(twl6040_get_trim_value); | ||
| 1031 | |||
| 1108 | static const struct snd_kcontrol_new twl6040_snd_controls[] = { | 1032 | static const struct snd_kcontrol_new twl6040_snd_controls[] = { |
| 1109 | /* Capture gains */ | 1033 | /* Capture gains */ |
| 1110 | SOC_DOUBLE_TLV("Capture Preamplifier Volume", | 1034 | SOC_DOUBLE_TLV("Capture Preamplifier Volume", |
| @@ -1117,10 +1041,12 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { | |||
| 1117 | TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), | 1041 | TWL6040_REG_LINEGAIN, 0, 3, 7, 0, afm_amp_tlv), |
| 1118 | 1042 | ||
| 1119 | /* Playback gains */ | 1043 | /* Playback gains */ |
| 1120 | SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", | 1044 | SOC_DOUBLE_EXT_TLV("Headset Playback Volume", |
| 1121 | TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), | 1045 | TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, twl6040_get_volsw, |
| 1122 | SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume", | 1046 | twl6040_put_volsw, hs_tlv), |
| 1123 | TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), | 1047 | SOC_DOUBLE_R_EXT_TLV("Handsfree Playback Volume", |
| 1048 | TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, | ||
| 1049 | twl6040_get_volsw, twl6040_put_volsw, hf_tlv), | ||
| 1124 | SOC_SINGLE_TLV("Earphone Playback Volume", | 1050 | SOC_SINGLE_TLV("Earphone Playback Volume", |
| 1125 | TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), | 1051 | TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), |
| 1126 | 1052 | ||
| @@ -1146,6 +1072,10 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
| 1146 | SND_SOC_DAPM_OUTPUT("HFL"), | 1072 | SND_SOC_DAPM_OUTPUT("HFL"), |
| 1147 | SND_SOC_DAPM_OUTPUT("HFR"), | 1073 | SND_SOC_DAPM_OUTPUT("HFR"), |
| 1148 | SND_SOC_DAPM_OUTPUT("EP"), | 1074 | SND_SOC_DAPM_OUTPUT("EP"), |
| 1075 | SND_SOC_DAPM_OUTPUT("AUXL"), | ||
| 1076 | SND_SOC_DAPM_OUTPUT("AUXR"), | ||
| 1077 | SND_SOC_DAPM_OUTPUT("VIBRAL"), | ||
| 1078 | SND_SOC_DAPM_OUTPUT("VIBRAR"), | ||
| 1149 | 1079 | ||
| 1150 | /* Analog input muxes for the capture amplifiers */ | 1080 | /* Analog input muxes for the capture amplifiers */ |
| 1151 | SND_SOC_DAPM_MUX("Analog Left Capture Route", | 1081 | SND_SOC_DAPM_MUX("Analog Left Capture Route", |
| @@ -1182,59 +1112,76 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { | |||
| 1182 | TWL6040_REG_DMICBCTL, 4, 0), | 1112 | TWL6040_REG_DMICBCTL, 4, 0), |
| 1183 | 1113 | ||
| 1184 | /* DACs */ | 1114 | /* DACs */ |
| 1185 | SND_SOC_DAPM_DAC_E("HSDAC Left", "Headset Playback", | 1115 | SND_SOC_DAPM_DAC("HSDAC Left", "Headset Playback", SND_SOC_NOPM, 0, 0), |
| 1186 | TWL6040_REG_HSLCTL, 0, 0, | 1116 | SND_SOC_DAPM_DAC("HSDAC Right", "Headset Playback", SND_SOC_NOPM, 0, 0), |
| 1187 | twl6040_hs_dac_event, | 1117 | SND_SOC_DAPM_DAC("HFDAC Left", "Handsfree Playback", |
| 1188 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 1118 | TWL6040_REG_HFLCTL, 0, 0), |
| 1189 | SND_SOC_DAPM_DAC_E("HSDAC Right", "Headset Playback", | 1119 | SND_SOC_DAPM_DAC("HFDAC Right", "Handsfree Playback", |
| 1190 | TWL6040_REG_HSRCTL, 0, 0, | 1120 | TWL6040_REG_HFRCTL, 0, 0), |
| 1191 | twl6040_hs_dac_event, | 1121 | /* Virtual DAC for vibra path (DL4 channel) */ |
| 1192 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 1122 | SND_SOC_DAPM_DAC("VIBRA DAC", "Vibra Playback", |
| 1193 | SND_SOC_DAPM_DAC_E("HFDAC Left", "Handsfree Playback", | 1123 | SND_SOC_NOPM, 0, 0), |
| 1194 | TWL6040_REG_HFLCTL, 0, 0, | 1124 | |
| 1195 | twl6040_power_mode_event, | 1125 | SND_SOC_DAPM_MUX("Handsfree Left Playback", |
| 1196 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 1197 | SND_SOC_DAPM_DAC_E("HFDAC Right", "Handsfree Playback", | ||
| 1198 | TWL6040_REG_HFRCTL, 0, 0, | ||
| 1199 | twl6040_power_mode_event, | ||
| 1200 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 1201 | |||
| 1202 | SND_SOC_DAPM_MUX("HF Left Playback", | ||
| 1203 | SND_SOC_NOPM, 0, 0, &hfl_mux_controls), | 1126 | SND_SOC_NOPM, 0, 0, &hfl_mux_controls), |
| 1204 | SND_SOC_DAPM_MUX("HF Right Playback", | 1127 | SND_SOC_DAPM_MUX("Handsfree Right Playback", |
| 1205 | SND_SOC_NOPM, 0, 0, &hfr_mux_controls), | 1128 | SND_SOC_NOPM, 0, 0, &hfr_mux_controls), |
| 1206 | /* Analog playback Muxes */ | 1129 | /* Analog playback Muxes */ |
| 1207 | SND_SOC_DAPM_MUX("HS Left Playback", | 1130 | SND_SOC_DAPM_MUX("Headset Left Playback", |
| 1208 | SND_SOC_NOPM, 0, 0, &hsl_mux_controls), | 1131 | SND_SOC_NOPM, 0, 0, &hsl_mux_controls), |
| 1209 | SND_SOC_DAPM_MUX("HS Right Playback", | 1132 | SND_SOC_DAPM_MUX("Headset Right Playback", |
| 1210 | SND_SOC_NOPM, 0, 0, &hsr_mux_controls), | 1133 | SND_SOC_NOPM, 0, 0, &hsr_mux_controls), |
| 1211 | 1134 | ||
| 1135 | SND_SOC_DAPM_MUX("Vibra Left Playback", SND_SOC_NOPM, 0, 0, | ||
| 1136 | &vibral_mux_controls), | ||
| 1137 | SND_SOC_DAPM_MUX("Vibra Right Playback", SND_SOC_NOPM, 0, 0, | ||
| 1138 | &vibrar_mux_controls), | ||
| 1139 | |||
| 1140 | SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0, | ||
| 1141 | &ep_path_enable_control), | ||
| 1142 | SND_SOC_DAPM_SWITCH("AUXL Playback", SND_SOC_NOPM, 0, 0, | ||
| 1143 | &auxl_switch_control), | ||
| 1144 | SND_SOC_DAPM_SWITCH("AUXR Playback", SND_SOC_NOPM, 0, 0, | ||
| 1145 | &auxr_switch_control), | ||
| 1146 | |||
| 1212 | /* Analog playback drivers */ | 1147 | /* Analog playback drivers */ |
| 1213 | SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", | 1148 | SND_SOC_DAPM_OUT_DRV_E("HF Left Driver", |
| 1214 | TWL6040_REG_HFLCTL, 4, 0, NULL, 0, | 1149 | TWL6040_REG_HFLCTL, 4, 0, NULL, 0, |
| 1215 | pga_event, | 1150 | out_drv_event, |
| 1216 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1151 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 1217 | SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver", | 1152 | SND_SOC_DAPM_OUT_DRV_E("HF Right Driver", |
| 1218 | TWL6040_REG_HFRCTL, 4, 0, NULL, 0, | 1153 | TWL6040_REG_HFRCTL, 4, 0, NULL, 0, |
| 1219 | pga_event, | 1154 | out_drv_event, |
| 1220 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1155 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 1221 | SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver", | 1156 | SND_SOC_DAPM_OUT_DRV_E("HS Left Driver", |
| 1222 | TWL6040_REG_HSLCTL, 2, 0, NULL, 0, | 1157 | TWL6040_REG_HSLCTL, 2, 0, NULL, 0, |
| 1223 | pga_event, | 1158 | out_drv_event, |
| 1224 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1159 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 1225 | SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver", | 1160 | SND_SOC_DAPM_OUT_DRV_E("HS Right Driver", |
| 1226 | TWL6040_REG_HSRCTL, 2, 0, NULL, 0, | 1161 | TWL6040_REG_HSRCTL, 2, 0, NULL, 0, |
| 1227 | pga_event, | 1162 | out_drv_event, |
| 1228 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1163 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| 1229 | SND_SOC_DAPM_SWITCH_E("Earphone Driver", | 1164 | SND_SOC_DAPM_OUT_DRV_E("Earphone Driver", |
| 1230 | SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, | 1165 | TWL6040_REG_EARCTL, 0, 0, NULL, 0, |
| 1231 | twl6040_power_mode_event, | 1166 | twl6040_ep_drv_event, |
| 1232 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | 1167 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
| 1168 | SND_SOC_DAPM_OUT_DRV("Vibra Left Driver", | ||
| 1169 | TWL6040_REG_VIBCTLL, 0, 0, NULL, 0), | ||
| 1170 | SND_SOC_DAPM_OUT_DRV("Vibra Right Driver", | ||
| 1171 | TWL6040_REG_VIBCTLR, 0, 0, NULL, 0), | ||
| 1172 | |||
| 1173 | SND_SOC_DAPM_SUPPLY("Vibra Left Control", TWL6040_REG_VIBCTLL, 2, 0, | ||
| 1174 | NULL, 0), | ||
| 1175 | SND_SOC_DAPM_SUPPLY("Vibra Right Control", TWL6040_REG_VIBCTLR, 2, 0, | ||
| 1176 | NULL, 0), | ||
| 1177 | SND_SOC_DAPM_SUPPLY_S("HSDAC Power", 1, SND_SOC_NOPM, 0, 0, | ||
| 1178 | twl6040_hs_dac_event, | ||
| 1179 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 1233 | 1180 | ||
| 1234 | /* Analog playback PGAs */ | 1181 | /* Analog playback PGAs */ |
| 1235 | SND_SOC_DAPM_PGA("HFDAC Left PGA", | 1182 | SND_SOC_DAPM_PGA("HF Left PGA", |
| 1236 | TWL6040_REG_HFLCTL, 1, 0, NULL, 0), | 1183 | TWL6040_REG_HFLCTL, 1, 0, NULL, 0), |
| 1237 | SND_SOC_DAPM_PGA("HFDAC Right PGA", | 1184 | SND_SOC_DAPM_PGA("HF Right PGA", |
| 1238 | TWL6040_REG_HFRCTL, 1, 0, NULL, 0), | 1185 | TWL6040_REG_HFRCTL, 1, 0, NULL, 0), |
| 1239 | 1186 | ||
| 1240 | }; | 1187 | }; |
| @@ -1256,52 +1203,62 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
| 1256 | {"ADC Right", NULL, "MicAmpR"}, | 1203 | {"ADC Right", NULL, "MicAmpR"}, |
| 1257 | 1204 | ||
| 1258 | /* AFM path */ | 1205 | /* AFM path */ |
| 1259 | {"AFMAmpL", "NULL", "AFML"}, | 1206 | {"AFMAmpL", NULL, "AFML"}, |
| 1260 | {"AFMAmpR", "NULL", "AFMR"}, | 1207 | {"AFMAmpR", NULL, "AFMR"}, |
| 1208 | |||
| 1209 | {"HSDAC Left", NULL, "HSDAC Power"}, | ||
| 1210 | {"HSDAC Right", NULL, "HSDAC Power"}, | ||
| 1261 | 1211 | ||
| 1262 | {"HS Left Playback", "HS DAC", "HSDAC Left"}, | 1212 | {"Headset Left Playback", "HS DAC", "HSDAC Left"}, |
| 1263 | {"HS Left Playback", "Line-In amp", "AFMAmpL"}, | 1213 | {"Headset Left Playback", "Line-In amp", "AFMAmpL"}, |
| 1264 | 1214 | ||
| 1265 | {"HS Right Playback", "HS DAC", "HSDAC Right"}, | 1215 | {"Headset Right Playback", "HS DAC", "HSDAC Right"}, |
| 1266 | {"HS Right Playback", "Line-In amp", "AFMAmpR"}, | 1216 | {"Headset Right Playback", "Line-In amp", "AFMAmpR"}, |
| 1267 | 1217 | ||
| 1268 | {"Headset Left Driver", "NULL", "HS Left Playback"}, | 1218 | {"HS Left Driver", NULL, "Headset Left Playback"}, |
| 1269 | {"Headset Right Driver", "NULL", "HS Right Playback"}, | 1219 | {"HS Right Driver", NULL, "Headset Right Playback"}, |
| 1270 | 1220 | ||
| 1271 | {"HSOL", NULL, "Headset Left Driver"}, | 1221 | {"HSOL", NULL, "HS Left Driver"}, |
| 1272 | {"HSOR", NULL, "Headset Right Driver"}, | 1222 | {"HSOR", NULL, "HS Right Driver"}, |
| 1273 | 1223 | ||
| 1274 | /* Earphone playback path */ | 1224 | /* Earphone playback path */ |
| 1275 | {"Earphone Driver", "Switch", "HSDAC Left"}, | 1225 | {"Earphone Playback", "Switch", "HSDAC Left"}, |
| 1226 | {"Earphone Driver", NULL, "Earphone Playback"}, | ||
| 1276 | {"EP", NULL, "Earphone Driver"}, | 1227 | {"EP", NULL, "Earphone Driver"}, |
| 1277 | 1228 | ||
| 1278 | {"HF Left Playback", "HF DAC", "HFDAC Left"}, | 1229 | {"Handsfree Left Playback", "HF DAC", "HFDAC Left"}, |
| 1279 | {"HF Left Playback", "Line-In amp", "AFMAmpL"}, | 1230 | {"Handsfree Left Playback", "Line-In amp", "AFMAmpL"}, |
| 1280 | 1231 | ||
| 1281 | {"HF Right Playback", "HF DAC", "HFDAC Right"}, | 1232 | {"Handsfree Right Playback", "HF DAC", "HFDAC Right"}, |
| 1282 | {"HF Right Playback", "Line-In amp", "AFMAmpR"}, | 1233 | {"Handsfree Right Playback", "Line-In amp", "AFMAmpR"}, |
| 1283 | 1234 | ||
| 1284 | {"HFDAC Left PGA", NULL, "HF Left Playback"}, | 1235 | {"HF Left PGA", NULL, "Handsfree Left Playback"}, |
| 1285 | {"HFDAC Right PGA", NULL, "HF Right Playback"}, | 1236 | {"HF Right PGA", NULL, "Handsfree Right Playback"}, |
| 1286 | 1237 | ||
| 1287 | {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, | 1238 | {"HF Left Driver", NULL, "HF Left PGA"}, |
| 1288 | {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, | 1239 | {"HF Right Driver", NULL, "HF Right PGA"}, |
| 1289 | 1240 | ||
| 1290 | {"HFL", NULL, "Handsfree Left Driver"}, | 1241 | {"HFL", NULL, "HF Left Driver"}, |
| 1291 | {"HFR", NULL, "Handsfree Right Driver"}, | 1242 | {"HFR", NULL, "HF Right Driver"}, |
| 1292 | }; | ||
| 1293 | 1243 | ||
| 1294 | static int twl6040_add_widgets(struct snd_soc_codec *codec) | 1244 | {"AUXL Playback", "Switch", "HF Left PGA"}, |
| 1295 | { | 1245 | {"AUXR Playback", "Switch", "HF Right PGA"}, |
| 1296 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 1297 | 1246 | ||
| 1298 | snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets, | 1247 | {"AUXL", NULL, "AUXL Playback"}, |
| 1299 | ARRAY_SIZE(twl6040_dapm_widgets)); | 1248 | {"AUXR", NULL, "AUXR Playback"}, |
| 1300 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | ||
| 1301 | snd_soc_dapm_new_widgets(dapm); | ||
| 1302 | 1249 | ||
| 1303 | return 0; | 1250 | /* Vibrator paths */ |
| 1304 | } | 1251 | {"Vibra Left Playback", "Audio PDM", "VIBRA DAC"}, |
| 1252 | {"Vibra Right Playback", "Audio PDM", "VIBRA DAC"}, | ||
| 1253 | |||
| 1254 | {"Vibra Left Driver", NULL, "Vibra Left Playback"}, | ||
| 1255 | {"Vibra Right Driver", NULL, "Vibra Right Playback"}, | ||
| 1256 | {"Vibra Left Driver", NULL, "Vibra Left Control"}, | ||
| 1257 | {"Vibra Right Driver", NULL, "Vibra Right Control"}, | ||
| 1258 | |||
| 1259 | {"VIBRAL", NULL, "Vibra Left Driver"}, | ||
| 1260 | {"VIBRAR", NULL, "Vibra Right Driver"}, | ||
| 1261 | }; | ||
| 1305 | 1262 | ||
| 1306 | static int twl6040_set_bias_level(struct snd_soc_codec *codec, | 1263 | static int twl6040_set_bias_level(struct snd_soc_codec *codec, |
| 1307 | enum snd_soc_bias_level level) | 1264 | enum snd_soc_bias_level level) |
| @@ -1325,8 +1282,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, | |||
| 1325 | 1282 | ||
| 1326 | priv->codec_powered = 1; | 1283 | priv->codec_powered = 1; |
| 1327 | 1284 | ||
| 1328 | /* initialize vdd/vss registers with reg_cache */ | 1285 | twl6040_restore_regs(codec); |
| 1329 | twl6040_init_vdd_regs(codec); | ||
| 1330 | 1286 | ||
| 1331 | /* Set external boost GPO */ | 1287 | /* Set external boost GPO */ |
| 1332 | twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); | 1288 | twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); |
| @@ -1380,13 +1336,6 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream, | |||
| 1380 | rate); | 1336 | rate); |
| 1381 | return -EINVAL; | 1337 | return -EINVAL; |
| 1382 | } | 1338 | } |
| 1383 | /* Capture is not supported with 17.64MHz sysclk */ | ||
| 1384 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | ||
| 1385 | dev_err(codec->dev, | ||
| 1386 | "capture mode is not supported at %dHz\n", | ||
| 1387 | rate); | ||
| 1388 | return -EINVAL; | ||
| 1389 | } | ||
| 1390 | priv->sysclk = 17640000; | 1339 | priv->sysclk = 17640000; |
| 1391 | break; | 1340 | break; |
| 1392 | case 8000: | 1341 | case 8000: |
| @@ -1419,13 +1368,6 @@ static int twl6040_prepare(struct snd_pcm_substream *substream, | |||
| 1419 | return -EINVAL; | 1368 | return -EINVAL; |
| 1420 | } | 1369 | } |
| 1421 | 1370 | ||
| 1422 | if ((priv->sysclk == 17640000) && priv->non_lp) { | ||
| 1423 | dev_err(codec->dev, | ||
| 1424 | "some enabled paths aren't supported at %dHz\n", | ||
| 1425 | priv->sysclk); | ||
| 1426 | return -EPERM; | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); | 1371 | ret = twl6040_set_pll(twl6040, priv->pll, priv->clk_in, priv->sysclk); |
| 1430 | if (ret) { | 1372 | if (ret) { |
| 1431 | dev_err(codec->dev, "Can not set PLL (%d)\n", ret); | 1373 | dev_err(codec->dev, "Can not set PLL (%d)\n", ret); |
| @@ -1464,11 +1406,11 @@ static struct snd_soc_dai_ops twl6040_dai_ops = { | |||
| 1464 | 1406 | ||
| 1465 | static struct snd_soc_dai_driver twl6040_dai[] = { | 1407 | static struct snd_soc_dai_driver twl6040_dai[] = { |
| 1466 | { | 1408 | { |
| 1467 | .name = "twl6040-hifi", | 1409 | .name = "twl6040-legacy", |
| 1468 | .playback = { | 1410 | .playback = { |
| 1469 | .stream_name = "Playback", | 1411 | .stream_name = "Playback", |
| 1470 | .channels_min = 1, | 1412 | .channels_min = 1, |
| 1471 | .channels_max = 2, | 1413 | .channels_max = 5, |
| 1472 | .rates = TWL6040_RATES, | 1414 | .rates = TWL6040_RATES, |
| 1473 | .formats = TWL6040_FORMATS, | 1415 | .formats = TWL6040_FORMATS, |
| 1474 | }, | 1416 | }, |
| @@ -1518,8 +1460,8 @@ static struct snd_soc_dai_driver twl6040_dai[] = { | |||
| 1518 | .name = "twl6040-vib", | 1460 | .name = "twl6040-vib", |
| 1519 | .playback = { | 1461 | .playback = { |
| 1520 | .stream_name = "Vibra Playback", | 1462 | .stream_name = "Vibra Playback", |
| 1521 | .channels_min = 2, | 1463 | .channels_min = 1, |
| 1522 | .channels_max = 2, | 1464 | .channels_max = 1, |
| 1523 | .rates = SNDRV_PCM_RATE_CONTINUOUS, | 1465 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
| 1524 | .formats = TWL6040_FORMATS, | 1466 | .formats = TWL6040_FORMATS, |
| 1525 | }, | 1467 | }, |
| @@ -1562,6 +1504,7 @@ static int twl6040_probe(struct snd_soc_codec *codec) | |||
| 1562 | 1504 | ||
| 1563 | priv->codec = codec; | 1505 | priv->codec = codec; |
| 1564 | codec->control_data = dev_get_drvdata(codec->dev->parent); | 1506 | codec->control_data = dev_get_drvdata(codec->dev->parent); |
| 1507 | codec->ignore_pmdown_time = 1; | ||
| 1565 | 1508 | ||
| 1566 | if (pdata && pdata->hs_left_step && pdata->hs_right_step) { | 1509 | if (pdata && pdata->hs_left_step && pdata->hs_right_step) { |
| 1567 | priv->hs_left_step = pdata->hs_left_step; | 1510 | priv->hs_left_step = pdata->hs_left_step; |
| @@ -1586,33 +1529,21 @@ static int twl6040_probe(struct snd_soc_codec *codec) | |||
| 1586 | goto work_err; | 1529 | goto work_err; |
| 1587 | } | 1530 | } |
| 1588 | 1531 | ||
| 1589 | priv->workqueue = create_singlethread_workqueue("twl6040-codec"); | 1532 | priv->workqueue = alloc_workqueue("twl6040-codec", 0, 0); |
| 1590 | if (!priv->workqueue) { | 1533 | if (!priv->workqueue) { |
| 1591 | ret = -ENOMEM; | 1534 | ret = -ENOMEM; |
| 1592 | goto work_err; | 1535 | goto work_err; |
| 1593 | } | 1536 | } |
| 1594 | 1537 | ||
| 1595 | INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work); | 1538 | INIT_DELAYED_WORK(&priv->hs_jack.work, twl6040_accessory_work); |
| 1539 | INIT_DELAYED_WORK(&priv->headset.work, twl6040_pga_hs_work); | ||
| 1540 | INIT_DELAYED_WORK(&priv->handsfree.work, twl6040_pga_hf_work); | ||
| 1596 | 1541 | ||
| 1597 | mutex_init(&priv->mutex); | 1542 | mutex_init(&priv->mutex); |
| 1598 | 1543 | ||
| 1599 | init_completion(&priv->headset.ramp_done); | 1544 | init_completion(&priv->headset.ramp_done); |
| 1600 | init_completion(&priv->handsfree.ramp_done); | 1545 | init_completion(&priv->handsfree.ramp_done); |
| 1601 | 1546 | ||
| 1602 | priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf"); | ||
| 1603 | if (priv->hf_workqueue == NULL) { | ||
| 1604 | ret = -ENOMEM; | ||
| 1605 | goto hfwq_err; | ||
| 1606 | } | ||
| 1607 | priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs"); | ||
| 1608 | if (priv->hs_workqueue == NULL) { | ||
| 1609 | ret = -ENOMEM; | ||
| 1610 | goto hswq_err; | ||
| 1611 | } | ||
| 1612 | |||
| 1613 | INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work); | ||
| 1614 | INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work); | ||
| 1615 | |||
| 1616 | ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler, | 1547 | ret = request_threaded_irq(priv->plug_irq, NULL, twl6040_audio_handler, |
| 1617 | 0, "twl6040_irq_plug", codec); | 1548 | 0, "twl6040_irq_plug", codec); |
| 1618 | if (ret) { | 1549 | if (ret) { |
| @@ -1620,27 +1551,16 @@ static int twl6040_probe(struct snd_soc_codec *codec) | |||
| 1620 | goto plugirq_err; | 1551 | goto plugirq_err; |
| 1621 | } | 1552 | } |
| 1622 | 1553 | ||
| 1623 | /* init vio registers */ | 1554 | twl6040_init_chip(codec); |
| 1624 | twl6040_init_vio_regs(codec); | ||
| 1625 | 1555 | ||
| 1626 | /* power on device */ | 1556 | /* power on device */ |
| 1627 | ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1557 | ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 1628 | if (ret) | 1558 | if (!ret) |
| 1629 | goto bias_err; | 1559 | return 0; |
| 1630 | |||
| 1631 | snd_soc_add_controls(codec, twl6040_snd_controls, | ||
| 1632 | ARRAY_SIZE(twl6040_snd_controls)); | ||
| 1633 | twl6040_add_widgets(codec); | ||
| 1634 | |||
| 1635 | return 0; | ||
| 1636 | 1560 | ||
| 1637 | bias_err: | 1561 | /* Error path */ |
| 1638 | free_irq(priv->plug_irq, codec); | 1562 | free_irq(priv->plug_irq, codec); |
| 1639 | plugirq_err: | 1563 | plugirq_err: |
| 1640 | destroy_workqueue(priv->hs_workqueue); | ||
| 1641 | hswq_err: | ||
| 1642 | destroy_workqueue(priv->hf_workqueue); | ||
| 1643 | hfwq_err: | ||
| 1644 | destroy_workqueue(priv->workqueue); | 1564 | destroy_workqueue(priv->workqueue); |
| 1645 | work_err: | 1565 | work_err: |
| 1646 | kfree(priv); | 1566 | kfree(priv); |
| @@ -1654,8 +1574,6 @@ static int twl6040_remove(struct snd_soc_codec *codec) | |||
| 1654 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1574 | twl6040_set_bias_level(codec, SND_SOC_BIAS_OFF); |
| 1655 | free_irq(priv->plug_irq, codec); | 1575 | free_irq(priv->plug_irq, codec); |
| 1656 | destroy_workqueue(priv->workqueue); | 1576 | destroy_workqueue(priv->workqueue); |
| 1657 | destroy_workqueue(priv->hf_workqueue); | ||
| 1658 | destroy_workqueue(priv->hs_workqueue); | ||
| 1659 | kfree(priv); | 1577 | kfree(priv); |
| 1660 | 1578 | ||
| 1661 | return 0; | 1579 | return 0; |
| @@ -1672,6 +1590,13 @@ static struct snd_soc_codec_driver soc_codec_dev_twl6040 = { | |||
| 1672 | .reg_cache_size = ARRAY_SIZE(twl6040_reg), | 1590 | .reg_cache_size = ARRAY_SIZE(twl6040_reg), |
| 1673 | .reg_word_size = sizeof(u8), | 1591 | .reg_word_size = sizeof(u8), |
| 1674 | .reg_cache_default = twl6040_reg, | 1592 | .reg_cache_default = twl6040_reg, |
| 1593 | |||
| 1594 | .controls = twl6040_snd_controls, | ||
| 1595 | .num_controls = ARRAY_SIZE(twl6040_snd_controls), | ||
| 1596 | .dapm_widgets = twl6040_dapm_widgets, | ||
| 1597 | .num_dapm_widgets = ARRAY_SIZE(twl6040_dapm_widgets), | ||
| 1598 | .dapm_routes = intercon, | ||
| 1599 | .num_dapm_routes = ARRAY_SIZE(intercon), | ||
| 1675 | }; | 1600 | }; |
| 1676 | 1601 | ||
| 1677 | static int __devinit twl6040_codec_probe(struct platform_device *pdev) | 1602 | static int __devinit twl6040_codec_probe(struct platform_device *pdev) |
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index d8de67869dd9..a83277bdb851 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h | |||
| @@ -22,8 +22,21 @@ | |||
| 22 | #ifndef __TWL6040_H__ | 22 | #ifndef __TWL6040_H__ |
| 23 | #define __TWL6040_H__ | 23 | #define __TWL6040_H__ |
| 24 | 24 | ||
| 25 | enum twl6040_trim { | ||
| 26 | TWL6040_TRIM_TRIM1 = 0, | ||
| 27 | TWL6040_TRIM_TRIM2, | ||
| 28 | TWL6040_TRIM_TRIM3, | ||
| 29 | TWL6040_TRIM_HSOTRIM, | ||
| 30 | TWL6040_TRIM_HFOTRIM, | ||
| 31 | TWL6040_TRIM_INVAL, | ||
| 32 | }; | ||
| 33 | |||
| 34 | #define TWL6040_HSF_TRIM_LEFT(x) (x & 0x0f) | ||
| 35 | #define TWL6040_HSF_TRIM_RIGHT(x) ((x >> 4) & 0x0f) | ||
| 36 | |||
| 25 | void twl6040_hs_jack_detect(struct snd_soc_codec *codec, | 37 | void twl6040_hs_jack_detect(struct snd_soc_codec *codec, |
| 26 | struct snd_soc_jack *jack, int report); | 38 | struct snd_soc_jack *jack, int report); |
| 27 | int twl6040_get_clk_id(struct snd_soc_codec *codec); | 39 | int twl6040_get_clk_id(struct snd_soc_codec *codec); |
| 40 | int twl6040_get_trim_value(struct snd_soc_codec *codec, enum twl6040_trim trim); | ||
| 28 | 41 | ||
| 29 | #endif /* End of __TWL6040_H__ */ | 42 | #endif /* End of __TWL6040_H__ */ |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 5836201834d9..9fa14299cf2c 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
| @@ -462,7 +462,6 @@ static int wl1273_probe(struct snd_soc_codec *codec) | |||
| 462 | wl1273->core = *core; | 462 | wl1273->core = *core; |
| 463 | 463 | ||
| 464 | snd_soc_codec_set_drvdata(codec, wl1273); | 464 | snd_soc_codec_set_drvdata(codec, wl1273); |
| 465 | mutex_init(&codec->mutex); | ||
| 466 | 465 | ||
| 467 | r = snd_soc_add_controls(codec, wl1273_controls, | 466 | r = snd_soc_add_controls(codec, wl1273_controls, |
| 468 | ARRAY_SIZE(wl1273_controls)); | 467 | ARRAY_SIZE(wl1273_controls)); |
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c index bcc208967917..cd0ec0fd1dba 100644 --- a/sound/soc/codecs/wm1250-ev1.c +++ b/sound/soc/codecs/wm1250-ev1.c | |||
| @@ -12,10 +12,59 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/slab.h> | ||
| 15 | #include <linux/i2c.h> | 16 | #include <linux/i2c.h> |
| 17 | #include <linux/gpio.h> | ||
| 16 | 18 | ||
| 17 | #include <sound/soc.h> | 19 | #include <sound/soc.h> |
| 18 | #include <sound/soc-dapm.h> | 20 | #include <sound/soc-dapm.h> |
| 21 | #include <sound/wm1250-ev1.h> | ||
| 22 | |||
| 23 | static const char *wm1250_gpio_names[WM1250_EV1_NUM_GPIOS] = { | ||
| 24 | "WM1250 CLK_ENA", | ||
| 25 | "WM1250 CLK_SEL0", | ||
| 26 | "WM1250 CLK_SEL1", | ||
| 27 | "WM1250 OSR", | ||
| 28 | "WM1250 MASTER", | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct wm1250_priv { | ||
| 32 | struct gpio gpios[WM1250_EV1_NUM_GPIOS]; | ||
| 33 | }; | ||
| 34 | |||
| 35 | static int wm1250_ev1_set_bias_level(struct snd_soc_codec *codec, | ||
| 36 | enum snd_soc_bias_level level) | ||
| 37 | { | ||
| 38 | struct wm1250_priv *wm1250 = dev_get_drvdata(codec->dev); | ||
| 39 | int ena; | ||
| 40 | |||
| 41 | if (wm1250) | ||
| 42 | ena = wm1250->gpios[WM1250_EV1_GPIO_CLK_ENA].gpio; | ||
| 43 | else | ||
| 44 | ena = -1; | ||
| 45 | |||
| 46 | switch (level) { | ||
| 47 | case SND_SOC_BIAS_ON: | ||
| 48 | break; | ||
| 49 | |||
| 50 | case SND_SOC_BIAS_PREPARE: | ||
| 51 | break; | ||
| 52 | |||
| 53 | case SND_SOC_BIAS_STANDBY: | ||
| 54 | if (ena >= 0) | ||
| 55 | gpio_set_value_cansleep(ena, 1); | ||
| 56 | break; | ||
| 57 | |||
| 58 | case SND_SOC_BIAS_OFF: | ||
| 59 | if (ena >= 0) | ||
| 60 | gpio_set_value_cansleep(ena, 0); | ||
| 61 | break; | ||
| 62 | } | ||
| 63 | |||
| 64 | codec->dapm.bias_level = level; | ||
| 65 | |||
| 66 | return 0; | ||
| 67 | } | ||
| 19 | 68 | ||
| 20 | static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = { | 69 | static const struct snd_soc_dapm_widget wm1250_ev1_dapm_widgets[] = { |
| 21 | SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), | 70 | SND_SOC_DAPM_ADC("ADC", "wm1250-ev1 Capture", SND_SOC_NOPM, 0, 0), |
| @@ -53,18 +102,103 @@ static struct snd_soc_codec_driver soc_codec_dev_wm1250_ev1 = { | |||
| 53 | .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), | 102 | .num_dapm_widgets = ARRAY_SIZE(wm1250_ev1_dapm_widgets), |
| 54 | .dapm_routes = wm1250_ev1_dapm_routes, | 103 | .dapm_routes = wm1250_ev1_dapm_routes, |
| 55 | .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), | 104 | .num_dapm_routes = ARRAY_SIZE(wm1250_ev1_dapm_routes), |
| 105 | |||
| 106 | .set_bias_level = wm1250_ev1_set_bias_level, | ||
| 107 | .idle_bias_off = true, | ||
| 56 | }; | 108 | }; |
| 57 | 109 | ||
| 110 | static int __devinit wm1250_ev1_pdata(struct i2c_client *i2c) | ||
| 111 | { | ||
| 112 | struct wm1250_ev1_pdata *pdata = dev_get_platdata(&i2c->dev); | ||
| 113 | struct wm1250_priv *wm1250; | ||
| 114 | int i, ret; | ||
| 115 | |||
| 116 | if (!pdata) | ||
| 117 | return 0; | ||
| 118 | |||
| 119 | wm1250 = kzalloc(sizeof(*wm1250), GFP_KERNEL); | ||
| 120 | if (!wm1250) { | ||
| 121 | dev_err(&i2c->dev, "Unable to allocate private data\n"); | ||
| 122 | ret = -ENOMEM; | ||
| 123 | goto err; | ||
| 124 | } | ||
| 125 | |||
| 126 | for (i = 0; i < ARRAY_SIZE(wm1250->gpios); i++) { | ||
| 127 | wm1250->gpios[i].gpio = pdata->gpios[i]; | ||
| 128 | wm1250->gpios[i].label = wm1250_gpio_names[i]; | ||
| 129 | wm1250->gpios[i].flags = GPIOF_OUT_INIT_LOW; | ||
| 130 | } | ||
| 131 | wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL0].flags = GPIOF_OUT_INIT_HIGH; | ||
| 132 | wm1250->gpios[WM1250_EV1_GPIO_CLK_SEL1].flags = GPIOF_OUT_INIT_HIGH; | ||
| 133 | |||
| 134 | ret = gpio_request_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios)); | ||
| 135 | if (ret != 0) { | ||
| 136 | dev_err(&i2c->dev, "Failed to get GPIOs: %d\n", ret); | ||
| 137 | goto err_alloc; | ||
| 138 | } | ||
| 139 | |||
| 140 | dev_set_drvdata(&i2c->dev, wm1250); | ||
| 141 | |||
| 142 | return ret; | ||
| 143 | |||
| 144 | err_alloc: | ||
| 145 | kfree(wm1250); | ||
| 146 | err: | ||
| 147 | return ret; | ||
| 148 | } | ||
| 149 | |||
| 150 | static void wm1250_ev1_free(struct i2c_client *i2c) | ||
| 151 | { | ||
| 152 | struct wm1250_priv *wm1250 = dev_get_drvdata(&i2c->dev); | ||
| 153 | |||
| 154 | if (wm1250) { | ||
| 155 | gpio_free_array(wm1250->gpios, ARRAY_SIZE(wm1250->gpios)); | ||
| 156 | kfree(wm1250); | ||
| 157 | } | ||
| 158 | } | ||
| 159 | |||
| 58 | static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, | 160 | static int __devinit wm1250_ev1_probe(struct i2c_client *i2c, |
| 59 | const struct i2c_device_id *id) | 161 | const struct i2c_device_id *i2c_id) |
| 60 | { | 162 | { |
| 61 | return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1, | 163 | int id, board, rev, ret; |
| 62 | &wm1250_ev1_dai, 1); | 164 | |
| 165 | dev_set_drvdata(&i2c->dev, NULL); | ||
| 166 | |||
| 167 | board = i2c_smbus_read_byte_data(i2c, 0); | ||
| 168 | if (board < 0) { | ||
| 169 | dev_err(&i2c->dev, "Failed to read ID: %d\n", board); | ||
| 170 | return board; | ||
| 171 | } | ||
| 172 | |||
| 173 | id = (board & 0xfe) >> 2; | ||
| 174 | rev = board & 0x3; | ||
| 175 | |||
| 176 | if (id != 1) { | ||
| 177 | dev_err(&i2c->dev, "Unknown board ID %d\n", id); | ||
| 178 | return -ENODEV; | ||
| 179 | } | ||
| 180 | |||
| 181 | dev_info(&i2c->dev, "revision %d\n", rev + 1); | ||
| 182 | |||
| 183 | ret = wm1250_ev1_pdata(i2c); | ||
| 184 | if (ret != 0) | ||
| 185 | return ret; | ||
| 186 | |||
| 187 | ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm1250_ev1, | ||
| 188 | &wm1250_ev1_dai, 1); | ||
| 189 | if (ret != 0) { | ||
| 190 | dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); | ||
| 191 | wm1250_ev1_free(i2c); | ||
| 192 | return ret; | ||
| 193 | } | ||
| 194 | |||
| 195 | return 0; | ||
| 63 | } | 196 | } |
| 64 | 197 | ||
| 65 | static int __devexit wm1250_ev1_remove(struct i2c_client *i2c) | 198 | static int __devexit wm1250_ev1_remove(struct i2c_client *i2c) |
| 66 | { | 199 | { |
| 67 | snd_soc_unregister_codec(&i2c->dev); | 200 | snd_soc_unregister_codec(&i2c->dev); |
| 201 | wm1250_ev1_free(i2c); | ||
| 68 | 202 | ||
| 69 | return 0; | 203 | return 0; |
| 70 | } | 204 | } |
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c new file mode 100644 index 000000000000..e9ce81a57b85 --- /dev/null +++ b/sound/soc/codecs/wm5100-tables.c | |||
| @@ -0,0 +1,1531 @@ | |||
| 1 | /* | ||
| 2 | * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data | ||
| 3 | * | ||
| 4 | * Copyright 2011 Wolfson Microelectronics plc | ||
| 5 | * | ||
| 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "wm5100.h" | ||
| 15 | |||
| 16 | int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg) | ||
| 17 | { | ||
| 18 | switch (reg) { | ||
| 19 | case WM5100_SOFTWARE_RESET: | ||
| 20 | case WM5100_DEVICE_REVISION: | ||
| 21 | case WM5100_FX_CTRL: | ||
| 22 | case WM5100_INTERRUPT_STATUS_1: | ||
| 23 | case WM5100_INTERRUPT_STATUS_2: | ||
| 24 | case WM5100_INTERRUPT_STATUS_3: | ||
| 25 | case WM5100_INTERRUPT_STATUS_4: | ||
| 26 | case WM5100_INTERRUPT_RAW_STATUS_2: | ||
| 27 | case WM5100_INTERRUPT_RAW_STATUS_3: | ||
| 28 | case WM5100_INTERRUPT_RAW_STATUS_4: | ||
| 29 | case WM5100_OUTPUT_STATUS_1: | ||
| 30 | case WM5100_OUTPUT_STATUS_2: | ||
| 31 | case WM5100_INPUT_ENABLES_STATUS: | ||
| 32 | case WM5100_MIC_DETECT_3: | ||
| 33 | return 1; | ||
| 34 | default: | ||
| 35 | return 0; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg) | ||
| 40 | { | ||
| 41 | switch (reg) { | ||
| 42 | case WM5100_SOFTWARE_RESET: | ||
| 43 | case WM5100_DEVICE_REVISION: | ||
| 44 | case WM5100_CTRL_IF_1: | ||
| 45 | case WM5100_TONE_GENERATOR_1: | ||
| 46 | case WM5100_PWM_DRIVE_1: | ||
| 47 | case WM5100_PWM_DRIVE_2: | ||
| 48 | case WM5100_PWM_DRIVE_3: | ||
| 49 | case WM5100_CLOCKING_1: | ||
| 50 | case WM5100_CLOCKING_3: | ||
| 51 | case WM5100_CLOCKING_4: | ||
| 52 | case WM5100_CLOCKING_5: | ||
| 53 | case WM5100_CLOCKING_6: | ||
| 54 | case WM5100_CLOCKING_7: | ||
| 55 | case WM5100_CLOCKING_8: | ||
| 56 | case WM5100_ASRC_ENABLE: | ||
| 57 | case WM5100_ASRC_STATUS: | ||
| 58 | case WM5100_ASRC_RATE1: | ||
| 59 | case WM5100_ISRC_1_CTRL_1: | ||
| 60 | case WM5100_ISRC_1_CTRL_2: | ||
| 61 | case WM5100_ISRC_2_CTRL1: | ||
| 62 | case WM5100_ISRC_2_CTRL_2: | ||
| 63 | case WM5100_FLL1_CONTROL_1: | ||
| 64 | case WM5100_FLL1_CONTROL_2: | ||
| 65 | case WM5100_FLL1_CONTROL_3: | ||
| 66 | case WM5100_FLL1_CONTROL_5: | ||
| 67 | case WM5100_FLL1_CONTROL_6: | ||
| 68 | case WM5100_FLL1_EFS_1: | ||
| 69 | case WM5100_FLL2_CONTROL_1: | ||
| 70 | case WM5100_FLL2_CONTROL_2: | ||
| 71 | case WM5100_FLL2_CONTROL_3: | ||
| 72 | case WM5100_FLL2_CONTROL_5: | ||
| 73 | case WM5100_FLL2_CONTROL_6: | ||
| 74 | case WM5100_FLL2_EFS_1: | ||
| 75 | case WM5100_MIC_CHARGE_PUMP_1: | ||
| 76 | case WM5100_MIC_CHARGE_PUMP_2: | ||
| 77 | case WM5100_HP_CHARGE_PUMP_1: | ||
| 78 | case WM5100_LDO1_CONTROL: | ||
| 79 | case WM5100_MIC_BIAS_CTRL_1: | ||
| 80 | case WM5100_MIC_BIAS_CTRL_2: | ||
| 81 | case WM5100_MIC_BIAS_CTRL_3: | ||
| 82 | case WM5100_ACCESSORY_DETECT_MODE_1: | ||
| 83 | case WM5100_HEADPHONE_DETECT_1: | ||
| 84 | case WM5100_HEADPHONE_DETECT_2: | ||
| 85 | case WM5100_MIC_DETECT_1: | ||
| 86 | case WM5100_MIC_DETECT_2: | ||
| 87 | case WM5100_MIC_DETECT_3: | ||
| 88 | case WM5100_INPUT_ENABLES: | ||
| 89 | case WM5100_INPUT_ENABLES_STATUS: | ||
| 90 | case WM5100_IN1L_CONTROL: | ||
| 91 | case WM5100_IN1R_CONTROL: | ||
| 92 | case WM5100_IN2L_CONTROL: | ||
| 93 | case WM5100_IN2R_CONTROL: | ||
| 94 | case WM5100_IN3L_CONTROL: | ||
| 95 | case WM5100_IN3R_CONTROL: | ||
| 96 | case WM5100_IN4L_CONTROL: | ||
| 97 | case WM5100_IN4R_CONTROL: | ||
| 98 | case WM5100_RXANC_SRC: | ||
| 99 | case WM5100_INPUT_VOLUME_RAMP: | ||
| 100 | case WM5100_ADC_DIGITAL_VOLUME_1L: | ||
| 101 | case WM5100_ADC_DIGITAL_VOLUME_1R: | ||
| 102 | case WM5100_ADC_DIGITAL_VOLUME_2L: | ||
| 103 | case WM5100_ADC_DIGITAL_VOLUME_2R: | ||
| 104 | case WM5100_ADC_DIGITAL_VOLUME_3L: | ||
| 105 | case WM5100_ADC_DIGITAL_VOLUME_3R: | ||
| 106 | case WM5100_ADC_DIGITAL_VOLUME_4L: | ||
| 107 | case WM5100_ADC_DIGITAL_VOLUME_4R: | ||
| 108 | case WM5100_OUTPUT_ENABLES_2: | ||
| 109 | case WM5100_OUTPUT_STATUS_1: | ||
| 110 | case WM5100_OUTPUT_STATUS_2: | ||
| 111 | case WM5100_CHANNEL_ENABLES_1: | ||
| 112 | case WM5100_OUT_VOLUME_1L: | ||
| 113 | case WM5100_OUT_VOLUME_1R: | ||
| 114 | case WM5100_DAC_VOLUME_LIMIT_1L: | ||
| 115 | case WM5100_DAC_VOLUME_LIMIT_1R: | ||
| 116 | case WM5100_OUT_VOLUME_2L: | ||
| 117 | case WM5100_OUT_VOLUME_2R: | ||
| 118 | case WM5100_DAC_VOLUME_LIMIT_2L: | ||
| 119 | case WM5100_DAC_VOLUME_LIMIT_2R: | ||
| 120 | case WM5100_OUT_VOLUME_3L: | ||
| 121 | case WM5100_OUT_VOLUME_3R: | ||
| 122 | case WM5100_DAC_VOLUME_LIMIT_3L: | ||
| 123 | case WM5100_DAC_VOLUME_LIMIT_3R: | ||
| 124 | case WM5100_OUT_VOLUME_4L: | ||
| 125 | case WM5100_OUT_VOLUME_4R: | ||
| 126 | case WM5100_DAC_VOLUME_LIMIT_5L: | ||
| 127 | case WM5100_DAC_VOLUME_LIMIT_5R: | ||
| 128 | case WM5100_DAC_VOLUME_LIMIT_6L: | ||
| 129 | case WM5100_DAC_VOLUME_LIMIT_6R: | ||
| 130 | case WM5100_DAC_AEC_CONTROL_1: | ||
| 131 | case WM5100_OUTPUT_VOLUME_RAMP: | ||
| 132 | case WM5100_DAC_DIGITAL_VOLUME_1L: | ||
| 133 | case WM5100_DAC_DIGITAL_VOLUME_1R: | ||
| 134 | case WM5100_DAC_DIGITAL_VOLUME_2L: | ||
| 135 | case WM5100_DAC_DIGITAL_VOLUME_2R: | ||
| 136 | case WM5100_DAC_DIGITAL_VOLUME_3L: | ||
| 137 | case WM5100_DAC_DIGITAL_VOLUME_3R: | ||
| 138 | case WM5100_DAC_DIGITAL_VOLUME_4L: | ||
| 139 | case WM5100_DAC_DIGITAL_VOLUME_4R: | ||
| 140 | case WM5100_DAC_DIGITAL_VOLUME_5L: | ||
| 141 | case WM5100_DAC_DIGITAL_VOLUME_5R: | ||
| 142 | case WM5100_DAC_DIGITAL_VOLUME_6L: | ||
| 143 | case WM5100_DAC_DIGITAL_VOLUME_6R: | ||
| 144 | case WM5100_PDM_SPK1_CTRL_1: | ||
| 145 | case WM5100_PDM_SPK1_CTRL_2: | ||
| 146 | case WM5100_PDM_SPK2_CTRL_1: | ||
| 147 | case WM5100_PDM_SPK2_CTRL_2: | ||
| 148 | case WM5100_AUDIO_IF_1_1: | ||
| 149 | case WM5100_AUDIO_IF_1_2: | ||
| 150 | case WM5100_AUDIO_IF_1_3: | ||
| 151 | case WM5100_AUDIO_IF_1_4: | ||
| 152 | case WM5100_AUDIO_IF_1_5: | ||
| 153 | case WM5100_AUDIO_IF_1_6: | ||
| 154 | case WM5100_AUDIO_IF_1_7: | ||
| 155 | case WM5100_AUDIO_IF_1_8: | ||
| 156 | case WM5100_AUDIO_IF_1_9: | ||
| 157 | case WM5100_AUDIO_IF_1_10: | ||
| 158 | case WM5100_AUDIO_IF_1_11: | ||
| 159 | case WM5100_AUDIO_IF_1_12: | ||
| 160 | case WM5100_AUDIO_IF_1_13: | ||
| 161 | case WM5100_AUDIO_IF_1_14: | ||
| 162 | case WM5100_AUDIO_IF_1_15: | ||
| 163 | case WM5100_AUDIO_IF_1_16: | ||
| 164 | case WM5100_AUDIO_IF_1_17: | ||
| 165 | case WM5100_AUDIO_IF_1_18: | ||
| 166 | case WM5100_AUDIO_IF_1_19: | ||
| 167 | case WM5100_AUDIO_IF_1_20: | ||
| 168 | case WM5100_AUDIO_IF_1_21: | ||
| 169 | case WM5100_AUDIO_IF_1_22: | ||
| 170 | case WM5100_AUDIO_IF_1_23: | ||
| 171 | case WM5100_AUDIO_IF_1_24: | ||
| 172 | case WM5100_AUDIO_IF_1_25: | ||
| 173 | case WM5100_AUDIO_IF_1_26: | ||
| 174 | case WM5100_AUDIO_IF_1_27: | ||
| 175 | case WM5100_AUDIO_IF_2_1: | ||
| 176 | case WM5100_AUDIO_IF_2_2: | ||
| 177 | case WM5100_AUDIO_IF_2_3: | ||
| 178 | case WM5100_AUDIO_IF_2_4: | ||
| 179 | case WM5100_AUDIO_IF_2_5: | ||
| 180 | case WM5100_AUDIO_IF_2_6: | ||
| 181 | case WM5100_AUDIO_IF_2_7: | ||
| 182 | case WM5100_AUDIO_IF_2_8: | ||
| 183 | case WM5100_AUDIO_IF_2_9: | ||
| 184 | case WM5100_AUDIO_IF_2_10: | ||
| 185 | case WM5100_AUDIO_IF_2_11: | ||
| 186 | case WM5100_AUDIO_IF_2_18: | ||
| 187 | case WM5100_AUDIO_IF_2_19: | ||
| 188 | case WM5100_AUDIO_IF_2_26: | ||
| 189 | case WM5100_AUDIO_IF_2_27: | ||
| 190 | case WM5100_AUDIO_IF_3_1: | ||
| 191 | case WM5100_AUDIO_IF_3_2: | ||
| 192 | case WM5100_AUDIO_IF_3_3: | ||
| 193 | case WM5100_AUDIO_IF_3_4: | ||
| 194 | case WM5100_AUDIO_IF_3_5: | ||
| 195 | case WM5100_AUDIO_IF_3_6: | ||
| 196 | case WM5100_AUDIO_IF_3_7: | ||
| 197 | case WM5100_AUDIO_IF_3_8: | ||
| 198 | case WM5100_AUDIO_IF_3_9: | ||
| 199 | case WM5100_AUDIO_IF_3_10: | ||
| 200 | case WM5100_AUDIO_IF_3_11: | ||
| 201 | case WM5100_AUDIO_IF_3_18: | ||
| 202 | case WM5100_AUDIO_IF_3_19: | ||
| 203 | case WM5100_AUDIO_IF_3_26: | ||
| 204 | case WM5100_AUDIO_IF_3_27: | ||
| 205 | case WM5100_PWM1MIX_INPUT_1_SOURCE: | ||
| 206 | case WM5100_PWM1MIX_INPUT_1_VOLUME: | ||
| 207 | case WM5100_PWM1MIX_INPUT_2_SOURCE: | ||
| 208 | case WM5100_PWM1MIX_INPUT_2_VOLUME: | ||
| 209 | case WM5100_PWM1MIX_INPUT_3_SOURCE: | ||
| 210 | case WM5100_PWM1MIX_INPUT_3_VOLUME: | ||
| 211 | case WM5100_PWM1MIX_INPUT_4_SOURCE: | ||
| 212 | case WM5100_PWM1MIX_INPUT_4_VOLUME: | ||
| 213 | case WM5100_PWM2MIX_INPUT_1_SOURCE: | ||
| 214 | case WM5100_PWM2MIX_INPUT_1_VOLUME: | ||
| 215 | case WM5100_PWM2MIX_INPUT_2_SOURCE: | ||
| 216 | case WM5100_PWM2MIX_INPUT_2_VOLUME: | ||
| 217 | case WM5100_PWM2MIX_INPUT_3_SOURCE: | ||
| 218 | case WM5100_PWM2MIX_INPUT_3_VOLUME: | ||
| 219 | case WM5100_PWM2MIX_INPUT_4_SOURCE: | ||
| 220 | case WM5100_PWM2MIX_INPUT_4_VOLUME: | ||
| 221 | case WM5100_OUT1LMIX_INPUT_1_SOURCE: | ||
| 222 | case WM5100_OUT1LMIX_INPUT_1_VOLUME: | ||
| 223 | case WM5100_OUT1LMIX_INPUT_2_SOURCE: | ||
| 224 | case WM5100_OUT1LMIX_INPUT_2_VOLUME: | ||
| 225 | case WM5100_OUT1LMIX_INPUT_3_SOURCE: | ||
| 226 | case WM5100_OUT1LMIX_INPUT_3_VOLUME: | ||
| 227 | case WM5100_OUT1LMIX_INPUT_4_SOURCE: | ||
| 228 | case WM5100_OUT1LMIX_INPUT_4_VOLUME: | ||
| 229 | case WM5100_OUT1RMIX_INPUT_1_SOURCE: | ||
| 230 | case WM5100_OUT1RMIX_INPUT_1_VOLUME: | ||
| 231 | case WM5100_OUT1RMIX_INPUT_2_SOURCE: | ||
| 232 | case WM5100_OUT1RMIX_INPUT_2_VOLUME: | ||
| 233 | case WM5100_OUT1RMIX_INPUT_3_SOURCE: | ||
| 234 | case WM5100_OUT1RMIX_INPUT_3_VOLUME: | ||
| 235 | case WM5100_OUT1RMIX_INPUT_4_SOURCE: | ||
| 236 | case WM5100_OUT1RMIX_INPUT_4_VOLUME: | ||
| 237 | case WM5100_OUT2LMIX_INPUT_1_SOURCE: | ||
| 238 | case WM5100_OUT2LMIX_INPUT_1_VOLUME: | ||
| 239 | case WM5100_OUT2LMIX_INPUT_2_SOURCE: | ||
| 240 | case WM5100_OUT2LMIX_INPUT_2_VOLUME: | ||
| 241 | case WM5100_OUT2LMIX_INPUT_3_SOURCE: | ||
| 242 | case WM5100_OUT2LMIX_INPUT_3_VOLUME: | ||
| 243 | case WM5100_OUT2LMIX_INPUT_4_SOURCE: | ||
| 244 | case WM5100_OUT2LMIX_INPUT_4_VOLUME: | ||
| 245 | case WM5100_OUT2RMIX_INPUT_1_SOURCE: | ||
| 246 | case WM5100_OUT2RMIX_INPUT_1_VOLUME: | ||
| 247 | case WM5100_OUT2RMIX_INPUT_2_SOURCE: | ||
| 248 | case WM5100_OUT2RMIX_INPUT_2_VOLUME: | ||
| 249 | case WM5100_OUT2RMIX_INPUT_3_SOURCE: | ||
| 250 | case WM5100_OUT2RMIX_INPUT_3_VOLUME: | ||
| 251 | case WM5100_OUT2RMIX_INPUT_4_SOURCE: | ||
| 252 | case WM5100_OUT2RMIX_INPUT_4_VOLUME: | ||
| 253 | case WM5100_OUT3LMIX_INPUT_1_SOURCE: | ||
| 254 | case WM5100_OUT3LMIX_INPUT_1_VOLUME: | ||
| 255 | case WM5100_OUT3LMIX_INPUT_2_SOURCE: | ||
| 256 | case WM5100_OUT3LMIX_INPUT_2_VOLUME: | ||
| 257 | case WM5100_OUT3LMIX_INPUT_3_SOURCE: | ||
| 258 | case WM5100_OUT3LMIX_INPUT_3_VOLUME: | ||
| 259 | case WM5100_OUT3LMIX_INPUT_4_SOURCE: | ||
| 260 | case WM5100_OUT3LMIX_INPUT_4_VOLUME: | ||
| 261 | case WM5100_OUT3RMIX_INPUT_1_SOURCE: | ||
| 262 | case WM5100_OUT3RMIX_INPUT_1_VOLUME: | ||
| 263 | case WM5100_OUT3RMIX_INPUT_2_SOURCE: | ||
| 264 | case WM5100_OUT3RMIX_INPUT_2_VOLUME: | ||
| 265 | case WM5100_OUT3RMIX_INPUT_3_SOURCE: | ||
| 266 | case WM5100_OUT3RMIX_INPUT_3_VOLUME: | ||
| 267 | case WM5100_OUT3RMIX_INPUT_4_SOURCE: | ||
| 268 | case WM5100_OUT3RMIX_INPUT_4_VOLUME: | ||
| 269 | case WM5100_OUT4LMIX_INPUT_1_SOURCE: | ||
| 270 | case WM5100_OUT4LMIX_INPUT_1_VOLUME: | ||
| 271 | case WM5100_OUT4LMIX_INPUT_2_SOURCE: | ||
| 272 | case WM5100_OUT4LMIX_INPUT_2_VOLUME: | ||
| 273 | case WM5100_OUT4LMIX_INPUT_3_SOURCE: | ||
| 274 | case WM5100_OUT4LMIX_INPUT_3_VOLUME: | ||
| 275 | case WM5100_OUT4LMIX_INPUT_4_SOURCE: | ||
| 276 | case WM5100_OUT4LMIX_INPUT_4_VOLUME: | ||
| 277 | case WM5100_OUT4RMIX_INPUT_1_SOURCE: | ||
| 278 | case WM5100_OUT4RMIX_INPUT_1_VOLUME: | ||
| 279 | case WM5100_OUT4RMIX_INPUT_2_SOURCE: | ||
| 280 | case WM5100_OUT4RMIX_INPUT_2_VOLUME: | ||
| 281 | case WM5100_OUT4RMIX_INPUT_3_SOURCE: | ||
| 282 | case WM5100_OUT4RMIX_INPUT_3_VOLUME: | ||
| 283 | case WM5100_OUT4RMIX_INPUT_4_SOURCE: | ||
| 284 | case WM5100_OUT4RMIX_INPUT_4_VOLUME: | ||
| 285 | case WM5100_OUT5LMIX_INPUT_1_SOURCE: | ||
| 286 | case WM5100_OUT5LMIX_INPUT_1_VOLUME: | ||
| 287 | case WM5100_OUT5LMIX_INPUT_2_SOURCE: | ||
| 288 | case WM5100_OUT5LMIX_INPUT_2_VOLUME: | ||
| 289 | case WM5100_OUT5LMIX_INPUT_3_SOURCE: | ||
| 290 | case WM5100_OUT5LMIX_INPUT_3_VOLUME: | ||
| 291 | case WM5100_OUT5LMIX_INPUT_4_SOURCE: | ||
| 292 | case WM5100_OUT5LMIX_INPUT_4_VOLUME: | ||
| 293 | case WM5100_OUT5RMIX_INPUT_1_SOURCE: | ||
| 294 | case WM5100_OUT5RMIX_INPUT_1_VOLUME: | ||
| 295 | case WM5100_OUT5RMIX_INPUT_2_SOURCE: | ||
| 296 | case WM5100_OUT5RMIX_INPUT_2_VOLUME: | ||
| 297 | case WM5100_OUT5RMIX_INPUT_3_SOURCE: | ||
| 298 | case WM5100_OUT5RMIX_INPUT_3_VOLUME: | ||
| 299 | case WM5100_OUT5RMIX_INPUT_4_SOURCE: | ||
| 300 | case WM5100_OUT5RMIX_INPUT_4_VOLUME: | ||
| 301 | case WM5100_OUT6LMIX_INPUT_1_SOURCE: | ||
| 302 | case WM5100_OUT6LMIX_INPUT_1_VOLUME: | ||
| 303 | case WM5100_OUT6LMIX_INPUT_2_SOURCE: | ||
| 304 | case WM5100_OUT6LMIX_INPUT_2_VOLUME: | ||
| 305 | case WM5100_OUT6LMIX_INPUT_3_SOURCE: | ||
| 306 | case WM5100_OUT6LMIX_INPUT_3_VOLUME: | ||
| 307 | case WM5100_OUT6LMIX_INPUT_4_SOURCE: | ||
| 308 | case WM5100_OUT6LMIX_INPUT_4_VOLUME: | ||
| 309 | case WM5100_OUT6RMIX_INPUT_1_SOURCE: | ||
| 310 | case WM5100_OUT6RMIX_INPUT_1_VOLUME: | ||
| 311 | case WM5100_OUT6RMIX_INPUT_2_SOURCE: | ||
| 312 | case WM5100_OUT6RMIX_INPUT_2_VOLUME: | ||
| 313 | case WM5100_OUT6RMIX_INPUT_3_SOURCE: | ||
| 314 | case WM5100_OUT6RMIX_INPUT_3_VOLUME: | ||
| 315 | case WM5100_OUT6RMIX_INPUT_4_SOURCE: | ||
| 316 | case WM5100_OUT6RMIX_INPUT_4_VOLUME: | ||
| 317 | case WM5100_AIF1TX1MIX_INPUT_1_SOURCE: | ||
| 318 | case WM5100_AIF1TX1MIX_INPUT_1_VOLUME: | ||
| 319 | case WM5100_AIF1TX1MIX_INPUT_2_SOURCE: | ||
| 320 | case WM5100_AIF1TX1MIX_INPUT_2_VOLUME: | ||
| 321 | case WM5100_AIF1TX1MIX_INPUT_3_SOURCE: | ||
| 322 | case WM5100_AIF1TX1MIX_INPUT_3_VOLUME: | ||
| 323 | case WM5100_AIF1TX1MIX_INPUT_4_SOURCE: | ||
| 324 | case WM5100_AIF1TX1MIX_INPUT_4_VOLUME: | ||
| 325 | case WM5100_AIF1TX2MIX_INPUT_1_SOURCE: | ||
| 326 | case WM5100_AIF1TX2MIX_INPUT_1_VOLUME: | ||
| 327 | case WM5100_AIF1TX2MIX_INPUT_2_SOURCE: | ||
| 328 | case WM5100_AIF1TX2MIX_INPUT_2_VOLUME: | ||
| 329 | case WM5100_AIF1TX2MIX_INPUT_3_SOURCE: | ||
| 330 | case WM5100_AIF1TX2MIX_INPUT_3_VOLUME: | ||
| 331 | case WM5100_AIF1TX2MIX_INPUT_4_SOURCE: | ||
| 332 | case WM5100_AIF1TX2MIX_INPUT_4_VOLUME: | ||
| 333 | case WM5100_AIF1TX3MIX_INPUT_1_SOURCE: | ||
| 334 | case WM5100_AIF1TX3MIX_INPUT_1_VOLUME: | ||
| 335 | case WM5100_AIF1TX3MIX_INPUT_2_SOURCE: | ||
| 336 | case WM5100_AIF1TX3MIX_INPUT_2_VOLUME: | ||
| 337 | case WM5100_AIF1TX3MIX_INPUT_3_SOURCE: | ||
| 338 | case WM5100_AIF1TX3MIX_INPUT_3_VOLUME: | ||
| 339 | case WM5100_AIF1TX3MIX_INPUT_4_SOURCE: | ||
| 340 | case WM5100_AIF1TX3MIX_INPUT_4_VOLUME: | ||
| 341 | case WM5100_AIF1TX4MIX_INPUT_1_SOURCE: | ||
| 342 | case WM5100_AIF1TX4MIX_INPUT_1_VOLUME: | ||
| 343 | case WM5100_AIF1TX4MIX_INPUT_2_SOURCE: | ||
| 344 | case WM5100_AIF1TX4MIX_INPUT_2_VOLUME: | ||
| 345 | case WM5100_AIF1TX4MIX_INPUT_3_SOURCE: | ||
| 346 | case WM5100_AIF1TX4MIX_INPUT_3_VOLUME: | ||
| 347 | case WM5100_AIF1TX4MIX_INPUT_4_SOURCE: | ||
| 348 | case WM5100_AIF1TX4MIX_INPUT_4_VOLUME: | ||
| 349 | case WM5100_AIF1TX5MIX_INPUT_1_SOURCE: | ||
| 350 | case WM5100_AIF1TX5MIX_INPUT_1_VOLUME: | ||
| 351 | case WM5100_AIF1TX5MIX_INPUT_2_SOURCE: | ||
| 352 | case WM5100_AIF1TX5MIX_INPUT_2_VOLUME: | ||
| 353 | case WM5100_AIF1TX5MIX_INPUT_3_SOURCE: | ||
| 354 | case WM5100_AIF1TX5MIX_INPUT_3_VOLUME: | ||
| 355 | case WM5100_AIF1TX5MIX_INPUT_4_SOURCE: | ||
| 356 | case WM5100_AIF1TX5MIX_INPUT_4_VOLUME: | ||
| 357 | case WM5100_AIF1TX6MIX_INPUT_1_SOURCE: | ||
| 358 | case WM5100_AIF1TX6MIX_INPUT_1_VOLUME: | ||
| 359 | case WM5100_AIF1TX6MIX_INPUT_2_SOURCE: | ||
| 360 | case WM5100_AIF1TX6MIX_INPUT_2_VOLUME: | ||
| 361 | case WM5100_AIF1TX6MIX_INPUT_3_SOURCE: | ||
| 362 | case WM5100_AIF1TX6MIX_INPUT_3_VOLUME: | ||
| 363 | case WM5100_AIF1TX6MIX_INPUT_4_SOURCE: | ||
| 364 | case WM5100_AIF1TX6MIX_INPUT_4_VOLUME: | ||
| 365 | case WM5100_AIF1TX7MIX_INPUT_1_SOURCE: | ||
| 366 | case WM5100_AIF1TX7MIX_INPUT_1_VOLUME: | ||
| 367 | case WM5100_AIF1TX7MIX_INPUT_2_SOURCE: | ||
| 368 | case WM5100_AIF1TX7MIX_INPUT_2_VOLUME: | ||
| 369 | case WM5100_AIF1TX7MIX_INPUT_3_SOURCE: | ||
| 370 | case WM5100_AIF1TX7MIX_INPUT_3_VOLUME: | ||
| 371 | case WM5100_AIF1TX7MIX_INPUT_4_SOURCE: | ||
| 372 | case WM5100_AIF1TX7MIX_INPUT_4_VOLUME: | ||
| 373 | case WM5100_AIF1TX8MIX_INPUT_1_SOURCE: | ||
| 374 | case WM5100_AIF1TX8MIX_INPUT_1_VOLUME: | ||
| 375 | case WM5100_AIF1TX8MIX_INPUT_2_SOURCE: | ||
| 376 | case WM5100_AIF1TX8MIX_INPUT_2_VOLUME: | ||
| 377 | case WM5100_AIF1TX8MIX_INPUT_3_SOURCE: | ||
| 378 | case WM5100_AIF1TX8MIX_INPUT_3_VOLUME: | ||
| 379 | case WM5100_AIF1TX8MIX_INPUT_4_SOURCE: | ||
| 380 | case WM5100_AIF1TX8MIX_INPUT_4_VOLUME: | ||
| 381 | case WM5100_AIF2TX1MIX_INPUT_1_SOURCE: | ||
| 382 | case WM5100_AIF2TX1MIX_INPUT_1_VOLUME: | ||
| 383 | case WM5100_AIF2TX1MIX_INPUT_2_SOURCE: | ||
| 384 | case WM5100_AIF2TX1MIX_INPUT_2_VOLUME: | ||
| 385 | case WM5100_AIF2TX1MIX_INPUT_3_SOURCE: | ||
| 386 | case WM5100_AIF2TX1MIX_INPUT_3_VOLUME: | ||
| 387 | case WM5100_AIF2TX1MIX_INPUT_4_SOURCE: | ||
| 388 | case WM5100_AIF2TX1MIX_INPUT_4_VOLUME: | ||
| 389 | case WM5100_AIF2TX2MIX_INPUT_1_SOURCE: | ||
| 390 | case WM5100_AIF2TX2MIX_INPUT_1_VOLUME: | ||
| 391 | case WM5100_AIF2TX2MIX_INPUT_2_SOURCE: | ||
| 392 | case WM5100_AIF2TX2MIX_INPUT_2_VOLUME: | ||
| 393 | case WM5100_AIF2TX2MIX_INPUT_3_SOURCE: | ||
| 394 | case WM5100_AIF2TX2MIX_INPUT_3_VOLUME: | ||
| 395 | case WM5100_AIF2TX2MIX_INPUT_4_SOURCE: | ||
| 396 | case WM5100_AIF2TX2MIX_INPUT_4_VOLUME: | ||
| 397 | case WM5100_AIF3TX1MIX_INPUT_1_SOURCE: | ||
| 398 | case WM5100_AIF3TX1MIX_INPUT_1_VOLUME: | ||
| 399 | case WM5100_AIF3TX1MIX_INPUT_2_SOURCE: | ||
| 400 | case WM5100_AIF3TX1MIX_INPUT_2_VOLUME: | ||
| 401 | case WM5100_AIF3TX1MIX_INPUT_3_SOURCE: | ||
| 402 | case WM5100_AIF3TX1MIX_INPUT_3_VOLUME: | ||
| 403 | case WM5100_AIF3TX1MIX_INPUT_4_SOURCE: | ||
| 404 | case WM5100_AIF3TX1MIX_INPUT_4_VOLUME: | ||
| 405 | case WM5100_AIF3TX2MIX_INPUT_1_SOURCE: | ||
| 406 | case WM5100_AIF3TX2MIX_INPUT_1_VOLUME: | ||
| 407 | case WM5100_AIF3TX2MIX_INPUT_2_SOURCE: | ||
| 408 | case WM5100_AIF3TX2MIX_INPUT_2_VOLUME: | ||
| 409 | case WM5100_AIF3TX2MIX_INPUT_3_SOURCE: | ||
| 410 | case WM5100_AIF3TX2MIX_INPUT_3_VOLUME: | ||
| 411 | case WM5100_AIF3TX2MIX_INPUT_4_SOURCE: | ||
| 412 | case WM5100_AIF3TX2MIX_INPUT_4_VOLUME: | ||
| 413 | case WM5100_EQ1MIX_INPUT_1_SOURCE: | ||
| 414 | case WM5100_EQ1MIX_INPUT_1_VOLUME: | ||
| 415 | case WM5100_EQ1MIX_INPUT_2_SOURCE: | ||
| 416 | case WM5100_EQ1MIX_INPUT_2_VOLUME: | ||
| 417 | case WM5100_EQ1MIX_INPUT_3_SOURCE: | ||
| 418 | case WM5100_EQ1MIX_INPUT_3_VOLUME: | ||
| 419 | case WM5100_EQ1MIX_INPUT_4_SOURCE: | ||
| 420 | case WM5100_EQ1MIX_INPUT_4_VOLUME: | ||
| 421 | case WM5100_EQ2MIX_INPUT_1_SOURCE: | ||
| 422 | case WM5100_EQ2MIX_INPUT_1_VOLUME: | ||
| 423 | case WM5100_EQ2MIX_INPUT_2_SOURCE: | ||
| 424 | case WM5100_EQ2MIX_INPUT_2_VOLUME: | ||
| 425 | case WM5100_EQ2MIX_INPUT_3_SOURCE: | ||
| 426 | case WM5100_EQ2MIX_INPUT_3_VOLUME: | ||
| 427 | case WM5100_EQ2MIX_INPUT_4_SOURCE: | ||
| 428 | case WM5100_EQ2MIX_INPUT_4_VOLUME: | ||
| 429 | case WM5100_EQ3MIX_INPUT_1_SOURCE: | ||
| 430 | case WM5100_EQ3MIX_INPUT_1_VOLUME: | ||
| 431 | case WM5100_EQ3MIX_INPUT_2_SOURCE: | ||
| 432 | case WM5100_EQ3MIX_INPUT_2_VOLUME: | ||
| 433 | case WM5100_EQ3MIX_INPUT_3_SOURCE: | ||
| 434 | case WM5100_EQ3MIX_INPUT_3_VOLUME: | ||
| 435 | case WM5100_EQ3MIX_INPUT_4_SOURCE: | ||
| 436 | case WM5100_EQ3MIX_INPUT_4_VOLUME: | ||
| 437 | case WM5100_EQ4MIX_INPUT_1_SOURCE: | ||
| 438 | case WM5100_EQ4MIX_INPUT_1_VOLUME: | ||
| 439 | case WM5100_EQ4MIX_INPUT_2_SOURCE: | ||
| 440 | case WM5100_EQ4MIX_INPUT_2_VOLUME: | ||
| 441 | case WM5100_EQ4MIX_INPUT_3_SOURCE: | ||
| 442 | case WM5100_EQ4MIX_INPUT_3_VOLUME: | ||
| 443 | case WM5100_EQ4MIX_INPUT_4_SOURCE: | ||
| 444 | case WM5100_EQ4MIX_INPUT_4_VOLUME: | ||
| 445 | case WM5100_DRC1LMIX_INPUT_1_SOURCE: | ||
| 446 | case WM5100_DRC1LMIX_INPUT_1_VOLUME: | ||
| 447 | case WM5100_DRC1LMIX_INPUT_2_SOURCE: | ||
| 448 | case WM5100_DRC1LMIX_INPUT_2_VOLUME: | ||
| 449 | case WM5100_DRC1LMIX_INPUT_3_SOURCE: | ||
| 450 | case WM5100_DRC1LMIX_INPUT_3_VOLUME: | ||
| 451 | case WM5100_DRC1LMIX_INPUT_4_SOURCE: | ||
| 452 | case WM5100_DRC1LMIX_INPUT_4_VOLUME: | ||
| 453 | case WM5100_DRC1RMIX_INPUT_1_SOURCE: | ||
| 454 | case WM5100_DRC1RMIX_INPUT_1_VOLUME: | ||
| 455 | case WM5100_DRC1RMIX_INPUT_2_SOURCE: | ||
| 456 | case WM5100_DRC1RMIX_INPUT_2_VOLUME: | ||
| 457 | case WM5100_DRC1RMIX_INPUT_3_SOURCE: | ||
| 458 | case WM5100_DRC1RMIX_INPUT_3_VOLUME: | ||
| 459 | case WM5100_DRC1RMIX_INPUT_4_SOURCE: | ||
| 460 | case WM5100_DRC1RMIX_INPUT_4_VOLUME: | ||
| 461 | case WM5100_HPLP1MIX_INPUT_1_SOURCE: | ||
| 462 | case WM5100_HPLP1MIX_INPUT_1_VOLUME: | ||
| 463 | case WM5100_HPLP1MIX_INPUT_2_SOURCE: | ||
| 464 | case WM5100_HPLP1MIX_INPUT_2_VOLUME: | ||
| 465 | case WM5100_HPLP1MIX_INPUT_3_SOURCE: | ||
| 466 | case WM5100_HPLP1MIX_INPUT_3_VOLUME: | ||
| 467 | case WM5100_HPLP1MIX_INPUT_4_SOURCE: | ||
| 468 | case WM5100_HPLP1MIX_INPUT_4_VOLUME: | ||
| 469 | case WM5100_HPLP2MIX_INPUT_1_SOURCE: | ||
| 470 | case WM5100_HPLP2MIX_INPUT_1_VOLUME: | ||
| 471 | case WM5100_HPLP2MIX_INPUT_2_SOURCE: | ||
| 472 | case WM5100_HPLP2MIX_INPUT_2_VOLUME: | ||
| 473 | case WM5100_HPLP2MIX_INPUT_3_SOURCE: | ||
| 474 | case WM5100_HPLP2MIX_INPUT_3_VOLUME: | ||
| 475 | case WM5100_HPLP2MIX_INPUT_4_SOURCE: | ||
| 476 | case WM5100_HPLP2MIX_INPUT_4_VOLUME: | ||
| 477 | case WM5100_HPLP3MIX_INPUT_1_SOURCE: | ||
| 478 | case WM5100_HPLP3MIX_INPUT_1_VOLUME: | ||
| 479 | case WM5100_HPLP3MIX_INPUT_2_SOURCE: | ||
| 480 | case WM5100_HPLP3MIX_INPUT_2_VOLUME: | ||
| 481 | case WM5100_HPLP3MIX_INPUT_3_SOURCE: | ||
| 482 | case WM5100_HPLP3MIX_INPUT_3_VOLUME: | ||
| 483 | case WM5100_HPLP3MIX_INPUT_4_SOURCE: | ||
| 484 | case WM5100_HPLP3MIX_INPUT_4_VOLUME: | ||
| 485 | case WM5100_HPLP4MIX_INPUT_1_SOURCE: | ||
| 486 | case WM5100_HPLP4MIX_INPUT_1_VOLUME: | ||
| 487 | case WM5100_HPLP4MIX_INPUT_2_SOURCE: | ||
| 488 | case WM5100_HPLP4MIX_INPUT_2_VOLUME: | ||
| 489 | case WM5100_HPLP4MIX_INPUT_3_SOURCE: | ||
| 490 | case WM5100_HPLP4MIX_INPUT_3_VOLUME: | ||
| 491 | case WM5100_HPLP4MIX_INPUT_4_SOURCE: | ||
| 492 | case WM5100_HPLP4MIX_INPUT_4_VOLUME: | ||
| 493 | case WM5100_DSP1LMIX_INPUT_1_SOURCE: | ||
| 494 | case WM5100_DSP1LMIX_INPUT_1_VOLUME: | ||
| 495 | case WM5100_DSP1LMIX_INPUT_2_SOURCE: | ||
| 496 | case WM5100_DSP1LMIX_INPUT_2_VOLUME: | ||
| 497 | case WM5100_DSP1LMIX_INPUT_3_SOURCE: | ||
| 498 | case WM5100_DSP1LMIX_INPUT_3_VOLUME: | ||
| 499 | case WM5100_DSP1LMIX_INPUT_4_SOURCE: | ||
| 500 | case WM5100_DSP1LMIX_INPUT_4_VOLUME: | ||
| 501 | case WM5100_DSP1RMIX_INPUT_1_SOURCE: | ||
| 502 | case WM5100_DSP1RMIX_INPUT_1_VOLUME: | ||
| 503 | case WM5100_DSP1RMIX_INPUT_2_SOURCE: | ||
| 504 | case WM5100_DSP1RMIX_INPUT_2_VOLUME: | ||
| 505 | case WM5100_DSP1RMIX_INPUT_3_SOURCE: | ||
| 506 | case WM5100_DSP1RMIX_INPUT_3_VOLUME: | ||
| 507 | case WM5100_DSP1RMIX_INPUT_4_SOURCE: | ||
| 508 | case WM5100_DSP1RMIX_INPUT_4_VOLUME: | ||
| 509 | case WM5100_DSP1AUX1MIX_INPUT_1_SOURCE: | ||
| 510 | case WM5100_DSP1AUX2MIX_INPUT_1_SOURCE: | ||
| 511 | case WM5100_DSP1AUX3MIX_INPUT_1_SOURCE: | ||
| 512 | case WM5100_DSP1AUX4MIX_INPUT_1_SOURCE: | ||
| 513 | case WM5100_DSP1AUX5MIX_INPUT_1_SOURCE: | ||
| 514 | case WM5100_DSP1AUX6MIX_INPUT_1_SOURCE: | ||
| 515 | case WM5100_DSP2LMIX_INPUT_1_SOURCE: | ||
| 516 | case WM5100_DSP2LMIX_INPUT_1_VOLUME: | ||
| 517 | case WM5100_DSP2LMIX_INPUT_2_SOURCE: | ||
| 518 | case WM5100_DSP2LMIX_INPUT_2_VOLUME: | ||
| 519 | case WM5100_DSP2LMIX_INPUT_3_SOURCE: | ||
| 520 | case WM5100_DSP2LMIX_INPUT_3_VOLUME: | ||
| 521 | case WM5100_DSP2LMIX_INPUT_4_SOURCE: | ||
| 522 | case WM5100_DSP2LMIX_INPUT_4_VOLUME: | ||
| 523 | case WM5100_DSP2RMIX_INPUT_1_SOURCE: | ||
| 524 | case WM5100_DSP2RMIX_INPUT_1_VOLUME: | ||
| 525 | case WM5100_DSP2RMIX_INPUT_2_SOURCE: | ||
| 526 | case WM5100_DSP2RMIX_INPUT_2_VOLUME: | ||
| 527 | case WM5100_DSP2RMIX_INPUT_3_SOURCE: | ||
| 528 | case WM5100_DSP2RMIX_INPUT_3_VOLUME: | ||
| 529 | case WM5100_DSP2RMIX_INPUT_4_SOURCE: | ||
| 530 | case WM5100_DSP2RMIX_INPUT_4_VOLUME: | ||
| 531 | case WM5100_DSP2AUX1MIX_INPUT_1_SOURCE: | ||
| 532 | case WM5100_DSP2AUX2MIX_INPUT_1_SOURCE: | ||
| 533 | case WM5100_DSP2AUX3MIX_INPUT_1_SOURCE: | ||
| 534 | case WM5100_DSP2AUX4MIX_INPUT_1_SOURCE: | ||
| 535 | case WM5100_DSP2AUX5MIX_INPUT_1_SOURCE: | ||
| 536 | case WM5100_DSP2AUX6MIX_INPUT_1_SOURCE: | ||
| 537 | case WM5100_DSP3LMIX_INPUT_1_SOURCE: | ||
| 538 | case WM5100_DSP3LMIX_INPUT_1_VOLUME: | ||
| 539 | case WM5100_DSP3LMIX_INPUT_2_SOURCE: | ||
| 540 | case WM5100_DSP3LMIX_INPUT_2_VOLUME: | ||
| 541 | case WM5100_DSP3LMIX_INPUT_3_SOURCE: | ||
| 542 | case WM5100_DSP3LMIX_INPUT_3_VOLUME: | ||
| 543 | case WM5100_DSP3LMIX_INPUT_4_SOURCE: | ||
| 544 | case WM5100_DSP3LMIX_INPUT_4_VOLUME: | ||
| 545 | case WM5100_DSP3RMIX_INPUT_1_SOURCE: | ||
| 546 | case WM5100_DSP3RMIX_INPUT_1_VOLUME: | ||
| 547 | case WM5100_DSP3RMIX_INPUT_2_SOURCE: | ||
| 548 | case WM5100_DSP3RMIX_INPUT_2_VOLUME: | ||
| 549 | case WM5100_DSP3RMIX_INPUT_3_SOURCE: | ||
| 550 | case WM5100_DSP3RMIX_INPUT_3_VOLUME: | ||
| 551 | case WM5100_DSP3RMIX_INPUT_4_SOURCE: | ||
| 552 | case WM5100_DSP3RMIX_INPUT_4_VOLUME: | ||
| 553 | case WM5100_DSP3AUX1MIX_INPUT_1_SOURCE: | ||
| 554 | case WM5100_DSP3AUX2MIX_INPUT_1_SOURCE: | ||
| 555 | case WM5100_DSP3AUX3MIX_INPUT_1_SOURCE: | ||
| 556 | case WM5100_DSP3AUX4MIX_INPUT_1_SOURCE: | ||
| 557 | case WM5100_DSP3AUX5MIX_INPUT_1_SOURCE: | ||
| 558 | case WM5100_DSP3AUX6MIX_INPUT_1_SOURCE: | ||
| 559 | case WM5100_ASRC1LMIX_INPUT_1_SOURCE: | ||
| 560 | case WM5100_ASRC1RMIX_INPUT_1_SOURCE: | ||
| 561 | case WM5100_ASRC2LMIX_INPUT_1_SOURCE: | ||
| 562 | case WM5100_ASRC2RMIX_INPUT_1_SOURCE: | ||
| 563 | case WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE: | ||
| 564 | case WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE: | ||
| 565 | case WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE: | ||
| 566 | case WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE: | ||
| 567 | case WM5100_ISRC1INT1MIX_INPUT_1_SOURCE: | ||
| 568 | case WM5100_ISRC1INT2MIX_INPUT_1_SOURCE: | ||
| 569 | case WM5100_ISRC1INT3MIX_INPUT_1_SOURCE: | ||
| 570 | case WM5100_ISRC1INT4MIX_INPUT_1_SOURCE: | ||
| 571 | case WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE: | ||
| 572 | case WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE: | ||
| 573 | case WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE: | ||
| 574 | case WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE: | ||
| 575 | case WM5100_ISRC2INT1MIX_INPUT_1_SOURCE: | ||
| 576 | case WM5100_ISRC2INT2MIX_INPUT_1_SOURCE: | ||
| 577 | case WM5100_ISRC2INT3MIX_INPUT_1_SOURCE: | ||
| 578 | case WM5100_ISRC2INT4MIX_INPUT_1_SOURCE: | ||
| 579 | case WM5100_GPIO_CTRL_1: | ||
| 580 | case WM5100_GPIO_CTRL_2: | ||
| 581 | case WM5100_GPIO_CTRL_3: | ||
| 582 | case WM5100_GPIO_CTRL_4: | ||
| 583 | case WM5100_GPIO_CTRL_5: | ||
| 584 | case WM5100_GPIO_CTRL_6: | ||
| 585 | case WM5100_MISC_PAD_CTRL_1: | ||
| 586 | case WM5100_MISC_PAD_CTRL_2: | ||
| 587 | case WM5100_MISC_PAD_CTRL_3: | ||
| 588 | case WM5100_MISC_PAD_CTRL_4: | ||
| 589 | case WM5100_MISC_PAD_CTRL_5: | ||
| 590 | case WM5100_MISC_GPIO_1: | ||
| 591 | case WM5100_INTERRUPT_STATUS_1: | ||
| 592 | case WM5100_INTERRUPT_STATUS_2: | ||
| 593 | case WM5100_INTERRUPT_STATUS_3: | ||
| 594 | case WM5100_INTERRUPT_STATUS_4: | ||
| 595 | case WM5100_INTERRUPT_RAW_STATUS_2: | ||
| 596 | case WM5100_INTERRUPT_RAW_STATUS_3: | ||
| 597 | case WM5100_INTERRUPT_RAW_STATUS_4: | ||
| 598 | case WM5100_INTERRUPT_STATUS_1_MASK: | ||
| 599 | case WM5100_INTERRUPT_STATUS_2_MASK: | ||
| 600 | case WM5100_INTERRUPT_STATUS_3_MASK: | ||
| 601 | case WM5100_INTERRUPT_STATUS_4_MASK: | ||
| 602 | case WM5100_INTERRUPT_CONTROL: | ||
| 603 | case WM5100_IRQ_DEBOUNCE_1: | ||
| 604 | case WM5100_IRQ_DEBOUNCE_2: | ||
| 605 | case WM5100_FX_CTRL: | ||
| 606 | case WM5100_EQ1_1: | ||
| 607 | case WM5100_EQ1_2: | ||
| 608 | case WM5100_EQ1_3: | ||
| 609 | case WM5100_EQ1_4: | ||
| 610 | case WM5100_EQ1_5: | ||
| 611 | case WM5100_EQ1_6: | ||
| 612 | case WM5100_EQ1_7: | ||
| 613 | case WM5100_EQ1_8: | ||
| 614 | case WM5100_EQ1_9: | ||
| 615 | case WM5100_EQ1_10: | ||
| 616 | case WM5100_EQ1_11: | ||
| 617 | case WM5100_EQ1_12: | ||
| 618 | case WM5100_EQ1_13: | ||
| 619 | case WM5100_EQ1_14: | ||
| 620 | case WM5100_EQ1_15: | ||
| 621 | case WM5100_EQ1_16: | ||
| 622 | case WM5100_EQ1_17: | ||
| 623 | case WM5100_EQ1_18: | ||
| 624 | case WM5100_EQ1_19: | ||
| 625 | case WM5100_EQ1_20: | ||
| 626 | case WM5100_EQ2_1: | ||
| 627 | case WM5100_EQ2_2: | ||
| 628 | case WM5100_EQ2_3: | ||
| 629 | case WM5100_EQ2_4: | ||
| 630 | case WM5100_EQ2_5: | ||
| 631 | case WM5100_EQ2_6: | ||
| 632 | case WM5100_EQ2_7: | ||
| 633 | case WM5100_EQ2_8: | ||
| 634 | case WM5100_EQ2_9: | ||
| 635 | case WM5100_EQ2_10: | ||
| 636 | case WM5100_EQ2_11: | ||
| 637 | case WM5100_EQ2_12: | ||
| 638 | case WM5100_EQ2_13: | ||
| 639 | case WM5100_EQ2_14: | ||
| 640 | case WM5100_EQ2_15: | ||
| 641 | case WM5100_EQ2_16: | ||
| 642 | case WM5100_EQ2_17: | ||
| 643 | case WM5100_EQ2_18: | ||
| 644 | case WM5100_EQ2_19: | ||
| 645 | case WM5100_EQ2_20: | ||
| 646 | case WM5100_EQ3_1: | ||
| 647 | case WM5100_EQ3_2: | ||
| 648 | case WM5100_EQ3_3: | ||
| 649 | case WM5100_EQ3_4: | ||
| 650 | case WM5100_EQ3_5: | ||
| 651 | case WM5100_EQ3_6: | ||
| 652 | case WM5100_EQ3_7: | ||
| 653 | case WM5100_EQ3_8: | ||
| 654 | case WM5100_EQ3_9: | ||
| 655 | case WM5100_EQ3_10: | ||
| 656 | case WM5100_EQ3_11: | ||
| 657 | case WM5100_EQ3_12: | ||
| 658 | case WM5100_EQ3_13: | ||
| 659 | case WM5100_EQ3_14: | ||
| 660 | case WM5100_EQ3_15: | ||
| 661 | case WM5100_EQ3_16: | ||
| 662 | case WM5100_EQ3_17: | ||
| 663 | case WM5100_EQ3_18: | ||
| 664 | case WM5100_EQ3_19: | ||
| 665 | case WM5100_EQ3_20: | ||
| 666 | case WM5100_EQ4_1: | ||
| 667 | case WM5100_EQ4_2: | ||
| 668 | case WM5100_EQ4_3: | ||
| 669 | case WM5100_EQ4_4: | ||
| 670 | case WM5100_EQ4_5: | ||
| 671 | case WM5100_EQ4_6: | ||
| 672 | case WM5100_EQ4_7: | ||
| 673 | case WM5100_EQ4_8: | ||
| 674 | case WM5100_EQ4_9: | ||
| 675 | case WM5100_EQ4_10: | ||
| 676 | case WM5100_EQ4_11: | ||
| 677 | case WM5100_EQ4_12: | ||
| 678 | case WM5100_EQ4_13: | ||
| 679 | case WM5100_EQ4_14: | ||
| 680 | case WM5100_EQ4_15: | ||
| 681 | case WM5100_EQ4_16: | ||
| 682 | case WM5100_EQ4_17: | ||
| 683 | case WM5100_EQ4_18: | ||
| 684 | case WM5100_EQ4_19: | ||
| 685 | case WM5100_EQ4_20: | ||
| 686 | case WM5100_DRC1_CTRL1: | ||
| 687 | case WM5100_DRC1_CTRL2: | ||
| 688 | case WM5100_DRC1_CTRL3: | ||
| 689 | case WM5100_DRC1_CTRL4: | ||
| 690 | case WM5100_DRC1_CTRL5: | ||
| 691 | case WM5100_HPLPF1_1: | ||
| 692 | case WM5100_HPLPF1_2: | ||
| 693 | case WM5100_HPLPF2_1: | ||
| 694 | case WM5100_HPLPF2_2: | ||
| 695 | case WM5100_HPLPF3_1: | ||
| 696 | case WM5100_HPLPF3_2: | ||
| 697 | case WM5100_HPLPF4_1: | ||
| 698 | case WM5100_HPLPF4_2: | ||
| 699 | case WM5100_DSP1_DM_0: | ||
| 700 | case WM5100_DSP1_DM_1: | ||
| 701 | case WM5100_DSP1_DM_2: | ||
| 702 | case WM5100_DSP1_DM_3: | ||
| 703 | case WM5100_DSP1_DM_508: | ||
| 704 | case WM5100_DSP1_DM_509: | ||
| 705 | case WM5100_DSP1_DM_510: | ||
| 706 | case WM5100_DSP1_DM_511: | ||
| 707 | case WM5100_DSP1_PM_0: | ||
| 708 | case WM5100_DSP1_PM_1: | ||
| 709 | case WM5100_DSP1_PM_2: | ||
| 710 | case WM5100_DSP1_PM_3: | ||
| 711 | case WM5100_DSP1_PM_4: | ||
| 712 | case WM5100_DSP1_PM_5: | ||
| 713 | case WM5100_DSP1_PM_1530: | ||
| 714 | case WM5100_DSP1_PM_1531: | ||
| 715 | case WM5100_DSP1_PM_1532: | ||
| 716 | case WM5100_DSP1_PM_1533: | ||
| 717 | case WM5100_DSP1_PM_1534: | ||
| 718 | case WM5100_DSP1_PM_1535: | ||
| 719 | case WM5100_DSP1_ZM_0: | ||
| 720 | case WM5100_DSP1_ZM_1: | ||
| 721 | case WM5100_DSP1_ZM_2: | ||
| 722 | case WM5100_DSP1_ZM_3: | ||
| 723 | case WM5100_DSP1_ZM_2044: | ||
| 724 | case WM5100_DSP1_ZM_2045: | ||
| 725 | case WM5100_DSP1_ZM_2046: | ||
| 726 | case WM5100_DSP1_ZM_2047: | ||
| 727 | case WM5100_DSP2_DM_0: | ||
| 728 | case WM5100_DSP2_DM_1: | ||
| 729 | case WM5100_DSP2_DM_2: | ||
| 730 | case WM5100_DSP2_DM_3: | ||
| 731 | case WM5100_DSP2_DM_508: | ||
| 732 | case WM5100_DSP2_DM_509: | ||
| 733 | case WM5100_DSP2_DM_510: | ||
| 734 | case WM5100_DSP2_DM_511: | ||
| 735 | case WM5100_DSP2_PM_0: | ||
| 736 | case WM5100_DSP2_PM_1: | ||
| 737 | case WM5100_DSP2_PM_2: | ||
| 738 | case WM5100_DSP2_PM_3: | ||
| 739 | case WM5100_DSP2_PM_4: | ||
| 740 | case WM5100_DSP2_PM_5: | ||
| 741 | case WM5100_DSP2_PM_1530: | ||
| 742 | case WM5100_DSP2_PM_1531: | ||
| 743 | case WM5100_DSP2_PM_1532: | ||
| 744 | case WM5100_DSP2_PM_1533: | ||
| 745 | case WM5100_DSP2_PM_1534: | ||
| 746 | case WM5100_DSP2_PM_1535: | ||
| 747 | case WM5100_DSP2_ZM_0: | ||
| 748 | case WM5100_DSP2_ZM_1: | ||
| 749 | case WM5100_DSP2_ZM_2: | ||
| 750 | case WM5100_DSP2_ZM_3: | ||
| 751 | case WM5100_DSP2_ZM_2044: | ||
| 752 | case WM5100_DSP2_ZM_2045: | ||
| 753 | case WM5100_DSP2_ZM_2046: | ||
| 754 | case WM5100_DSP2_ZM_2047: | ||
| 755 | case WM5100_DSP3_DM_0: | ||
| 756 | case WM5100_DSP3_DM_1: | ||
| 757 | case WM5100_DSP3_DM_2: | ||
| 758 | case WM5100_DSP3_DM_3: | ||
| 759 | case WM5100_DSP3_DM_508: | ||
| 760 | case WM5100_DSP3_DM_509: | ||
| 761 | case WM5100_DSP3_DM_510: | ||
| 762 | case WM5100_DSP3_DM_511: | ||
| 763 | case WM5100_DSP3_PM_0: | ||
| 764 | case WM5100_DSP3_PM_1: | ||
| 765 | case WM5100_DSP3_PM_2: | ||
| 766 | case WM5100_DSP3_PM_3: | ||
| 767 | case WM5100_DSP3_PM_4: | ||
| 768 | case WM5100_DSP3_PM_5: | ||
| 769 | case WM5100_DSP3_PM_1530: | ||
| 770 | case WM5100_DSP3_PM_1531: | ||
| 771 | case WM5100_DSP3_PM_1532: | ||
| 772 | case WM5100_DSP3_PM_1533: | ||
| 773 | case WM5100_DSP3_PM_1534: | ||
| 774 | case WM5100_DSP3_PM_1535: | ||
| 775 | case WM5100_DSP3_ZM_0: | ||
| 776 | case WM5100_DSP3_ZM_1: | ||
| 777 | case WM5100_DSP3_ZM_2: | ||
| 778 | case WM5100_DSP3_ZM_3: | ||
| 779 | case WM5100_DSP3_ZM_2044: | ||
| 780 | case WM5100_DSP3_ZM_2045: | ||
| 781 | case WM5100_DSP3_ZM_2046: | ||
| 782 | case WM5100_DSP3_ZM_2047: | ||
| 783 | return 1; | ||
| 784 | default: | ||
| 785 | return 0; | ||
| 786 | } | ||
| 787 | } | ||
| 788 | |||
| 789 | u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1] = { | ||
| 790 | [0x0000] = 0x0000, /* R0 - software reset */ | ||
| 791 | [0x0001] = 0x0000, /* R1 - Device Revision */ | ||
| 792 | [0x0010] = 0x0801, /* R16 - Ctrl IF 1 */ | ||
| 793 | [0x0020] = 0x0000, /* R32 - Tone Generator 1 */ | ||
| 794 | [0x0030] = 0x0000, /* R48 - PWM Drive 1 */ | ||
| 795 | [0x0031] = 0x0100, /* R49 - PWM Drive 2 */ | ||
| 796 | [0x0032] = 0x0100, /* R50 - PWM Drive 3 */ | ||
| 797 | [0x0100] = 0x0002, /* R256 - Clocking 1 */ | ||
| 798 | [0x0101] = 0x0000, /* R257 - Clocking 3 */ | ||
| 799 | [0x0102] = 0x0011, /* R258 - Clocking 4 */ | ||
| 800 | [0x0103] = 0x0011, /* R259 - Clocking 5 */ | ||
| 801 | [0x0104] = 0x0011, /* R260 - Clocking 6 */ | ||
| 802 | [0x0107] = 0x0000, /* R263 - Clocking 7 */ | ||
| 803 | [0x0108] = 0x0000, /* R264 - Clocking 8 */ | ||
| 804 | [0x0120] = 0x0000, /* R288 - ASRC_ENABLE */ | ||
| 805 | [0x0121] = 0x0000, /* R289 - ASRC_STATUS */ | ||
| 806 | [0x0122] = 0x0000, /* R290 - ASRC_RATE1 */ | ||
| 807 | [0x0141] = 0x8000, /* R321 - ISRC 1 CTRL 1 */ | ||
| 808 | [0x0142] = 0x0000, /* R322 - ISRC 1 CTRL 2 */ | ||
| 809 | [0x0143] = 0x8000, /* R323 - ISRC 2 CTRL1 */ | ||
| 810 | [0x0144] = 0x0000, /* R324 - ISRC 2 CTRL 2 */ | ||
| 811 | [0x0182] = 0x0000, /* R386 - FLL1 Control 1 */ | ||
| 812 | [0x0183] = 0x0000, /* R387 - FLL1 Control 2 */ | ||
| 813 | [0x0184] = 0x0000, /* R388 - FLL1 Control 3 */ | ||
| 814 | [0x0186] = 0x0177, /* R390 - FLL1 Control 5 */ | ||
| 815 | [0x0187] = 0x0001, /* R391 - FLL1 Control 6 */ | ||
| 816 | [0x0188] = 0x0000, /* R392 - FLL1 EFS 1 */ | ||
| 817 | [0x01A2] = 0x0000, /* R418 - FLL2 Control 1 */ | ||
| 818 | [0x01A3] = 0x0000, /* R419 - FLL2 Control 2 */ | ||
| 819 | [0x01A4] = 0x0000, /* R420 - FLL2 Control 3 */ | ||
| 820 | [0x01A6] = 0x0177, /* R422 - FLL2 Control 5 */ | ||
| 821 | [0x01A7] = 0x0001, /* R423 - FLL2 Control 6 */ | ||
| 822 | [0x01A8] = 0x0000, /* R424 - FLL2 EFS 1 */ | ||
| 823 | [0x0200] = 0x0020, /* R512 - Mic Charge Pump 1 */ | ||
| 824 | [0x0201] = 0xB084, /* R513 - Mic Charge Pump 2 */ | ||
| 825 | [0x0202] = 0xBBDE, /* R514 - HP Charge Pump 1 */ | ||
| 826 | [0x0211] = 0x20D4, /* R529 - LDO1 Control */ | ||
| 827 | [0x0215] = 0x0062, /* R533 - Mic Bias Ctrl 1 */ | ||
| 828 | [0x0216] = 0x0062, /* R534 - Mic Bias Ctrl 2 */ | ||
| 829 | [0x0217] = 0x0062, /* R535 - Mic Bias Ctrl 3 */ | ||
| 830 | [0x0280] = 0x0004, /* R640 - Accessory Detect Mode 1 */ | ||
| 831 | [0x0288] = 0x0020, /* R648 - Headphone Detect 1 */ | ||
| 832 | [0x0289] = 0x0000, /* R649 - Headphone Detect 2 */ | ||
| 833 | [0x0290] = 0x1100, /* R656 - Mic Detect 1 */ | ||
| 834 | [0x0291] = 0x009F, /* R657 - Mic Detect 2 */ | ||
| 835 | [0x0292] = 0x0000, /* R658 - Mic Detect 3 */ | ||
| 836 | [0x0301] = 0x0000, /* R769 - Input Enables */ | ||
| 837 | [0x0302] = 0x0000, /* R770 - Input Enables Status */ | ||
| 838 | [0x0310] = 0x2280, /* R784 - Status */ | ||
| 839 | [0x0311] = 0x0080, /* R785 - IN1R Control */ | ||
| 840 | [0x0312] = 0x2280, /* R786 - IN2L Control */ | ||
| 841 | [0x0313] = 0x0080, /* R787 - IN2R Control */ | ||
| 842 | [0x0314] = 0x2280, /* R788 - IN3L Control */ | ||
| 843 | [0x0315] = 0x0080, /* R789 - IN3R Control */ | ||
| 844 | [0x0316] = 0x2280, /* R790 - IN4L Control */ | ||
| 845 | [0x0317] = 0x0080, /* R791 - IN4R Control */ | ||
| 846 | [0x0318] = 0x0000, /* R792 - RXANC_SRC */ | ||
| 847 | [0x0319] = 0x0022, /* R793 - Input Volume Ramp */ | ||
| 848 | [0x0320] = 0x0180, /* R800 - ADC Digital Volume 1L */ | ||
| 849 | [0x0321] = 0x0180, /* R801 - ADC Digital Volume 1R */ | ||
| 850 | [0x0322] = 0x0180, /* R802 - ADC Digital Volume 2L */ | ||
| 851 | [0x0323] = 0x0180, /* R803 - ADC Digital Volume 2R */ | ||
| 852 | [0x0324] = 0x0180, /* R804 - ADC Digital Volume 3L */ | ||
| 853 | [0x0325] = 0x0180, /* R805 - ADC Digital Volume 3R */ | ||
| 854 | [0x0326] = 0x0180, /* R806 - ADC Digital Volume 4L */ | ||
| 855 | [0x0327] = 0x0180, /* R807 - ADC Digital Volume 4R */ | ||
| 856 | [0x0401] = 0x0000, /* R1025 - Output Enables 2 */ | ||
| 857 | [0x0402] = 0x0000, /* R1026 - Output Status 1 */ | ||
| 858 | [0x0403] = 0x0000, /* R1027 - Output Status 2 */ | ||
| 859 | [0x0408] = 0x0000, /* R1032 - Channel Enables 1 */ | ||
| 860 | [0x0410] = 0x0080, /* R1040 - Out Volume 1L */ | ||
| 861 | [0x0411] = 0x0080, /* R1041 - Out Volume 1R */ | ||
| 862 | [0x0412] = 0x0080, /* R1042 - DAC Volume Limit 1L */ | ||
| 863 | [0x0413] = 0x0080, /* R1043 - DAC Volume Limit 1R */ | ||
| 864 | [0x0414] = 0x0080, /* R1044 - Out Volume 2L */ | ||
| 865 | [0x0415] = 0x0080, /* R1045 - Out Volume 2R */ | ||
| 866 | [0x0416] = 0x0080, /* R1046 - DAC Volume Limit 2L */ | ||
| 867 | [0x0417] = 0x0080, /* R1047 - DAC Volume Limit 2R */ | ||
| 868 | [0x0418] = 0x0080, /* R1048 - Out Volume 3L */ | ||
| 869 | [0x0419] = 0x0080, /* R1049 - Out Volume 3R */ | ||
| 870 | [0x041A] = 0x0080, /* R1050 - DAC Volume Limit 3L */ | ||
| 871 | [0x041B] = 0x0080, /* R1051 - DAC Volume Limit 3R */ | ||
| 872 | [0x041C] = 0x0080, /* R1052 - Out Volume 4L */ | ||
| 873 | [0x041D] = 0x0080, /* R1053 - Out Volume 4R */ | ||
| 874 | [0x041E] = 0x0080, /* R1054 - DAC Volume Limit 5L */ | ||
| 875 | [0x041F] = 0x0080, /* R1055 - DAC Volume Limit 5R */ | ||
| 876 | [0x0420] = 0x0080, /* R1056 - DAC Volume Limit 6L */ | ||
| 877 | [0x0421] = 0x0080, /* R1057 - DAC Volume Limit 6R */ | ||
| 878 | [0x0440] = 0x0000, /* R1088 - DAC AEC Control 1 */ | ||
| 879 | [0x0441] = 0x0022, /* R1089 - Output Volume Ramp */ | ||
| 880 | [0x0480] = 0x0180, /* R1152 - DAC Digital Volume 1L */ | ||
| 881 | [0x0481] = 0x0180, /* R1153 - DAC Digital Volume 1R */ | ||
| 882 | [0x0482] = 0x0180, /* R1154 - DAC Digital Volume 2L */ | ||
| 883 | [0x0483] = 0x0180, /* R1155 - DAC Digital Volume 2R */ | ||
| 884 | [0x0484] = 0x0180, /* R1156 - DAC Digital Volume 3L */ | ||
| 885 | [0x0485] = 0x0180, /* R1157 - DAC Digital Volume 3R */ | ||
| 886 | [0x0486] = 0x0180, /* R1158 - DAC Digital Volume 4L */ | ||
| 887 | [0x0487] = 0x0180, /* R1159 - DAC Digital Volume 4R */ | ||
| 888 | [0x0488] = 0x0180, /* R1160 - DAC Digital Volume 5L */ | ||
| 889 | [0x0489] = 0x0180, /* R1161 - DAC Digital Volume 5R */ | ||
| 890 | [0x048A] = 0x0180, /* R1162 - DAC Digital Volume 6L */ | ||
| 891 | [0x048B] = 0x0180, /* R1163 - DAC Digital Volume 6R */ | ||
| 892 | [0x04C0] = 0x0069, /* R1216 - PDM SPK1 CTRL 1 */ | ||
| 893 | [0x04C1] = 0x0000, /* R1217 - PDM SPK1 CTRL 2 */ | ||
| 894 | [0x04C2] = 0x0069, /* R1218 - PDM SPK2 CTRL 1 */ | ||
| 895 | [0x04C3] = 0x0000, /* R1219 - PDM SPK2 CTRL 2 */ | ||
| 896 | [0x0500] = 0x000C, /* R1280 - Audio IF 1_1 */ | ||
| 897 | [0x0501] = 0x0008, /* R1281 - Audio IF 1_2 */ | ||
| 898 | [0x0502] = 0x0000, /* R1282 - Audio IF 1_3 */ | ||
| 899 | [0x0503] = 0x0000, /* R1283 - Audio IF 1_4 */ | ||
| 900 | [0x0504] = 0x0000, /* R1284 - Audio IF 1_5 */ | ||
| 901 | [0x0505] = 0x0300, /* R1285 - Audio IF 1_6 */ | ||
| 902 | [0x0506] = 0x0300, /* R1286 - Audio IF 1_7 */ | ||
| 903 | [0x0507] = 0x1820, /* R1287 - Audio IF 1_8 */ | ||
| 904 | [0x0508] = 0x1820, /* R1288 - Audio IF 1_9 */ | ||
| 905 | [0x0509] = 0x0000, /* R1289 - Audio IF 1_10 */ | ||
| 906 | [0x050A] = 0x0001, /* R1290 - Audio IF 1_11 */ | ||
| 907 | [0x050B] = 0x0002, /* R1291 - Audio IF 1_12 */ | ||
| 908 | [0x050C] = 0x0003, /* R1292 - Audio IF 1_13 */ | ||
| 909 | [0x050D] = 0x0004, /* R1293 - Audio IF 1_14 */ | ||
| 910 | [0x050E] = 0x0005, /* R1294 - Audio IF 1_15 */ | ||
| 911 | [0x050F] = 0x0006, /* R1295 - Audio IF 1_16 */ | ||
| 912 | [0x0510] = 0x0007, /* R1296 - Audio IF 1_17 */ | ||
| 913 | [0x0511] = 0x0000, /* R1297 - Audio IF 1_18 */ | ||
| 914 | [0x0512] = 0x0001, /* R1298 - Audio IF 1_19 */ | ||
| 915 | [0x0513] = 0x0002, /* R1299 - Audio IF 1_20 */ | ||
| 916 | [0x0514] = 0x0003, /* R1300 - Audio IF 1_21 */ | ||
| 917 | [0x0515] = 0x0004, /* R1301 - Audio IF 1_22 */ | ||
| 918 | [0x0516] = 0x0005, /* R1302 - Audio IF 1_23 */ | ||
| 919 | [0x0517] = 0x0006, /* R1303 - Audio IF 1_24 */ | ||
| 920 | [0x0518] = 0x0007, /* R1304 - Audio IF 1_25 */ | ||
| 921 | [0x0519] = 0x0000, /* R1305 - Audio IF 1_26 */ | ||
| 922 | [0x051A] = 0x0000, /* R1306 - Audio IF 1_27 */ | ||
| 923 | [0x0540] = 0x000C, /* R1344 - Audio IF 2_1 */ | ||
| 924 | [0x0541] = 0x0008, /* R1345 - Audio IF 2_2 */ | ||
| 925 | [0x0542] = 0x0000, /* R1346 - Audio IF 2_3 */ | ||
| 926 | [0x0543] = 0x0000, /* R1347 - Audio IF 2_4 */ | ||
| 927 | [0x0544] = 0x0000, /* R1348 - Audio IF 2_5 */ | ||
| 928 | [0x0545] = 0x0300, /* R1349 - Audio IF 2_6 */ | ||
| 929 | [0x0546] = 0x0300, /* R1350 - Audio IF 2_7 */ | ||
| 930 | [0x0547] = 0x1820, /* R1351 - Audio IF 2_8 */ | ||
| 931 | [0x0548] = 0x1820, /* R1352 - Audio IF 2_9 */ | ||
| 932 | [0x0549] = 0x0000, /* R1353 - Audio IF 2_10 */ | ||
| 933 | [0x054A] = 0x0001, /* R1354 - Audio IF 2_11 */ | ||
| 934 | [0x0551] = 0x0000, /* R1361 - Audio IF 2_18 */ | ||
| 935 | [0x0552] = 0x0001, /* R1362 - Audio IF 2_19 */ | ||
| 936 | [0x0559] = 0x0000, /* R1369 - Audio IF 2_26 */ | ||
| 937 | [0x055A] = 0x0000, /* R1370 - Audio IF 2_27 */ | ||
| 938 | [0x0580] = 0x000C, /* R1408 - Audio IF 3_1 */ | ||
| 939 | [0x0581] = 0x0008, /* R1409 - Audio IF 3_2 */ | ||
| 940 | [0x0582] = 0x0000, /* R1410 - Audio IF 3_3 */ | ||
| 941 | [0x0583] = 0x0000, /* R1411 - Audio IF 3_4 */ | ||
| 942 | [0x0584] = 0x0000, /* R1412 - Audio IF 3_5 */ | ||
| 943 | [0x0585] = 0x0300, /* R1413 - Audio IF 3_6 */ | ||
| 944 | [0x0586] = 0x0300, /* R1414 - Audio IF 3_7 */ | ||
| 945 | [0x0587] = 0x1820, /* R1415 - Audio IF 3_8 */ | ||
| 946 | [0x0588] = 0x1820, /* R1416 - Audio IF 3_9 */ | ||
| 947 | [0x0589] = 0x0000, /* R1417 - Audio IF 3_10 */ | ||
| 948 | [0x058A] = 0x0001, /* R1418 - Audio IF 3_11 */ | ||
| 949 | [0x0591] = 0x0000, /* R1425 - Audio IF 3_18 */ | ||
| 950 | [0x0592] = 0x0001, /* R1426 - Audio IF 3_19 */ | ||
| 951 | [0x0599] = 0x0000, /* R1433 - Audio IF 3_26 */ | ||
| 952 | [0x059A] = 0x0000, /* R1434 - Audio IF 3_27 */ | ||
| 953 | [0x0640] = 0x0000, /* R1600 - PWM1MIX Input 1 Source */ | ||
| 954 | [0x0641] = 0x0080, /* R1601 - PWM1MIX Input 1 Volume */ | ||
| 955 | [0x0642] = 0x0000, /* R1602 - PWM1MIX Input 2 Source */ | ||
| 956 | [0x0643] = 0x0080, /* R1603 - PWM1MIX Input 2 Volume */ | ||
| 957 | [0x0644] = 0x0000, /* R1604 - PWM1MIX Input 3 Source */ | ||
| 958 | [0x0645] = 0x0080, /* R1605 - PWM1MIX Input 3 Volume */ | ||
| 959 | [0x0646] = 0x0000, /* R1606 - PWM1MIX Input 4 Source */ | ||
| 960 | [0x0647] = 0x0080, /* R1607 - PWM1MIX Input 4 Volume */ | ||
| 961 | [0x0648] = 0x0000, /* R1608 - PWM2MIX Input 1 Source */ | ||
| 962 | [0x0649] = 0x0080, /* R1609 - PWM2MIX Input 1 Volume */ | ||
| 963 | [0x064A] = 0x0000, /* R1610 - PWM2MIX Input 2 Source */ | ||
| 964 | [0x064B] = 0x0080, /* R1611 - PWM2MIX Input 2 Volume */ | ||
| 965 | [0x064C] = 0x0000, /* R1612 - PWM2MIX Input 3 Source */ | ||
| 966 | [0x064D] = 0x0080, /* R1613 - PWM2MIX Input 3 Volume */ | ||
| 967 | [0x064E] = 0x0000, /* R1614 - PWM2MIX Input 4 Source */ | ||
| 968 | [0x064F] = 0x0080, /* R1615 - PWM2MIX Input 4 Volume */ | ||
| 969 | [0x0680] = 0x0000, /* R1664 - OUT1LMIX Input 1 Source */ | ||
| 970 | [0x0681] = 0x0080, /* R1665 - OUT1LMIX Input 1 Volume */ | ||
| 971 | [0x0682] = 0x0000, /* R1666 - OUT1LMIX Input 2 Source */ | ||
| 972 | [0x0683] = 0x0080, /* R1667 - OUT1LMIX Input 2 Volume */ | ||
| 973 | [0x0684] = 0x0000, /* R1668 - OUT1LMIX Input 3 Source */ | ||
| 974 | [0x0685] = 0x0080, /* R1669 - OUT1LMIX Input 3 Volume */ | ||
| 975 | [0x0686] = 0x0000, /* R1670 - OUT1LMIX Input 4 Source */ | ||
| 976 | [0x0687] = 0x0080, /* R1671 - OUT1LMIX Input 4 Volume */ | ||
| 977 | [0x0688] = 0x0000, /* R1672 - OUT1RMIX Input 1 Source */ | ||
| 978 | [0x0689] = 0x0080, /* R1673 - OUT1RMIX Input 1 Volume */ | ||
| 979 | [0x068A] = 0x0000, /* R1674 - OUT1RMIX Input 2 Source */ | ||
| 980 | [0x068B] = 0x0080, /* R1675 - OUT1RMIX Input 2 Volume */ | ||
| 981 | [0x068C] = 0x0000, /* R1676 - OUT1RMIX Input 3 Source */ | ||
| 982 | [0x068D] = 0x0080, /* R1677 - OUT1RMIX Input 3 Volume */ | ||
| 983 | [0x068E] = 0x0000, /* R1678 - OUT1RMIX Input 4 Source */ | ||
| 984 | [0x068F] = 0x0080, /* R1679 - OUT1RMIX Input 4 Volume */ | ||
| 985 | [0x0690] = 0x0000, /* R1680 - OUT2LMIX Input 1 Source */ | ||
| 986 | [0x0691] = 0x0080, /* R1681 - OUT2LMIX Input 1 Volume */ | ||
| 987 | [0x0692] = 0x0000, /* R1682 - OUT2LMIX Input 2 Source */ | ||
| 988 | [0x0693] = 0x0080, /* R1683 - OUT2LMIX Input 2 Volume */ | ||
| 989 | [0x0694] = 0x0000, /* R1684 - OUT2LMIX Input 3 Source */ | ||
| 990 | [0x0695] = 0x0080, /* R1685 - OUT2LMIX Input 3 Volume */ | ||
| 991 | [0x0696] = 0x0000, /* R1686 - OUT2LMIX Input 4 Source */ | ||
| 992 | [0x0697] = 0x0080, /* R1687 - OUT2LMIX Input 4 Volume */ | ||
| 993 | [0x0698] = 0x0000, /* R1688 - OUT2RMIX Input 1 Source */ | ||
| 994 | [0x0699] = 0x0080, /* R1689 - OUT2RMIX Input 1 Volume */ | ||
| 995 | [0x069A] = 0x0000, /* R1690 - OUT2RMIX Input 2 Source */ | ||
| 996 | [0x069B] = 0x0080, /* R1691 - OUT2RMIX Input 2 Volume */ | ||
| 997 | [0x069C] = 0x0000, /* R1692 - OUT2RMIX Input 3 Source */ | ||
| 998 | [0x069D] = 0x0080, /* R1693 - OUT2RMIX Input 3 Volume */ | ||
| 999 | [0x069E] = 0x0000, /* R1694 - OUT2RMIX Input 4 Source */ | ||
| 1000 | [0x069F] = 0x0080, /* R1695 - OUT2RMIX Input 4 Volume */ | ||
| 1001 | [0x06A0] = 0x0000, /* R1696 - OUT3LMIX Input 1 Source */ | ||
| 1002 | [0x06A1] = 0x0080, /* R1697 - OUT3LMIX Input 1 Volume */ | ||
| 1003 | [0x06A2] = 0x0000, /* R1698 - OUT3LMIX Input 2 Source */ | ||
| 1004 | [0x06A3] = 0x0080, /* R1699 - OUT3LMIX Input 2 Volume */ | ||
| 1005 | [0x06A4] = 0x0000, /* R1700 - OUT3LMIX Input 3 Source */ | ||
| 1006 | [0x06A5] = 0x0080, /* R1701 - OUT3LMIX Input 3 Volume */ | ||
| 1007 | [0x06A6] = 0x0000, /* R1702 - OUT3LMIX Input 4 Source */ | ||
| 1008 | [0x06A7] = 0x0080, /* R1703 - OUT3LMIX Input 4 Volume */ | ||
| 1009 | [0x06A8] = 0x0000, /* R1704 - OUT3RMIX Input 1 Source */ | ||
| 1010 | [0x06A9] = 0x0080, /* R1705 - OUT3RMIX Input 1 Volume */ | ||
| 1011 | [0x06AA] = 0x0000, /* R1706 - OUT3RMIX Input 2 Source */ | ||
| 1012 | [0x06AB] = 0x0080, /* R1707 - OUT3RMIX Input 2 Volume */ | ||
| 1013 | [0x06AC] = 0x0000, /* R1708 - OUT3RMIX Input 3 Source */ | ||
| 1014 | [0x06AD] = 0x0080, /* R1709 - OUT3RMIX Input 3 Volume */ | ||
| 1015 | [0x06AE] = 0x0000, /* R1710 - OUT3RMIX Input 4 Source */ | ||
| 1016 | [0x06AF] = 0x0080, /* R1711 - OUT3RMIX Input 4 Volume */ | ||
| 1017 | [0x06B0] = 0x0000, /* R1712 - OUT4LMIX Input 1 Source */ | ||
| 1018 | [0x06B1] = 0x0080, /* R1713 - OUT4LMIX Input 1 Volume */ | ||
| 1019 | [0x06B2] = 0x0000, /* R1714 - OUT4LMIX Input 2 Source */ | ||
| 1020 | [0x06B3] = 0x0080, /* R1715 - OUT4LMIX Input 2 Volume */ | ||
| 1021 | [0x06B4] = 0x0000, /* R1716 - OUT4LMIX Input 3 Source */ | ||
| 1022 | [0x06B5] = 0x0080, /* R1717 - OUT4LMIX Input 3 Volume */ | ||
| 1023 | [0x06B6] = 0x0000, /* R1718 - OUT4LMIX Input 4 Source */ | ||
| 1024 | [0x06B7] = 0x0080, /* R1719 - OUT4LMIX Input 4 Volume */ | ||
| 1025 | [0x06B8] = 0x0000, /* R1720 - OUT4RMIX Input 1 Source */ | ||
| 1026 | [0x06B9] = 0x0080, /* R1721 - OUT4RMIX Input 1 Volume */ | ||
| 1027 | [0x06BA] = 0x0000, /* R1722 - OUT4RMIX Input 2 Source */ | ||
| 1028 | [0x06BB] = 0x0080, /* R1723 - OUT4RMIX Input 2 Volume */ | ||
| 1029 | [0x06BC] = 0x0000, /* R1724 - OUT4RMIX Input 3 Source */ | ||
| 1030 | [0x06BD] = 0x0080, /* R1725 - OUT4RMIX Input 3 Volume */ | ||
| 1031 | [0x06BE] = 0x0000, /* R1726 - OUT4RMIX Input 4 Source */ | ||
| 1032 | [0x06BF] = 0x0080, /* R1727 - OUT4RMIX Input 4 Volume */ | ||
| 1033 | [0x06C0] = 0x0000, /* R1728 - OUT5LMIX Input 1 Source */ | ||
| 1034 | [0x06C1] = 0x0080, /* R1729 - OUT5LMIX Input 1 Volume */ | ||
| 1035 | [0x06C2] = 0x0000, /* R1730 - OUT5LMIX Input 2 Source */ | ||
| 1036 | [0x06C3] = 0x0080, /* R1731 - OUT5LMIX Input 2 Volume */ | ||
| 1037 | [0x06C4] = 0x0000, /* R1732 - OUT5LMIX Input 3 Source */ | ||
| 1038 | [0x06C5] = 0x0080, /* R1733 - OUT5LMIX Input 3 Volume */ | ||
| 1039 | [0x06C6] = 0x0000, /* R1734 - OUT5LMIX Input 4 Source */ | ||
| 1040 | [0x06C7] = 0x0080, /* R1735 - OUT5LMIX Input 4 Volume */ | ||
| 1041 | [0x06C8] = 0x0000, /* R1736 - OUT5RMIX Input 1 Source */ | ||
| 1042 | [0x06C9] = 0x0080, /* R1737 - OUT5RMIX Input 1 Volume */ | ||
| 1043 | [0x06CA] = 0x0000, /* R1738 - OUT5RMIX Input 2 Source */ | ||
| 1044 | [0x06CB] = 0x0080, /* R1739 - OUT5RMIX Input 2 Volume */ | ||
| 1045 | [0x06CC] = 0x0000, /* R1740 - OUT5RMIX Input 3 Source */ | ||
| 1046 | [0x06CD] = 0x0080, /* R1741 - OUT5RMIX Input 3 Volume */ | ||
| 1047 | [0x06CE] = 0x0000, /* R1742 - OUT5RMIX Input 4 Source */ | ||
| 1048 | [0x06CF] = 0x0080, /* R1743 - OUT5RMIX Input 4 Volume */ | ||
| 1049 | [0x06D0] = 0x0000, /* R1744 - OUT6LMIX Input 1 Source */ | ||
| 1050 | [0x06D1] = 0x0080, /* R1745 - OUT6LMIX Input 1 Volume */ | ||
| 1051 | [0x06D2] = 0x0000, /* R1746 - OUT6LMIX Input 2 Source */ | ||
| 1052 | [0x06D3] = 0x0080, /* R1747 - OUT6LMIX Input 2 Volume */ | ||
| 1053 | [0x06D4] = 0x0000, /* R1748 - OUT6LMIX Input 3 Source */ | ||
| 1054 | [0x06D5] = 0x0080, /* R1749 - OUT6LMIX Input 3 Volume */ | ||
| 1055 | [0x06D6] = 0x0000, /* R1750 - OUT6LMIX Input 4 Source */ | ||
| 1056 | [0x06D7] = 0x0080, /* R1751 - OUT6LMIX Input 4 Volume */ | ||
| 1057 | [0x06D8] = 0x0000, /* R1752 - OUT6RMIX Input 1 Source */ | ||
| 1058 | [0x06D9] = 0x0080, /* R1753 - OUT6RMIX Input 1 Volume */ | ||
| 1059 | [0x06DA] = 0x0000, /* R1754 - OUT6RMIX Input 2 Source */ | ||
| 1060 | [0x06DB] = 0x0080, /* R1755 - OUT6RMIX Input 2 Volume */ | ||
| 1061 | [0x06DC] = 0x0000, /* R1756 - OUT6RMIX Input 3 Source */ | ||
| 1062 | [0x06DD] = 0x0080, /* R1757 - OUT6RMIX Input 3 Volume */ | ||
| 1063 | [0x06DE] = 0x0000, /* R1758 - OUT6RMIX Input 4 Source */ | ||
| 1064 | [0x06DF] = 0x0080, /* R1759 - OUT6RMIX Input 4 Volume */ | ||
| 1065 | [0x0700] = 0x0000, /* R1792 - AIF1TX1MIX Input 1 Source */ | ||
| 1066 | [0x0701] = 0x0080, /* R1793 - AIF1TX1MIX Input 1 Volume */ | ||
| 1067 | [0x0702] = 0x0000, /* R1794 - AIF1TX1MIX Input 2 Source */ | ||
| 1068 | [0x0703] = 0x0080, /* R1795 - AIF1TX1MIX Input 2 Volume */ | ||
| 1069 | [0x0704] = 0x0000, /* R1796 - AIF1TX1MIX Input 3 Source */ | ||
| 1070 | [0x0705] = 0x0080, /* R1797 - AIF1TX1MIX Input 3 Volume */ | ||
| 1071 | [0x0706] = 0x0000, /* R1798 - AIF1TX1MIX Input 4 Source */ | ||
| 1072 | [0x0707] = 0x0080, /* R1799 - AIF1TX1MIX Input 4 Volume */ | ||
| 1073 | [0x0708] = 0x0000, /* R1800 - AIF1TX2MIX Input 1 Source */ | ||
| 1074 | [0x0709] = 0x0080, /* R1801 - AIF1TX2MIX Input 1 Volume */ | ||
| 1075 | [0x070A] = 0x0000, /* R1802 - AIF1TX2MIX Input 2 Source */ | ||
| 1076 | [0x070B] = 0x0080, /* R1803 - AIF1TX2MIX Input 2 Volume */ | ||
| 1077 | [0x070C] = 0x0000, /* R1804 - AIF1TX2MIX Input 3 Source */ | ||
| 1078 | [0x070D] = 0x0080, /* R1805 - AIF1TX2MIX Input 3 Volume */ | ||
| 1079 | [0x070E] = 0x0000, /* R1806 - AIF1TX2MIX Input 4 Source */ | ||
| 1080 | [0x070F] = 0x0080, /* R1807 - AIF1TX2MIX Input 4 Volume */ | ||
| 1081 | [0x0710] = 0x0000, /* R1808 - AIF1TX3MIX Input 1 Source */ | ||
| 1082 | [0x0711] = 0x0080, /* R1809 - AIF1TX3MIX Input 1 Volume */ | ||
| 1083 | [0x0712] = 0x0000, /* R1810 - AIF1TX3MIX Input 2 Source */ | ||
| 1084 | [0x0713] = 0x0080, /* R1811 - AIF1TX3MIX Input 2 Volume */ | ||
| 1085 | [0x0714] = 0x0000, /* R1812 - AIF1TX3MIX Input 3 Source */ | ||
| 1086 | [0x0715] = 0x0080, /* R1813 - AIF1TX3MIX Input 3 Volume */ | ||
| 1087 | [0x0716] = 0x0000, /* R1814 - AIF1TX3MIX Input 4 Source */ | ||
| 1088 | [0x0717] = 0x0080, /* R1815 - AIF1TX3MIX Input 4 Volume */ | ||
| 1089 | [0x0718] = 0x0000, /* R1816 - AIF1TX4MIX Input 1 Source */ | ||
| 1090 | [0x0719] = 0x0080, /* R1817 - AIF1TX4MIX Input 1 Volume */ | ||
| 1091 | [0x071A] = 0x0000, /* R1818 - AIF1TX4MIX Input 2 Source */ | ||
| 1092 | [0x071B] = 0x0080, /* R1819 - AIF1TX4MIX Input 2 Volume */ | ||
| 1093 | [0x071C] = 0x0000, /* R1820 - AIF1TX4MIX Input 3 Source */ | ||
| 1094 | [0x071D] = 0x0080, /* R1821 - AIF1TX4MIX Input 3 Volume */ | ||
| 1095 | [0x071E] = 0x0000, /* R1822 - AIF1TX4MIX Input 4 Source */ | ||
| 1096 | [0x071F] = 0x0080, /* R1823 - AIF1TX4MIX Input 4 Volume */ | ||
| 1097 | [0x0720] = 0x0000, /* R1824 - AIF1TX5MIX Input 1 Source */ | ||
| 1098 | [0x0721] = 0x0080, /* R1825 - AIF1TX5MIX Input 1 Volume */ | ||
| 1099 | [0x0722] = 0x0000, /* R1826 - AIF1TX5MIX Input 2 Source */ | ||
| 1100 | [0x0723] = 0x0080, /* R1827 - AIF1TX5MIX Input 2 Volume */ | ||
| 1101 | [0x0724] = 0x0000, /* R1828 - AIF1TX5MIX Input 3 Source */ | ||
| 1102 | [0x0725] = 0x0080, /* R1829 - AIF1TX5MIX Input 3 Volume */ | ||
| 1103 | [0x0726] = 0x0000, /* R1830 - AIF1TX5MIX Input 4 Source */ | ||
| 1104 | [0x0727] = 0x0080, /* R1831 - AIF1TX5MIX Input 4 Volume */ | ||
| 1105 | [0x0728] = 0x0000, /* R1832 - AIF1TX6MIX Input 1 Source */ | ||
| 1106 | [0x0729] = 0x0080, /* R1833 - AIF1TX6MIX Input 1 Volume */ | ||
| 1107 | [0x072A] = 0x0000, /* R1834 - AIF1TX6MIX Input 2 Source */ | ||
| 1108 | [0x072B] = 0x0080, /* R1835 - AIF1TX6MIX Input 2 Volume */ | ||
| 1109 | [0x072C] = 0x0000, /* R1836 - AIF1TX6MIX Input 3 Source */ | ||
| 1110 | [0x072D] = 0x0080, /* R1837 - AIF1TX6MIX Input 3 Volume */ | ||
| 1111 | [0x072E] = 0x0000, /* R1838 - AIF1TX6MIX Input 4 Source */ | ||
| 1112 | [0x072F] = 0x0080, /* R1839 - AIF1TX6MIX Input 4 Volume */ | ||
| 1113 | [0x0730] = 0x0000, /* R1840 - AIF1TX7MIX Input 1 Source */ | ||
| 1114 | [0x0731] = 0x0080, /* R1841 - AIF1TX7MIX Input 1 Volume */ | ||
| 1115 | [0x0732] = 0x0000, /* R1842 - AIF1TX7MIX Input 2 Source */ | ||
| 1116 | [0x0733] = 0x0080, /* R1843 - AIF1TX7MIX Input 2 Volume */ | ||
| 1117 | [0x0734] = 0x0000, /* R1844 - AIF1TX7MIX Input 3 Source */ | ||
| 1118 | [0x0735] = 0x0080, /* R1845 - AIF1TX7MIX Input 3 Volume */ | ||
| 1119 | [0x0736] = 0x0000, /* R1846 - AIF1TX7MIX Input 4 Source */ | ||
| 1120 | [0x0737] = 0x0080, /* R1847 - AIF1TX7MIX Input 4 Volume */ | ||
| 1121 | [0x0738] = 0x0000, /* R1848 - AIF1TX8MIX Input 1 Source */ | ||
| 1122 | [0x0739] = 0x0080, /* R1849 - AIF1TX8MIX Input 1 Volume */ | ||
| 1123 | [0x073A] = 0x0000, /* R1850 - AIF1TX8MIX Input 2 Source */ | ||
| 1124 | [0x073B] = 0x0080, /* R1851 - AIF1TX8MIX Input 2 Volume */ | ||
| 1125 | [0x073C] = 0x0000, /* R1852 - AIF1TX8MIX Input 3 Source */ | ||
| 1126 | [0x073D] = 0x0080, /* R1853 - AIF1TX8MIX Input 3 Volume */ | ||
| 1127 | [0x073E] = 0x0000, /* R1854 - AIF1TX8MIX Input 4 Source */ | ||
| 1128 | [0x073F] = 0x0080, /* R1855 - AIF1TX8MIX Input 4 Volume */ | ||
| 1129 | [0x0740] = 0x0000, /* R1856 - AIF2TX1MIX Input 1 Source */ | ||
| 1130 | [0x0741] = 0x0080, /* R1857 - AIF2TX1MIX Input 1 Volume */ | ||
| 1131 | [0x0742] = 0x0000, /* R1858 - AIF2TX1MIX Input 2 Source */ | ||
| 1132 | [0x0743] = 0x0080, /* R1859 - AIF2TX1MIX Input 2 Volume */ | ||
| 1133 | [0x0744] = 0x0000, /* R1860 - AIF2TX1MIX Input 3 Source */ | ||
| 1134 | [0x0745] = 0x0080, /* R1861 - AIF2TX1MIX Input 3 Volume */ | ||
| 1135 | [0x0746] = 0x0000, /* R1862 - AIF2TX1MIX Input 4 Source */ | ||
| 1136 | [0x0747] = 0x0080, /* R1863 - AIF2TX1MIX Input 4 Volume */ | ||
| 1137 | [0x0748] = 0x0000, /* R1864 - AIF2TX2MIX Input 1 Source */ | ||
| 1138 | [0x0749] = 0x0080, /* R1865 - AIF2TX2MIX Input 1 Volume */ | ||
| 1139 | [0x074A] = 0x0000, /* R1866 - AIF2TX2MIX Input 2 Source */ | ||
| 1140 | [0x074B] = 0x0080, /* R1867 - AIF2TX2MIX Input 2 Volume */ | ||
| 1141 | [0x074C] = 0x0000, /* R1868 - AIF2TX2MIX Input 3 Source */ | ||
| 1142 | [0x074D] = 0x0080, /* R1869 - AIF2TX2MIX Input 3 Volume */ | ||
| 1143 | [0x074E] = 0x0000, /* R1870 - AIF2TX2MIX Input 4 Source */ | ||
| 1144 | [0x074F] = 0x0080, /* R1871 - AIF2TX2MIX Input 4 Volume */ | ||
| 1145 | [0x0780] = 0x0000, /* R1920 - AIF3TX1MIX Input 1 Source */ | ||
| 1146 | [0x0781] = 0x0080, /* R1921 - AIF3TX1MIX Input 1 Volume */ | ||
| 1147 | [0x0782] = 0x0000, /* R1922 - AIF3TX1MIX Input 2 Source */ | ||
| 1148 | [0x0783] = 0x0080, /* R1923 - AIF3TX1MIX Input 2 Volume */ | ||
| 1149 | [0x0784] = 0x0000, /* R1924 - AIF3TX1MIX Input 3 Source */ | ||
| 1150 | [0x0785] = 0x0080, /* R1925 - AIF3TX1MIX Input 3 Volume */ | ||
| 1151 | [0x0786] = 0x0000, /* R1926 - AIF3TX1MIX Input 4 Source */ | ||
| 1152 | [0x0787] = 0x0080, /* R1927 - AIF3TX1MIX Input 4 Volume */ | ||
| 1153 | [0x0788] = 0x0000, /* R1928 - AIF3TX2MIX Input 1 Source */ | ||
| 1154 | [0x0789] = 0x0080, /* R1929 - AIF3TX2MIX Input 1 Volume */ | ||
| 1155 | [0x078A] = 0x0000, /* R1930 - AIF3TX2MIX Input 2 Source */ | ||
| 1156 | [0x078B] = 0x0080, /* R1931 - AIF3TX2MIX Input 2 Volume */ | ||
| 1157 | [0x078C] = 0x0000, /* R1932 - AIF3TX2MIX Input 3 Source */ | ||
| 1158 | [0x078D] = 0x0080, /* R1933 - AIF3TX2MIX Input 3 Volume */ | ||
| 1159 | [0x078E] = 0x0000, /* R1934 - AIF3TX2MIX Input 4 Source */ | ||
| 1160 | [0x078F] = 0x0080, /* R1935 - AIF3TX2MIX Input 4 Volume */ | ||
| 1161 | [0x0880] = 0x0000, /* R2176 - EQ1MIX Input 1 Source */ | ||
| 1162 | [0x0881] = 0x0080, /* R2177 - EQ1MIX Input 1 Volume */ | ||
| 1163 | [0x0882] = 0x0000, /* R2178 - EQ1MIX Input 2 Source */ | ||
| 1164 | [0x0883] = 0x0080, /* R2179 - EQ1MIX Input 2 Volume */ | ||
| 1165 | [0x0884] = 0x0000, /* R2180 - EQ1MIX Input 3 Source */ | ||
| 1166 | [0x0885] = 0x0080, /* R2181 - EQ1MIX Input 3 Volume */ | ||
| 1167 | [0x0886] = 0x0000, /* R2182 - EQ1MIX Input 4 Source */ | ||
| 1168 | [0x0887] = 0x0080, /* R2183 - EQ1MIX Input 4 Volume */ | ||
| 1169 | [0x0888] = 0x0000, /* R2184 - EQ2MIX Input 1 Source */ | ||
| 1170 | [0x0889] = 0x0080, /* R2185 - EQ2MIX Input 1 Volume */ | ||
| 1171 | [0x088A] = 0x0000, /* R2186 - EQ2MIX Input 2 Source */ | ||
| 1172 | [0x088B] = 0x0080, /* R2187 - EQ2MIX Input 2 Volume */ | ||
| 1173 | [0x088C] = 0x0000, /* R2188 - EQ2MIX Input 3 Source */ | ||
| 1174 | [0x088D] = 0x0080, /* R2189 - EQ2MIX Input 3 Volume */ | ||
| 1175 | [0x088E] = 0x0000, /* R2190 - EQ2MIX Input 4 Source */ | ||
| 1176 | [0x088F] = 0x0080, /* R2191 - EQ2MIX Input 4 Volume */ | ||
| 1177 | [0x0890] = 0x0000, /* R2192 - EQ3MIX Input 1 Source */ | ||
| 1178 | [0x0891] = 0x0080, /* R2193 - EQ3MIX Input 1 Volume */ | ||
| 1179 | [0x0892] = 0x0000, /* R2194 - EQ3MIX Input 2 Source */ | ||
| 1180 | [0x0893] = 0x0080, /* R2195 - EQ3MIX Input 2 Volume */ | ||
| 1181 | [0x0894] = 0x0000, /* R2196 - EQ3MIX Input 3 Source */ | ||
| 1182 | [0x0895] = 0x0080, /* R2197 - EQ3MIX Input 3 Volume */ | ||
| 1183 | [0x0896] = 0x0000, /* R2198 - EQ3MIX Input 4 Source */ | ||
| 1184 | [0x0897] = 0x0080, /* R2199 - EQ3MIX Input 4 Volume */ | ||
| 1185 | [0x0898] = 0x0000, /* R2200 - EQ4MIX Input 1 Source */ | ||
| 1186 | [0x0899] = 0x0080, /* R2201 - EQ4MIX Input 1 Volume */ | ||
| 1187 | [0x089A] = 0x0000, /* R2202 - EQ4MIX Input 2 Source */ | ||
| 1188 | [0x089B] = 0x0080, /* R2203 - EQ4MIX Input 2 Volume */ | ||
| 1189 | [0x089C] = 0x0000, /* R2204 - EQ4MIX Input 3 Source */ | ||
| 1190 | [0x089D] = 0x0080, /* R2205 - EQ4MIX Input 3 Volume */ | ||
| 1191 | [0x089E] = 0x0000, /* R2206 - EQ4MIX Input 4 Source */ | ||
| 1192 | [0x089F] = 0x0080, /* R2207 - EQ4MIX Input 4 Volume */ | ||
| 1193 | [0x08C0] = 0x0000, /* R2240 - DRC1LMIX Input 1 Source */ | ||
| 1194 | [0x08C1] = 0x0080, /* R2241 - DRC1LMIX Input 1 Volume */ | ||
| 1195 | [0x08C2] = 0x0000, /* R2242 - DRC1LMIX Input 2 Source */ | ||
| 1196 | [0x08C3] = 0x0080, /* R2243 - DRC1LMIX Input 2 Volume */ | ||
| 1197 | [0x08C4] = 0x0000, /* R2244 - DRC1LMIX Input 3 Source */ | ||
| 1198 | [0x08C5] = 0x0080, /* R2245 - DRC1LMIX Input 3 Volume */ | ||
| 1199 | [0x08C6] = 0x0000, /* R2246 - DRC1LMIX Input 4 Source */ | ||
| 1200 | [0x08C7] = 0x0080, /* R2247 - DRC1LMIX Input 4 Volume */ | ||
| 1201 | [0x08C8] = 0x0000, /* R2248 - DRC1RMIX Input 1 Source */ | ||
| 1202 | [0x08C9] = 0x0080, /* R2249 - DRC1RMIX Input 1 Volume */ | ||
| 1203 | [0x08CA] = 0x0000, /* R2250 - DRC1RMIX Input 2 Source */ | ||
| 1204 | [0x08CB] = 0x0080, /* R2251 - DRC1RMIX Input 2 Volume */ | ||
| 1205 | [0x08CC] = 0x0000, /* R2252 - DRC1RMIX Input 3 Source */ | ||
| 1206 | [0x08CD] = 0x0080, /* R2253 - DRC1RMIX Input 3 Volume */ | ||
| 1207 | [0x08CE] = 0x0000, /* R2254 - DRC1RMIX Input 4 Source */ | ||
| 1208 | [0x08CF] = 0x0080, /* R2255 - DRC1RMIX Input 4 Volume */ | ||
| 1209 | [0x0900] = 0x0000, /* R2304 - HPLP1MIX Input 1 Source */ | ||
| 1210 | [0x0901] = 0x0080, /* R2305 - HPLP1MIX Input 1 Volume */ | ||
| 1211 | [0x0902] = 0x0000, /* R2306 - HPLP1MIX Input 2 Source */ | ||
| 1212 | [0x0903] = 0x0080, /* R2307 - HPLP1MIX Input 2 Volume */ | ||
| 1213 | [0x0904] = 0x0000, /* R2308 - HPLP1MIX Input 3 Source */ | ||
| 1214 | [0x0905] = 0x0080, /* R2309 - HPLP1MIX Input 3 Volume */ | ||
| 1215 | [0x0906] = 0x0000, /* R2310 - HPLP1MIX Input 4 Source */ | ||
| 1216 | [0x0907] = 0x0080, /* R2311 - HPLP1MIX Input 4 Volume */ | ||
| 1217 | [0x0908] = 0x0000, /* R2312 - HPLP2MIX Input 1 Source */ | ||
| 1218 | [0x0909] = 0x0080, /* R2313 - HPLP2MIX Input 1 Volume */ | ||
| 1219 | [0x090A] = 0x0000, /* R2314 - HPLP2MIX Input 2 Source */ | ||
| 1220 | [0x090B] = 0x0080, /* R2315 - HPLP2MIX Input 2 Volume */ | ||
| 1221 | [0x090C] = 0x0000, /* R2316 - HPLP2MIX Input 3 Source */ | ||
| 1222 | [0x090D] = 0x0080, /* R2317 - HPLP2MIX Input 3 Volume */ | ||
| 1223 | [0x090E] = 0x0000, /* R2318 - HPLP2MIX Input 4 Source */ | ||
| 1224 | [0x090F] = 0x0080, /* R2319 - HPLP2MIX Input 4 Volume */ | ||
| 1225 | [0x0910] = 0x0000, /* R2320 - HPLP3MIX Input 1 Source */ | ||
| 1226 | [0x0911] = 0x0080, /* R2321 - HPLP3MIX Input 1 Volume */ | ||
| 1227 | [0x0912] = 0x0000, /* R2322 - HPLP3MIX Input 2 Source */ | ||
| 1228 | [0x0913] = 0x0080, /* R2323 - HPLP3MIX Input 2 Volume */ | ||
| 1229 | [0x0914] = 0x0000, /* R2324 - HPLP3MIX Input 3 Source */ | ||
| 1230 | [0x0915] = 0x0080, /* R2325 - HPLP3MIX Input 3 Volume */ | ||
| 1231 | [0x0916] = 0x0000, /* R2326 - HPLP3MIX Input 4 Source */ | ||
| 1232 | [0x0917] = 0x0080, /* R2327 - HPLP3MIX Input 4 Volume */ | ||
| 1233 | [0x0918] = 0x0000, /* R2328 - HPLP4MIX Input 1 Source */ | ||
| 1234 | [0x0919] = 0x0080, /* R2329 - HPLP4MIX Input 1 Volume */ | ||
| 1235 | [0x091A] = 0x0000, /* R2330 - HPLP4MIX Input 2 Source */ | ||
| 1236 | [0x091B] = 0x0080, /* R2331 - HPLP4MIX Input 2 Volume */ | ||
| 1237 | [0x091C] = 0x0000, /* R2332 - HPLP4MIX Input 3 Source */ | ||
| 1238 | [0x091D] = 0x0080, /* R2333 - HPLP4MIX Input 3 Volume */ | ||
| 1239 | [0x091E] = 0x0000, /* R2334 - HPLP4MIX Input 4 Source */ | ||
| 1240 | [0x091F] = 0x0080, /* R2335 - HPLP4MIX Input 4 Volume */ | ||
| 1241 | [0x0940] = 0x0000, /* R2368 - DSP1LMIX Input 1 Source */ | ||
| 1242 | [0x0941] = 0x0080, /* R2369 - DSP1LMIX Input 1 Volume */ | ||
| 1243 | [0x0942] = 0x0000, /* R2370 - DSP1LMIX Input 2 Source */ | ||
| 1244 | [0x0943] = 0x0080, /* R2371 - DSP1LMIX Input 2 Volume */ | ||
| 1245 | [0x0944] = 0x0000, /* R2372 - DSP1LMIX Input 3 Source */ | ||
| 1246 | [0x0945] = 0x0080, /* R2373 - DSP1LMIX Input 3 Volume */ | ||
| 1247 | [0x0946] = 0x0000, /* R2374 - DSP1LMIX Input 4 Source */ | ||
| 1248 | [0x0947] = 0x0080, /* R2375 - DSP1LMIX Input 4 Volume */ | ||
| 1249 | [0x0948] = 0x0000, /* R2376 - DSP1RMIX Input 1 Source */ | ||
| 1250 | [0x0949] = 0x0080, /* R2377 - DSP1RMIX Input 1 Volume */ | ||
| 1251 | [0x094A] = 0x0000, /* R2378 - DSP1RMIX Input 2 Source */ | ||
| 1252 | [0x094B] = 0x0080, /* R2379 - DSP1RMIX Input 2 Volume */ | ||
| 1253 | [0x094C] = 0x0000, /* R2380 - DSP1RMIX Input 3 Source */ | ||
| 1254 | [0x094D] = 0x0080, /* R2381 - DSP1RMIX Input 3 Volume */ | ||
| 1255 | [0x094E] = 0x0000, /* R2382 - DSP1RMIX Input 4 Source */ | ||
| 1256 | [0x094F] = 0x0080, /* R2383 - DSP1RMIX Input 4 Volume */ | ||
| 1257 | [0x0950] = 0x0000, /* R2384 - DSP1AUX1MIX Input 1 Source */ | ||
| 1258 | [0x0958] = 0x0000, /* R2392 - DSP1AUX2MIX Input 1 Source */ | ||
| 1259 | [0x0960] = 0x0000, /* R2400 - DSP1AUX3MIX Input 1 Source */ | ||
| 1260 | [0x0968] = 0x0000, /* R2408 - DSP1AUX4MIX Input 1 Source */ | ||
| 1261 | [0x0970] = 0x0000, /* R2416 - DSP1AUX5MIX Input 1 Source */ | ||
| 1262 | [0x0978] = 0x0000, /* R2424 - DSP1AUX6MIX Input 1 Source */ | ||
| 1263 | [0x0980] = 0x0000, /* R2432 - DSP2LMIX Input 1 Source */ | ||
| 1264 | [0x0981] = 0x0080, /* R2433 - DSP2LMIX Input 1 Volume */ | ||
| 1265 | [0x0982] = 0x0000, /* R2434 - DSP2LMIX Input 2 Source */ | ||
| 1266 | [0x0983] = 0x0080, /* R2435 - DSP2LMIX Input 2 Volume */ | ||
| 1267 | [0x0984] = 0x0000, /* R2436 - DSP2LMIX Input 3 Source */ | ||
| 1268 | [0x0985] = 0x0080, /* R2437 - DSP2LMIX Input 3 Volume */ | ||
| 1269 | [0x0986] = 0x0000, /* R2438 - DSP2LMIX Input 4 Source */ | ||
| 1270 | [0x0987] = 0x0080, /* R2439 - DSP2LMIX Input 4 Volume */ | ||
| 1271 | [0x0988] = 0x0000, /* R2440 - DSP2RMIX Input 1 Source */ | ||
| 1272 | [0x0989] = 0x0080, /* R2441 - DSP2RMIX Input 1 Volume */ | ||
| 1273 | [0x098A] = 0x0000, /* R2442 - DSP2RMIX Input 2 Source */ | ||
| 1274 | [0x098B] = 0x0080, /* R2443 - DSP2RMIX Input 2 Volume */ | ||
| 1275 | [0x098C] = 0x0000, /* R2444 - DSP2RMIX Input 3 Source */ | ||
| 1276 | [0x098D] = 0x0080, /* R2445 - DSP2RMIX Input 3 Volume */ | ||
| 1277 | [0x098E] = 0x0000, /* R2446 - DSP2RMIX Input 4 Source */ | ||
| 1278 | [0x098F] = 0x0080, /* R2447 - DSP2RMIX Input 4 Volume */ | ||
| 1279 | [0x0990] = 0x0000, /* R2448 - DSP2AUX1MIX Input 1 Source */ | ||
| 1280 | [0x0998] = 0x0000, /* R2456 - DSP2AUX2MIX Input 1 Source */ | ||
| 1281 | [0x09A0] = 0x0000, /* R2464 - DSP2AUX3MIX Input 1 Source */ | ||
| 1282 | [0x09A8] = 0x0000, /* R2472 - DSP2AUX4MIX Input 1 Source */ | ||
| 1283 | [0x09B0] = 0x0000, /* R2480 - DSP2AUX5MIX Input 1 Source */ | ||
| 1284 | [0x09B8] = 0x0000, /* R2488 - DSP2AUX6MIX Input 1 Source */ | ||
| 1285 | [0x09C0] = 0x0000, /* R2496 - DSP3LMIX Input 1 Source */ | ||
| 1286 | [0x09C1] = 0x0080, /* R2497 - DSP3LMIX Input 1 Volume */ | ||
| 1287 | [0x09C2] = 0x0000, /* R2498 - DSP3LMIX Input 2 Source */ | ||
| 1288 | [0x09C3] = 0x0080, /* R2499 - DSP3LMIX Input 2 Volume */ | ||
| 1289 | [0x09C4] = 0x0000, /* R2500 - DSP3LMIX Input 3 Source */ | ||
| 1290 | [0x09C5] = 0x0080, /* R2501 - DSP3LMIX Input 3 Volume */ | ||
| 1291 | [0x09C6] = 0x0000, /* R2502 - DSP3LMIX Input 4 Source */ | ||
| 1292 | [0x09C7] = 0x0080, /* R2503 - DSP3LMIX Input 4 Volume */ | ||
| 1293 | [0x09C8] = 0x0000, /* R2504 - DSP3RMIX Input 1 Source */ | ||
| 1294 | [0x09C9] = 0x0080, /* R2505 - DSP3RMIX Input 1 Volume */ | ||
| 1295 | [0x09CA] = 0x0000, /* R2506 - DSP3RMIX Input 2 Source */ | ||
| 1296 | [0x09CB] = 0x0080, /* R2507 - DSP3RMIX Input 2 Volume */ | ||
| 1297 | [0x09CC] = 0x0000, /* R2508 - DSP3RMIX Input 3 Source */ | ||
| 1298 | [0x09CD] = 0x0080, /* R2509 - DSP3RMIX Input 3 Volume */ | ||
| 1299 | [0x09CE] = 0x0000, /* R2510 - DSP3RMIX Input 4 Source */ | ||
| 1300 | [0x09CF] = 0x0080, /* R2511 - DSP3RMIX Input 4 Volume */ | ||
| 1301 | [0x09D0] = 0x0000, /* R2512 - DSP3AUX1MIX Input 1 Source */ | ||
| 1302 | [0x09D8] = 0x0000, /* R2520 - DSP3AUX2MIX Input 1 Source */ | ||
| 1303 | [0x09E0] = 0x0000, /* R2528 - DSP3AUX3MIX Input 1 Source */ | ||
| 1304 | [0x09E8] = 0x0000, /* R2536 - DSP3AUX4MIX Input 1 Source */ | ||
| 1305 | [0x09F0] = 0x0000, /* R2544 - DSP3AUX5MIX Input 1 Source */ | ||
| 1306 | [0x09F8] = 0x0000, /* R2552 - DSP3AUX6MIX Input 1 Source */ | ||
| 1307 | [0x0A80] = 0x0000, /* R2688 - ASRC1LMIX Input 1 Source */ | ||
| 1308 | [0x0A88] = 0x0000, /* R2696 - ASRC1RMIX Input 1 Source */ | ||
| 1309 | [0x0A90] = 0x0000, /* R2704 - ASRC2LMIX Input 1 Source */ | ||
| 1310 | [0x0A98] = 0x0000, /* R2712 - ASRC2RMIX Input 1 Source */ | ||
| 1311 | [0x0B00] = 0x0000, /* R2816 - ISRC1DEC1MIX Input 1 Source */ | ||
| 1312 | [0x0B08] = 0x0000, /* R2824 - ISRC1DEC2MIX Input 1 Source */ | ||
| 1313 | [0x0B10] = 0x0000, /* R2832 - ISRC1DEC3MIX Input 1 Source */ | ||
| 1314 | [0x0B18] = 0x0000, /* R2840 - ISRC1DEC4MIX Input 1 Source */ | ||
| 1315 | [0x0B20] = 0x0000, /* R2848 - ISRC1INT1MIX Input 1 Source */ | ||
| 1316 | [0x0B28] = 0x0000, /* R2856 - ISRC1INT2MIX Input 1 Source */ | ||
| 1317 | [0x0B30] = 0x0000, /* R2864 - ISRC1INT3MIX Input 1 Source */ | ||
| 1318 | [0x0B38] = 0x0000, /* R2872 - ISRC1INT4MIX Input 1 Source */ | ||
| 1319 | [0x0B40] = 0x0000, /* R2880 - ISRC2DEC1MIX Input 1 Source */ | ||
| 1320 | [0x0B48] = 0x0000, /* R2888 - ISRC2DEC2MIX Input 1 Source */ | ||
| 1321 | [0x0B50] = 0x0000, /* R2896 - ISRC2DEC3MIX Input 1 Source */ | ||
| 1322 | [0x0B58] = 0x0000, /* R2904 - ISRC2DEC4MIX Input 1 Source */ | ||
| 1323 | [0x0B60] = 0x0000, /* R2912 - ISRC2INT1MIX Input 1 Source */ | ||
| 1324 | [0x0B68] = 0x0000, /* R2920 - ISRC2INT2MIX Input 1 Source */ | ||
| 1325 | [0x0B70] = 0x0000, /* R2928 - ISRC2INT3MIX Input 1 Source */ | ||
| 1326 | [0x0B78] = 0x0000, /* R2936 - ISRC2INT4MIX Input 1 Source */ | ||
| 1327 | [0x0C00] = 0xA001, /* R3072 - GPIO CTRL 1 */ | ||
| 1328 | [0x0C01] = 0xA001, /* R3073 - GPIO CTRL 2 */ | ||
| 1329 | [0x0C02] = 0xA001, /* R3074 - GPIO CTRL 3 */ | ||
| 1330 | [0x0C03] = 0xA001, /* R3075 - GPIO CTRL 4 */ | ||
| 1331 | [0x0C04] = 0xA001, /* R3076 - GPIO CTRL 5 */ | ||
| 1332 | [0x0C05] = 0xA001, /* R3077 - GPIO CTRL 6 */ | ||
| 1333 | [0x0C23] = 0x4003, /* R3107 - Misc Pad Ctrl 1 */ | ||
| 1334 | [0x0C24] = 0x0000, /* R3108 - Misc Pad Ctrl 2 */ | ||
| 1335 | [0x0C25] = 0x0000, /* R3109 - Misc Pad Ctrl 3 */ | ||
| 1336 | [0x0C26] = 0x0000, /* R3110 - Misc Pad Ctrl 4 */ | ||
| 1337 | [0x0C27] = 0x0000, /* R3111 - Misc Pad Ctrl 5 */ | ||
| 1338 | [0x0C28] = 0x0000, /* R3112 - Misc GPIO 1 */ | ||
| 1339 | [0x0D00] = 0x0000, /* R3328 - Interrupt Status 1 */ | ||
| 1340 | [0x0D01] = 0x0000, /* R3329 - Interrupt Status 2 */ | ||
| 1341 | [0x0D02] = 0x0000, /* R3330 - Interrupt Status 3 */ | ||
| 1342 | [0x0D03] = 0x0000, /* R3331 - Interrupt Status 4 */ | ||
| 1343 | [0x0D04] = 0x0000, /* R3332 - Interrupt Raw Status 2 */ | ||
| 1344 | [0x0D05] = 0x0000, /* R3333 - Interrupt Raw Status 3 */ | ||
| 1345 | [0x0D06] = 0x0000, /* R3334 - Interrupt Raw Status 4 */ | ||
| 1346 | [0x0D07] = 0xFFFF, /* R3335 - Interrupt Status 1 Mask */ | ||
| 1347 | [0x0D08] = 0xFFFF, /* R3336 - Interrupt Status 2 Mask */ | ||
| 1348 | [0x0D09] = 0xFFFF, /* R3337 - Interrupt Status 3 Mask */ | ||
| 1349 | [0x0D0A] = 0xFFFF, /* R3338 - Interrupt Status 4 Mask */ | ||
| 1350 | [0x0D1F] = 0x0000, /* R3359 - Interrupt Control */ | ||
| 1351 | [0x0D20] = 0xFFFF, /* R3360 - IRQ Debounce 1 */ | ||
| 1352 | [0x0D21] = 0xFFFF, /* R3361 - IRQ Debounce 2 */ | ||
| 1353 | [0x0E00] = 0x0000, /* R3584 - FX_Ctrl */ | ||
| 1354 | [0x0E10] = 0x6318, /* R3600 - EQ1_1 */ | ||
| 1355 | [0x0E11] = 0x6300, /* R3601 - EQ1_2 */ | ||
| 1356 | [0x0E12] = 0x0FC8, /* R3602 - EQ1_3 */ | ||
| 1357 | [0x0E13] = 0x03FE, /* R3603 - EQ1_4 */ | ||
| 1358 | [0x0E14] = 0x00E0, /* R3604 - EQ1_5 */ | ||
| 1359 | [0x0E15] = 0x1EC4, /* R3605 - EQ1_6 */ | ||
| 1360 | [0x0E16] = 0xF136, /* R3606 - EQ1_7 */ | ||
| 1361 | [0x0E17] = 0x0409, /* R3607 - EQ1_8 */ | ||
| 1362 | [0x0E18] = 0x04CC, /* R3608 - EQ1_9 */ | ||
| 1363 | [0x0E19] = 0x1C9B, /* R3609 - EQ1_10 */ | ||
| 1364 | [0x0E1A] = 0xF337, /* R3610 - EQ1_11 */ | ||
| 1365 | [0x0E1B] = 0x040B, /* R3611 - EQ1_12 */ | ||
| 1366 | [0x0E1C] = 0x0CBB, /* R3612 - EQ1_13 */ | ||
| 1367 | [0x0E1D] = 0x16F8, /* R3613 - EQ1_14 */ | ||
| 1368 | [0x0E1E] = 0xF7D9, /* R3614 - EQ1_15 */ | ||
| 1369 | [0x0E1F] = 0x040A, /* R3615 - EQ1_16 */ | ||
| 1370 | [0x0E20] = 0x1F14, /* R3616 - EQ1_17 */ | ||
| 1371 | [0x0E21] = 0x058C, /* R3617 - EQ1_18 */ | ||
| 1372 | [0x0E22] = 0x0563, /* R3618 - EQ1_19 */ | ||
| 1373 | [0x0E23] = 0x4000, /* R3619 - EQ1_20 */ | ||
| 1374 | [0x0E26] = 0x6318, /* R3622 - EQ2_1 */ | ||
| 1375 | [0x0E27] = 0x6300, /* R3623 - EQ2_2 */ | ||
| 1376 | [0x0E28] = 0x0FC8, /* R3624 - EQ2_3 */ | ||
| 1377 | [0x0E29] = 0x03FE, /* R3625 - EQ2_4 */ | ||
| 1378 | [0x0E2A] = 0x00E0, /* R3626 - EQ2_5 */ | ||
| 1379 | [0x0E2B] = 0x1EC4, /* R3627 - EQ2_6 */ | ||
| 1380 | [0x0E2C] = 0xF136, /* R3628 - EQ2_7 */ | ||
| 1381 | [0x0E2D] = 0x0409, /* R3629 - EQ2_8 */ | ||
| 1382 | [0x0E2E] = 0x04CC, /* R3630 - EQ2_9 */ | ||
| 1383 | [0x0E2F] = 0x1C9B, /* R3631 - EQ2_10 */ | ||
| 1384 | [0x0E30] = 0xF337, /* R3632 - EQ2_11 */ | ||
| 1385 | [0x0E31] = 0x040B, /* R3633 - EQ2_12 */ | ||
| 1386 | [0x0E32] = 0x0CBB, /* R3634 - EQ2_13 */ | ||
| 1387 | [0x0E33] = 0x16F8, /* R3635 - EQ2_14 */ | ||
| 1388 | [0x0E34] = 0xF7D9, /* R3636 - EQ2_15 */ | ||
| 1389 | [0x0E35] = 0x040A, /* R3637 - EQ2_16 */ | ||
| 1390 | [0x0E36] = 0x1F14, /* R3638 - EQ2_17 */ | ||
| 1391 | [0x0E37] = 0x058C, /* R3639 - EQ2_18 */ | ||
| 1392 | [0x0E38] = 0x0563, /* R3640 - EQ2_19 */ | ||
| 1393 | [0x0E39] = 0x4000, /* R3641 - EQ2_20 */ | ||
| 1394 | [0x0E3C] = 0x6318, /* R3644 - EQ3_1 */ | ||
| 1395 | [0x0E3D] = 0x6300, /* R3645 - EQ3_2 */ | ||
| 1396 | [0x0E3E] = 0x0FC8, /* R3646 - EQ3_3 */ | ||
| 1397 | [0x0E3F] = 0x03FE, /* R3647 - EQ3_4 */ | ||
| 1398 | [0x0E40] = 0x00E0, /* R3648 - EQ3_5 */ | ||
| 1399 | [0x0E41] = 0x1EC4, /* R3649 - EQ3_6 */ | ||
| 1400 | [0x0E42] = 0xF136, /* R3650 - EQ3_7 */ | ||
| 1401 | [0x0E43] = 0x0409, /* R3651 - EQ3_8 */ | ||
| 1402 | [0x0E44] = 0x04CC, /* R3652 - EQ3_9 */ | ||
| 1403 | [0x0E45] = 0x1C9B, /* R3653 - EQ3_10 */ | ||
| 1404 | [0x0E46] = 0xF337, /* R3654 - EQ3_11 */ | ||
| 1405 | [0x0E47] = 0x040B, /* R3655 - EQ3_12 */ | ||
| 1406 | [0x0E48] = 0x0CBB, /* R3656 - EQ3_13 */ | ||
| 1407 | [0x0E49] = 0x16F8, /* R3657 - EQ3_14 */ | ||
| 1408 | [0x0E4A] = 0xF7D9, /* R3658 - EQ3_15 */ | ||
| 1409 | [0x0E4B] = 0x040A, /* R3659 - EQ3_16 */ | ||
| 1410 | [0x0E4C] = 0x1F14, /* R3660 - EQ3_17 */ | ||
| 1411 | [0x0E4D] = 0x058C, /* R3661 - EQ3_18 */ | ||
| 1412 | [0x0E4E] = 0x0563, /* R3662 - EQ3_19 */ | ||
| 1413 | [0x0E4F] = 0x4000, /* R3663 - EQ3_20 */ | ||
| 1414 | [0x0E52] = 0x6318, /* R3666 - EQ4_1 */ | ||
| 1415 | [0x0E53] = 0x6300, /* R3667 - EQ4_2 */ | ||
| 1416 | [0x0E54] = 0x0FC8, /* R3668 - EQ4_3 */ | ||
| 1417 | [0x0E55] = 0x03FE, /* R3669 - EQ4_4 */ | ||
| 1418 | [0x0E56] = 0x00E0, /* R3670 - EQ4_5 */ | ||
| 1419 | [0x0E57] = 0x1EC4, /* R3671 - EQ4_6 */ | ||
| 1420 | [0x0E58] = 0xF136, /* R3672 - EQ4_7 */ | ||
| 1421 | [0x0E59] = 0x0409, /* R3673 - EQ4_8 */ | ||
| 1422 | [0x0E5A] = 0x04CC, /* R3674 - EQ4_9 */ | ||
| 1423 | [0x0E5B] = 0x1C9B, /* R3675 - EQ4_10 */ | ||
| 1424 | [0x0E5C] = 0xF337, /* R3676 - EQ4_11 */ | ||
| 1425 | [0x0E5D] = 0x040B, /* R3677 - EQ4_12 */ | ||
| 1426 | [0x0E5E] = 0x0CBB, /* R3678 - EQ4_13 */ | ||
| 1427 | [0x0E5F] = 0x16F8, /* R3679 - EQ4_14 */ | ||
| 1428 | [0x0E60] = 0xF7D9, /* R3680 - EQ4_15 */ | ||
| 1429 | [0x0E61] = 0x040A, /* R3681 - EQ4_16 */ | ||
| 1430 | [0x0E62] = 0x1F14, /* R3682 - EQ4_17 */ | ||
| 1431 | [0x0E63] = 0x058C, /* R3683 - EQ4_18 */ | ||
| 1432 | [0x0E64] = 0x0563, /* R3684 - EQ4_19 */ | ||
| 1433 | [0x0E65] = 0x4000, /* R3685 - EQ4_20 */ | ||
| 1434 | [0x0E80] = 0x0018, /* R3712 - DRC1 ctrl1 */ | ||
| 1435 | [0x0E81] = 0x0933, /* R3713 - DRC1 ctrl2 */ | ||
| 1436 | [0x0E82] = 0x0018, /* R3714 - DRC1 ctrl3 */ | ||
| 1437 | [0x0E83] = 0x0000, /* R3715 - DRC1 ctrl4 */ | ||
| 1438 | [0x0E84] = 0x0000, /* R3716 - DRC1 ctrl5 */ | ||
| 1439 | [0x0EC0] = 0x0000, /* R3776 - HPLPF1_1 */ | ||
| 1440 | [0x0EC1] = 0x0000, /* R3777 - HPLPF1_2 */ | ||
| 1441 | [0x0EC4] = 0x0000, /* R3780 - HPLPF2_1 */ | ||
| 1442 | [0x0EC5] = 0x0000, /* R3781 - HPLPF2_2 */ | ||
| 1443 | [0x0EC8] = 0x0000, /* R3784 - HPLPF3_1 */ | ||
| 1444 | [0x0EC9] = 0x0000, /* R3785 - HPLPF3_2 */ | ||
| 1445 | [0x0ECC] = 0x0000, /* R3788 - HPLPF4_1 */ | ||
| 1446 | [0x0ECD] = 0x0000, /* R3789 - HPLPF4_2 */ | ||
| 1447 | [0x4000] = 0x0000, /* R16384 - DSP1 DM 0 */ | ||
| 1448 | [0x4001] = 0x0000, /* R16385 - DSP1 DM 1 */ | ||
| 1449 | [0x4002] = 0x0000, /* R16386 - DSP1 DM 2 */ | ||
| 1450 | [0x4003] = 0x0000, /* R16387 - DSP1 DM 3 */ | ||
| 1451 | [0x41FC] = 0x0000, /* R16892 - DSP1 DM 508 */ | ||
| 1452 | [0x41FD] = 0x0000, /* R16893 - DSP1 DM 509 */ | ||
| 1453 | [0x41FE] = 0x0000, /* R16894 - DSP1 DM 510 */ | ||
| 1454 | [0x41FF] = 0x0000, /* R16895 - DSP1 DM 511 */ | ||
| 1455 | [0x4800] = 0x0000, /* R18432 - DSP1 PM 0 */ | ||
| 1456 | [0x4801] = 0x0000, /* R18433 - DSP1 PM 1 */ | ||
| 1457 | [0x4802] = 0x0000, /* R18434 - DSP1 PM 2 */ | ||
| 1458 | [0x4803] = 0x0000, /* R18435 - DSP1 PM 3 */ | ||
| 1459 | [0x4804] = 0x0000, /* R18436 - DSP1 PM 4 */ | ||
| 1460 | [0x4805] = 0x0000, /* R18437 - DSP1 PM 5 */ | ||
| 1461 | [0x4DFA] = 0x0000, /* R19962 - DSP1 PM 1530 */ | ||
| 1462 | [0x4DFB] = 0x0000, /* R19963 - DSP1 PM 1531 */ | ||
| 1463 | [0x4DFC] = 0x0000, /* R19964 - DSP1 PM 1532 */ | ||
| 1464 | [0x4DFD] = 0x0000, /* R19965 - DSP1 PM 1533 */ | ||
| 1465 | [0x4DFE] = 0x0000, /* R19966 - DSP1 PM 1534 */ | ||
| 1466 | [0x4DFF] = 0x0000, /* R19967 - DSP1 PM 1535 */ | ||
| 1467 | [0x5000] = 0x0000, /* R20480 - DSP1 ZM 0 */ | ||
| 1468 | [0x5001] = 0x0000, /* R20481 - DSP1 ZM 1 */ | ||
| 1469 | [0x5002] = 0x0000, /* R20482 - DSP1 ZM 2 */ | ||
| 1470 | [0x5003] = 0x0000, /* R20483 - DSP1 ZM 3 */ | ||
| 1471 | [0x57FC] = 0x0000, /* R22524 - DSP1 ZM 2044 */ | ||
| 1472 | [0x57FD] = 0x0000, /* R22525 - DSP1 ZM 2045 */ | ||
| 1473 | [0x57FE] = 0x0000, /* R22526 - DSP1 ZM 2046 */ | ||
| 1474 | [0x57FF] = 0x0000, /* R22527 - DSP1 ZM 2047 */ | ||
| 1475 | [0x6000] = 0x0000, /* R24576 - DSP2 DM 0 */ | ||
| 1476 | [0x6001] = 0x0000, /* R24577 - DSP2 DM 1 */ | ||
| 1477 | [0x6002] = 0x0000, /* R24578 - DSP2 DM 2 */ | ||
| 1478 | [0x6003] = 0x0000, /* R24579 - DSP2 DM 3 */ | ||
| 1479 | [0x61FC] = 0x0000, /* R25084 - DSP2 DM 508 */ | ||
| 1480 | [0x61FD] = 0x0000, /* R25085 - DSP2 DM 509 */ | ||
| 1481 | [0x61FE] = 0x0000, /* R25086 - DSP2 DM 510 */ | ||
| 1482 | [0x61FF] = 0x0000, /* R25087 - DSP2 DM 511 */ | ||
| 1483 | [0x6800] = 0x0000, /* R26624 - DSP2 PM 0 */ | ||
| 1484 | [0x6801] = 0x0000, /* R26625 - DSP2 PM 1 */ | ||
| 1485 | [0x6802] = 0x0000, /* R26626 - DSP2 PM 2 */ | ||
| 1486 | [0x6803] = 0x0000, /* R26627 - DSP2 PM 3 */ | ||
| 1487 | [0x6804] = 0x0000, /* R26628 - DSP2 PM 4 */ | ||
| 1488 | [0x6805] = 0x0000, /* R26629 - DSP2 PM 5 */ | ||
| 1489 | [0x6DFA] = 0x0000, /* R28154 - DSP2 PM 1530 */ | ||
| 1490 | [0x6DFB] = 0x0000, /* R28155 - DSP2 PM 1531 */ | ||
| 1491 | [0x6DFC] = 0x0000, /* R28156 - DSP2 PM 1532 */ | ||
| 1492 | [0x6DFD] = 0x0000, /* R28157 - DSP2 PM 1533 */ | ||
| 1493 | [0x6DFE] = 0x0000, /* R28158 - DSP2 PM 1534 */ | ||
| 1494 | [0x6DFF] = 0x0000, /* R28159 - DSP2 PM 1535 */ | ||
| 1495 | [0x7000] = 0x0000, /* R28672 - DSP2 ZM 0 */ | ||
| 1496 | [0x7001] = 0x0000, /* R28673 - DSP2 ZM 1 */ | ||
| 1497 | [0x7002] = 0x0000, /* R28674 - DSP2 ZM 2 */ | ||
| 1498 | [0x7003] = 0x0000, /* R28675 - DSP2 ZM 3 */ | ||
| 1499 | [0x77FC] = 0x0000, /* R30716 - DSP2 ZM 2044 */ | ||
| 1500 | [0x77FD] = 0x0000, /* R30717 - DSP2 ZM 2045 */ | ||
| 1501 | [0x77FE] = 0x0000, /* R30718 - DSP2 ZM 2046 */ | ||
| 1502 | [0x77FF] = 0x0000, /* R30719 - DSP2 ZM 2047 */ | ||
| 1503 | [0x8000] = 0x0000, /* R32768 - DSP3 DM 0 */ | ||
| 1504 | [0x8001] = 0x0000, /* R32769 - DSP3 DM 1 */ | ||
| 1505 | [0x8002] = 0x0000, /* R32770 - DSP3 DM 2 */ | ||
| 1506 | [0x8003] = 0x0000, /* R32771 - DSP3 DM 3 */ | ||
| 1507 | [0x81FC] = 0x0000, /* R33276 - DSP3 DM 508 */ | ||
| 1508 | [0x81FD] = 0x0000, /* R33277 - DSP3 DM 509 */ | ||
| 1509 | [0x81FE] = 0x0000, /* R33278 - DSP3 DM 510 */ | ||
| 1510 | [0x81FF] = 0x0000, /* R33279 - DSP3 DM 511 */ | ||
| 1511 | [0x8800] = 0x0000, /* R34816 - DSP3 PM 0 */ | ||
| 1512 | [0x8801] = 0x0000, /* R34817 - DSP3 PM 1 */ | ||
| 1513 | [0x8802] = 0x0000, /* R34818 - DSP3 PM 2 */ | ||
| 1514 | [0x8803] = 0x0000, /* R34819 - DSP3 PM 3 */ | ||
| 1515 | [0x8804] = 0x0000, /* R34820 - DSP3 PM 4 */ | ||
| 1516 | [0x8805] = 0x0000, /* R34821 - DSP3 PM 5 */ | ||
| 1517 | [0x8DFA] = 0x0000, /* R36346 - DSP3 PM 1530 */ | ||
| 1518 | [0x8DFB] = 0x0000, /* R36347 - DSP3 PM 1531 */ | ||
| 1519 | [0x8DFC] = 0x0000, /* R36348 - DSP3 PM 1532 */ | ||
| 1520 | [0x8DFD] = 0x0000, /* R36349 - DSP3 PM 1533 */ | ||
| 1521 | [0x8DFE] = 0x0000, /* R36350 - DSP3 PM 1534 */ | ||
| 1522 | [0x8DFF] = 0x0000, /* R36351 - DSP3 PM 1535 */ | ||
| 1523 | [0x9000] = 0x0000, /* R36864 - DSP3 ZM 0 */ | ||
| 1524 | [0x9001] = 0x0000, /* R36865 - DSP3 ZM 1 */ | ||
| 1525 | [0x9002] = 0x0000, /* R36866 - DSP3 ZM 2 */ | ||
| 1526 | [0x9003] = 0x0000, /* R36867 - DSP3 ZM 3 */ | ||
| 1527 | [0x97FC] = 0x0000, /* R38908 - DSP3 ZM 2044 */ | ||
| 1528 | [0x97FD] = 0x0000, /* R38909 - DSP3 ZM 2045 */ | ||
| 1529 | [0x97FE] = 0x0000, /* R38910 - DSP3 ZM 2046 */ | ||
| 1530 | [0x97FF] = 0x0000 /* R38911 - DSP3 ZM 2047 */ | ||
| 1531 | }; | ||
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c new file mode 100644 index 000000000000..5d88c99aaea6 --- /dev/null +++ b/sound/soc/codecs/wm5100.c | |||
| @@ -0,0 +1,2809 @@ | |||
| 1 | /* | ||
| 2 | * wm5100.c -- WM5100 ALSA SoC Audio driver | ||
| 3 | * | ||
| 4 | * Copyright 2011 Wolfson Microelectronics plc | ||
| 5 | * | ||
| 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.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 | #include <linux/module.h> | ||
| 14 | #include <linux/moduleparam.h> | ||
| 15 | #include <linux/init.h> | ||
| 16 | #include <linux/delay.h> | ||
| 17 | #include <linux/pm.h> | ||
| 18 | #include <linux/gcd.h> | ||
| 19 | #include <linux/gpio.h> | ||
| 20 | #include <linux/i2c.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/regulator/consumer.h> | ||
| 23 | #include <linux/regulator/fixed.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | #include <sound/core.h> | ||
| 26 | #include <sound/pcm.h> | ||
| 27 | #include <sound/pcm_params.h> | ||
| 28 | #include <sound/soc.h> | ||
| 29 | #include <sound/jack.h> | ||
| 30 | #include <sound/initval.h> | ||
| 31 | #include <sound/tlv.h> | ||
| 32 | #include <sound/wm5100.h> | ||
| 33 | |||
| 34 | #include "wm5100.h" | ||
| 35 | |||
| 36 | #define WM5100_NUM_CORE_SUPPLIES 2 | ||
| 37 | static const char *wm5100_core_supply_names[WM5100_NUM_CORE_SUPPLIES] = { | ||
| 38 | "DBVDD1", | ||
| 39 | "LDOVDD", /* If DCVDD is supplied externally specify as LDOVDD */ | ||
| 40 | }; | ||
| 41 | |||
| 42 | #define WM5100_AIFS 3 | ||
| 43 | #define WM5100_SYNC_SRS 3 | ||
| 44 | |||
| 45 | struct wm5100_fll { | ||
| 46 | int fref; | ||
| 47 | int fout; | ||
| 48 | int src; | ||
| 49 | struct completion lock; | ||
| 50 | }; | ||
| 51 | |||
| 52 | /* codec private data */ | ||
| 53 | struct wm5100_priv { | ||
| 54 | struct snd_soc_codec *codec; | ||
| 55 | |||
| 56 | struct regulator_bulk_data core_supplies[WM5100_NUM_CORE_SUPPLIES]; | ||
| 57 | struct regulator *cpvdd; | ||
| 58 | struct regulator *dbvdd2; | ||
| 59 | struct regulator *dbvdd3; | ||
| 60 | |||
| 61 | int rev; | ||
| 62 | |||
| 63 | int sysclk; | ||
| 64 | int asyncclk; | ||
| 65 | |||
| 66 | bool aif_async[WM5100_AIFS]; | ||
| 67 | bool aif_symmetric[WM5100_AIFS]; | ||
| 68 | int sr_ref[WM5100_SYNC_SRS]; | ||
| 69 | |||
| 70 | bool out_ena[2]; | ||
| 71 | |||
| 72 | struct snd_soc_jack *jack; | ||
| 73 | bool jack_detecting; | ||
| 74 | bool jack_mic; | ||
| 75 | int jack_mode; | ||
| 76 | |||
| 77 | struct wm5100_fll fll[2]; | ||
| 78 | |||
| 79 | struct wm5100_pdata pdata; | ||
| 80 | |||
| 81 | #ifdef CONFIG_GPIOLIB | ||
| 82 | struct gpio_chip gpio_chip; | ||
| 83 | #endif | ||
| 84 | }; | ||
| 85 | |||
| 86 | static int wm5100_sr_code[] = { | ||
| 87 | 0, | ||
| 88 | 12000, | ||
| 89 | 24000, | ||
| 90 | 48000, | ||
| 91 | 96000, | ||
| 92 | 192000, | ||
| 93 | 384000, | ||
| 94 | 768000, | ||
| 95 | 0, | ||
| 96 | 11025, | ||
| 97 | 22050, | ||
| 98 | 44100, | ||
| 99 | 88200, | ||
| 100 | 176400, | ||
| 101 | 352800, | ||
| 102 | 705600, | ||
| 103 | 4000, | ||
| 104 | 8000, | ||
| 105 | 16000, | ||
| 106 | 32000, | ||
| 107 | 64000, | ||
| 108 | 128000, | ||
| 109 | 256000, | ||
| 110 | 512000, | ||
| 111 | }; | ||
| 112 | |||
| 113 | static int wm5100_sr_regs[WM5100_SYNC_SRS] = { | ||
| 114 | WM5100_CLOCKING_4, | ||
| 115 | WM5100_CLOCKING_5, | ||
| 116 | WM5100_CLOCKING_6, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static int wm5100_alloc_sr(struct snd_soc_codec *codec, int rate) | ||
| 120 | { | ||
| 121 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 122 | int sr_code, sr_free, i; | ||
| 123 | |||
| 124 | for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++) | ||
| 125 | if (wm5100_sr_code[i] == rate) | ||
| 126 | break; | ||
| 127 | if (i == ARRAY_SIZE(wm5100_sr_code)) { | ||
| 128 | dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate); | ||
| 129 | return -EINVAL; | ||
| 130 | } | ||
| 131 | sr_code = i; | ||
| 132 | |||
| 133 | if ((wm5100->sysclk % rate) == 0) { | ||
| 134 | /* Is this rate already in use? */ | ||
| 135 | sr_free = -1; | ||
| 136 | for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) { | ||
| 137 | if (!wm5100->sr_ref[i] && sr_free == -1) { | ||
| 138 | sr_free = i; | ||
| 139 | continue; | ||
| 140 | } | ||
| 141 | if ((snd_soc_read(codec, wm5100_sr_regs[i]) & | ||
| 142 | WM5100_SAMPLE_RATE_1_MASK) == sr_code) | ||
| 143 | break; | ||
| 144 | } | ||
| 145 | |||
| 146 | if (i < ARRAY_SIZE(wm5100_sr_regs)) { | ||
| 147 | wm5100->sr_ref[i]++; | ||
| 148 | dev_dbg(codec->dev, "SR %dHz, slot %d, ref %d\n", | ||
| 149 | rate, i, wm5100->sr_ref[i]); | ||
| 150 | return i; | ||
| 151 | } | ||
| 152 | |||
| 153 | if (sr_free == -1) { | ||
| 154 | dev_err(codec->dev, "All SR slots already in use\n"); | ||
| 155 | return -EBUSY; | ||
| 156 | } | ||
| 157 | |||
| 158 | dev_dbg(codec->dev, "Allocating SR slot %d for %dHz\n", | ||
| 159 | sr_free, rate); | ||
| 160 | wm5100->sr_ref[sr_free]++; | ||
| 161 | snd_soc_update_bits(codec, wm5100_sr_regs[sr_free], | ||
| 162 | WM5100_SAMPLE_RATE_1_MASK, | ||
| 163 | sr_code); | ||
| 164 | |||
| 165 | return sr_free; | ||
| 166 | |||
| 167 | } else { | ||
| 168 | dev_err(codec->dev, | ||
| 169 | "SR %dHz incompatible with %dHz SYSCLK and %dHz ASYNCCLK\n", | ||
| 170 | rate, wm5100->sysclk, wm5100->asyncclk); | ||
| 171 | return -EINVAL; | ||
| 172 | } | ||
| 173 | } | ||
| 174 | |||
| 175 | static void wm5100_free_sr(struct snd_soc_codec *codec, int rate) | ||
| 176 | { | ||
| 177 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 178 | int i, sr_code; | ||
| 179 | |||
| 180 | for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++) | ||
| 181 | if (wm5100_sr_code[i] == rate) | ||
| 182 | break; | ||
| 183 | if (i == ARRAY_SIZE(wm5100_sr_code)) { | ||
| 184 | dev_err(codec->dev, "Unsupported sample rate: %dHz\n", rate); | ||
| 185 | return; | ||
| 186 | } | ||
| 187 | sr_code = wm5100_sr_code[i]; | ||
| 188 | |||
| 189 | for (i = 0; i < ARRAY_SIZE(wm5100_sr_regs); i++) { | ||
| 190 | if (!wm5100->sr_ref[i]) | ||
| 191 | continue; | ||
| 192 | |||
| 193 | if ((snd_soc_read(codec, wm5100_sr_regs[i]) & | ||
| 194 | WM5100_SAMPLE_RATE_1_MASK) == sr_code) | ||
| 195 | break; | ||
| 196 | } | ||
| 197 | if (i < ARRAY_SIZE(wm5100_sr_regs)) { | ||
| 198 | wm5100->sr_ref[i]--; | ||
| 199 | dev_dbg(codec->dev, "Dereference SR %dHz, count now %d\n", | ||
| 200 | rate, wm5100->sr_ref[i]); | ||
| 201 | } else { | ||
| 202 | dev_warn(codec->dev, "Freeing unreferenced sample rate %dHz\n", | ||
| 203 | rate); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | static int wm5100_reset(struct snd_soc_codec *codec) | ||
| 208 | { | ||
| 209 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 210 | |||
| 211 | if (wm5100->pdata.reset) { | ||
| 212 | gpio_set_value_cansleep(wm5100->pdata.reset, 0); | ||
| 213 | gpio_set_value_cansleep(wm5100->pdata.reset, 1); | ||
| 214 | |||
| 215 | return 0; | ||
| 216 | } else { | ||
| 217 | return snd_soc_write(codec, WM5100_SOFTWARE_RESET, 0); | ||
| 218 | } | ||
| 219 | } | ||
| 220 | |||
| 221 | static DECLARE_TLV_DB_SCALE(in_tlv, -6300, 100, 0); | ||
| 222 | static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | ||
| 223 | static DECLARE_TLV_DB_SCALE(mixer_tlv, -3200, 100, 0); | ||
| 224 | static DECLARE_TLV_DB_SCALE(out_tlv, -6400, 100, 0); | ||
| 225 | static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0); | ||
| 226 | |||
| 227 | static const char *wm5100_mixer_texts[] = { | ||
| 228 | "None", | ||
| 229 | "Tone Generator 1", | ||
| 230 | "Tone Generator 2", | ||
| 231 | "AEC loopback", | ||
| 232 | "IN1L", | ||
| 233 | "IN1R", | ||
| 234 | "IN2L", | ||
| 235 | "IN2R", | ||
| 236 | "IN3L", | ||
| 237 | "IN3R", | ||
| 238 | "IN4L", | ||
| 239 | "IN4R", | ||
| 240 | "AIF1RX1", | ||
| 241 | "AIF1RX2", | ||
| 242 | "AIF1RX3", | ||
| 243 | "AIF1RX4", | ||
| 244 | "AIF1RX5", | ||
| 245 | "AIF1RX6", | ||
| 246 | "AIF1RX7", | ||
| 247 | "AIF1RX8", | ||
| 248 | "AIF2RX1", | ||
| 249 | "AIF2RX2", | ||
| 250 | "AIF3RX1", | ||
| 251 | "AIF3RX2", | ||
| 252 | "EQ1", | ||
| 253 | "EQ2", | ||
| 254 | "EQ3", | ||
| 255 | "EQ4", | ||
| 256 | "DRC1L", | ||
| 257 | "DRC1R", | ||
| 258 | "LHPF1", | ||
| 259 | "LHPF2", | ||
| 260 | "LHPF3", | ||
| 261 | "LHPF4", | ||
| 262 | "DSP1.1", | ||
| 263 | "DSP1.2", | ||
| 264 | "DSP1.3", | ||
| 265 | "DSP1.4", | ||
| 266 | "DSP1.5", | ||
| 267 | "DSP1.6", | ||
| 268 | "DSP2.1", | ||
| 269 | "DSP2.2", | ||
| 270 | "DSP2.3", | ||
| 271 | "DSP2.4", | ||
| 272 | "DSP2.5", | ||
| 273 | "DSP2.6", | ||
| 274 | "DSP3.1", | ||
| 275 | "DSP3.2", | ||
| 276 | "DSP3.3", | ||
| 277 | "DSP3.4", | ||
| 278 | "DSP3.5", | ||
| 279 | "DSP3.6", | ||
| 280 | "ASRC1L", | ||
| 281 | "ASRC1R", | ||
| 282 | "ASRC2L", | ||
| 283 | "ASRC2R", | ||
| 284 | "ISRC1INT1", | ||
| 285 | "ISRC1INT2", | ||
| 286 | "ISRC1INT3", | ||
| 287 | "ISRC1INT4", | ||
| 288 | "ISRC2INT1", | ||
| 289 | "ISRC2INT2", | ||
| 290 | "ISRC2INT3", | ||
| 291 | "ISRC2INT4", | ||
| 292 | "ISRC1DEC1", | ||
| 293 | "ISRC1DEC2", | ||
| 294 | "ISRC1DEC3", | ||
| 295 | "ISRC1DEC4", | ||
| 296 | "ISRC2DEC1", | ||
| 297 | "ISRC2DEC2", | ||
| 298 | "ISRC2DEC3", | ||
| 299 | "ISRC2DEC4", | ||
| 300 | }; | ||
| 301 | |||
| 302 | static int wm5100_mixer_values[] = { | ||
| 303 | 0x00, | ||
| 304 | 0x04, /* Tone */ | ||
| 305 | 0x05, | ||
| 306 | 0x08, /* AEC */ | ||
| 307 | 0x10, /* Input */ | ||
| 308 | 0x11, | ||
| 309 | 0x12, | ||
| 310 | 0x13, | ||
| 311 | 0x14, | ||
| 312 | 0x15, | ||
| 313 | 0x16, | ||
| 314 | 0x17, | ||
| 315 | 0x20, /* AIF */ | ||
| 316 | 0x21, | ||
| 317 | 0x22, | ||
| 318 | 0x23, | ||
| 319 | 0x24, | ||
| 320 | 0x25, | ||
| 321 | 0x26, | ||
| 322 | 0x27, | ||
| 323 | 0x28, | ||
| 324 | 0x29, | ||
| 325 | 0x30, /* AIF3 - check */ | ||
| 326 | 0x31, | ||
| 327 | 0x50, /* EQ */ | ||
| 328 | 0x51, | ||
| 329 | 0x52, | ||
| 330 | 0x53, | ||
| 331 | 0x54, | ||
| 332 | 0x58, /* DRC */ | ||
| 333 | 0x59, | ||
| 334 | 0x60, /* LHPF1 */ | ||
| 335 | 0x61, /* LHPF2 */ | ||
| 336 | 0x62, /* LHPF3 */ | ||
| 337 | 0x63, /* LHPF4 */ | ||
| 338 | 0x68, /* DSP1 */ | ||
| 339 | 0x69, | ||
| 340 | 0x6a, | ||
| 341 | 0x6b, | ||
| 342 | 0x6c, | ||
| 343 | 0x6d, | ||
| 344 | 0x70, /* DSP2 */ | ||
| 345 | 0x71, | ||
| 346 | 0x72, | ||
| 347 | 0x73, | ||
| 348 | 0x74, | ||
| 349 | 0x75, | ||
| 350 | 0x78, /* DSP3 */ | ||
| 351 | 0x79, | ||
| 352 | 0x7a, | ||
| 353 | 0x7b, | ||
| 354 | 0x7c, | ||
| 355 | 0x7d, | ||
| 356 | 0x90, /* ASRC1 */ | ||
| 357 | 0x91, | ||
| 358 | 0x92, /* ASRC2 */ | ||
| 359 | 0x93, | ||
| 360 | 0xa0, /* ISRC1DEC1 */ | ||
| 361 | 0xa1, | ||
| 362 | 0xa2, | ||
| 363 | 0xa3, | ||
| 364 | 0xa4, /* ISRC1INT1 */ | ||
| 365 | 0xa5, | ||
| 366 | 0xa6, | ||
| 367 | 0xa7, | ||
| 368 | 0xa8, /* ISRC2DEC1 */ | ||
| 369 | 0xa9, | ||
| 370 | 0xaa, | ||
| 371 | 0xab, | ||
| 372 | 0xac, /* ISRC2INT1 */ | ||
| 373 | 0xad, | ||
| 374 | 0xae, | ||
| 375 | 0xaf, | ||
| 376 | }; | ||
| 377 | |||
| 378 | #define WM5100_MIXER_CONTROLS(name, base) \ | ||
| 379 | SOC_SINGLE_TLV(name " Input 1 Volume", base + 1 , \ | ||
| 380 | WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ | ||
| 381 | SOC_SINGLE_TLV(name " Input 2 Volume", base + 3 , \ | ||
| 382 | WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ | ||
| 383 | SOC_SINGLE_TLV(name " Input 3 Volume", base + 5 , \ | ||
| 384 | WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv), \ | ||
| 385 | SOC_SINGLE_TLV(name " Input 4 Volume", base + 7 , \ | ||
| 386 | WM5100_MIXER_VOL_SHIFT, 80, 0, mixer_tlv) | ||
| 387 | |||
| 388 | #define WM5100_MUX_ENUM_DECL(name, reg) \ | ||
| 389 | SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \ | ||
| 390 | wm5100_mixer_texts, wm5100_mixer_values) | ||
| 391 | |||
| 392 | #define WM5100_MUX_CTL_DECL(name) \ | ||
| 393 | const struct snd_kcontrol_new name##_mux = \ | ||
| 394 | SOC_DAPM_VALUE_ENUM("Route", name##_enum) | ||
| 395 | |||
| 396 | #define WM5100_MIXER_ENUMS(name, base_reg) \ | ||
| 397 | static WM5100_MUX_ENUM_DECL(name##_in1_enum, base_reg); \ | ||
| 398 | static WM5100_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \ | ||
| 399 | static WM5100_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \ | ||
| 400 | static WM5100_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \ | ||
| 401 | static WM5100_MUX_CTL_DECL(name##_in1); \ | ||
| 402 | static WM5100_MUX_CTL_DECL(name##_in2); \ | ||
| 403 | static WM5100_MUX_CTL_DECL(name##_in3); \ | ||
| 404 | static WM5100_MUX_CTL_DECL(name##_in4) | ||
| 405 | |||
| 406 | WM5100_MIXER_ENUMS(HPOUT1L, WM5100_OUT1LMIX_INPUT_1_SOURCE); | ||
| 407 | WM5100_MIXER_ENUMS(HPOUT1R, WM5100_OUT1RMIX_INPUT_1_SOURCE); | ||
| 408 | WM5100_MIXER_ENUMS(HPOUT2L, WM5100_OUT2LMIX_INPUT_1_SOURCE); | ||
| 409 | WM5100_MIXER_ENUMS(HPOUT2R, WM5100_OUT2RMIX_INPUT_1_SOURCE); | ||
| 410 | WM5100_MIXER_ENUMS(HPOUT3L, WM5100_OUT3LMIX_INPUT_1_SOURCE); | ||
| 411 | WM5100_MIXER_ENUMS(HPOUT3R, WM5100_OUT3RMIX_INPUT_1_SOURCE); | ||
| 412 | |||
| 413 | WM5100_MIXER_ENUMS(SPKOUTL, WM5100_OUT4LMIX_INPUT_1_SOURCE); | ||
| 414 | WM5100_MIXER_ENUMS(SPKOUTR, WM5100_OUT4RMIX_INPUT_1_SOURCE); | ||
| 415 | WM5100_MIXER_ENUMS(SPKDAT1L, WM5100_OUT5LMIX_INPUT_1_SOURCE); | ||
| 416 | WM5100_MIXER_ENUMS(SPKDAT1R, WM5100_OUT5RMIX_INPUT_1_SOURCE); | ||
| 417 | WM5100_MIXER_ENUMS(SPKDAT2L, WM5100_OUT6LMIX_INPUT_1_SOURCE); | ||
| 418 | WM5100_MIXER_ENUMS(SPKDAT2R, WM5100_OUT6RMIX_INPUT_1_SOURCE); | ||
| 419 | |||
| 420 | WM5100_MIXER_ENUMS(PWM1, WM5100_PWM1MIX_INPUT_1_SOURCE); | ||
| 421 | WM5100_MIXER_ENUMS(PWM2, WM5100_PWM1MIX_INPUT_1_SOURCE); | ||
| 422 | |||
| 423 | WM5100_MIXER_ENUMS(AIF1TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE); | ||
| 424 | WM5100_MIXER_ENUMS(AIF1TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE); | ||
| 425 | WM5100_MIXER_ENUMS(AIF1TX3, WM5100_AIF1TX3MIX_INPUT_1_SOURCE); | ||
| 426 | WM5100_MIXER_ENUMS(AIF1TX4, WM5100_AIF1TX4MIX_INPUT_1_SOURCE); | ||
| 427 | WM5100_MIXER_ENUMS(AIF1TX5, WM5100_AIF1TX5MIX_INPUT_1_SOURCE); | ||
| 428 | WM5100_MIXER_ENUMS(AIF1TX6, WM5100_AIF1TX6MIX_INPUT_1_SOURCE); | ||
| 429 | WM5100_MIXER_ENUMS(AIF1TX7, WM5100_AIF1TX7MIX_INPUT_1_SOURCE); | ||
| 430 | WM5100_MIXER_ENUMS(AIF1TX8, WM5100_AIF1TX8MIX_INPUT_1_SOURCE); | ||
| 431 | |||
| 432 | WM5100_MIXER_ENUMS(AIF2TX1, WM5100_AIF2TX1MIX_INPUT_1_SOURCE); | ||
| 433 | WM5100_MIXER_ENUMS(AIF2TX2, WM5100_AIF2TX2MIX_INPUT_1_SOURCE); | ||
| 434 | |||
| 435 | WM5100_MIXER_ENUMS(AIF3TX1, WM5100_AIF1TX1MIX_INPUT_1_SOURCE); | ||
| 436 | WM5100_MIXER_ENUMS(AIF3TX2, WM5100_AIF1TX2MIX_INPUT_1_SOURCE); | ||
| 437 | |||
| 438 | WM5100_MIXER_ENUMS(EQ1, WM5100_EQ1MIX_INPUT_1_SOURCE); | ||
| 439 | WM5100_MIXER_ENUMS(EQ2, WM5100_EQ2MIX_INPUT_1_SOURCE); | ||
| 440 | WM5100_MIXER_ENUMS(EQ3, WM5100_EQ3MIX_INPUT_1_SOURCE); | ||
| 441 | WM5100_MIXER_ENUMS(EQ4, WM5100_EQ4MIX_INPUT_1_SOURCE); | ||
| 442 | |||
| 443 | WM5100_MIXER_ENUMS(DRC1L, WM5100_DRC1LMIX_INPUT_1_SOURCE); | ||
| 444 | WM5100_MIXER_ENUMS(DRC1R, WM5100_DRC1RMIX_INPUT_1_SOURCE); | ||
| 445 | |||
| 446 | WM5100_MIXER_ENUMS(LHPF1, WM5100_HPLP1MIX_INPUT_1_SOURCE); | ||
| 447 | WM5100_MIXER_ENUMS(LHPF2, WM5100_HPLP2MIX_INPUT_1_SOURCE); | ||
| 448 | WM5100_MIXER_ENUMS(LHPF3, WM5100_HPLP3MIX_INPUT_1_SOURCE); | ||
| 449 | WM5100_MIXER_ENUMS(LHPF4, WM5100_HPLP4MIX_INPUT_1_SOURCE); | ||
| 450 | |||
| 451 | #define WM5100_MUX(name, ctrl) \ | ||
| 452 | SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl) | ||
| 453 | |||
| 454 | #define WM5100_MIXER_WIDGETS(name, name_str) \ | ||
| 455 | WM5100_MUX(name_str " Input 1", &name##_in1_mux), \ | ||
| 456 | WM5100_MUX(name_str " Input 2", &name##_in2_mux), \ | ||
| 457 | WM5100_MUX(name_str " Input 3", &name##_in3_mux), \ | ||
| 458 | WM5100_MUX(name_str " Input 4", &name##_in4_mux), \ | ||
| 459 | SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0) | ||
| 460 | |||
| 461 | #define WM5100_MIXER_INPUT_ROUTES(name) \ | ||
| 462 | { name, "Tone Generator 1", "Tone Generator 1" }, \ | ||
| 463 | { name, "Tone Generator 2", "Tone Generator 2" }, \ | ||
| 464 | { name, "IN1L", "IN1L PGA" }, \ | ||
| 465 | { name, "IN1R", "IN1R PGA" }, \ | ||
| 466 | { name, "IN2L", "IN2L PGA" }, \ | ||
| 467 | { name, "IN2R", "IN2R PGA" }, \ | ||
| 468 | { name, "IN3L", "IN3L PGA" }, \ | ||
| 469 | { name, "IN3R", "IN3R PGA" }, \ | ||
| 470 | { name, "IN4L", "IN4L PGA" }, \ | ||
| 471 | { name, "IN4R", "IN4R PGA" }, \ | ||
| 472 | { name, "AIF1RX1", "AIF1RX1" }, \ | ||
| 473 | { name, "AIF1RX2", "AIF1RX2" }, \ | ||
| 474 | { name, "AIF1RX3", "AIF1RX3" }, \ | ||
| 475 | { name, "AIF1RX4", "AIF1RX4" }, \ | ||
| 476 | { name, "AIF1RX5", "AIF1RX5" }, \ | ||
| 477 | { name, "AIF1RX6", "AIF1RX6" }, \ | ||
| 478 | { name, "AIF1RX7", "AIF1RX7" }, \ | ||
| 479 | { name, "AIF1RX8", "AIF1RX8" }, \ | ||
| 480 | { name, "AIF2RX1", "AIF2RX1" }, \ | ||
| 481 | { name, "AIF2RX2", "AIF2RX2" }, \ | ||
| 482 | { name, "AIF3RX1", "AIF3RX1" }, \ | ||
| 483 | { name, "AIF3RX2", "AIF3RX2" }, \ | ||
| 484 | { name, "EQ1", "EQ1" }, \ | ||
| 485 | { name, "EQ2", "EQ2" }, \ | ||
| 486 | { name, "EQ3", "EQ3" }, \ | ||
| 487 | { name, "EQ4", "EQ4" }, \ | ||
| 488 | { name, "DRC1L", "DRC1L" }, \ | ||
| 489 | { name, "DRC1R", "DRC1R" }, \ | ||
| 490 | { name, "LHPF1", "LHPF1" }, \ | ||
| 491 | { name, "LHPF2", "LHPF2" }, \ | ||
| 492 | { name, "LHPF3", "LHPF3" }, \ | ||
| 493 | { name, "LHPF4", "LHPF4" } | ||
| 494 | |||
| 495 | #define WM5100_MIXER_ROUTES(widget, name) \ | ||
| 496 | { widget, NULL, name " Mixer" }, \ | ||
| 497 | { name " Mixer", NULL, name " Input 1" }, \ | ||
| 498 | { name " Mixer", NULL, name " Input 2" }, \ | ||
| 499 | { name " Mixer", NULL, name " Input 3" }, \ | ||
| 500 | { name " Mixer", NULL, name " Input 4" }, \ | ||
| 501 | WM5100_MIXER_INPUT_ROUTES(name " Input 1"), \ | ||
| 502 | WM5100_MIXER_INPUT_ROUTES(name " Input 2"), \ | ||
| 503 | WM5100_MIXER_INPUT_ROUTES(name " Input 3"), \ | ||
| 504 | WM5100_MIXER_INPUT_ROUTES(name " Input 4") | ||
| 505 | |||
| 506 | static const char *wm5100_lhpf_mode_text[] = { | ||
| 507 | "Low-pass", "High-pass" | ||
| 508 | }; | ||
| 509 | |||
| 510 | static const struct soc_enum wm5100_lhpf1_mode = | ||
| 511 | SOC_ENUM_SINGLE(WM5100_HPLPF1_1, WM5100_LHPF1_MODE_SHIFT, 2, | ||
| 512 | wm5100_lhpf_mode_text); | ||
| 513 | |||
| 514 | static const struct soc_enum wm5100_lhpf2_mode = | ||
| 515 | SOC_ENUM_SINGLE(WM5100_HPLPF2_1, WM5100_LHPF2_MODE_SHIFT, 2, | ||
| 516 | wm5100_lhpf_mode_text); | ||
| 517 | |||
| 518 | static const struct soc_enum wm5100_lhpf3_mode = | ||
| 519 | SOC_ENUM_SINGLE(WM5100_HPLPF3_1, WM5100_LHPF3_MODE_SHIFT, 2, | ||
| 520 | wm5100_lhpf_mode_text); | ||
| 521 | |||
| 522 | static const struct soc_enum wm5100_lhpf4_mode = | ||
| 523 | SOC_ENUM_SINGLE(WM5100_HPLPF4_1, WM5100_LHPF4_MODE_SHIFT, 2, | ||
| 524 | wm5100_lhpf_mode_text); | ||
| 525 | |||
| 526 | static const struct snd_kcontrol_new wm5100_snd_controls[] = { | ||
| 527 | SOC_SINGLE("IN1 High Performance Switch", WM5100_IN1L_CONTROL, | ||
| 528 | WM5100_IN1_OSR_SHIFT, 1, 0), | ||
| 529 | SOC_SINGLE("IN2 High Performance Switch", WM5100_IN2L_CONTROL, | ||
| 530 | WM5100_IN2_OSR_SHIFT, 1, 0), | ||
| 531 | SOC_SINGLE("IN3 High Performance Switch", WM5100_IN3L_CONTROL, | ||
| 532 | WM5100_IN3_OSR_SHIFT, 1, 0), | ||
| 533 | SOC_SINGLE("IN4 High Performance Switch", WM5100_IN4L_CONTROL, | ||
| 534 | WM5100_IN4_OSR_SHIFT, 1, 0), | ||
| 535 | |||
| 536 | /* Only applicable for analogue inputs */ | ||
| 537 | SOC_DOUBLE_R_TLV("IN1 Volume", WM5100_IN1L_CONTROL, WM5100_IN1R_CONTROL, | ||
| 538 | WM5100_IN1L_PGA_VOL_SHIFT, 94, 0, in_tlv), | ||
| 539 | SOC_DOUBLE_R_TLV("IN2 Volume", WM5100_IN2L_CONTROL, WM5100_IN2R_CONTROL, | ||
| 540 | WM5100_IN2L_PGA_VOL_SHIFT, 94, 0, in_tlv), | ||
| 541 | SOC_DOUBLE_R_TLV("IN3 Volume", WM5100_IN3L_CONTROL, WM5100_IN3R_CONTROL, | ||
| 542 | WM5100_IN3L_PGA_VOL_SHIFT, 94, 0, in_tlv), | ||
| 543 | SOC_DOUBLE_R_TLV("IN4 Volume", WM5100_IN4L_CONTROL, WM5100_IN4R_CONTROL, | ||
| 544 | WM5100_IN4L_PGA_VOL_SHIFT, 94, 0, in_tlv), | ||
| 545 | |||
| 546 | SOC_DOUBLE_R_TLV("IN1 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_1L, | ||
| 547 | WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_VOL_SHIFT, 191, | ||
| 548 | 0, digital_tlv), | ||
| 549 | SOC_DOUBLE_R_TLV("IN2 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_2L, | ||
| 550 | WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_VOL_SHIFT, 191, | ||
| 551 | 0, digital_tlv), | ||
| 552 | SOC_DOUBLE_R_TLV("IN3 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_3L, | ||
| 553 | WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_VOL_SHIFT, 191, | ||
| 554 | 0, digital_tlv), | ||
| 555 | SOC_DOUBLE_R_TLV("IN4 Digital Volume", WM5100_ADC_DIGITAL_VOLUME_4L, | ||
| 556 | WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_VOL_SHIFT, 191, | ||
| 557 | 0, digital_tlv), | ||
| 558 | |||
| 559 | SOC_DOUBLE_R("IN1 Switch", WM5100_ADC_DIGITAL_VOLUME_1L, | ||
| 560 | WM5100_ADC_DIGITAL_VOLUME_1R, WM5100_IN1L_MUTE_SHIFT, 1, 1), | ||
| 561 | SOC_DOUBLE_R("IN2 Switch", WM5100_ADC_DIGITAL_VOLUME_2L, | ||
| 562 | WM5100_ADC_DIGITAL_VOLUME_2R, WM5100_IN2L_MUTE_SHIFT, 1, 1), | ||
| 563 | SOC_DOUBLE_R("IN3 Switch", WM5100_ADC_DIGITAL_VOLUME_3L, | ||
| 564 | WM5100_ADC_DIGITAL_VOLUME_3R, WM5100_IN3L_MUTE_SHIFT, 1, 1), | ||
| 565 | SOC_DOUBLE_R("IN4 Switch", WM5100_ADC_DIGITAL_VOLUME_4L, | ||
| 566 | WM5100_ADC_DIGITAL_VOLUME_4R, WM5100_IN4L_MUTE_SHIFT, 1, 1), | ||
| 567 | |||
| 568 | SOC_SINGLE("HPOUT1 High Performance Switch", WM5100_OUT_VOLUME_1L, | ||
| 569 | WM5100_OUT1_OSR_SHIFT, 1, 0), | ||
| 570 | SOC_SINGLE("HPOUT2 High Performance Switch", WM5100_OUT_VOLUME_2L, | ||
| 571 | WM5100_OUT2_OSR_SHIFT, 1, 0), | ||
| 572 | SOC_SINGLE("HPOUT3 High Performance Switch", WM5100_OUT_VOLUME_3L, | ||
| 573 | WM5100_OUT3_OSR_SHIFT, 1, 0), | ||
| 574 | SOC_SINGLE("SPKOUT High Performance Switch", WM5100_OUT_VOLUME_4L, | ||
| 575 | WM5100_OUT4_OSR_SHIFT, 1, 0), | ||
| 576 | SOC_SINGLE("SPKDAT1 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_5L, | ||
| 577 | WM5100_OUT5_OSR_SHIFT, 1, 0), | ||
| 578 | SOC_SINGLE("SPKDAT2 High Performance Switch", WM5100_DAC_VOLUME_LIMIT_6L, | ||
| 579 | WM5100_OUT6_OSR_SHIFT, 1, 0), | ||
| 580 | |||
| 581 | SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_1L, | ||
| 582 | WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_VOL_SHIFT, 159, 0, | ||
| 583 | digital_tlv), | ||
| 584 | SOC_DOUBLE_R_TLV("HPOUT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_2L, | ||
| 585 | WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_VOL_SHIFT, 159, 0, | ||
| 586 | digital_tlv), | ||
| 587 | SOC_DOUBLE_R_TLV("HPOUT3 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_3L, | ||
| 588 | WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_VOL_SHIFT, 159, 0, | ||
| 589 | digital_tlv), | ||
| 590 | SOC_DOUBLE_R_TLV("SPKOUT Digital Volume", WM5100_DAC_DIGITAL_VOLUME_4L, | ||
| 591 | WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_VOL_SHIFT, 159, 0, | ||
| 592 | digital_tlv), | ||
| 593 | SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_5L, | ||
| 594 | WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_VOL_SHIFT, 159, 0, | ||
| 595 | digital_tlv), | ||
| 596 | SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", WM5100_DAC_DIGITAL_VOLUME_6L, | ||
| 597 | WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_VOL_SHIFT, 159, 0, | ||
| 598 | digital_tlv), | ||
| 599 | |||
| 600 | SOC_DOUBLE_R("HPOUT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_1L, | ||
| 601 | WM5100_DAC_DIGITAL_VOLUME_1R, WM5100_OUT1L_MUTE_SHIFT, 1, 1), | ||
| 602 | SOC_DOUBLE_R("HPOUT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_2L, | ||
| 603 | WM5100_DAC_DIGITAL_VOLUME_2R, WM5100_OUT2L_MUTE_SHIFT, 1, 1), | ||
| 604 | SOC_DOUBLE_R("HPOUT3 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_3L, | ||
| 605 | WM5100_DAC_DIGITAL_VOLUME_3R, WM5100_OUT3L_MUTE_SHIFT, 1, 1), | ||
| 606 | SOC_DOUBLE_R("SPKOUT Digital Switch", WM5100_DAC_DIGITAL_VOLUME_4L, | ||
| 607 | WM5100_DAC_DIGITAL_VOLUME_4R, WM5100_OUT4L_MUTE_SHIFT, 1, 1), | ||
| 608 | SOC_DOUBLE_R("SPKDAT1 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_5L, | ||
| 609 | WM5100_DAC_DIGITAL_VOLUME_5R, WM5100_OUT5L_MUTE_SHIFT, 1, 1), | ||
| 610 | SOC_DOUBLE_R("SPKDAT2 Digital Switch", WM5100_DAC_DIGITAL_VOLUME_6L, | ||
| 611 | WM5100_DAC_DIGITAL_VOLUME_6R, WM5100_OUT6L_MUTE_SHIFT, 1, 1), | ||
| 612 | |||
| 613 | /* FIXME: Only valid from -12dB to 0dB (52-64) */ | ||
| 614 | SOC_DOUBLE_R_TLV("HPOUT1 Volume", WM5100_OUT_VOLUME_1L, WM5100_OUT_VOLUME_1R, | ||
| 615 | WM5100_OUT1L_PGA_VOL_SHIFT, 64, 0, out_tlv), | ||
| 616 | SOC_DOUBLE_R_TLV("HPOUT2 Volume", WM5100_OUT_VOLUME_2L, WM5100_OUT_VOLUME_2R, | ||
| 617 | WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv), | ||
| 618 | SOC_DOUBLE_R_TLV("HPOUT3 Volume", WM5100_OUT_VOLUME_3L, WM5100_OUT_VOLUME_3R, | ||
| 619 | WM5100_OUT2L_PGA_VOL_SHIFT, 64, 0, out_tlv), | ||
| 620 | |||
| 621 | SOC_DOUBLE("SPKDAT1 Switch", WM5100_PDM_SPK1_CTRL_1, WM5100_SPK1L_MUTE_SHIFT, | ||
| 622 | WM5100_SPK1R_MUTE_SHIFT, 1, 1), | ||
| 623 | SOC_DOUBLE("SPKDAT2 Switch", WM5100_PDM_SPK2_CTRL_1, WM5100_SPK2L_MUTE_SHIFT, | ||
| 624 | WM5100_SPK2R_MUTE_SHIFT, 1, 1), | ||
| 625 | |||
| 626 | SOC_SINGLE_TLV("EQ1 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ1_B1_GAIN_SHIFT, | ||
| 627 | 24, 0, eq_tlv), | ||
| 628 | SOC_SINGLE_TLV("EQ1 Band 2 Volume", WM5100_EQ1_1, WM5100_EQ1_B2_GAIN_SHIFT, | ||
| 629 | 24, 0, eq_tlv), | ||
| 630 | SOC_SINGLE_TLV("EQ1 Band 3 Volume", WM5100_EQ1_1, WM5100_EQ1_B3_GAIN_SHIFT, | ||
| 631 | 24, 0, eq_tlv), | ||
| 632 | SOC_SINGLE_TLV("EQ1 Band 4 Volume", WM5100_EQ1_2, WM5100_EQ1_B4_GAIN_SHIFT, | ||
| 633 | 24, 0, eq_tlv), | ||
| 634 | SOC_SINGLE_TLV("EQ1 Band 5 Volume", WM5100_EQ1_2, WM5100_EQ1_B5_GAIN_SHIFT, | ||
| 635 | 24, 0, eq_tlv), | ||
| 636 | |||
| 637 | SOC_SINGLE_TLV("EQ2 Band 1 Volume", WM5100_EQ2_1, WM5100_EQ2_B1_GAIN_SHIFT, | ||
| 638 | 24, 0, eq_tlv), | ||
| 639 | SOC_SINGLE_TLV("EQ2 Band 2 Volume", WM5100_EQ2_1, WM5100_EQ2_B2_GAIN_SHIFT, | ||
| 640 | 24, 0, eq_tlv), | ||
| 641 | SOC_SINGLE_TLV("EQ2 Band 3 Volume", WM5100_EQ2_1, WM5100_EQ2_B3_GAIN_SHIFT, | ||
| 642 | 24, 0, eq_tlv), | ||
| 643 | SOC_SINGLE_TLV("EQ2 Band 4 Volume", WM5100_EQ2_2, WM5100_EQ2_B4_GAIN_SHIFT, | ||
| 644 | 24, 0, eq_tlv), | ||
| 645 | SOC_SINGLE_TLV("EQ2 Band 5 Volume", WM5100_EQ2_2, WM5100_EQ2_B5_GAIN_SHIFT, | ||
| 646 | 24, 0, eq_tlv), | ||
| 647 | |||
| 648 | SOC_SINGLE_TLV("EQ3 Band 1 Volume", WM5100_EQ1_1, WM5100_EQ3_B1_GAIN_SHIFT, | ||
| 649 | 24, 0, eq_tlv), | ||
| 650 | SOC_SINGLE_TLV("EQ3 Band 2 Volume", WM5100_EQ3_1, WM5100_EQ3_B2_GAIN_SHIFT, | ||
| 651 | 24, 0, eq_tlv), | ||
| 652 | SOC_SINGLE_TLV("EQ3 Band 3 Volume", WM5100_EQ3_1, WM5100_EQ3_B3_GAIN_SHIFT, | ||
| 653 | 24, 0, eq_tlv), | ||
| 654 | SOC_SINGLE_TLV("EQ3 Band 4 Volume", WM5100_EQ3_2, WM5100_EQ3_B4_GAIN_SHIFT, | ||
| 655 | 24, 0, eq_tlv), | ||
| 656 | SOC_SINGLE_TLV("EQ3 Band 5 Volume", WM5100_EQ3_2, WM5100_EQ3_B5_GAIN_SHIFT, | ||
| 657 | 24, 0, eq_tlv), | ||
| 658 | |||
| 659 | SOC_SINGLE_TLV("EQ4 Band 1 Volume", WM5100_EQ4_1, WM5100_EQ4_B1_GAIN_SHIFT, | ||
| 660 | 24, 0, eq_tlv), | ||
| 661 | SOC_SINGLE_TLV("EQ4 Band 2 Volume", WM5100_EQ4_1, WM5100_EQ4_B2_GAIN_SHIFT, | ||
| 662 | 24, 0, eq_tlv), | ||
| 663 | SOC_SINGLE_TLV("EQ4 Band 3 Volume", WM5100_EQ4_1, WM5100_EQ4_B3_GAIN_SHIFT, | ||
| 664 | 24, 0, eq_tlv), | ||
| 665 | SOC_SINGLE_TLV("EQ4 Band 4 Volume", WM5100_EQ4_2, WM5100_EQ4_B4_GAIN_SHIFT, | ||
| 666 | 24, 0, eq_tlv), | ||
| 667 | SOC_SINGLE_TLV("EQ4 Band 5 Volume", WM5100_EQ4_2, WM5100_EQ4_B5_GAIN_SHIFT, | ||
| 668 | 24, 0, eq_tlv), | ||
| 669 | |||
| 670 | SOC_ENUM("LHPF1 Mode", wm5100_lhpf1_mode), | ||
| 671 | SOC_ENUM("LHPF2 Mode", wm5100_lhpf2_mode), | ||
| 672 | SOC_ENUM("LHPF3 Mode", wm5100_lhpf3_mode), | ||
| 673 | SOC_ENUM("LHPF4 Mode", wm5100_lhpf4_mode), | ||
| 674 | |||
| 675 | WM5100_MIXER_CONTROLS("HPOUT1L", WM5100_OUT1LMIX_INPUT_1_SOURCE), | ||
| 676 | WM5100_MIXER_CONTROLS("HPOUT1R", WM5100_OUT1RMIX_INPUT_1_SOURCE), | ||
| 677 | WM5100_MIXER_CONTROLS("HPOUT2L", WM5100_OUT2LMIX_INPUT_1_SOURCE), | ||
| 678 | WM5100_MIXER_CONTROLS("HPOUT2R", WM5100_OUT2RMIX_INPUT_1_SOURCE), | ||
| 679 | WM5100_MIXER_CONTROLS("HPOUT3L", WM5100_OUT3LMIX_INPUT_1_SOURCE), | ||
| 680 | WM5100_MIXER_CONTROLS("HPOUT3R", WM5100_OUT3RMIX_INPUT_1_SOURCE), | ||
| 681 | |||
| 682 | WM5100_MIXER_CONTROLS("SPKOUTL", WM5100_OUT4LMIX_INPUT_1_SOURCE), | ||
| 683 | WM5100_MIXER_CONTROLS("SPKOUTR", WM5100_OUT4RMIX_INPUT_1_SOURCE), | ||
| 684 | WM5100_MIXER_CONTROLS("SPKDAT1L", WM5100_OUT5LMIX_INPUT_1_SOURCE), | ||
| 685 | WM5100_MIXER_CONTROLS("SPKDAT1R", WM5100_OUT5RMIX_INPUT_1_SOURCE), | ||
| 686 | WM5100_MIXER_CONTROLS("SPKDAT2L", WM5100_OUT6LMIX_INPUT_1_SOURCE), | ||
| 687 | WM5100_MIXER_CONTROLS("SPKDAT2R", WM5100_OUT6RMIX_INPUT_1_SOURCE), | ||
| 688 | |||
| 689 | WM5100_MIXER_CONTROLS("PWM1", WM5100_PWM1MIX_INPUT_1_SOURCE), | ||
| 690 | WM5100_MIXER_CONTROLS("PWM2", WM5100_PWM2MIX_INPUT_1_SOURCE), | ||
| 691 | |||
| 692 | WM5100_MIXER_CONTROLS("AIF1TX1", WM5100_AIF1TX1MIX_INPUT_1_SOURCE), | ||
| 693 | WM5100_MIXER_CONTROLS("AIF1TX2", WM5100_AIF1TX2MIX_INPUT_1_SOURCE), | ||
| 694 | WM5100_MIXER_CONTROLS("AIF1TX3", WM5100_AIF1TX3MIX_INPUT_1_SOURCE), | ||
| 695 | WM5100_MIXER_CONTROLS("AIF1TX4", WM5100_AIF1TX4MIX_INPUT_1_SOURCE), | ||
| 696 | WM5100_MIXER_CONTROLS("AIF1TX5", WM5100_AIF1TX5MIX_INPUT_1_SOURCE), | ||
| 697 | WM5100_MIXER_CONTROLS("AIF1TX6", WM5100_AIF1TX6MIX_INPUT_1_SOURCE), | ||
| 698 | WM5100_MIXER_CONTROLS("AIF1TX7", WM5100_AIF1TX7MIX_INPUT_1_SOURCE), | ||
| 699 | WM5100_MIXER_CONTROLS("AIF1TX8", WM5100_AIF1TX8MIX_INPUT_1_SOURCE), | ||
| 700 | |||
| 701 | WM5100_MIXER_CONTROLS("AIF2TX1", WM5100_AIF2TX1MIX_INPUT_1_SOURCE), | ||
| 702 | WM5100_MIXER_CONTROLS("AIF2TX2", WM5100_AIF2TX2MIX_INPUT_1_SOURCE), | ||
| 703 | |||
| 704 | WM5100_MIXER_CONTROLS("AIF3TX1", WM5100_AIF3TX1MIX_INPUT_1_SOURCE), | ||
| 705 | WM5100_MIXER_CONTROLS("AIF3TX2", WM5100_AIF3TX2MIX_INPUT_1_SOURCE), | ||
| 706 | |||
| 707 | WM5100_MIXER_CONTROLS("EQ1", WM5100_EQ1MIX_INPUT_1_SOURCE), | ||
| 708 | WM5100_MIXER_CONTROLS("EQ2", WM5100_EQ2MIX_INPUT_1_SOURCE), | ||
| 709 | WM5100_MIXER_CONTROLS("EQ3", WM5100_EQ3MIX_INPUT_1_SOURCE), | ||
| 710 | WM5100_MIXER_CONTROLS("EQ4", WM5100_EQ4MIX_INPUT_1_SOURCE), | ||
| 711 | |||
| 712 | WM5100_MIXER_CONTROLS("DRC1L", WM5100_DRC1LMIX_INPUT_1_SOURCE), | ||
| 713 | WM5100_MIXER_CONTROLS("DRC1R", WM5100_DRC1RMIX_INPUT_1_SOURCE), | ||
| 714 | |||
| 715 | WM5100_MIXER_CONTROLS("LHPF1", WM5100_HPLP1MIX_INPUT_1_SOURCE), | ||
| 716 | WM5100_MIXER_CONTROLS("LHPF2", WM5100_HPLP2MIX_INPUT_1_SOURCE), | ||
| 717 | WM5100_MIXER_CONTROLS("LHPF3", WM5100_HPLP3MIX_INPUT_1_SOURCE), | ||
| 718 | WM5100_MIXER_CONTROLS("LHPF4", WM5100_HPLP4MIX_INPUT_1_SOURCE), | ||
| 719 | }; | ||
| 720 | |||
| 721 | static void wm5100_seq_notifier(struct snd_soc_dapm_context *dapm, | ||
| 722 | enum snd_soc_dapm_type event, int subseq) | ||
| 723 | { | ||
| 724 | struct snd_soc_codec *codec = container_of(dapm, | ||
| 725 | struct snd_soc_codec, dapm); | ||
| 726 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 727 | u16 val, expect, i; | ||
| 728 | |||
| 729 | /* Wait for the outputs to flag themselves as enabled */ | ||
| 730 | if (wm5100->out_ena[0]) { | ||
| 731 | expect = snd_soc_read(codec, WM5100_CHANNEL_ENABLES_1); | ||
| 732 | for (i = 0; i < 200; i++) { | ||
| 733 | val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_1); | ||
| 734 | if (val == expect) { | ||
| 735 | wm5100->out_ena[0] = false; | ||
| 736 | break; | ||
| 737 | } | ||
| 738 | } | ||
| 739 | if (i == 200) { | ||
| 740 | dev_err(codec->dev, "Timeout waiting for OUTPUT1 %x\n", | ||
| 741 | expect); | ||
| 742 | } | ||
| 743 | } | ||
| 744 | |||
| 745 | if (wm5100->out_ena[1]) { | ||
| 746 | expect = snd_soc_read(codec, WM5100_OUTPUT_ENABLES_2); | ||
| 747 | for (i = 0; i < 200; i++) { | ||
| 748 | val = snd_soc_read(codec, WM5100_OUTPUT_STATUS_2); | ||
| 749 | if (val == expect) { | ||
| 750 | wm5100->out_ena[1] = false; | ||
| 751 | break; | ||
| 752 | } | ||
| 753 | } | ||
| 754 | if (i == 200) { | ||
| 755 | dev_err(codec->dev, "Timeout waiting for OUTPUT2 %x\n", | ||
| 756 | expect); | ||
| 757 | } | ||
| 758 | } | ||
| 759 | } | ||
| 760 | |||
| 761 | static int wm5100_out_ev(struct snd_soc_dapm_widget *w, | ||
| 762 | struct snd_kcontrol *kcontrol, | ||
| 763 | int event) | ||
| 764 | { | ||
| 765 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(w->codec); | ||
| 766 | |||
| 767 | switch (w->reg) { | ||
| 768 | case WM5100_CHANNEL_ENABLES_1: | ||
| 769 | wm5100->out_ena[0] = true; | ||
| 770 | break; | ||
| 771 | case WM5100_OUTPUT_ENABLES_2: | ||
| 772 | wm5100->out_ena[0] = true; | ||
| 773 | break; | ||
| 774 | default: | ||
| 775 | break; | ||
| 776 | } | ||
| 777 | |||
| 778 | return 0; | ||
| 779 | } | ||
| 780 | |||
| 781 | static int wm5100_cp_ev(struct snd_soc_dapm_widget *w, | ||
| 782 | struct snd_kcontrol *kcontrol, | ||
| 783 | int event) | ||
| 784 | { | ||
| 785 | struct snd_soc_codec *codec = w->codec; | ||
| 786 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 787 | int ret; | ||
| 788 | |||
| 789 | switch (event) { | ||
| 790 | case SND_SOC_DAPM_PRE_PMU: | ||
| 791 | ret = regulator_enable(wm5100->cpvdd); | ||
| 792 | if (ret != 0) { | ||
| 793 | dev_err(codec->dev, "Failed to enable CPVDD: %d\n", | ||
| 794 | ret); | ||
| 795 | return ret; | ||
| 796 | } | ||
| 797 | return ret; | ||
| 798 | |||
| 799 | case SND_SOC_DAPM_POST_PMD: | ||
| 800 | ret = regulator_disable_deferred(wm5100->cpvdd, 20); | ||
| 801 | if (ret != 0) { | ||
| 802 | dev_err(codec->dev, "Failed to disable CPVDD: %d\n", | ||
| 803 | ret); | ||
| 804 | return ret; | ||
| 805 | } | ||
| 806 | return ret; | ||
| 807 | |||
| 808 | default: | ||
| 809 | BUG(); | ||
| 810 | return 0; | ||
| 811 | } | ||
| 812 | } | ||
| 813 | |||
| 814 | static int wm5100_dbvdd_ev(struct snd_soc_dapm_widget *w, | ||
| 815 | struct snd_kcontrol *kcontrol, | ||
| 816 | int event) | ||
| 817 | { | ||
| 818 | struct snd_soc_codec *codec = w->codec; | ||
| 819 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 820 | struct regulator *regulator; | ||
| 821 | int ret; | ||
| 822 | |||
| 823 | switch (w->shift) { | ||
| 824 | case 2: | ||
| 825 | regulator = wm5100->dbvdd2; | ||
| 826 | break; | ||
| 827 | case 3: | ||
| 828 | regulator = wm5100->dbvdd3; | ||
| 829 | break; | ||
| 830 | default: | ||
| 831 | BUG(); | ||
| 832 | return 0; | ||
| 833 | } | ||
| 834 | |||
| 835 | switch (event) { | ||
| 836 | case SND_SOC_DAPM_PRE_PMU: | ||
| 837 | ret = regulator_enable(regulator); | ||
| 838 | if (ret != 0) { | ||
| 839 | dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n", | ||
| 840 | w->shift, ret); | ||
| 841 | return ret; | ||
| 842 | } | ||
| 843 | return ret; | ||
| 844 | |||
| 845 | case SND_SOC_DAPM_POST_PMD: | ||
| 846 | ret = regulator_disable(regulator); | ||
| 847 | if (ret != 0) { | ||
| 848 | dev_err(codec->dev, "Failed to enable DBVDD%d: %d\n", | ||
| 849 | w->shift, ret); | ||
| 850 | return ret; | ||
| 851 | } | ||
| 852 | return ret; | ||
| 853 | |||
| 854 | default: | ||
| 855 | BUG(); | ||
| 856 | return 0; | ||
| 857 | } | ||
| 858 | } | ||
| 859 | |||
| 860 | static void wm5100_log_status3(struct snd_soc_codec *codec, int val) | ||
| 861 | { | ||
| 862 | if (val & WM5100_SPK_SHUTDOWN_WARN_EINT) | ||
| 863 | dev_crit(codec->dev, "Speaker shutdown warning\n"); | ||
| 864 | if (val & WM5100_SPK_SHUTDOWN_EINT) | ||
| 865 | dev_crit(codec->dev, "Speaker shutdown\n"); | ||
| 866 | if (val & WM5100_CLKGEN_ERR_EINT) | ||
| 867 | dev_crit(codec->dev, "SYSCLK underclocked\n"); | ||
| 868 | if (val & WM5100_CLKGEN_ERR_ASYNC_EINT) | ||
| 869 | dev_crit(codec->dev, "ASYNCCLK underclocked\n"); | ||
| 870 | } | ||
| 871 | |||
| 872 | static void wm5100_log_status4(struct snd_soc_codec *codec, int val) | ||
| 873 | { | ||
| 874 | if (val & WM5100_AIF3_ERR_EINT) | ||
| 875 | dev_err(codec->dev, "AIF3 configuration error\n"); | ||
| 876 | if (val & WM5100_AIF2_ERR_EINT) | ||
| 877 | dev_err(codec->dev, "AIF2 configuration error\n"); | ||
| 878 | if (val & WM5100_AIF1_ERR_EINT) | ||
| 879 | dev_err(codec->dev, "AIF1 configuration error\n"); | ||
| 880 | if (val & WM5100_CTRLIF_ERR_EINT) | ||
| 881 | dev_err(codec->dev, "Control interface error\n"); | ||
| 882 | if (val & WM5100_ISRC2_UNDERCLOCKED_EINT) | ||
| 883 | dev_err(codec->dev, "ISRC2 underclocked\n"); | ||
| 884 | if (val & WM5100_ISRC1_UNDERCLOCKED_EINT) | ||
| 885 | dev_err(codec->dev, "ISRC1 underclocked\n"); | ||
| 886 | if (val & WM5100_FX_UNDERCLOCKED_EINT) | ||
| 887 | dev_err(codec->dev, "FX underclocked\n"); | ||
| 888 | if (val & WM5100_AIF3_UNDERCLOCKED_EINT) | ||
| 889 | dev_err(codec->dev, "AIF3 underclocked\n"); | ||
| 890 | if (val & WM5100_AIF2_UNDERCLOCKED_EINT) | ||
| 891 | dev_err(codec->dev, "AIF2 underclocked\n"); | ||
| 892 | if (val & WM5100_AIF1_UNDERCLOCKED_EINT) | ||
| 893 | dev_err(codec->dev, "AIF1 underclocked\n"); | ||
| 894 | if (val & WM5100_ASRC_UNDERCLOCKED_EINT) | ||
| 895 | dev_err(codec->dev, "ASRC underclocked\n"); | ||
| 896 | if (val & WM5100_DAC_UNDERCLOCKED_EINT) | ||
| 897 | dev_err(codec->dev, "DAC underclocked\n"); | ||
| 898 | if (val & WM5100_ADC_UNDERCLOCKED_EINT) | ||
| 899 | dev_err(codec->dev, "ADC underclocked\n"); | ||
| 900 | if (val & WM5100_MIXER_UNDERCLOCKED_EINT) | ||
| 901 | dev_err(codec->dev, "Mixer underclocked\n"); | ||
| 902 | } | ||
| 903 | |||
| 904 | static int wm5100_post_ev(struct snd_soc_dapm_widget *w, | ||
| 905 | struct snd_kcontrol *kcontrol, | ||
| 906 | int event) | ||
| 907 | { | ||
| 908 | struct snd_soc_codec *codec = w->codec; | ||
| 909 | int ret; | ||
| 910 | |||
| 911 | ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_3); | ||
| 912 | ret &= WM5100_SPK_SHUTDOWN_WARN_STS | | ||
| 913 | WM5100_SPK_SHUTDOWN_STS | WM5100_CLKGEN_ERR_STS | | ||
| 914 | WM5100_CLKGEN_ERR_ASYNC_STS; | ||
| 915 | wm5100_log_status3(codec, ret); | ||
| 916 | |||
| 917 | ret = snd_soc_read(codec, WM5100_INTERRUPT_RAW_STATUS_4); | ||
| 918 | wm5100_log_status4(codec, ret); | ||
| 919 | |||
| 920 | return 0; | ||
| 921 | } | ||
| 922 | |||
| 923 | static const struct snd_soc_dapm_widget wm5100_dapm_widgets[] = { | ||
| 924 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM5100_CLOCKING_3, WM5100_SYSCLK_ENA_SHIFT, 0, | ||
| 925 | NULL, 0), | ||
| 926 | SND_SOC_DAPM_SUPPLY("ASYNCCLK", WM5100_CLOCKING_6, WM5100_ASYNC_CLK_ENA_SHIFT, | ||
| 927 | 0, NULL, 0), | ||
| 928 | |||
| 929 | SND_SOC_DAPM_SUPPLY("CP1", WM5100_HP_CHARGE_PUMP_1, WM5100_CP1_ENA_SHIFT, 0, | ||
| 930 | wm5100_cp_ev, | ||
| 931 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 932 | SND_SOC_DAPM_SUPPLY("CP2", WM5100_MIC_CHARGE_PUMP_1, WM5100_CP2_ENA_SHIFT, 0, | ||
| 933 | NULL, 0), | ||
| 934 | SND_SOC_DAPM_SUPPLY("CP2 Active", WM5100_MIC_CHARGE_PUMP_1, | ||
| 935 | WM5100_CP2_BYPASS_SHIFT, 1, wm5100_cp_ev, | ||
| 936 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 937 | SND_SOC_DAPM_SUPPLY("DBVDD2", SND_SOC_NOPM, 2, 0, wm5100_dbvdd_ev, | ||
| 938 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 939 | SND_SOC_DAPM_SUPPLY("DBVDD3", SND_SOC_NOPM, 3, 0, wm5100_dbvdd_ev, | ||
| 940 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 941 | |||
| 942 | SND_SOC_DAPM_SUPPLY("MICBIAS1", WM5100_MIC_BIAS_CTRL_1, WM5100_MICB1_ENA_SHIFT, | ||
| 943 | 0, NULL, 0), | ||
| 944 | SND_SOC_DAPM_SUPPLY("MICBIAS2", WM5100_MIC_BIAS_CTRL_2, WM5100_MICB2_ENA_SHIFT, | ||
| 945 | 0, NULL, 0), | ||
| 946 | SND_SOC_DAPM_SUPPLY("MICBIAS3", WM5100_MIC_BIAS_CTRL_3, WM5100_MICB3_ENA_SHIFT, | ||
| 947 | 0, NULL, 0), | ||
| 948 | |||
| 949 | SND_SOC_DAPM_INPUT("IN1L"), | ||
| 950 | SND_SOC_DAPM_INPUT("IN1R"), | ||
| 951 | SND_SOC_DAPM_INPUT("IN2L"), | ||
| 952 | SND_SOC_DAPM_INPUT("IN2R"), | ||
| 953 | SND_SOC_DAPM_INPUT("IN3L"), | ||
| 954 | SND_SOC_DAPM_INPUT("IN3R"), | ||
| 955 | SND_SOC_DAPM_INPUT("IN4L"), | ||
| 956 | SND_SOC_DAPM_INPUT("IN4R"), | ||
| 957 | SND_SOC_DAPM_INPUT("TONE"), | ||
| 958 | |||
| 959 | SND_SOC_DAPM_PGA_E("IN1L PGA", WM5100_INPUT_ENABLES, WM5100_IN1L_ENA_SHIFT, 0, | ||
| 960 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 961 | SND_SOC_DAPM_PGA_E("IN1R PGA", WM5100_INPUT_ENABLES, WM5100_IN1R_ENA_SHIFT, 0, | ||
| 962 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 963 | SND_SOC_DAPM_PGA_E("IN2L PGA", WM5100_INPUT_ENABLES, WM5100_IN2L_ENA_SHIFT, 0, | ||
| 964 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 965 | SND_SOC_DAPM_PGA_E("IN2R PGA", WM5100_INPUT_ENABLES, WM5100_IN2R_ENA_SHIFT, 0, | ||
| 966 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 967 | SND_SOC_DAPM_PGA_E("IN3L PGA", WM5100_INPUT_ENABLES, WM5100_IN3L_ENA_SHIFT, 0, | ||
| 968 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 969 | SND_SOC_DAPM_PGA_E("IN3R PGA", WM5100_INPUT_ENABLES, WM5100_IN3R_ENA_SHIFT, 0, | ||
| 970 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 971 | SND_SOC_DAPM_PGA_E("IN4L PGA", WM5100_INPUT_ENABLES, WM5100_IN4L_ENA_SHIFT, 0, | ||
| 972 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 973 | SND_SOC_DAPM_PGA_E("IN4R PGA", WM5100_INPUT_ENABLES, WM5100_IN4R_ENA_SHIFT, 0, | ||
| 974 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 975 | |||
| 976 | SND_SOC_DAPM_PGA("Tone Generator 1", WM5100_TONE_GENERATOR_1, | ||
| 977 | WM5100_TONE1_ENA_SHIFT, 0, NULL, 0), | ||
| 978 | SND_SOC_DAPM_PGA("Tone Generator 2", WM5100_TONE_GENERATOR_1, | ||
| 979 | WM5100_TONE2_ENA_SHIFT, 0, NULL, 0), | ||
| 980 | |||
| 981 | SND_SOC_DAPM_AIF_IN("AIF1RX1", "AIF1 Playback", 0, | ||
| 982 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX1_ENA_SHIFT, 0), | ||
| 983 | SND_SOC_DAPM_AIF_IN("AIF1RX2", "AIF1 Playback", 1, | ||
| 984 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX2_ENA_SHIFT, 0), | ||
| 985 | SND_SOC_DAPM_AIF_IN("AIF1RX3", "AIF1 Playback", 2, | ||
| 986 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX3_ENA_SHIFT, 0), | ||
| 987 | SND_SOC_DAPM_AIF_IN("AIF1RX4", "AIF1 Playback", 3, | ||
| 988 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX4_ENA_SHIFT, 0), | ||
| 989 | SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 4, | ||
| 990 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX5_ENA_SHIFT, 0), | ||
| 991 | SND_SOC_DAPM_AIF_IN("AIF1RX6", "AIF1 Playback", 5, | ||
| 992 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX6_ENA_SHIFT, 0), | ||
| 993 | SND_SOC_DAPM_AIF_IN("AIF1RX7", "AIF1 Playback", 6, | ||
| 994 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX7_ENA_SHIFT, 0), | ||
| 995 | SND_SOC_DAPM_AIF_IN("AIF1RX8", "AIF1 Playback", 7, | ||
| 996 | WM5100_AUDIO_IF_1_27, WM5100_AIF1RX8_ENA_SHIFT, 0), | ||
| 997 | |||
| 998 | SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0, | ||
| 999 | WM5100_AUDIO_IF_2_27, WM5100_AIF2RX1_ENA_SHIFT, 0), | ||
| 1000 | SND_SOC_DAPM_AIF_IN("AIF2RX2", "AIF2 Playback", 1, | ||
| 1001 | WM5100_AUDIO_IF_2_27, WM5100_AIF2RX2_ENA_SHIFT, 0), | ||
| 1002 | |||
| 1003 | SND_SOC_DAPM_AIF_IN("AIF3RX1", "AIF3 Playback", 0, | ||
| 1004 | WM5100_AUDIO_IF_3_27, WM5100_AIF3RX1_ENA_SHIFT, 0), | ||
| 1005 | SND_SOC_DAPM_AIF_IN("AIF3RX2", "AIF3 Playback", 1, | ||
| 1006 | WM5100_AUDIO_IF_3_27, WM5100_AIF3RX2_ENA_SHIFT, 0), | ||
| 1007 | |||
| 1008 | SND_SOC_DAPM_AIF_OUT("AIF1TX1", "AIF1 Capture", 0, | ||
| 1009 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX1_ENA_SHIFT, 0), | ||
| 1010 | SND_SOC_DAPM_AIF_OUT("AIF1TX2", "AIF1 Capture", 1, | ||
| 1011 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX2_ENA_SHIFT, 0), | ||
| 1012 | SND_SOC_DAPM_AIF_OUT("AIF1TX3", "AIF1 Capture", 2, | ||
| 1013 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX3_ENA_SHIFT, 0), | ||
| 1014 | SND_SOC_DAPM_AIF_OUT("AIF1TX4", "AIF1 Capture", 3, | ||
| 1015 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX4_ENA_SHIFT, 0), | ||
| 1016 | SND_SOC_DAPM_AIF_OUT("AIF1TX5", "AIF1 Capture", 4, | ||
| 1017 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX5_ENA_SHIFT, 0), | ||
| 1018 | SND_SOC_DAPM_AIF_OUT("AIF1TX6", "AIF1 Capture", 5, | ||
| 1019 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX6_ENA_SHIFT, 0), | ||
| 1020 | SND_SOC_DAPM_AIF_OUT("AIF1TX7", "AIF1 Capture", 6, | ||
| 1021 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX7_ENA_SHIFT, 0), | ||
| 1022 | SND_SOC_DAPM_AIF_OUT("AIF1TX8", "AIF1 Capture", 7, | ||
| 1023 | WM5100_AUDIO_IF_1_26, WM5100_AIF1TX8_ENA_SHIFT, 0), | ||
| 1024 | |||
| 1025 | SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0, | ||
| 1026 | WM5100_AUDIO_IF_2_26, WM5100_AIF2TX1_ENA_SHIFT, 0), | ||
| 1027 | SND_SOC_DAPM_AIF_OUT("AIF2TX2", "AIF2 Capture", 1, | ||
| 1028 | WM5100_AUDIO_IF_2_26, WM5100_AIF2TX2_ENA_SHIFT, 0), | ||
| 1029 | |||
| 1030 | SND_SOC_DAPM_AIF_OUT("AIF3TX1", "AIF3 Capture", 0, | ||
| 1031 | WM5100_AUDIO_IF_3_26, WM5100_AIF3TX1_ENA_SHIFT, 0), | ||
| 1032 | SND_SOC_DAPM_AIF_OUT("AIF3TX2", "AIF3 Capture", 1, | ||
| 1033 | WM5100_AUDIO_IF_3_26, WM5100_AIF3TX2_ENA_SHIFT, 0), | ||
| 1034 | |||
| 1035 | SND_SOC_DAPM_PGA_E("OUT6L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6L_ENA_SHIFT, 0, | ||
| 1036 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1037 | SND_SOC_DAPM_PGA_E("OUT6R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT6R_ENA_SHIFT, 0, | ||
| 1038 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1039 | SND_SOC_DAPM_PGA_E("OUT5L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5L_ENA_SHIFT, 0, | ||
| 1040 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1041 | SND_SOC_DAPM_PGA_E("OUT5R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT5R_ENA_SHIFT, 0, | ||
| 1042 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1043 | SND_SOC_DAPM_PGA_E("OUT4L", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4L_ENA_SHIFT, 0, | ||
| 1044 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1045 | SND_SOC_DAPM_PGA_E("OUT4R", WM5100_OUTPUT_ENABLES_2, WM5100_OUT4R_ENA_SHIFT, 0, | ||
| 1046 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1047 | SND_SOC_DAPM_PGA_E("OUT3L", WM5100_CHANNEL_ENABLES_1, WM5100_HP3L_ENA_SHIFT, 0, | ||
| 1048 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1049 | SND_SOC_DAPM_PGA_E("OUT3R", WM5100_CHANNEL_ENABLES_1, WM5100_HP3R_ENA_SHIFT, 0, | ||
| 1050 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1051 | SND_SOC_DAPM_PGA_E("OUT2L", WM5100_CHANNEL_ENABLES_1, WM5100_HP2L_ENA_SHIFT, 0, | ||
| 1052 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1053 | SND_SOC_DAPM_PGA_E("OUT2R", WM5100_CHANNEL_ENABLES_1, WM5100_HP2R_ENA_SHIFT, 0, | ||
| 1054 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1055 | SND_SOC_DAPM_PGA_E("OUT1L", WM5100_CHANNEL_ENABLES_1, WM5100_HP1L_ENA_SHIFT, 0, | ||
| 1056 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1057 | SND_SOC_DAPM_PGA_E("OUT1R", WM5100_CHANNEL_ENABLES_1, WM5100_HP1R_ENA_SHIFT, 0, | ||
| 1058 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1059 | SND_SOC_DAPM_PGA_E("PWM1 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM1_ENA_SHIFT, 0, | ||
| 1060 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1061 | SND_SOC_DAPM_PGA_E("PWM2 Driver", WM5100_PWM_DRIVE_1, WM5100_PWM2_ENA_SHIFT, 0, | ||
| 1062 | NULL, 0, wm5100_out_ev, SND_SOC_DAPM_POST_PMU), | ||
| 1063 | |||
| 1064 | SND_SOC_DAPM_PGA("EQ1", WM5100_EQ1_1, WM5100_EQ1_ENA_SHIFT, 0, NULL, 0), | ||
| 1065 | SND_SOC_DAPM_PGA("EQ2", WM5100_EQ2_1, WM5100_EQ2_ENA_SHIFT, 0, NULL, 0), | ||
| 1066 | SND_SOC_DAPM_PGA("EQ3", WM5100_EQ3_1, WM5100_EQ3_ENA_SHIFT, 0, NULL, 0), | ||
| 1067 | SND_SOC_DAPM_PGA("EQ4", WM5100_EQ4_1, WM5100_EQ4_ENA_SHIFT, 0, NULL, 0), | ||
| 1068 | |||
| 1069 | SND_SOC_DAPM_PGA("DRC1L", WM5100_DRC1_CTRL1, WM5100_DRCL_ENA_SHIFT, 0, | ||
| 1070 | NULL, 0), | ||
| 1071 | SND_SOC_DAPM_PGA("DRC1R", WM5100_DRC1_CTRL1, WM5100_DRCR_ENA_SHIFT, 0, | ||
| 1072 | NULL, 0), | ||
| 1073 | |||
| 1074 | SND_SOC_DAPM_PGA("LHPF1", WM5100_HPLPF1_1, WM5100_LHPF1_ENA_SHIFT, 0, | ||
| 1075 | NULL, 0), | ||
| 1076 | SND_SOC_DAPM_PGA("LHPF2", WM5100_HPLPF2_1, WM5100_LHPF2_ENA_SHIFT, 0, | ||
| 1077 | NULL, 0), | ||
| 1078 | SND_SOC_DAPM_PGA("LHPF3", WM5100_HPLPF3_1, WM5100_LHPF3_ENA_SHIFT, 0, | ||
| 1079 | NULL, 0), | ||
| 1080 | SND_SOC_DAPM_PGA("LHPF4", WM5100_HPLPF4_1, WM5100_LHPF4_ENA_SHIFT, 0, | ||
| 1081 | NULL, 0), | ||
| 1082 | |||
| 1083 | WM5100_MIXER_WIDGETS(EQ1, "EQ1"), | ||
| 1084 | WM5100_MIXER_WIDGETS(EQ2, "EQ2"), | ||
| 1085 | WM5100_MIXER_WIDGETS(EQ3, "EQ3"), | ||
| 1086 | WM5100_MIXER_WIDGETS(EQ4, "EQ4"), | ||
| 1087 | |||
| 1088 | WM5100_MIXER_WIDGETS(DRC1L, "DRC1L"), | ||
| 1089 | WM5100_MIXER_WIDGETS(DRC1R, "DRC1R"), | ||
| 1090 | |||
| 1091 | WM5100_MIXER_WIDGETS(LHPF1, "LHPF1"), | ||
| 1092 | WM5100_MIXER_WIDGETS(LHPF2, "LHPF2"), | ||
| 1093 | WM5100_MIXER_WIDGETS(LHPF3, "LHPF3"), | ||
| 1094 | WM5100_MIXER_WIDGETS(LHPF4, "LHPF4"), | ||
| 1095 | |||
| 1096 | WM5100_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"), | ||
| 1097 | WM5100_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"), | ||
| 1098 | WM5100_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"), | ||
| 1099 | WM5100_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"), | ||
| 1100 | WM5100_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"), | ||
| 1101 | WM5100_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"), | ||
| 1102 | WM5100_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"), | ||
| 1103 | WM5100_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"), | ||
| 1104 | |||
| 1105 | WM5100_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"), | ||
| 1106 | WM5100_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"), | ||
| 1107 | |||
| 1108 | WM5100_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"), | ||
| 1109 | WM5100_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"), | ||
| 1110 | |||
| 1111 | WM5100_MIXER_WIDGETS(HPOUT1L, "HPOUT1L"), | ||
| 1112 | WM5100_MIXER_WIDGETS(HPOUT1R, "HPOUT1R"), | ||
| 1113 | WM5100_MIXER_WIDGETS(HPOUT2L, "HPOUT2L"), | ||
| 1114 | WM5100_MIXER_WIDGETS(HPOUT2R, "HPOUT2R"), | ||
| 1115 | WM5100_MIXER_WIDGETS(HPOUT3L, "HPOUT3L"), | ||
| 1116 | WM5100_MIXER_WIDGETS(HPOUT3R, "HPOUT3R"), | ||
| 1117 | |||
| 1118 | WM5100_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"), | ||
| 1119 | WM5100_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"), | ||
| 1120 | WM5100_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"), | ||
| 1121 | WM5100_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"), | ||
| 1122 | WM5100_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"), | ||
| 1123 | WM5100_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"), | ||
| 1124 | |||
| 1125 | WM5100_MIXER_WIDGETS(PWM1, "PWM1"), | ||
| 1126 | WM5100_MIXER_WIDGETS(PWM2, "PWM2"), | ||
| 1127 | |||
| 1128 | SND_SOC_DAPM_OUTPUT("HPOUT1L"), | ||
| 1129 | SND_SOC_DAPM_OUTPUT("HPOUT1R"), | ||
| 1130 | SND_SOC_DAPM_OUTPUT("HPOUT2L"), | ||
| 1131 | SND_SOC_DAPM_OUTPUT("HPOUT2R"), | ||
| 1132 | SND_SOC_DAPM_OUTPUT("HPOUT3L"), | ||
| 1133 | SND_SOC_DAPM_OUTPUT("HPOUT3R"), | ||
| 1134 | SND_SOC_DAPM_OUTPUT("SPKOUTL"), | ||
| 1135 | SND_SOC_DAPM_OUTPUT("SPKOUTR"), | ||
| 1136 | SND_SOC_DAPM_OUTPUT("SPKDAT1"), | ||
| 1137 | SND_SOC_DAPM_OUTPUT("SPKDAT2"), | ||
| 1138 | SND_SOC_DAPM_OUTPUT("PWM1"), | ||
| 1139 | SND_SOC_DAPM_OUTPUT("PWM2"), | ||
| 1140 | }; | ||
| 1141 | |||
| 1142 | /* We register a _POST event if we don't have IRQ support so we can | ||
| 1143 | * look at the error status from the CODEC - if we've got the IRQ | ||
| 1144 | * hooked up then we will get prompted to look by an interrupt. | ||
| 1145 | */ | ||
| 1146 | static const struct snd_soc_dapm_widget wm5100_dapm_widgets_noirq[] = { | ||
| 1147 | SND_SOC_DAPM_POST("Post", wm5100_post_ev), | ||
| 1148 | }; | ||
| 1149 | |||
| 1150 | static const struct snd_soc_dapm_route wm5100_dapm_routes[] = { | ||
| 1151 | { "IN1L", NULL, "SYSCLK" }, | ||
| 1152 | { "IN1R", NULL, "SYSCLK" }, | ||
| 1153 | { "IN2L", NULL, "SYSCLK" }, | ||
| 1154 | { "IN2R", NULL, "SYSCLK" }, | ||
| 1155 | { "IN3L", NULL, "SYSCLK" }, | ||
| 1156 | { "IN3R", NULL, "SYSCLK" }, | ||
| 1157 | { "IN4L", NULL, "SYSCLK" }, | ||
| 1158 | { "IN4R", NULL, "SYSCLK" }, | ||
| 1159 | |||
| 1160 | { "OUT1L", NULL, "SYSCLK" }, | ||
| 1161 | { "OUT1R", NULL, "SYSCLK" }, | ||
| 1162 | { "OUT2L", NULL, "SYSCLK" }, | ||
| 1163 | { "OUT2R", NULL, "SYSCLK" }, | ||
| 1164 | { "OUT3L", NULL, "SYSCLK" }, | ||
| 1165 | { "OUT3R", NULL, "SYSCLK" }, | ||
| 1166 | { "OUT4L", NULL, "SYSCLK" }, | ||
| 1167 | { "OUT4R", NULL, "SYSCLK" }, | ||
| 1168 | { "OUT5L", NULL, "SYSCLK" }, | ||
| 1169 | { "OUT5R", NULL, "SYSCLK" }, | ||
| 1170 | { "OUT6L", NULL, "SYSCLK" }, | ||
| 1171 | { "OUT6R", NULL, "SYSCLK" }, | ||
| 1172 | |||
| 1173 | { "AIF1RX1", NULL, "SYSCLK" }, | ||
| 1174 | { "AIF1RX2", NULL, "SYSCLK" }, | ||
| 1175 | { "AIF1RX3", NULL, "SYSCLK" }, | ||
| 1176 | { "AIF1RX4", NULL, "SYSCLK" }, | ||
| 1177 | { "AIF1RX5", NULL, "SYSCLK" }, | ||
| 1178 | { "AIF1RX6", NULL, "SYSCLK" }, | ||
| 1179 | { "AIF1RX7", NULL, "SYSCLK" }, | ||
| 1180 | { "AIF1RX8", NULL, "SYSCLK" }, | ||
| 1181 | |||
| 1182 | { "AIF2RX1", NULL, "SYSCLK" }, | ||
| 1183 | { "AIF2RX1", NULL, "DBVDD2" }, | ||
| 1184 | { "AIF2RX2", NULL, "SYSCLK" }, | ||
| 1185 | { "AIF2RX2", NULL, "DBVDD2" }, | ||
| 1186 | |||
| 1187 | { "AIF3RX1", NULL, "SYSCLK" }, | ||
| 1188 | { "AIF3RX1", NULL, "DBVDD3" }, | ||
| 1189 | { "AIF3RX2", NULL, "SYSCLK" }, | ||
| 1190 | { "AIF3RX2", NULL, "DBVDD3" }, | ||
| 1191 | |||
| 1192 | { "AIF1TX1", NULL, "SYSCLK" }, | ||
| 1193 | { "AIF1TX2", NULL, "SYSCLK" }, | ||
| 1194 | { "AIF1TX3", NULL, "SYSCLK" }, | ||
| 1195 | { "AIF1TX4", NULL, "SYSCLK" }, | ||
| 1196 | { "AIF1TX5", NULL, "SYSCLK" }, | ||
| 1197 | { "AIF1TX6", NULL, "SYSCLK" }, | ||
| 1198 | { "AIF1TX7", NULL, "SYSCLK" }, | ||
| 1199 | { "AIF1TX8", NULL, "SYSCLK" }, | ||
| 1200 | |||
| 1201 | { "AIF2TX1", NULL, "SYSCLK" }, | ||
| 1202 | { "AIF2TX1", NULL, "DBVDD2" }, | ||
| 1203 | { "AIF2TX2", NULL, "SYSCLK" }, | ||
| 1204 | { "AIF2TX2", NULL, "DBVDD2" }, | ||
| 1205 | |||
| 1206 | { "AIF3TX1", NULL, "SYSCLK" }, | ||
| 1207 | { "AIF3TX1", NULL, "DBVDD3" }, | ||
| 1208 | { "AIF3TX2", NULL, "SYSCLK" }, | ||
| 1209 | { "AIF3TX2", NULL, "DBVDD3" }, | ||
| 1210 | |||
| 1211 | { "MICBIAS1", NULL, "CP2" }, | ||
| 1212 | { "MICBIAS2", NULL, "CP2" }, | ||
| 1213 | { "MICBIAS3", NULL, "CP2" }, | ||
| 1214 | |||
| 1215 | { "IN1L PGA", NULL, "CP2" }, | ||
| 1216 | { "IN1R PGA", NULL, "CP2" }, | ||
| 1217 | { "IN2L PGA", NULL, "CP2" }, | ||
| 1218 | { "IN2R PGA", NULL, "CP2" }, | ||
| 1219 | { "IN3L PGA", NULL, "CP2" }, | ||
| 1220 | { "IN3R PGA", NULL, "CP2" }, | ||
| 1221 | { "IN4L PGA", NULL, "CP2" }, | ||
| 1222 | { "IN4R PGA", NULL, "CP2" }, | ||
| 1223 | |||
| 1224 | { "IN1L PGA", NULL, "CP2 Active" }, | ||
| 1225 | { "IN1R PGA", NULL, "CP2 Active" }, | ||
| 1226 | { "IN2L PGA", NULL, "CP2 Active" }, | ||
| 1227 | { "IN2R PGA", NULL, "CP2 Active" }, | ||
| 1228 | { "IN3L PGA", NULL, "CP2 Active" }, | ||
| 1229 | { "IN3R PGA", NULL, "CP2 Active" }, | ||
| 1230 | { "IN4L PGA", NULL, "CP2 Active" }, | ||
| 1231 | { "IN4R PGA", NULL, "CP2 Active" }, | ||
| 1232 | |||
| 1233 | { "OUT1L", NULL, "CP1" }, | ||
| 1234 | { "OUT1R", NULL, "CP1" }, | ||
| 1235 | { "OUT2L", NULL, "CP1" }, | ||
| 1236 | { "OUT2R", NULL, "CP1" }, | ||
| 1237 | { "OUT3L", NULL, "CP1" }, | ||
| 1238 | { "OUT3R", NULL, "CP1" }, | ||
| 1239 | |||
| 1240 | { "Tone Generator 1", NULL, "TONE" }, | ||
| 1241 | { "Tone Generator 2", NULL, "TONE" }, | ||
| 1242 | |||
| 1243 | { "IN1L PGA", NULL, "IN1L" }, | ||
| 1244 | { "IN1R PGA", NULL, "IN1R" }, | ||
| 1245 | { "IN2L PGA", NULL, "IN2L" }, | ||
| 1246 | { "IN2R PGA", NULL, "IN2R" }, | ||
| 1247 | { "IN3L PGA", NULL, "IN3L" }, | ||
| 1248 | { "IN3R PGA", NULL, "IN3R" }, | ||
| 1249 | { "IN4L PGA", NULL, "IN4L" }, | ||
| 1250 | { "IN4R PGA", NULL, "IN4R" }, | ||
| 1251 | |||
| 1252 | WM5100_MIXER_ROUTES("OUT1L", "HPOUT1L"), | ||
| 1253 | WM5100_MIXER_ROUTES("OUT1R", "HPOUT1R"), | ||
| 1254 | WM5100_MIXER_ROUTES("OUT2L", "HPOUT2L"), | ||
| 1255 | WM5100_MIXER_ROUTES("OUT2R", "HPOUT2R"), | ||
| 1256 | WM5100_MIXER_ROUTES("OUT3L", "HPOUT3L"), | ||
| 1257 | WM5100_MIXER_ROUTES("OUT3R", "HPOUT3R"), | ||
| 1258 | |||
| 1259 | WM5100_MIXER_ROUTES("OUT4L", "SPKOUTL"), | ||
| 1260 | WM5100_MIXER_ROUTES("OUT4R", "SPKOUTR"), | ||
| 1261 | WM5100_MIXER_ROUTES("OUT5L", "SPKDAT1L"), | ||
| 1262 | WM5100_MIXER_ROUTES("OUT5R", "SPKDAT1R"), | ||
| 1263 | WM5100_MIXER_ROUTES("OUT6L", "SPKDAT2L"), | ||
| 1264 | WM5100_MIXER_ROUTES("OUT6R", "SPKDAT2R"), | ||
| 1265 | |||
| 1266 | WM5100_MIXER_ROUTES("PWM1 Driver", "PWM1"), | ||
| 1267 | WM5100_MIXER_ROUTES("PWM2 Driver", "PWM2"), | ||
| 1268 | |||
| 1269 | WM5100_MIXER_ROUTES("AIF1TX1", "AIF1TX1"), | ||
| 1270 | WM5100_MIXER_ROUTES("AIF1TX2", "AIF1TX2"), | ||
| 1271 | WM5100_MIXER_ROUTES("AIF1TX3", "AIF1TX3"), | ||
| 1272 | WM5100_MIXER_ROUTES("AIF1TX4", "AIF1TX4"), | ||
| 1273 | WM5100_MIXER_ROUTES("AIF1TX5", "AIF1TX5"), | ||
| 1274 | WM5100_MIXER_ROUTES("AIF1TX6", "AIF1TX6"), | ||
| 1275 | WM5100_MIXER_ROUTES("AIF1TX7", "AIF1TX7"), | ||
| 1276 | WM5100_MIXER_ROUTES("AIF1TX8", "AIF1TX8"), | ||
| 1277 | |||
| 1278 | WM5100_MIXER_ROUTES("AIF2TX1", "AIF2TX1"), | ||
| 1279 | WM5100_MIXER_ROUTES("AIF2TX2", "AIF2TX2"), | ||
| 1280 | |||
| 1281 | WM5100_MIXER_ROUTES("AIF3TX1", "AIF3TX1"), | ||
| 1282 | WM5100_MIXER_ROUTES("AIF3TX2", "AIF3TX2"), | ||
| 1283 | |||
| 1284 | WM5100_MIXER_ROUTES("EQ1", "EQ1"), | ||
| 1285 | WM5100_MIXER_ROUTES("EQ2", "EQ2"), | ||
| 1286 | WM5100_MIXER_ROUTES("EQ3", "EQ3"), | ||
| 1287 | WM5100_MIXER_ROUTES("EQ4", "EQ4"), | ||
| 1288 | |||
| 1289 | WM5100_MIXER_ROUTES("DRC1L", "DRC1L"), | ||
| 1290 | WM5100_MIXER_ROUTES("DRC1R", "DRC1R"), | ||
| 1291 | |||
| 1292 | WM5100_MIXER_ROUTES("LHPF1", "LHPF1"), | ||
| 1293 | WM5100_MIXER_ROUTES("LHPF2", "LHPF2"), | ||
| 1294 | WM5100_MIXER_ROUTES("LHPF3", "LHPF3"), | ||
| 1295 | WM5100_MIXER_ROUTES("LHPF4", "LHPF4"), | ||
| 1296 | |||
| 1297 | { "HPOUT1L", NULL, "OUT1L" }, | ||
| 1298 | { "HPOUT1R", NULL, "OUT1R" }, | ||
| 1299 | { "HPOUT2L", NULL, "OUT2L" }, | ||
| 1300 | { "HPOUT2R", NULL, "OUT2R" }, | ||
| 1301 | { "HPOUT3L", NULL, "OUT3L" }, | ||
| 1302 | { "HPOUT3R", NULL, "OUT3R" }, | ||
| 1303 | { "SPKOUTL", NULL, "OUT4L" }, | ||
| 1304 | { "SPKOUTR", NULL, "OUT4R" }, | ||
| 1305 | { "SPKDAT1", NULL, "OUT5L" }, | ||
| 1306 | { "SPKDAT1", NULL, "OUT5R" }, | ||
| 1307 | { "SPKDAT2", NULL, "OUT6L" }, | ||
| 1308 | { "SPKDAT2", NULL, "OUT6R" }, | ||
| 1309 | { "PWM1", NULL, "PWM1 Driver" }, | ||
| 1310 | { "PWM2", NULL, "PWM2 Driver" }, | ||
| 1311 | }; | ||
| 1312 | |||
| 1313 | static struct { | ||
| 1314 | int reg; | ||
| 1315 | int val; | ||
| 1316 | } wm5100_reva_patches[] = { | ||
| 1317 | { WM5100_AUDIO_IF_1_10, 0 }, | ||
| 1318 | { WM5100_AUDIO_IF_1_11, 1 }, | ||
| 1319 | { WM5100_AUDIO_IF_1_12, 2 }, | ||
| 1320 | { WM5100_AUDIO_IF_1_13, 3 }, | ||
| 1321 | { WM5100_AUDIO_IF_1_14, 4 }, | ||
| 1322 | { WM5100_AUDIO_IF_1_15, 5 }, | ||
| 1323 | { WM5100_AUDIO_IF_1_16, 6 }, | ||
| 1324 | { WM5100_AUDIO_IF_1_17, 7 }, | ||
| 1325 | |||
| 1326 | { WM5100_AUDIO_IF_1_18, 0 }, | ||
| 1327 | { WM5100_AUDIO_IF_1_19, 1 }, | ||
| 1328 | { WM5100_AUDIO_IF_1_20, 2 }, | ||
| 1329 | { WM5100_AUDIO_IF_1_21, 3 }, | ||
| 1330 | { WM5100_AUDIO_IF_1_22, 4 }, | ||
| 1331 | { WM5100_AUDIO_IF_1_23, 5 }, | ||
| 1332 | { WM5100_AUDIO_IF_1_24, 6 }, | ||
| 1333 | { WM5100_AUDIO_IF_1_25, 7 }, | ||
| 1334 | |||
| 1335 | { WM5100_AUDIO_IF_2_10, 0 }, | ||
| 1336 | { WM5100_AUDIO_IF_2_11, 1 }, | ||
| 1337 | |||
| 1338 | { WM5100_AUDIO_IF_2_18, 0 }, | ||
| 1339 | { WM5100_AUDIO_IF_2_19, 1 }, | ||
| 1340 | |||
| 1341 | { WM5100_AUDIO_IF_3_10, 0 }, | ||
| 1342 | { WM5100_AUDIO_IF_3_11, 1 }, | ||
| 1343 | |||
| 1344 | { WM5100_AUDIO_IF_3_18, 0 }, | ||
| 1345 | { WM5100_AUDIO_IF_3_19, 1 }, | ||
| 1346 | }; | ||
| 1347 | |||
| 1348 | static int wm5100_set_bias_level(struct snd_soc_codec *codec, | ||
| 1349 | enum snd_soc_bias_level level) | ||
| 1350 | { | ||
| 1351 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 1352 | int ret, i; | ||
| 1353 | |||
| 1354 | switch (level) { | ||
| 1355 | case SND_SOC_BIAS_ON: | ||
| 1356 | break; | ||
| 1357 | |||
| 1358 | case SND_SOC_BIAS_PREPARE: | ||
| 1359 | break; | ||
| 1360 | |||
| 1361 | case SND_SOC_BIAS_STANDBY: | ||
| 1362 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
| 1363 | ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), | ||
| 1364 | wm5100->core_supplies); | ||
| 1365 | if (ret != 0) { | ||
| 1366 | dev_err(codec->dev, | ||
| 1367 | "Failed to enable supplies: %d\n", | ||
| 1368 | ret); | ||
| 1369 | return ret; | ||
| 1370 | } | ||
| 1371 | |||
| 1372 | if (wm5100->pdata.ldo_ena) { | ||
| 1373 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, | ||
| 1374 | 1); | ||
| 1375 | msleep(2); | ||
| 1376 | } | ||
| 1377 | |||
| 1378 | codec->cache_only = false; | ||
| 1379 | |||
| 1380 | switch (wm5100->rev) { | ||
| 1381 | case 0: | ||
| 1382 | snd_soc_write(codec, 0x11, 0x3); | ||
| 1383 | snd_soc_write(codec, 0x203, 0xc); | ||
| 1384 | snd_soc_write(codec, 0x206, 0); | ||
| 1385 | snd_soc_write(codec, 0x207, 0xf0); | ||
| 1386 | snd_soc_write(codec, 0x208, 0x3c); | ||
| 1387 | snd_soc_write(codec, 0x209, 0); | ||
| 1388 | snd_soc_write(codec, 0x211, 0x20d8); | ||
| 1389 | snd_soc_write(codec, 0x11, 0); | ||
| 1390 | |||
| 1391 | for (i = 0; | ||
| 1392 | i < ARRAY_SIZE(wm5100_reva_patches); | ||
| 1393 | i++) | ||
| 1394 | snd_soc_write(codec, | ||
| 1395 | wm5100_reva_patches[i].reg, | ||
| 1396 | wm5100_reva_patches[i].val); | ||
| 1397 | break; | ||
| 1398 | default: | ||
| 1399 | break; | ||
| 1400 | } | ||
| 1401 | |||
| 1402 | snd_soc_cache_sync(codec); | ||
| 1403 | } | ||
| 1404 | break; | ||
| 1405 | |||
| 1406 | case SND_SOC_BIAS_OFF: | ||
| 1407 | if (wm5100->pdata.ldo_ena) | ||
| 1408 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
| 1409 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | ||
| 1410 | wm5100->core_supplies); | ||
| 1411 | break; | ||
| 1412 | } | ||
| 1413 | codec->dapm.bias_level = level; | ||
| 1414 | |||
| 1415 | return 0; | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | static int wm5100_dai_to_base(struct snd_soc_dai *dai) | ||
| 1419 | { | ||
| 1420 | switch (dai->id) { | ||
| 1421 | case 0: | ||
| 1422 | return WM5100_AUDIO_IF_1_1 - 1; | ||
| 1423 | case 1: | ||
| 1424 | return WM5100_AUDIO_IF_2_1 - 1; | ||
| 1425 | case 2: | ||
| 1426 | return WM5100_AUDIO_IF_3_1 - 1; | ||
| 1427 | default: | ||
| 1428 | BUG(); | ||
| 1429 | return -EINVAL; | ||
| 1430 | } | ||
| 1431 | } | ||
| 1432 | |||
| 1433 | static int wm5100_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | ||
| 1434 | { | ||
| 1435 | struct snd_soc_codec *codec = dai->codec; | ||
| 1436 | int lrclk, bclk, mask, base; | ||
| 1437 | |||
| 1438 | base = wm5100_dai_to_base(dai); | ||
| 1439 | if (base < 0) | ||
| 1440 | return base; | ||
| 1441 | |||
| 1442 | lrclk = 0; | ||
| 1443 | bclk = 0; | ||
| 1444 | |||
| 1445 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 1446 | case SND_SOC_DAIFMT_DSP_A: | ||
| 1447 | mask = 0; | ||
| 1448 | break; | ||
| 1449 | case SND_SOC_DAIFMT_DSP_B: | ||
| 1450 | mask = 1; | ||
| 1451 | break; | ||
| 1452 | case SND_SOC_DAIFMT_I2S: | ||
| 1453 | mask = 2; | ||
| 1454 | break; | ||
| 1455 | case SND_SOC_DAIFMT_LEFT_J: | ||
| 1456 | mask = 3; | ||
| 1457 | break; | ||
| 1458 | default: | ||
| 1459 | dev_err(codec->dev, "Unsupported DAI format %d\n", | ||
| 1460 | fmt & SND_SOC_DAIFMT_FORMAT_MASK); | ||
| 1461 | return -EINVAL; | ||
| 1462 | } | ||
| 1463 | |||
| 1464 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 1465 | case SND_SOC_DAIFMT_CBS_CFS: | ||
| 1466 | break; | ||
| 1467 | case SND_SOC_DAIFMT_CBS_CFM: | ||
| 1468 | lrclk |= WM5100_AIF1TX_LRCLK_MSTR; | ||
| 1469 | break; | ||
| 1470 | case SND_SOC_DAIFMT_CBM_CFS: | ||
| 1471 | bclk |= WM5100_AIF1_BCLK_MSTR; | ||
| 1472 | break; | ||
| 1473 | case SND_SOC_DAIFMT_CBM_CFM: | ||
| 1474 | lrclk |= WM5100_AIF1TX_LRCLK_MSTR; | ||
| 1475 | bclk |= WM5100_AIF1_BCLK_MSTR; | ||
| 1476 | break; | ||
| 1477 | default: | ||
| 1478 | dev_err(codec->dev, "Unsupported master mode %d\n", | ||
| 1479 | fmt & SND_SOC_DAIFMT_MASTER_MASK); | ||
| 1480 | return -EINVAL; | ||
| 1481 | } | ||
| 1482 | |||
| 1483 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
| 1484 | case SND_SOC_DAIFMT_NB_NF: | ||
| 1485 | break; | ||
| 1486 | case SND_SOC_DAIFMT_IB_IF: | ||
| 1487 | bclk |= WM5100_AIF1_BCLK_INV; | ||
| 1488 | lrclk |= WM5100_AIF1TX_LRCLK_INV; | ||
| 1489 | break; | ||
| 1490 | case SND_SOC_DAIFMT_IB_NF: | ||
| 1491 | bclk |= WM5100_AIF1_BCLK_INV; | ||
| 1492 | break; | ||
| 1493 | case SND_SOC_DAIFMT_NB_IF: | ||
| 1494 | lrclk |= WM5100_AIF1TX_LRCLK_INV; | ||
| 1495 | break; | ||
| 1496 | default: | ||
| 1497 | return -EINVAL; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_MSTR | | ||
| 1501 | WM5100_AIF1_BCLK_INV, bclk); | ||
| 1502 | snd_soc_update_bits(codec, base + 2, WM5100_AIF1TX_LRCLK_MSTR | | ||
| 1503 | WM5100_AIF1TX_LRCLK_INV, lrclk); | ||
| 1504 | snd_soc_update_bits(codec, base + 3, WM5100_AIF1TX_LRCLK_MSTR | | ||
| 1505 | WM5100_AIF1TX_LRCLK_INV, lrclk); | ||
| 1506 | snd_soc_update_bits(codec, base + 5, WM5100_AIF1_FMT_MASK, mask); | ||
| 1507 | |||
| 1508 | return 0; | ||
| 1509 | } | ||
| 1510 | |||
| 1511 | #define WM5100_NUM_BCLK_RATES 19 | ||
| 1512 | |||
| 1513 | static int wm5100_bclk_rates_dat[WM5100_NUM_BCLK_RATES] = { | ||
| 1514 | 32000, | ||
| 1515 | 48000, | ||
| 1516 | 64000, | ||
| 1517 | 96000, | ||
| 1518 | 128000, | ||
| 1519 | 192000, | ||
| 1520 | 256000, | ||
| 1521 | 384000, | ||
| 1522 | 512000, | ||
| 1523 | 768000, | ||
| 1524 | 1024000, | ||
| 1525 | 1536000, | ||
| 1526 | 2048000, | ||
| 1527 | 3072000, | ||
| 1528 | 4096000, | ||
| 1529 | 6144000, | ||
| 1530 | 8192000, | ||
| 1531 | 12288000, | ||
| 1532 | 24576000, | ||
| 1533 | }; | ||
| 1534 | |||
| 1535 | static int wm5100_bclk_rates_cd[WM5100_NUM_BCLK_RATES] = { | ||
| 1536 | 29400, | ||
| 1537 | 44100, | ||
| 1538 | 58800, | ||
| 1539 | 88200, | ||
| 1540 | 117600, | ||
| 1541 | 176400, | ||
| 1542 | 235200, | ||
| 1543 | 352800, | ||
| 1544 | 470400, | ||
| 1545 | 705600, | ||
| 1546 | 940800, | ||
| 1547 | 1411200, | ||
| 1548 | 1881600, | ||
| 1549 | 2882400, | ||
| 1550 | 3763200, | ||
| 1551 | 5644800, | ||
| 1552 | 7526400, | ||
| 1553 | 11289600, | ||
| 1554 | 22579600, | ||
| 1555 | }; | ||
| 1556 | |||
| 1557 | static int wm5100_hw_params(struct snd_pcm_substream *substream, | ||
| 1558 | struct snd_pcm_hw_params *params, | ||
| 1559 | struct snd_soc_dai *dai) | ||
| 1560 | { | ||
| 1561 | struct snd_soc_codec *codec = dai->codec; | ||
| 1562 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 1563 | bool async = wm5100->aif_async[dai->id]; | ||
| 1564 | int i, base, bclk, aif_rate, lrclk, wl, fl, sr; | ||
| 1565 | int *bclk_rates; | ||
| 1566 | |||
| 1567 | base = wm5100_dai_to_base(dai); | ||
| 1568 | if (base < 0) | ||
| 1569 | return base; | ||
| 1570 | |||
| 1571 | /* Data sizes if not using TDM */ | ||
| 1572 | wl = snd_pcm_format_width(params_format(params)); | ||
| 1573 | if (wl < 0) | ||
| 1574 | return wl; | ||
| 1575 | fl = snd_soc_params_to_frame_size(params); | ||
| 1576 | if (fl < 0) | ||
| 1577 | return fl; | ||
| 1578 | |||
| 1579 | dev_dbg(codec->dev, "Word length %d bits, frame length %d bits\n", | ||
| 1580 | wl, fl); | ||
| 1581 | |||
| 1582 | /* Target BCLK rate */ | ||
| 1583 | bclk = snd_soc_params_to_bclk(params); | ||
| 1584 | if (bclk < 0) | ||
| 1585 | return bclk; | ||
| 1586 | |||
| 1587 | /* Root for BCLK depends on SYS/ASYNCCLK */ | ||
| 1588 | if (!async) { | ||
| 1589 | aif_rate = wm5100->sysclk; | ||
| 1590 | sr = wm5100_alloc_sr(codec, params_rate(params)); | ||
| 1591 | if (sr < 0) | ||
| 1592 | return sr; | ||
| 1593 | } else { | ||
| 1594 | /* If we're in ASYNCCLK set the ASYNC sample rate */ | ||
| 1595 | aif_rate = wm5100->asyncclk; | ||
| 1596 | sr = 3; | ||
| 1597 | |||
| 1598 | for (i = 0; i < ARRAY_SIZE(wm5100_sr_code); i++) | ||
| 1599 | if (params_rate(params) == wm5100_sr_code[i]) | ||
| 1600 | break; | ||
| 1601 | if (i == ARRAY_SIZE(wm5100_sr_code)) { | ||
| 1602 | dev_err(codec->dev, "Invalid rate %dHzn", | ||
| 1603 | params_rate(params)); | ||
| 1604 | return -EINVAL; | ||
| 1605 | } | ||
| 1606 | |||
| 1607 | /* TODO: We should really check for symmetry */ | ||
| 1608 | snd_soc_update_bits(codec, WM5100_CLOCKING_8, | ||
| 1609 | WM5100_ASYNC_SAMPLE_RATE_MASK, i); | ||
| 1610 | } | ||
| 1611 | |||
| 1612 | if (!aif_rate) { | ||
| 1613 | dev_err(codec->dev, "%s has no rate set\n", | ||
| 1614 | async ? "ASYNCCLK" : "SYSCLK"); | ||
| 1615 | return -EINVAL; | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | dev_dbg(codec->dev, "Target BCLK is %dHz, using %dHz %s\n", | ||
| 1619 | bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK"); | ||
| 1620 | |||
| 1621 | if (aif_rate % 4000) | ||
| 1622 | bclk_rates = wm5100_bclk_rates_cd; | ||
| 1623 | else | ||
| 1624 | bclk_rates = wm5100_bclk_rates_dat; | ||
| 1625 | |||
| 1626 | for (i = 0; i < WM5100_NUM_BCLK_RATES; i++) | ||
| 1627 | if (bclk_rates[i] >= bclk && (bclk_rates[i] % bclk == 0)) | ||
| 1628 | break; | ||
| 1629 | if (i == WM5100_NUM_BCLK_RATES) { | ||
| 1630 | dev_err(codec->dev, | ||
| 1631 | "No valid BCLK for %dHz found from %dHz %s\n", | ||
| 1632 | bclk, aif_rate, async ? "ASYNCCLK" : "SYSCLK"); | ||
| 1633 | return -EINVAL; | ||
| 1634 | } | ||
| 1635 | |||
| 1636 | bclk = i; | ||
| 1637 | dev_dbg(codec->dev, "Setting %dHz BCLK\n", bclk_rates[bclk]); | ||
| 1638 | snd_soc_update_bits(codec, base + 1, WM5100_AIF1_BCLK_FREQ_MASK, bclk); | ||
| 1639 | |||
| 1640 | lrclk = bclk_rates[bclk] / params_rate(params); | ||
| 1641 | dev_dbg(codec->dev, "Setting %dHz LRCLK\n", bclk_rates[bclk] / lrclk); | ||
| 1642 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || | ||
| 1643 | wm5100->aif_symmetric[dai->id]) | ||
| 1644 | snd_soc_update_bits(codec, base + 7, | ||
| 1645 | WM5100_AIF1RX_BCPF_MASK, lrclk); | ||
| 1646 | else | ||
| 1647 | snd_soc_update_bits(codec, base + 6, | ||
| 1648 | WM5100_AIF1TX_BCPF_MASK, lrclk); | ||
| 1649 | |||
| 1650 | i = (wl << WM5100_AIF1TX_WL_SHIFT) | fl; | ||
| 1651 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 1652 | snd_soc_update_bits(codec, base + 9, | ||
| 1653 | WM5100_AIF1RX_WL_MASK | | ||
| 1654 | WM5100_AIF1RX_SLOT_LEN_MASK, i); | ||
| 1655 | else | ||
| 1656 | snd_soc_update_bits(codec, base + 8, | ||
| 1657 | WM5100_AIF1TX_WL_MASK | | ||
| 1658 | WM5100_AIF1TX_SLOT_LEN_MASK, i); | ||
| 1659 | |||
| 1660 | snd_soc_update_bits(codec, base + 4, WM5100_AIF1_RATE_MASK, sr); | ||
| 1661 | |||
| 1662 | return 0; | ||
| 1663 | } | ||
| 1664 | |||
| 1665 | static struct snd_soc_dai_ops wm5100_dai_ops = { | ||
| 1666 | .set_fmt = wm5100_set_fmt, | ||
| 1667 | .hw_params = wm5100_hw_params, | ||
| 1668 | }; | ||
| 1669 | |||
| 1670 | static int wm5100_set_sysclk(struct snd_soc_codec *codec, int clk_id, | ||
| 1671 | int source, unsigned int freq, int dir) | ||
| 1672 | { | ||
| 1673 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 1674 | int *rate_store; | ||
| 1675 | int fval, audio_rate, ret, reg; | ||
| 1676 | |||
| 1677 | switch (clk_id) { | ||
| 1678 | case WM5100_CLK_SYSCLK: | ||
| 1679 | reg = WM5100_CLOCKING_3; | ||
| 1680 | rate_store = &wm5100->sysclk; | ||
| 1681 | break; | ||
| 1682 | case WM5100_CLK_ASYNCCLK: | ||
| 1683 | reg = WM5100_CLOCKING_7; | ||
| 1684 | rate_store = &wm5100->asyncclk; | ||
| 1685 | break; | ||
| 1686 | case WM5100_CLK_32KHZ: | ||
| 1687 | /* The 32kHz clock is slightly different to the others */ | ||
| 1688 | switch (source) { | ||
| 1689 | case WM5100_CLKSRC_MCLK1: | ||
| 1690 | case WM5100_CLKSRC_MCLK2: | ||
| 1691 | case WM5100_CLKSRC_SYSCLK: | ||
| 1692 | snd_soc_update_bits(codec, WM5100_CLOCKING_1, | ||
| 1693 | WM5100_CLK_32K_SRC_MASK, | ||
| 1694 | source); | ||
| 1695 | break; | ||
| 1696 | default: | ||
| 1697 | return -EINVAL; | ||
| 1698 | } | ||
| 1699 | return 0; | ||
| 1700 | |||
| 1701 | case WM5100_CLK_AIF1: | ||
| 1702 | case WM5100_CLK_AIF2: | ||
| 1703 | case WM5100_CLK_AIF3: | ||
| 1704 | /* Not real clocks, record which clock domain they're in */ | ||
| 1705 | switch (source) { | ||
| 1706 | case WM5100_CLKSRC_SYSCLK: | ||
| 1707 | wm5100->aif_async[clk_id - 1] = false; | ||
| 1708 | break; | ||
| 1709 | case WM5100_CLKSRC_ASYNCCLK: | ||
| 1710 | wm5100->aif_async[clk_id - 1] = true; | ||
| 1711 | break; | ||
| 1712 | default: | ||
| 1713 | dev_err(codec->dev, "Invalid source %d\n", source); | ||
| 1714 | return -EINVAL; | ||
| 1715 | } | ||
| 1716 | return 0; | ||
| 1717 | |||
| 1718 | case WM5100_CLK_OPCLK: | ||
| 1719 | switch (freq) { | ||
| 1720 | case 5644800: | ||
| 1721 | case 6144000: | ||
| 1722 | snd_soc_update_bits(codec, WM5100_MISC_GPIO_1, | ||
| 1723 | WM5100_OPCLK_SEL_MASK, 0); | ||
| 1724 | break; | ||
| 1725 | case 11289600: | ||
| 1726 | case 12288000: | ||
| 1727 | snd_soc_update_bits(codec, WM5100_MISC_GPIO_1, | ||
| 1728 | WM5100_OPCLK_SEL_MASK, 0); | ||
| 1729 | break; | ||
| 1730 | case 22579200: | ||
| 1731 | case 24576000: | ||
| 1732 | snd_soc_update_bits(codec, WM5100_MISC_GPIO_1, | ||
| 1733 | WM5100_OPCLK_SEL_MASK, 0); | ||
| 1734 | break; | ||
| 1735 | default: | ||
| 1736 | dev_err(codec->dev, "Unsupported OPCLK %dHz\n", | ||
| 1737 | freq); | ||
| 1738 | return -EINVAL; | ||
| 1739 | } | ||
| 1740 | return 0; | ||
| 1741 | |||
| 1742 | default: | ||
| 1743 | dev_err(codec->dev, "Unknown clock %d\n", clk_id); | ||
| 1744 | return -EINVAL; | ||
| 1745 | } | ||
| 1746 | |||
| 1747 | switch (source) { | ||
| 1748 | case WM5100_CLKSRC_SYSCLK: | ||
| 1749 | case WM5100_CLKSRC_ASYNCCLK: | ||
| 1750 | dev_err(codec->dev, "Invalid source %d\n", source); | ||
| 1751 | return -EINVAL; | ||
| 1752 | } | ||
| 1753 | |||
| 1754 | switch (freq) { | ||
| 1755 | case 5644800: | ||
| 1756 | case 6144000: | ||
| 1757 | fval = 0; | ||
| 1758 | break; | ||
| 1759 | case 11289600: | ||
| 1760 | case 12288000: | ||
| 1761 | fval = 1; | ||
| 1762 | break; | ||
| 1763 | case 22579200: | ||
| 1764 | case 24576000: | ||
| 1765 | fval = 2; | ||
| 1766 | break; | ||
| 1767 | default: | ||
| 1768 | dev_err(codec->dev, "Invalid clock rate: %d\n", freq); | ||
| 1769 | return -EINVAL; | ||
| 1770 | } | ||
| 1771 | |||
| 1772 | switch (freq) { | ||
| 1773 | case 5644800: | ||
| 1774 | case 11289600: | ||
| 1775 | case 22579200: | ||
| 1776 | audio_rate = 44100; | ||
| 1777 | break; | ||
| 1778 | |||
| 1779 | case 6144000: | ||
| 1780 | case 12288000: | ||
| 1781 | case 24576000: | ||
| 1782 | audio_rate = 48000; | ||
| 1783 | break; | ||
| 1784 | |||
| 1785 | default: | ||
| 1786 | BUG(); | ||
| 1787 | audio_rate = 0; | ||
| 1788 | break; | ||
| 1789 | } | ||
| 1790 | |||
| 1791 | /* TODO: Check if MCLKs are in use and enable/disable pulls to | ||
| 1792 | * match. | ||
| 1793 | */ | ||
| 1794 | |||
| 1795 | snd_soc_update_bits(codec, reg, WM5100_SYSCLK_FREQ_MASK | | ||
| 1796 | WM5100_SYSCLK_SRC_MASK, | ||
| 1797 | fval << WM5100_SYSCLK_FREQ_SHIFT | source); | ||
| 1798 | |||
| 1799 | /* If this is SYSCLK then configure the clock rate for the | ||
| 1800 | * internal audio functions to the natural sample rate for | ||
| 1801 | * this clock rate. | ||
| 1802 | */ | ||
| 1803 | if (clk_id == WM5100_CLK_SYSCLK) { | ||
| 1804 | dev_dbg(codec->dev, "Setting primary audio rate to %dHz", | ||
| 1805 | audio_rate); | ||
| 1806 | if (0 && *rate_store) | ||
| 1807 | wm5100_free_sr(codec, audio_rate); | ||
| 1808 | ret = wm5100_alloc_sr(codec, audio_rate); | ||
| 1809 | if (ret != 0) | ||
| 1810 | dev_warn(codec->dev, "Primary audio slot is %d\n", | ||
| 1811 | ret); | ||
| 1812 | } | ||
| 1813 | |||
| 1814 | *rate_store = freq; | ||
| 1815 | |||
| 1816 | return 0; | ||
| 1817 | } | ||
| 1818 | |||
| 1819 | struct _fll_div { | ||
| 1820 | u16 fll_fratio; | ||
| 1821 | u16 fll_outdiv; | ||
| 1822 | u16 fll_refclk_div; | ||
| 1823 | u16 n; | ||
| 1824 | u16 theta; | ||
| 1825 | u16 lambda; | ||
| 1826 | }; | ||
| 1827 | |||
| 1828 | static struct { | ||
| 1829 | unsigned int min; | ||
| 1830 | unsigned int max; | ||
| 1831 | u16 fll_fratio; | ||
| 1832 | int ratio; | ||
| 1833 | } fll_fratios[] = { | ||
| 1834 | { 0, 64000, 4, 16 }, | ||
| 1835 | { 64000, 128000, 3, 8 }, | ||
| 1836 | { 128000, 256000, 2, 4 }, | ||
| 1837 | { 256000, 1000000, 1, 2 }, | ||
| 1838 | { 1000000, 13500000, 0, 1 }, | ||
| 1839 | }; | ||
| 1840 | |||
| 1841 | static int fll_factors(struct _fll_div *fll_div, unsigned int Fref, | ||
| 1842 | unsigned int Fout) | ||
| 1843 | { | ||
| 1844 | unsigned int target; | ||
| 1845 | unsigned int div; | ||
| 1846 | unsigned int fratio, gcd_fll; | ||
| 1847 | int i; | ||
| 1848 | |||
| 1849 | /* Fref must be <=13.5MHz */ | ||
| 1850 | div = 1; | ||
| 1851 | fll_div->fll_refclk_div = 0; | ||
| 1852 | while ((Fref / div) > 13500000) { | ||
| 1853 | div *= 2; | ||
| 1854 | fll_div->fll_refclk_div++; | ||
| 1855 | |||
| 1856 | if (div > 8) { | ||
| 1857 | pr_err("Can't scale %dMHz input down to <=13.5MHz\n", | ||
| 1858 | Fref); | ||
| 1859 | return -EINVAL; | ||
| 1860 | } | ||
| 1861 | } | ||
| 1862 | |||
| 1863 | pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout); | ||
| 1864 | |||
| 1865 | /* Apply the division for our remaining calculations */ | ||
| 1866 | Fref /= div; | ||
| 1867 | |||
| 1868 | /* Fvco should be 90-100MHz; don't check the upper bound */ | ||
| 1869 | div = 2; | ||
| 1870 | while (Fout * div < 90000000) { | ||
| 1871 | div++; | ||
| 1872 | if (div > 64) { | ||
| 1873 | pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n", | ||
| 1874 | Fout); | ||
| 1875 | return -EINVAL; | ||
| 1876 | } | ||
| 1877 | } | ||
| 1878 | target = Fout * div; | ||
| 1879 | fll_div->fll_outdiv = div - 1; | ||
| 1880 | |||
| 1881 | pr_debug("FLL Fvco=%dHz\n", target); | ||
| 1882 | |||
| 1883 | /* Find an appropraite FLL_FRATIO and factor it out of the target */ | ||
| 1884 | for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { | ||
| 1885 | if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { | ||
| 1886 | fll_div->fll_fratio = fll_fratios[i].fll_fratio; | ||
| 1887 | fratio = fll_fratios[i].ratio; | ||
| 1888 | break; | ||
| 1889 | } | ||
| 1890 | } | ||
| 1891 | if (i == ARRAY_SIZE(fll_fratios)) { | ||
| 1892 | pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref); | ||
| 1893 | return -EINVAL; | ||
| 1894 | } | ||
| 1895 | |||
| 1896 | fll_div->n = target / (fratio * Fref); | ||
| 1897 | |||
| 1898 | if (target % Fref == 0) { | ||
| 1899 | fll_div->theta = 0; | ||
| 1900 | fll_div->lambda = 0; | ||
| 1901 | } else { | ||
| 1902 | gcd_fll = gcd(target, fratio * Fref); | ||
| 1903 | |||
| 1904 | fll_div->theta = (target - (fll_div->n * fratio * Fref)) | ||
| 1905 | / gcd_fll; | ||
| 1906 | fll_div->lambda = (fratio * Fref) / gcd_fll; | ||
| 1907 | } | ||
| 1908 | |||
| 1909 | pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n", | ||
| 1910 | fll_div->n, fll_div->theta, fll_div->lambda); | ||
| 1911 | pr_debug("FLL_FRATIO=%x(%d) FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n", | ||
| 1912 | fll_div->fll_fratio, fratio, fll_div->fll_outdiv, | ||
| 1913 | fll_div->fll_refclk_div); | ||
| 1914 | |||
| 1915 | return 0; | ||
| 1916 | } | ||
| 1917 | |||
| 1918 | static int wm5100_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | ||
| 1919 | unsigned int Fref, unsigned int Fout) | ||
| 1920 | { | ||
| 1921 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
| 1922 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 1923 | struct _fll_div factors; | ||
| 1924 | struct wm5100_fll *fll; | ||
| 1925 | int ret, base, lock, i, timeout; | ||
| 1926 | |||
| 1927 | switch (fll_id) { | ||
| 1928 | case WM5100_FLL1: | ||
| 1929 | fll = &wm5100->fll[0]; | ||
| 1930 | base = WM5100_FLL1_CONTROL_1 - 1; | ||
| 1931 | lock = WM5100_FLL1_LOCK_STS; | ||
| 1932 | break; | ||
| 1933 | case WM5100_FLL2: | ||
| 1934 | fll = &wm5100->fll[1]; | ||
| 1935 | base = WM5100_FLL2_CONTROL_2 - 1; | ||
| 1936 | lock = WM5100_FLL2_LOCK_STS; | ||
| 1937 | break; | ||
| 1938 | default: | ||
| 1939 | dev_err(codec->dev, "Unknown FLL %d\n",fll_id); | ||
| 1940 | return -EINVAL; | ||
| 1941 | } | ||
| 1942 | |||
| 1943 | if (!Fout) { | ||
| 1944 | dev_dbg(codec->dev, "FLL%d disabled", fll_id); | ||
| 1945 | fll->fout = 0; | ||
| 1946 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); | ||
| 1947 | return 0; | ||
| 1948 | } | ||
| 1949 | |||
| 1950 | switch (source) { | ||
| 1951 | case WM5100_FLL_SRC_MCLK1: | ||
| 1952 | case WM5100_FLL_SRC_MCLK2: | ||
| 1953 | case WM5100_FLL_SRC_FLL1: | ||
| 1954 | case WM5100_FLL_SRC_FLL2: | ||
| 1955 | case WM5100_FLL_SRC_AIF1BCLK: | ||
| 1956 | case WM5100_FLL_SRC_AIF2BCLK: | ||
| 1957 | case WM5100_FLL_SRC_AIF3BCLK: | ||
| 1958 | break; | ||
| 1959 | default: | ||
| 1960 | dev_err(codec->dev, "Invalid FLL source %d\n", source); | ||
| 1961 | return -EINVAL; | ||
| 1962 | } | ||
| 1963 | |||
| 1964 | ret = fll_factors(&factors, Fref, Fout); | ||
| 1965 | if (ret < 0) | ||
| 1966 | return ret; | ||
| 1967 | |||
| 1968 | /* Disable the FLL while we reconfigure */ | ||
| 1969 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, 0); | ||
| 1970 | |||
| 1971 | snd_soc_update_bits(codec, base + 2, | ||
| 1972 | WM5100_FLL1_OUTDIV_MASK | WM5100_FLL1_FRATIO_MASK, | ||
| 1973 | (factors.fll_outdiv << WM5100_FLL1_OUTDIV_SHIFT) | | ||
| 1974 | factors.fll_fratio); | ||
| 1975 | snd_soc_update_bits(codec, base + 3, WM5100_FLL1_THETA_MASK, | ||
| 1976 | factors.theta); | ||
| 1977 | snd_soc_update_bits(codec, base + 5, WM5100_FLL1_N_MASK, factors.n); | ||
| 1978 | snd_soc_update_bits(codec, base + 6, | ||
| 1979 | WM5100_FLL1_REFCLK_DIV_MASK | | ||
| 1980 | WM5100_FLL1_REFCLK_SRC_MASK, | ||
| 1981 | (factors.fll_refclk_div | ||
| 1982 | << WM5100_FLL1_REFCLK_DIV_SHIFT) | source); | ||
| 1983 | snd_soc_update_bits(codec, base + 7, WM5100_FLL1_LAMBDA_MASK, | ||
| 1984 | factors.lambda); | ||
| 1985 | |||
| 1986 | /* Clear any pending completions */ | ||
| 1987 | try_wait_for_completion(&fll->lock); | ||
| 1988 | |||
| 1989 | snd_soc_update_bits(codec, base + 1, WM5100_FLL1_ENA, WM5100_FLL1_ENA); | ||
| 1990 | |||
| 1991 | if (i2c->irq) | ||
| 1992 | timeout = 2; | ||
| 1993 | else | ||
| 1994 | timeout = 50; | ||
| 1995 | |||
| 1996 | /* Poll for the lock; will use interrupt when we can test */ | ||
| 1997 | for (i = 0; i < timeout; i++) { | ||
| 1998 | if (i2c->irq) { | ||
| 1999 | ret = wait_for_completion_timeout(&fll->lock, | ||
| 2000 | msecs_to_jiffies(25)); | ||
| 2001 | if (ret > 0) | ||
| 2002 | break; | ||
| 2003 | } else { | ||
| 2004 | msleep(1); | ||
| 2005 | } | ||
| 2006 | |||
| 2007 | ret = snd_soc_read(codec, | ||
| 2008 | WM5100_INTERRUPT_RAW_STATUS_3); | ||
| 2009 | if (ret < 0) { | ||
| 2010 | dev_err(codec->dev, | ||
| 2011 | "Failed to read FLL status: %d\n", | ||
| 2012 | ret); | ||
| 2013 | continue; | ||
| 2014 | } | ||
| 2015 | if (ret & lock) | ||
| 2016 | break; | ||
| 2017 | } | ||
| 2018 | if (i == timeout) { | ||
| 2019 | dev_err(codec->dev, "FLL%d lock timed out\n", fll_id); | ||
| 2020 | return -ETIMEDOUT; | ||
| 2021 | } | ||
| 2022 | |||
| 2023 | fll->src = source; | ||
| 2024 | fll->fref = Fref; | ||
| 2025 | fll->fout = Fout; | ||
| 2026 | |||
| 2027 | dev_dbg(codec->dev, "FLL%d running %dHz->%dHz\n", fll_id, | ||
| 2028 | Fref, Fout); | ||
| 2029 | |||
| 2030 | return 0; | ||
| 2031 | } | ||
| 2032 | |||
| 2033 | /* Actually go much higher */ | ||
| 2034 | #define WM5100_RATES SNDRV_PCM_RATE_8000_192000 | ||
| 2035 | |||
| 2036 | #define WM5100_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | ||
| 2037 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | ||
| 2038 | |||
| 2039 | static struct snd_soc_dai_driver wm5100_dai[] = { | ||
| 2040 | { | ||
| 2041 | .name = "wm5100-aif1", | ||
| 2042 | .playback = { | ||
| 2043 | .stream_name = "AIF1 Playback", | ||
| 2044 | .channels_min = 2, | ||
| 2045 | .channels_max = 2, | ||
| 2046 | .rates = WM5100_RATES, | ||
| 2047 | .formats = WM5100_FORMATS, | ||
| 2048 | }, | ||
| 2049 | .capture = { | ||
| 2050 | .stream_name = "AIF1 Capture", | ||
| 2051 | .channels_min = 2, | ||
| 2052 | .channels_max = 2, | ||
| 2053 | .rates = WM5100_RATES, | ||
| 2054 | .formats = WM5100_FORMATS, | ||
| 2055 | }, | ||
| 2056 | .ops = &wm5100_dai_ops, | ||
| 2057 | }, | ||
| 2058 | { | ||
| 2059 | .name = "wm5100-aif2", | ||
| 2060 | .id = 1, | ||
| 2061 | .playback = { | ||
| 2062 | .stream_name = "AIF2 Playback", | ||
| 2063 | .channels_min = 2, | ||
| 2064 | .channels_max = 2, | ||
| 2065 | .rates = WM5100_RATES, | ||
| 2066 | .formats = WM5100_FORMATS, | ||
| 2067 | }, | ||
| 2068 | .capture = { | ||
| 2069 | .stream_name = "AIF2 Capture", | ||
| 2070 | .channels_min = 2, | ||
| 2071 | .channels_max = 2, | ||
| 2072 | .rates = WM5100_RATES, | ||
| 2073 | .formats = WM5100_FORMATS, | ||
| 2074 | }, | ||
| 2075 | .ops = &wm5100_dai_ops, | ||
| 2076 | }, | ||
| 2077 | { | ||
| 2078 | .name = "wm5100-aif3", | ||
| 2079 | .id = 2, | ||
| 2080 | .playback = { | ||
| 2081 | .stream_name = "AIF3 Playback", | ||
| 2082 | .channels_min = 2, | ||
| 2083 | .channels_max = 2, | ||
| 2084 | .rates = WM5100_RATES, | ||
| 2085 | .formats = WM5100_FORMATS, | ||
| 2086 | }, | ||
| 2087 | .capture = { | ||
| 2088 | .stream_name = "AIF3 Capture", | ||
| 2089 | .channels_min = 2, | ||
| 2090 | .channels_max = 2, | ||
| 2091 | .rates = WM5100_RATES, | ||
| 2092 | .formats = WM5100_FORMATS, | ||
| 2093 | }, | ||
| 2094 | .ops = &wm5100_dai_ops, | ||
| 2095 | }, | ||
| 2096 | }; | ||
| 2097 | |||
| 2098 | static int wm5100_dig_vu[] = { | ||
| 2099 | WM5100_ADC_DIGITAL_VOLUME_1L, | ||
| 2100 | WM5100_ADC_DIGITAL_VOLUME_1R, | ||
| 2101 | WM5100_ADC_DIGITAL_VOLUME_2L, | ||
| 2102 | WM5100_ADC_DIGITAL_VOLUME_2R, | ||
| 2103 | WM5100_ADC_DIGITAL_VOLUME_3L, | ||
| 2104 | WM5100_ADC_DIGITAL_VOLUME_3R, | ||
| 2105 | WM5100_ADC_DIGITAL_VOLUME_4L, | ||
| 2106 | WM5100_ADC_DIGITAL_VOLUME_4R, | ||
| 2107 | |||
| 2108 | WM5100_DAC_DIGITAL_VOLUME_1L, | ||
| 2109 | WM5100_DAC_DIGITAL_VOLUME_1R, | ||
| 2110 | WM5100_DAC_DIGITAL_VOLUME_2L, | ||
| 2111 | WM5100_DAC_DIGITAL_VOLUME_2R, | ||
| 2112 | WM5100_DAC_DIGITAL_VOLUME_3L, | ||
| 2113 | WM5100_DAC_DIGITAL_VOLUME_3R, | ||
| 2114 | WM5100_DAC_DIGITAL_VOLUME_4L, | ||
| 2115 | WM5100_DAC_DIGITAL_VOLUME_4R, | ||
| 2116 | WM5100_DAC_DIGITAL_VOLUME_5L, | ||
| 2117 | WM5100_DAC_DIGITAL_VOLUME_5R, | ||
| 2118 | WM5100_DAC_DIGITAL_VOLUME_6L, | ||
| 2119 | WM5100_DAC_DIGITAL_VOLUME_6R, | ||
| 2120 | }; | ||
| 2121 | |||
| 2122 | static void wm5100_set_detect_mode(struct snd_soc_codec *codec, int the_mode) | ||
| 2123 | { | ||
| 2124 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2125 | struct wm5100_jack_mode *mode = &wm5100->pdata.jack_modes[the_mode]; | ||
| 2126 | |||
| 2127 | BUG_ON(the_mode >= ARRAY_SIZE(wm5100->pdata.jack_modes)); | ||
| 2128 | |||
| 2129 | gpio_set_value_cansleep(wm5100->pdata.hp_pol, mode->hp_pol); | ||
| 2130 | snd_soc_update_bits(codec, WM5100_ACCESSORY_DETECT_MODE_1, | ||
| 2131 | WM5100_ACCDET_BIAS_SRC_MASK | | ||
| 2132 | WM5100_ACCDET_SRC, | ||
| 2133 | (mode->bias << WM5100_ACCDET_BIAS_SRC_SHIFT) | | ||
| 2134 | mode->micd_src << WM5100_ACCDET_SRC_SHIFT); | ||
| 2135 | snd_soc_update_bits(codec, WM5100_MISC_CONTROL, | ||
| 2136 | WM5100_HPCOM_SRC, | ||
| 2137 | mode->micd_src << WM5100_HPCOM_SRC_SHIFT); | ||
| 2138 | |||
| 2139 | wm5100->jack_mode = the_mode; | ||
| 2140 | |||
| 2141 | dev_dbg(codec->dev, "Set microphone polarity to %d\n", | ||
| 2142 | wm5100->jack_mode); | ||
| 2143 | } | ||
| 2144 | |||
| 2145 | static void wm5100_micd_irq(struct snd_soc_codec *codec) | ||
| 2146 | { | ||
| 2147 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2148 | int val; | ||
| 2149 | |||
| 2150 | val = snd_soc_read(codec, WM5100_MIC_DETECT_3); | ||
| 2151 | |||
| 2152 | dev_dbg(codec->dev, "Microphone event: %x\n", val); | ||
| 2153 | |||
| 2154 | if (!(val & WM5100_ACCDET_VALID)) { | ||
| 2155 | dev_warn(codec->dev, "Microphone detection state invalid\n"); | ||
| 2156 | return; | ||
| 2157 | } | ||
| 2158 | |||
| 2159 | /* No accessory, reset everything and report removal */ | ||
| 2160 | if (!(val & WM5100_ACCDET_STS)) { | ||
| 2161 | dev_dbg(codec->dev, "Jack removal detected\n"); | ||
| 2162 | wm5100->jack_mic = false; | ||
| 2163 | wm5100->jack_detecting = true; | ||
| 2164 | snd_soc_jack_report(wm5100->jack, 0, | ||
| 2165 | SND_JACK_LINEOUT | SND_JACK_HEADSET | | ||
| 2166 | SND_JACK_BTN_0); | ||
| 2167 | |||
| 2168 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
| 2169 | WM5100_ACCDET_RATE_MASK, | ||
| 2170 | WM5100_ACCDET_RATE_MASK); | ||
| 2171 | return; | ||
| 2172 | } | ||
| 2173 | |||
| 2174 | /* If the measurement is very high we've got a microphone, | ||
| 2175 | * either we just detected one or if we already reported then | ||
| 2176 | * we've got a button release event. | ||
| 2177 | */ | ||
| 2178 | if (val & 0x400) { | ||
| 2179 | if (wm5100->jack_detecting) { | ||
| 2180 | dev_dbg(codec->dev, "Microphone detected\n"); | ||
| 2181 | wm5100->jack_mic = true; | ||
| 2182 | snd_soc_jack_report(wm5100->jack, | ||
| 2183 | SND_JACK_HEADSET, | ||
| 2184 | SND_JACK_HEADSET | SND_JACK_BTN_0); | ||
| 2185 | |||
| 2186 | /* Increase poll rate to give better responsiveness | ||
| 2187 | * for buttons */ | ||
| 2188 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
| 2189 | WM5100_ACCDET_RATE_MASK, | ||
| 2190 | 5 << WM5100_ACCDET_RATE_SHIFT); | ||
| 2191 | } else { | ||
| 2192 | dev_dbg(codec->dev, "Mic button up\n"); | ||
| 2193 | snd_soc_jack_report(wm5100->jack, 0, SND_JACK_BTN_0); | ||
| 2194 | } | ||
| 2195 | |||
| 2196 | return; | ||
| 2197 | } | ||
| 2198 | |||
| 2199 | /* If we detected a lower impedence during initial startup | ||
| 2200 | * then we probably have the wrong polarity, flip it. Don't | ||
| 2201 | * do this for the lowest impedences to speed up detection of | ||
| 2202 | * plain headphones. | ||
| 2203 | */ | ||
| 2204 | if (wm5100->jack_detecting && (val & 0x3f8)) { | ||
| 2205 | wm5100_set_detect_mode(codec, !wm5100->jack_mode); | ||
| 2206 | |||
| 2207 | return; | ||
| 2208 | } | ||
| 2209 | |||
| 2210 | /* Don't distinguish between buttons, just report any low | ||
| 2211 | * impedence as BTN_0. | ||
| 2212 | */ | ||
| 2213 | if (val & 0x3fc) { | ||
| 2214 | if (wm5100->jack_mic) { | ||
| 2215 | dev_dbg(codec->dev, "Mic button detected\n"); | ||
| 2216 | snd_soc_jack_report(wm5100->jack, SND_JACK_BTN_0, | ||
| 2217 | SND_JACK_BTN_0); | ||
| 2218 | } else if (wm5100->jack_detecting) { | ||
| 2219 | dev_dbg(codec->dev, "Headphone detected\n"); | ||
| 2220 | snd_soc_jack_report(wm5100->jack, SND_JACK_HEADPHONE, | ||
| 2221 | SND_JACK_HEADPHONE); | ||
| 2222 | |||
| 2223 | /* Increase the detection rate a bit for | ||
| 2224 | * responsiveness. | ||
| 2225 | */ | ||
| 2226 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
| 2227 | WM5100_ACCDET_RATE_MASK, | ||
| 2228 | 7 << WM5100_ACCDET_RATE_SHIFT); | ||
| 2229 | } | ||
| 2230 | } | ||
| 2231 | } | ||
| 2232 | |||
| 2233 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack) | ||
| 2234 | { | ||
| 2235 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2236 | |||
| 2237 | if (jack) { | ||
| 2238 | wm5100->jack = jack; | ||
| 2239 | wm5100->jack_detecting = true; | ||
| 2240 | |||
| 2241 | wm5100_set_detect_mode(codec, 0); | ||
| 2242 | |||
| 2243 | /* Slowest detection rate, gives debounce for initial | ||
| 2244 | * detection */ | ||
| 2245 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
| 2246 | WM5100_ACCDET_BIAS_STARTTIME_MASK | | ||
| 2247 | WM5100_ACCDET_RATE_MASK, | ||
| 2248 | (7 << WM5100_ACCDET_BIAS_STARTTIME_SHIFT) | | ||
| 2249 | WM5100_ACCDET_RATE_MASK); | ||
| 2250 | |||
| 2251 | /* We need the charge pump to power MICBIAS */ | ||
| 2252 | snd_soc_dapm_force_enable_pin(&codec->dapm, "CP2"); | ||
| 2253 | snd_soc_dapm_force_enable_pin(&codec->dapm, "SYSCLK"); | ||
| 2254 | snd_soc_dapm_sync(&codec->dapm); | ||
| 2255 | |||
| 2256 | /* We start off just enabling microphone detection - even a | ||
| 2257 | * plain headphone will trigger detection. | ||
| 2258 | */ | ||
| 2259 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
| 2260 | WM5100_ACCDET_ENA, WM5100_ACCDET_ENA); | ||
| 2261 | |||
| 2262 | snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK, | ||
| 2263 | WM5100_IM_ACCDET_EINT, 0); | ||
| 2264 | } else { | ||
| 2265 | snd_soc_update_bits(codec, WM5100_INTERRUPT_STATUS_3_MASK, | ||
| 2266 | WM5100_IM_HPDET_EINT | | ||
| 2267 | WM5100_IM_ACCDET_EINT, | ||
| 2268 | WM5100_IM_HPDET_EINT | | ||
| 2269 | WM5100_IM_ACCDET_EINT); | ||
| 2270 | snd_soc_update_bits(codec, WM5100_MIC_DETECT_1, | ||
| 2271 | WM5100_ACCDET_ENA, 0); | ||
| 2272 | wm5100->jack = NULL; | ||
| 2273 | } | ||
| 2274 | |||
| 2275 | return 0; | ||
| 2276 | } | ||
| 2277 | |||
| 2278 | static irqreturn_t wm5100_irq(int irq, void *data) | ||
| 2279 | { | ||
| 2280 | struct snd_soc_codec *codec = data; | ||
| 2281 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2282 | irqreturn_t status = IRQ_NONE; | ||
| 2283 | int irq_val; | ||
| 2284 | |||
| 2285 | irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3); | ||
| 2286 | if (irq_val < 0) { | ||
| 2287 | dev_err(codec->dev, "Failed to read IRQ status 3: %d\n", | ||
| 2288 | irq_val); | ||
| 2289 | irq_val = 0; | ||
| 2290 | } | ||
| 2291 | irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_3_MASK); | ||
| 2292 | |||
| 2293 | snd_soc_write(codec, WM5100_INTERRUPT_STATUS_3, irq_val); | ||
| 2294 | |||
| 2295 | if (irq_val) | ||
| 2296 | status = IRQ_HANDLED; | ||
| 2297 | |||
| 2298 | wm5100_log_status3(codec, irq_val); | ||
| 2299 | |||
| 2300 | if (irq_val & WM5100_FLL1_LOCK_EINT) { | ||
| 2301 | dev_dbg(codec->dev, "FLL1 locked\n"); | ||
| 2302 | complete(&wm5100->fll[0].lock); | ||
| 2303 | } | ||
| 2304 | if (irq_val & WM5100_FLL2_LOCK_EINT) { | ||
| 2305 | dev_dbg(codec->dev, "FLL2 locked\n"); | ||
| 2306 | complete(&wm5100->fll[1].lock); | ||
| 2307 | } | ||
| 2308 | |||
| 2309 | if (irq_val & WM5100_ACCDET_EINT) | ||
| 2310 | wm5100_micd_irq(codec); | ||
| 2311 | |||
| 2312 | irq_val = snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4); | ||
| 2313 | if (irq_val < 0) { | ||
| 2314 | dev_err(codec->dev, "Failed to read IRQ status 4: %d\n", | ||
| 2315 | irq_val); | ||
| 2316 | irq_val = 0; | ||
| 2317 | } | ||
| 2318 | irq_val &= ~snd_soc_read(codec, WM5100_INTERRUPT_STATUS_4_MASK); | ||
| 2319 | |||
| 2320 | if (irq_val) | ||
| 2321 | status = IRQ_HANDLED; | ||
| 2322 | |||
| 2323 | snd_soc_write(codec, WM5100_INTERRUPT_STATUS_4, irq_val); | ||
| 2324 | |||
| 2325 | wm5100_log_status4(codec, irq_val); | ||
| 2326 | |||
| 2327 | return status; | ||
| 2328 | } | ||
| 2329 | |||
| 2330 | static irqreturn_t wm5100_edge_irq(int irq, void *data) | ||
| 2331 | { | ||
| 2332 | irqreturn_t ret = IRQ_NONE; | ||
| 2333 | irqreturn_t val; | ||
| 2334 | |||
| 2335 | do { | ||
| 2336 | val = wm5100_irq(irq, data); | ||
| 2337 | if (val != IRQ_NONE) | ||
| 2338 | ret = val; | ||
| 2339 | } while (val != IRQ_NONE); | ||
| 2340 | |||
| 2341 | return ret; | ||
| 2342 | } | ||
| 2343 | |||
| 2344 | #ifdef CONFIG_GPIOLIB | ||
| 2345 | static inline struct wm5100_priv *gpio_to_wm5100(struct gpio_chip *chip) | ||
| 2346 | { | ||
| 2347 | return container_of(chip, struct wm5100_priv, gpio_chip); | ||
| 2348 | } | ||
| 2349 | |||
| 2350 | static void wm5100_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
| 2351 | { | ||
| 2352 | struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); | ||
| 2353 | struct snd_soc_codec *codec = wm5100->codec; | ||
| 2354 | |||
| 2355 | snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, | ||
| 2356 | WM5100_GP1_LVL, !!value << WM5100_GP1_LVL_SHIFT); | ||
| 2357 | } | ||
| 2358 | |||
| 2359 | static int wm5100_gpio_direction_out(struct gpio_chip *chip, | ||
| 2360 | unsigned offset, int value) | ||
| 2361 | { | ||
| 2362 | struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); | ||
| 2363 | struct snd_soc_codec *codec = wm5100->codec; | ||
| 2364 | int val; | ||
| 2365 | |||
| 2366 | val = (1 << WM5100_GP1_FN_SHIFT) | (!!value << WM5100_GP1_LVL_SHIFT); | ||
| 2367 | |||
| 2368 | return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, | ||
| 2369 | WM5100_GP1_FN_MASK | WM5100_GP1_DIR | | ||
| 2370 | WM5100_GP1_LVL, val); | ||
| 2371 | } | ||
| 2372 | |||
| 2373 | static int wm5100_gpio_get(struct gpio_chip *chip, unsigned offset) | ||
| 2374 | { | ||
| 2375 | struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); | ||
| 2376 | struct snd_soc_codec *codec = wm5100->codec; | ||
| 2377 | int ret; | ||
| 2378 | |||
| 2379 | ret = snd_soc_read(codec, WM5100_GPIO_CTRL_1 + offset); | ||
| 2380 | if (ret < 0) | ||
| 2381 | return ret; | ||
| 2382 | |||
| 2383 | return (ret & WM5100_GP1_LVL) != 0; | ||
| 2384 | } | ||
| 2385 | |||
| 2386 | static int wm5100_gpio_direction_in(struct gpio_chip *chip, unsigned offset) | ||
| 2387 | { | ||
| 2388 | struct wm5100_priv *wm5100 = gpio_to_wm5100(chip); | ||
| 2389 | struct snd_soc_codec *codec = wm5100->codec; | ||
| 2390 | |||
| 2391 | return snd_soc_update_bits(codec, WM5100_GPIO_CTRL_1 + offset, | ||
| 2392 | WM5100_GP1_FN_MASK | WM5100_GP1_DIR, | ||
| 2393 | (1 << WM5100_GP1_FN_SHIFT) | | ||
| 2394 | (1 << WM5100_GP1_DIR_SHIFT)); | ||
| 2395 | } | ||
| 2396 | |||
| 2397 | static struct gpio_chip wm5100_template_chip = { | ||
| 2398 | .label = "wm5100", | ||
| 2399 | .owner = THIS_MODULE, | ||
| 2400 | .direction_output = wm5100_gpio_direction_out, | ||
| 2401 | .set = wm5100_gpio_set, | ||
| 2402 | .direction_input = wm5100_gpio_direction_in, | ||
| 2403 | .get = wm5100_gpio_get, | ||
| 2404 | .can_sleep = 1, | ||
| 2405 | }; | ||
| 2406 | |||
| 2407 | static void wm5100_init_gpio(struct snd_soc_codec *codec) | ||
| 2408 | { | ||
| 2409 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2410 | int ret; | ||
| 2411 | |||
| 2412 | wm5100->gpio_chip = wm5100_template_chip; | ||
| 2413 | wm5100->gpio_chip.ngpio = 6; | ||
| 2414 | wm5100->gpio_chip.dev = codec->dev; | ||
| 2415 | |||
| 2416 | if (wm5100->pdata.gpio_base) | ||
| 2417 | wm5100->gpio_chip.base = wm5100->pdata.gpio_base; | ||
| 2418 | else | ||
| 2419 | wm5100->gpio_chip.base = -1; | ||
| 2420 | |||
| 2421 | ret = gpiochip_add(&wm5100->gpio_chip); | ||
| 2422 | if (ret != 0) | ||
| 2423 | dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); | ||
| 2424 | } | ||
| 2425 | |||
| 2426 | static void wm5100_free_gpio(struct snd_soc_codec *codec) | ||
| 2427 | { | ||
| 2428 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2429 | int ret; | ||
| 2430 | |||
| 2431 | ret = gpiochip_remove(&wm5100->gpio_chip); | ||
| 2432 | if (ret != 0) | ||
| 2433 | dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); | ||
| 2434 | } | ||
| 2435 | #else | ||
| 2436 | static void wm5100_init_gpio(struct snd_soc_codec *codec) | ||
| 2437 | { | ||
| 2438 | } | ||
| 2439 | |||
| 2440 | static void wm5100_free_gpio(struct snd_soc_codec *codec) | ||
| 2441 | { | ||
| 2442 | } | ||
| 2443 | #endif | ||
| 2444 | |||
| 2445 | static int wm5100_probe(struct snd_soc_codec *codec) | ||
| 2446 | { | ||
| 2447 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
| 2448 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2449 | int ret, i, irq_flags; | ||
| 2450 | |||
| 2451 | wm5100->codec = codec; | ||
| 2452 | |||
| 2453 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); | ||
| 2454 | if (ret != 0) { | ||
| 2455 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | ||
| 2456 | return ret; | ||
| 2457 | } | ||
| 2458 | |||
| 2459 | for (i = 0; i < ARRAY_SIZE(wm5100->core_supplies); i++) | ||
| 2460 | wm5100->core_supplies[i].supply = wm5100_core_supply_names[i]; | ||
| 2461 | |||
| 2462 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm5100->core_supplies), | ||
| 2463 | wm5100->core_supplies); | ||
| 2464 | if (ret != 0) { | ||
| 2465 | dev_err(codec->dev, "Failed to request core supplies: %d\n", | ||
| 2466 | ret); | ||
| 2467 | return ret; | ||
| 2468 | } | ||
| 2469 | |||
| 2470 | wm5100->cpvdd = regulator_get(&i2c->dev, "CPVDD"); | ||
| 2471 | if (IS_ERR(wm5100->cpvdd)) { | ||
| 2472 | ret = PTR_ERR(wm5100->cpvdd); | ||
| 2473 | dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); | ||
| 2474 | goto err_core; | ||
| 2475 | } | ||
| 2476 | |||
| 2477 | wm5100->dbvdd2 = regulator_get(&i2c->dev, "DBVDD2"); | ||
| 2478 | if (IS_ERR(wm5100->dbvdd2)) { | ||
| 2479 | ret = PTR_ERR(wm5100->dbvdd2); | ||
| 2480 | dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); | ||
| 2481 | goto err_cpvdd; | ||
| 2482 | } | ||
| 2483 | |||
| 2484 | wm5100->dbvdd3 = regulator_get(&i2c->dev, "DBVDD3"); | ||
| 2485 | if (IS_ERR(wm5100->dbvdd3)) { | ||
| 2486 | ret = PTR_ERR(wm5100->dbvdd3); | ||
| 2487 | dev_err(&i2c->dev, "Failed to get DBVDD2: %d\n", ret); | ||
| 2488 | goto err_dbvdd2; | ||
| 2489 | } | ||
| 2490 | |||
| 2491 | ret = regulator_bulk_enable(ARRAY_SIZE(wm5100->core_supplies), | ||
| 2492 | wm5100->core_supplies); | ||
| 2493 | if (ret != 0) { | ||
| 2494 | dev_err(codec->dev, "Failed to enable core supplies: %d\n", | ||
| 2495 | ret); | ||
| 2496 | goto err_dbvdd3; | ||
| 2497 | } | ||
| 2498 | |||
| 2499 | if (wm5100->pdata.ldo_ena) { | ||
| 2500 | ret = gpio_request_one(wm5100->pdata.ldo_ena, | ||
| 2501 | GPIOF_OUT_INIT_HIGH, "WM5100 LDOENA"); | ||
| 2502 | if (ret < 0) { | ||
| 2503 | dev_err(&i2c->dev, "Failed to request LDOENA %d: %d\n", | ||
| 2504 | wm5100->pdata.ldo_ena, ret); | ||
| 2505 | goto err_enable; | ||
| 2506 | } | ||
| 2507 | msleep(2); | ||
| 2508 | } | ||
| 2509 | |||
| 2510 | if (wm5100->pdata.reset) { | ||
| 2511 | ret = gpio_request_one(wm5100->pdata.reset, | ||
| 2512 | GPIOF_OUT_INIT_HIGH, "WM5100 /RESET"); | ||
| 2513 | if (ret < 0) { | ||
| 2514 | dev_err(&i2c->dev, "Failed to request /RESET %d: %d\n", | ||
| 2515 | wm5100->pdata.reset, ret); | ||
| 2516 | goto err_ldo; | ||
| 2517 | } | ||
| 2518 | } | ||
| 2519 | |||
| 2520 | ret = snd_soc_read(codec, WM5100_SOFTWARE_RESET); | ||
| 2521 | if (ret < 0) { | ||
| 2522 | dev_err(codec->dev, "Failed to read ID register\n"); | ||
| 2523 | goto err_reset; | ||
| 2524 | } | ||
| 2525 | switch (ret) { | ||
| 2526 | case 0x8997: | ||
| 2527 | case 0x5100: | ||
| 2528 | break; | ||
| 2529 | |||
| 2530 | default: | ||
| 2531 | dev_err(codec->dev, "Device is not a WM5100, ID is %x\n", ret); | ||
| 2532 | ret = -EINVAL; | ||
| 2533 | goto err_reset; | ||
| 2534 | } | ||
| 2535 | |||
| 2536 | ret = snd_soc_read(codec, WM5100_DEVICE_REVISION); | ||
| 2537 | if (ret < 0) { | ||
| 2538 | dev_err(codec->dev, "Failed to read revision register\n"); | ||
| 2539 | goto err_reset; | ||
| 2540 | } | ||
| 2541 | wm5100->rev = ret & WM5100_DEVICE_REVISION_MASK; | ||
| 2542 | |||
| 2543 | dev_info(codec->dev, "revision %c\n", wm5100->rev + 'A'); | ||
| 2544 | |||
| 2545 | ret = wm5100_reset(codec); | ||
| 2546 | if (ret < 0) { | ||
| 2547 | dev_err(codec->dev, "Failed to issue reset\n"); | ||
| 2548 | goto err_reset; | ||
| 2549 | } | ||
| 2550 | |||
| 2551 | codec->cache_only = true; | ||
| 2552 | |||
| 2553 | wm5100_init_gpio(codec); | ||
| 2554 | |||
| 2555 | for (i = 0; i < ARRAY_SIZE(wm5100_dig_vu); i++) | ||
| 2556 | snd_soc_update_bits(codec, wm5100_dig_vu[i], WM5100_OUT_VU, | ||
| 2557 | WM5100_OUT_VU); | ||
| 2558 | |||
| 2559 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.in_mode); i++) { | ||
| 2560 | snd_soc_update_bits(codec, WM5100_IN1L_CONTROL, | ||
| 2561 | WM5100_IN1_MODE_MASK | | ||
| 2562 | WM5100_IN1_DMIC_SUP_MASK, | ||
| 2563 | (wm5100->pdata.in_mode[i] << | ||
| 2564 | WM5100_IN1_MODE_SHIFT) | | ||
| 2565 | (wm5100->pdata.dmic_sup[i] << | ||
| 2566 | WM5100_IN1_DMIC_SUP_SHIFT)); | ||
| 2567 | } | ||
| 2568 | |||
| 2569 | for (i = 0; i < ARRAY_SIZE(wm5100->pdata.gpio_defaults); i++) { | ||
| 2570 | if (!wm5100->pdata.gpio_defaults[i]) | ||
| 2571 | continue; | ||
| 2572 | |||
| 2573 | snd_soc_write(codec, WM5100_GPIO_CTRL_1 + i, | ||
| 2574 | wm5100->pdata.gpio_defaults[i]); | ||
| 2575 | } | ||
| 2576 | |||
| 2577 | /* Don't debounce interrupts to support use of SYSCLK only */ | ||
| 2578 | snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_1, 0); | ||
| 2579 | snd_soc_write(codec, WM5100_IRQ_DEBOUNCE_2, 0); | ||
| 2580 | |||
| 2581 | /* TODO: check if we're symmetric */ | ||
| 2582 | |||
| 2583 | if (i2c->irq) { | ||
| 2584 | if (wm5100->pdata.irq_flags) | ||
| 2585 | irq_flags = wm5100->pdata.irq_flags; | ||
| 2586 | else | ||
| 2587 | irq_flags = IRQF_TRIGGER_LOW; | ||
| 2588 | |||
| 2589 | irq_flags |= IRQF_ONESHOT; | ||
| 2590 | |||
| 2591 | if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) | ||
| 2592 | ret = request_threaded_irq(i2c->irq, NULL, | ||
| 2593 | wm5100_edge_irq, | ||
| 2594 | irq_flags, "wm5100", codec); | ||
| 2595 | else | ||
| 2596 | ret = request_threaded_irq(i2c->irq, NULL, wm5100_irq, | ||
| 2597 | irq_flags, "wm5100", codec); | ||
| 2598 | |||
| 2599 | if (ret != 0) { | ||
| 2600 | dev_err(codec->dev, "Failed to request IRQ %d: %d\n", | ||
| 2601 | i2c->irq, ret); | ||
| 2602 | } else { | ||
| 2603 | /* Enable default interrupts */ | ||
| 2604 | snd_soc_update_bits(codec, | ||
| 2605 | WM5100_INTERRUPT_STATUS_3_MASK, | ||
| 2606 | WM5100_IM_SPK_SHUTDOWN_WARN_EINT | | ||
| 2607 | WM5100_IM_SPK_SHUTDOWN_EINT | | ||
| 2608 | WM5100_IM_ASRC2_LOCK_EINT | | ||
| 2609 | WM5100_IM_ASRC1_LOCK_EINT | | ||
| 2610 | WM5100_IM_FLL2_LOCK_EINT | | ||
| 2611 | WM5100_IM_FLL1_LOCK_EINT | | ||
| 2612 | WM5100_CLKGEN_ERR_EINT | | ||
| 2613 | WM5100_CLKGEN_ERR_ASYNC_EINT, 0); | ||
| 2614 | |||
| 2615 | snd_soc_update_bits(codec, | ||
| 2616 | WM5100_INTERRUPT_STATUS_4_MASK, | ||
| 2617 | WM5100_AIF3_ERR_EINT | | ||
| 2618 | WM5100_AIF2_ERR_EINT | | ||
| 2619 | WM5100_AIF1_ERR_EINT | | ||
| 2620 | WM5100_CTRLIF_ERR_EINT | | ||
| 2621 | WM5100_ISRC2_UNDERCLOCKED_EINT | | ||
| 2622 | WM5100_ISRC1_UNDERCLOCKED_EINT | | ||
| 2623 | WM5100_FX_UNDERCLOCKED_EINT | | ||
| 2624 | WM5100_AIF3_UNDERCLOCKED_EINT | | ||
| 2625 | WM5100_AIF2_UNDERCLOCKED_EINT | | ||
| 2626 | WM5100_AIF1_UNDERCLOCKED_EINT | | ||
| 2627 | WM5100_ASRC_UNDERCLOCKED_EINT | | ||
| 2628 | WM5100_DAC_UNDERCLOCKED_EINT | | ||
| 2629 | WM5100_ADC_UNDERCLOCKED_EINT | | ||
| 2630 | WM5100_MIXER_UNDERCLOCKED_EINT, 0); | ||
| 2631 | } | ||
| 2632 | } else { | ||
| 2633 | snd_soc_dapm_new_controls(&codec->dapm, | ||
| 2634 | wm5100_dapm_widgets_noirq, | ||
| 2635 | ARRAY_SIZE(wm5100_dapm_widgets_noirq)); | ||
| 2636 | } | ||
| 2637 | |||
| 2638 | if (wm5100->pdata.hp_pol) { | ||
| 2639 | ret = gpio_request_one(wm5100->pdata.hp_pol, | ||
| 2640 | GPIOF_OUT_INIT_HIGH, "WM5100 HP_POL"); | ||
| 2641 | if (ret < 0) { | ||
| 2642 | dev_err(&i2c->dev, "Failed to request HP_POL %d: %d\n", | ||
| 2643 | wm5100->pdata.hp_pol, ret); | ||
| 2644 | goto err_gpio; | ||
| 2645 | } | ||
| 2646 | } | ||
| 2647 | |||
| 2648 | /* We'll get woken up again when the system has something useful | ||
| 2649 | * for us to do. | ||
| 2650 | */ | ||
| 2651 | if (wm5100->pdata.ldo_ena) | ||
| 2652 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
| 2653 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | ||
| 2654 | wm5100->core_supplies); | ||
| 2655 | |||
| 2656 | return 0; | ||
| 2657 | |||
| 2658 | err_gpio: | ||
| 2659 | if (i2c->irq) | ||
| 2660 | free_irq(i2c->irq, codec); | ||
| 2661 | wm5100_free_gpio(codec); | ||
| 2662 | err_reset: | ||
| 2663 | if (wm5100->pdata.reset) { | ||
| 2664 | gpio_set_value_cansleep(wm5100->pdata.reset, 1); | ||
| 2665 | gpio_free(wm5100->pdata.reset); | ||
| 2666 | } | ||
| 2667 | err_ldo: | ||
| 2668 | if (wm5100->pdata.ldo_ena) { | ||
| 2669 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
| 2670 | gpio_free(wm5100->pdata.ldo_ena); | ||
| 2671 | } | ||
| 2672 | err_enable: | ||
| 2673 | regulator_bulk_disable(ARRAY_SIZE(wm5100->core_supplies), | ||
| 2674 | wm5100->core_supplies); | ||
| 2675 | err_dbvdd3: | ||
| 2676 | regulator_put(wm5100->dbvdd3); | ||
| 2677 | err_dbvdd2: | ||
| 2678 | regulator_put(wm5100->dbvdd2); | ||
| 2679 | err_cpvdd: | ||
| 2680 | regulator_put(wm5100->cpvdd); | ||
| 2681 | err_core: | ||
| 2682 | regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), | ||
| 2683 | wm5100->core_supplies); | ||
| 2684 | |||
| 2685 | return ret; | ||
| 2686 | } | ||
| 2687 | |||
| 2688 | static int wm5100_remove(struct snd_soc_codec *codec) | ||
| 2689 | { | ||
| 2690 | struct wm5100_priv *wm5100 = snd_soc_codec_get_drvdata(codec); | ||
| 2691 | struct i2c_client *i2c = to_i2c_client(codec->dev); | ||
| 2692 | |||
| 2693 | wm5100_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
| 2694 | if (wm5100->pdata.hp_pol) { | ||
| 2695 | gpio_free(wm5100->pdata.hp_pol); | ||
| 2696 | } | ||
| 2697 | if (i2c->irq) | ||
| 2698 | free_irq(i2c->irq, codec); | ||
| 2699 | wm5100_free_gpio(codec); | ||
| 2700 | if (wm5100->pdata.reset) { | ||
| 2701 | gpio_set_value_cansleep(wm5100->pdata.reset, 1); | ||
| 2702 | gpio_free(wm5100->pdata.reset); | ||
| 2703 | } | ||
| 2704 | if (wm5100->pdata.ldo_ena) { | ||
| 2705 | gpio_set_value_cansleep(wm5100->pdata.ldo_ena, 0); | ||
| 2706 | gpio_free(wm5100->pdata.ldo_ena); | ||
| 2707 | } | ||
| 2708 | regulator_put(wm5100->dbvdd3); | ||
| 2709 | regulator_put(wm5100->dbvdd2); | ||
| 2710 | regulator_put(wm5100->cpvdd); | ||
| 2711 | regulator_bulk_free(ARRAY_SIZE(wm5100->core_supplies), | ||
| 2712 | wm5100->core_supplies); | ||
| 2713 | return 0; | ||
| 2714 | } | ||
| 2715 | |||
| 2716 | static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { | ||
| 2717 | .probe = wm5100_probe, | ||
| 2718 | .remove = wm5100_remove, | ||
| 2719 | |||
| 2720 | .set_sysclk = wm5100_set_sysclk, | ||
| 2721 | .set_pll = wm5100_set_fll, | ||
| 2722 | .set_bias_level = wm5100_set_bias_level, | ||
| 2723 | .idle_bias_off = 1, | ||
| 2724 | |||
| 2725 | .seq_notifier = wm5100_seq_notifier, | ||
| 2726 | .controls = wm5100_snd_controls, | ||
| 2727 | .num_controls = ARRAY_SIZE(wm5100_snd_controls), | ||
| 2728 | .dapm_widgets = wm5100_dapm_widgets, | ||
| 2729 | .num_dapm_widgets = ARRAY_SIZE(wm5100_dapm_widgets), | ||
| 2730 | .dapm_routes = wm5100_dapm_routes, | ||
| 2731 | .num_dapm_routes = ARRAY_SIZE(wm5100_dapm_routes), | ||
| 2732 | |||
| 2733 | .reg_cache_size = ARRAY_SIZE(wm5100_reg_defaults), | ||
| 2734 | .reg_word_size = sizeof(u16), | ||
| 2735 | .compress_type = SND_SOC_RBTREE_COMPRESSION, | ||
| 2736 | .reg_cache_default = wm5100_reg_defaults, | ||
| 2737 | |||
| 2738 | .volatile_register = wm5100_volatile_register, | ||
| 2739 | .readable_register = wm5100_readable_register, | ||
| 2740 | }; | ||
| 2741 | |||
| 2742 | static __devinit int wm5100_i2c_probe(struct i2c_client *i2c, | ||
| 2743 | const struct i2c_device_id *id) | ||
| 2744 | { | ||
| 2745 | struct wm5100_pdata *pdata = dev_get_platdata(&i2c->dev); | ||
| 2746 | struct wm5100_priv *wm5100; | ||
| 2747 | int ret, i; | ||
| 2748 | |||
| 2749 | wm5100 = kzalloc(sizeof(struct wm5100_priv), GFP_KERNEL); | ||
| 2750 | if (wm5100 == NULL) | ||
| 2751 | return -ENOMEM; | ||
| 2752 | |||
| 2753 | for (i = 0; i < ARRAY_SIZE(wm5100->fll); i++) | ||
| 2754 | init_completion(&wm5100->fll[i].lock); | ||
| 2755 | |||
| 2756 | if (pdata) | ||
| 2757 | wm5100->pdata = *pdata; | ||
| 2758 | |||
| 2759 | i2c_set_clientdata(i2c, wm5100); | ||
| 2760 | |||
| 2761 | ret = snd_soc_register_codec(&i2c->dev, | ||
| 2762 | &soc_codec_dev_wm5100, wm5100_dai, | ||
| 2763 | ARRAY_SIZE(wm5100_dai)); | ||
| 2764 | if (ret < 0) { | ||
| 2765 | dev_err(&i2c->dev, "Failed to register WM5100: %d\n", ret); | ||
| 2766 | kfree(wm5100); | ||
| 2767 | } | ||
| 2768 | |||
| 2769 | return ret; | ||
| 2770 | } | ||
| 2771 | |||
| 2772 | static __devexit int wm5100_i2c_remove(struct i2c_client *client) | ||
| 2773 | { | ||
| 2774 | snd_soc_unregister_codec(&client->dev); | ||
| 2775 | kfree(i2c_get_clientdata(client)); | ||
| 2776 | return 0; | ||
| 2777 | } | ||
| 2778 | |||
| 2779 | static const struct i2c_device_id wm5100_i2c_id[] = { | ||
| 2780 | { "wm5100", 0 }, | ||
| 2781 | { } | ||
| 2782 | }; | ||
| 2783 | MODULE_DEVICE_TABLE(i2c, wm5100_i2c_id); | ||
| 2784 | |||
| 2785 | static struct i2c_driver wm5100_i2c_driver = { | ||
| 2786 | .driver = { | ||
| 2787 | .name = "wm5100", | ||
| 2788 | .owner = THIS_MODULE, | ||
| 2789 | }, | ||
| 2790 | .probe = wm5100_i2c_probe, | ||
| 2791 | .remove = __devexit_p(wm5100_i2c_remove), | ||
| 2792 | .id_table = wm5100_i2c_id, | ||
| 2793 | }; | ||
| 2794 | |||
| 2795 | static int __init wm5100_modinit(void) | ||
| 2796 | { | ||
| 2797 | return i2c_add_driver(&wm5100_i2c_driver); | ||
| 2798 | } | ||
| 2799 | module_init(wm5100_modinit); | ||
| 2800 | |||
| 2801 | static void __exit wm5100_exit(void) | ||
| 2802 | { | ||
| 2803 | i2c_del_driver(&wm5100_i2c_driver); | ||
| 2804 | } | ||
| 2805 | module_exit(wm5100_exit); | ||
| 2806 | |||
| 2807 | MODULE_DESCRIPTION("ASoC WM5100 driver"); | ||
| 2808 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
| 2809 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/wm5100.h b/sound/soc/codecs/wm5100.h new file mode 100644 index 000000000000..970759636bdc --- /dev/null +++ b/sound/soc/codecs/wm5100.h | |||
| @@ -0,0 +1,5155 @@ | |||
| 1 | /* | ||
| 2 | * wm5100.h -- WM5100 ALSA SoC Audio driver | ||
| 3 | * | ||
| 4 | * Copyright 2011 Wolfson Microelectronics plc | ||
| 5 | * | ||
| 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | ||
| 7 | * | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify | ||
| 10 | * it under the terms of the GNU General Public License version 2 as | ||
| 11 | * published by the Free Software Foundation. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #ifndef WM5100_ASOC_H | ||
| 15 | #define WM5100_ASOC_H | ||
| 16 | |||
| 17 | #include <sound/soc.h> | ||
| 18 | |||
| 19 | int wm5100_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack); | ||
| 20 | |||
| 21 | #define WM5100_CLK_AIF1 1 | ||
| 22 | #define WM5100_CLK_AIF2 2 | ||
| 23 | #define WM5100_CLK_AIF3 3 | ||
| 24 | #define WM5100_CLK_SYSCLK 4 | ||
| 25 | #define WM5100_CLK_ASYNCCLK 5 | ||
| 26 | #define WM5100_CLK_32KHZ 6 | ||
| 27 | #define WM5100_CLK_OPCLK 7 | ||
| 28 | |||
| 29 | #define WM5100_CLKSRC_MCLK1 0 | ||
| 30 | #define WM5100_CLKSRC_MCLK2 1 | ||
| 31 | #define WM5100_CLKSRC_SYSCLK 2 | ||
| 32 | #define WM5100_CLKSRC_FLL1 4 | ||
| 33 | #define WM5100_CLKSRC_FLL2 5 | ||
| 34 | #define WM5100_CLKSRC_AIF1BCLK 8 | ||
| 35 | #define WM5100_CLKSRC_AIF2BCLK 9 | ||
| 36 | #define WM5100_CLKSRC_AIF3BCLK 10 | ||
| 37 | #define WM5100_CLKSRC_ASYNCCLK 0x100 | ||
| 38 | |||
| 39 | #define WM5100_FLL1 1 | ||
| 40 | #define WM5100_FLL2 2 | ||
| 41 | |||
| 42 | #define WM5100_FLL_SRC_MCLK1 0x0 | ||
| 43 | #define WM5100_FLL_SRC_MCLK2 0x1 | ||
| 44 | #define WM5100_FLL_SRC_FLL1 0x4 | ||
| 45 | #define WM5100_FLL_SRC_FLL2 0x5 | ||
| 46 | #define WM5100_FLL_SRC_AIF1BCLK 0x8 | ||
| 47 | #define WM5100_FLL_SRC_AIF2BCLK 0x9 | ||
| 48 | #define WM5100_FLL_SRC_AIF3BCLK 0xa | ||
| 49 | |||
| 50 | /* | ||
| 51 | * Register values. | ||
| 52 | */ | ||
| 53 | #define WM5100_SOFTWARE_RESET 0x00 | ||
| 54 | #define WM5100_DEVICE_REVISION 0x01 | ||
| 55 | #define WM5100_CTRL_IF_1 0x10 | ||
| 56 | #define WM5100_TONE_GENERATOR_1 0x20 | ||
| 57 | #define WM5100_PWM_DRIVE_1 0x30 | ||
| 58 | #define WM5100_PWM_DRIVE_2 0x31 | ||
| 59 | #define WM5100_PWM_DRIVE_3 0x32 | ||
| 60 | #define WM5100_CLOCKING_1 0x100 | ||
| 61 | #define WM5100_CLOCKING_3 0x101 | ||
| 62 | #define WM5100_CLOCKING_4 0x102 | ||
| 63 | #define WM5100_CLOCKING_5 0x103 | ||
| 64 | #define WM5100_CLOCKING_6 0x104 | ||
| 65 | #define WM5100_CLOCKING_7 0x107 | ||
| 66 | #define WM5100_CLOCKING_8 0x108 | ||
| 67 | #define WM5100_ASRC_ENABLE 0x120 | ||
| 68 | #define WM5100_ASRC_STATUS 0x121 | ||
| 69 | #define WM5100_ASRC_RATE1 0x122 | ||
| 70 | #define WM5100_ISRC_1_CTRL_1 0x141 | ||
| 71 | #define WM5100_ISRC_1_CTRL_2 0x142 | ||
| 72 | #define WM5100_ISRC_2_CTRL1 0x143 | ||
| 73 | #define WM5100_ISRC_2_CTRL_2 0x144 | ||
| 74 | #define WM5100_FLL1_CONTROL_1 0x182 | ||
| 75 | #define WM5100_FLL1_CONTROL_2 0x183 | ||
| 76 | #define WM5100_FLL1_CONTROL_3 0x184 | ||
| 77 | #define WM5100_FLL1_CONTROL_5 0x186 | ||
| 78 | #define WM5100_FLL1_CONTROL_6 0x187 | ||
| 79 | #define WM5100_FLL1_EFS_1 0x188 | ||
| 80 | #define WM5100_FLL2_CONTROL_1 0x1A2 | ||
| 81 | #define WM5100_FLL2_CONTROL_2 0x1A3 | ||
| 82 | #define WM5100_FLL2_CONTROL_3 0x1A4 | ||
| 83 | #define WM5100_FLL2_CONTROL_5 0x1A6 | ||
| 84 | #define WM5100_FLL2_CONTROL_6 0x1A7 | ||
| 85 | #define WM5100_FLL2_EFS_1 0x1A8 | ||
| 86 | #define WM5100_MIC_CHARGE_PUMP_1 0x200 | ||
| 87 | #define WM5100_MIC_CHARGE_PUMP_2 0x201 | ||
| 88 | #define WM5100_HP_CHARGE_PUMP_1 0x202 | ||
| 89 | #define WM5100_LDO1_CONTROL 0x211 | ||
| 90 | #define WM5100_MIC_BIAS_CTRL_1 0x215 | ||
| 91 | #define WM5100_MIC_BIAS_CTRL_2 0x216 | ||
| 92 | #define WM5100_MIC_BIAS_CTRL_3 0x217 | ||
| 93 | #define WM5100_ACCESSORY_DETECT_MODE_1 0x280 | ||
| 94 | #define WM5100_HEADPHONE_DETECT_1 0x288 | ||
| 95 | #define WM5100_HEADPHONE_DETECT_2 0x289 | ||
| 96 | #define WM5100_MIC_DETECT_1 0x290 | ||
| 97 | #define WM5100_MIC_DETECT_2 0x291 | ||
| 98 | #define WM5100_MIC_DETECT_3 0x292 | ||
| 99 | #define WM5100_MISC_CONTROL 0x2BB | ||
| 100 | #define WM5100_INPUT_ENABLES 0x301 | ||
| 101 | #define WM5100_INPUT_ENABLES_STATUS 0x302 | ||
| 102 | #define WM5100_IN1L_CONTROL 0x310 | ||
| 103 | #define WM5100_IN1R_CONTROL 0x311 | ||
| 104 | #define WM5100_IN2L_CONTROL 0x312 | ||
| 105 | #define WM5100_IN2R_CONTROL 0x313 | ||
| 106 | #define WM5100_IN3L_CONTROL 0x314 | ||
| 107 | #define WM5100_IN3R_CONTROL 0x315 | ||
| 108 | #define WM5100_IN4L_CONTROL 0x316 | ||
| 109 | #define WM5100_IN4R_CONTROL 0x317 | ||
| 110 | #define WM5100_RXANC_SRC 0x318 | ||
| 111 | #define WM5100_INPUT_VOLUME_RAMP 0x319 | ||
| 112 | #define WM5100_ADC_DIGITAL_VOLUME_1L 0x320 | ||
| 113 | #define WM5100_ADC_DIGITAL_VOLUME_1R 0x321 | ||
| 114 | #define WM5100_ADC_DIGITAL_VOLUME_2L 0x322 | ||
| 115 | #define WM5100_ADC_DIGITAL_VOLUME_2R 0x323 | ||
| 116 | #define WM5100_ADC_DIGITAL_VOLUME_3L 0x324 | ||
| 117 | #define WM5100_ADC_DIGITAL_VOLUME_3R 0x325 | ||
| 118 | #define WM5100_ADC_DIGITAL_VOLUME_4L 0x326 | ||
| 119 | #define WM5100_ADC_DIGITAL_VOLUME_4R 0x327 | ||
| 120 | #define WM5100_OUTPUT_ENABLES_2 0x401 | ||
| 121 | #define WM5100_OUTPUT_STATUS_1 0x402 | ||
| 122 | #define WM5100_OUTPUT_STATUS_2 0x403 | ||
| 123 | #define WM5100_CHANNEL_ENABLES_1 0x408 | ||
| 124 | #define WM5100_OUT_VOLUME_1L 0x410 | ||
| 125 | #define WM5100_OUT_VOLUME_1R 0x411 | ||
| 126 | #define WM5100_DAC_VOLUME_LIMIT_1L 0x412 | ||
| 127 | #define WM5100_DAC_VOLUME_LIMIT_1R 0x413 | ||
| 128 | #define WM5100_OUT_VOLUME_2L 0x414 | ||
| 129 | #define WM5100_OUT_VOLUME_2R 0x415 | ||
| 130 | #define WM5100_DAC_VOLUME_LIMIT_2L 0x416 | ||
| 131 | #define WM5100_DAC_VOLUME_LIMIT_2R 0x417 | ||
| 132 | #define WM5100_OUT_VOLUME_3L 0x418 | ||
| 133 | #define WM5100_OUT_VOLUME_3R 0x419 | ||
| 134 | #define WM5100_DAC_VOLUME_LIMIT_3L 0x41A | ||
| 135 | #define WM5100_DAC_VOLUME_LIMIT_3R 0x41B | ||
| 136 | #define WM5100_OUT_VOLUME_4L 0x41C | ||
| 137 | #define WM5100_OUT_VOLUME_4R 0x41D | ||
| 138 | #define WM5100_DAC_VOLUME_LIMIT_5L 0x41E | ||
| 139 | #define WM5100_DAC_VOLUME_LIMIT_5R 0x41F | ||
| 140 | #define WM5100_DAC_VOLUME_LIMIT_6L 0x420 | ||
| 141 | #define WM5100_DAC_VOLUME_LIMIT_6R 0x421 | ||
| 142 | #define WM5100_DAC_AEC_CONTROL_1 0x440 | ||
| 143 | #define WM5100_OUTPUT_VOLUME_RAMP 0x441 | ||
| 144 | #define WM5100_DAC_DIGITAL_VOLUME_1L 0x480 | ||
| 145 | #define WM5100_DAC_DIGITAL_VOLUME_1R 0x481 | ||
| 146 | #define WM5100_DAC_DIGITAL_VOLUME_2L 0x482 | ||
| 147 | #define WM5100_DAC_DIGITAL_VOLUME_2R 0x483 | ||
| 148 | #define WM5100_DAC_DIGITAL_VOLUME_3L 0x484 | ||
| 149 | #define WM5100_DAC_DIGITAL_VOLUME_3R 0x485 | ||
| 150 | #define WM5100_DAC_DIGITAL_VOLUME_4L 0x486 | ||
| 151 | #define WM5100_DAC_DIGITAL_VOLUME_4R 0x487 | ||
| 152 | #define WM5100_DAC_DIGITAL_VOLUME_5L 0x488 | ||
| 153 | #define WM5100_DAC_DIGITAL_VOLUME_5R 0x489 | ||
| 154 | #define WM5100_DAC_DIGITAL_VOLUME_6L 0x48A | ||
| 155 | #define WM5100_DAC_DIGITAL_VOLUME_6R 0x48B | ||
| 156 | #define WM5100_PDM_SPK1_CTRL_1 0x4C0 | ||
| 157 | #define WM5100_PDM_SPK1_CTRL_2 0x4C1 | ||
| 158 | #define WM5100_PDM_SPK2_CTRL_1 0x4C2 | ||
| 159 | #define WM5100_PDM_SPK2_CTRL_2 0x4C3 | ||
| 160 | #define WM5100_AUDIO_IF_1_1 0x500 | ||
| 161 | #define WM5100_AUDIO_IF_1_2 0x501 | ||
| 162 | #define WM5100_AUDIO_IF_1_3 0x502 | ||
| 163 | #define WM5100_AUDIO_IF_1_4 0x503 | ||
| 164 | #define WM5100_AUDIO_IF_1_5 0x504 | ||
| 165 | #define WM5100_AUDIO_IF_1_6 0x505 | ||
| 166 | #define WM5100_AUDIO_IF_1_7 0x506 | ||
| 167 | #define WM5100_AUDIO_IF_1_8 0x507 | ||
| 168 | #define WM5100_AUDIO_IF_1_9 0x508 | ||
| 169 | #define WM5100_AUDIO_IF_1_10 0x509 | ||
| 170 | #define WM5100_AUDIO_IF_1_11 0x50A | ||
| 171 | #define WM5100_AUDIO_IF_1_12 0x50B | ||
| 172 | #define WM5100_AUDIO_IF_1_13 0x50C | ||
| 173 | #define WM5100_AUDIO_IF_1_14 0x50D | ||
| 174 | #define WM5100_AUDIO_IF_1_15 0x50E | ||
| 175 | #define WM5100_AUDIO_IF_1_16 0x50F | ||
| 176 | #define WM5100_AUDIO_IF_1_17 0x510 | ||
| 177 | #define WM5100_AUDIO_IF_1_18 0x511 | ||
| 178 | #define WM5100_AUDIO_IF_1_19 0x512 | ||
| 179 | #define WM5100_AUDIO_IF_1_20 0x513 | ||
| 180 | #define WM5100_AUDIO_IF_1_21 0x514 | ||
| 181 | #define WM5100_AUDIO_IF_1_22 0x515 | ||
| 182 | #define WM5100_AUDIO_IF_1_23 0x516 | ||
| 183 | #define WM5100_AUDIO_IF_1_24 0x517 | ||
| 184 | #define WM5100_AUDIO_IF_1_25 0x518 | ||
| 185 | #define WM5100_AUDIO_IF_1_26 0x519 | ||
| 186 | #define WM5100_AUDIO_IF_1_27 0x51A | ||
| 187 | #define WM5100_AUDIO_IF_2_1 0x540 | ||
| 188 | #define WM5100_AUDIO_IF_2_2 0x541 | ||
| 189 | #define WM5100_AUDIO_IF_2_3 0x542 | ||
| 190 | #define WM5100_AUDIO_IF_2_4 0x543 | ||
| 191 | #define WM5100_AUDIO_IF_2_5 0x544 | ||
| 192 | #define WM5100_AUDIO_IF_2_6 0x545 | ||
| 193 | #define WM5100_AUDIO_IF_2_7 0x546 | ||
| 194 | #define WM5100_AUDIO_IF_2_8 0x547 | ||
| 195 | #define WM5100_AUDIO_IF_2_9 0x548 | ||
| 196 | #define WM5100_AUDIO_IF_2_10 0x549 | ||
| 197 | #define WM5100_AUDIO_IF_2_11 0x54A | ||
| 198 | #define WM5100_AUDIO_IF_2_18 0x551 | ||
| 199 | #define WM5100_AUDIO_IF_2_19 0x552 | ||
| 200 | #define WM5100_AUDIO_IF_2_26 0x559 | ||
| 201 | #define WM5100_AUDIO_IF_2_27 0x55A | ||
| 202 | #define WM5100_AUDIO_IF_3_1 0x580 | ||
| 203 | #define WM5100_AUDIO_IF_3_2 0x581 | ||
| 204 | #define WM5100_AUDIO_IF_3_3 0x582 | ||
| 205 | #define WM5100_AUDIO_IF_3_4 0x583 | ||
| 206 | #define WM5100_AUDIO_IF_3_5 0x584 | ||
| 207 | #define WM5100_AUDIO_IF_3_6 0x585 | ||
| 208 | #define WM5100_AUDIO_IF_3_7 0x586 | ||
| 209 | #define WM5100_AUDIO_IF_3_8 0x587 | ||
| 210 | #define WM5100_AUDIO_IF_3_9 0x588 | ||
| 211 | #define WM5100_AUDIO_IF_3_10 0x589 | ||
| 212 | #define WM5100_AUDIO_IF_3_11 0x58A | ||
| 213 | #define WM5100_AUDIO_IF_3_18 0x591 | ||
| 214 | #define WM5100_AUDIO_IF_3_19 0x592 | ||
| 215 | #define WM5100_AUDIO_IF_3_26 0x599 | ||
| 216 | #define WM5100_AUDIO_IF_3_27 0x59A | ||
| 217 | #define WM5100_PWM1MIX_INPUT_1_SOURCE 0x640 | ||
| 218 | #define WM5100_PWM1MIX_INPUT_1_VOLUME 0x641 | ||
| 219 | #define WM5100_PWM1MIX_INPUT_2_SOURCE 0x642 | ||
| 220 | #define WM5100_PWM1MIX_INPUT_2_VOLUME 0x643 | ||
| 221 | #define WM5100_PWM1MIX_INPUT_3_SOURCE 0x644 | ||
| 222 | #define WM5100_PWM1MIX_INPUT_3_VOLUME 0x645 | ||
| 223 | #define WM5100_PWM1MIX_INPUT_4_SOURCE 0x646 | ||
| 224 | #define WM5100_PWM1MIX_INPUT_4_VOLUME 0x647 | ||
| 225 | #define WM5100_PWM2MIX_INPUT_1_SOURCE 0x648 | ||
| 226 | #define WM5100_PWM2MIX_INPUT_1_VOLUME 0x649 | ||
| 227 | #define WM5100_PWM2MIX_INPUT_2_SOURCE 0x64A | ||
| 228 | #define WM5100_PWM2MIX_INPUT_2_VOLUME 0x64B | ||
| 229 | #define WM5100_PWM2MIX_INPUT_3_SOURCE 0x64C | ||
| 230 | #define WM5100_PWM2MIX_INPUT_3_VOLUME 0x64D | ||
| 231 | #define WM5100_PWM2MIX_INPUT_4_SOURCE 0x64E | ||
| 232 | #define WM5100_PWM2MIX_INPUT_4_VOLUME 0x64F | ||
| 233 | #define WM5100_OUT1LMIX_INPUT_1_SOURCE 0x680 | ||
| 234 | #define WM5100_OUT1LMIX_INPUT_1_VOLUME 0x681 | ||
| 235 | #define WM5100_OUT1LMIX_INPUT_2_SOURCE 0x682 | ||
| 236 | #define WM5100_OUT1LMIX_INPUT_2_VOLUME 0x683 | ||
| 237 | #define WM5100_OUT1LMIX_INPUT_3_SOURCE 0x684 | ||
| 238 | #define WM5100_OUT1LMIX_INPUT_3_VOLUME 0x685 | ||
| 239 | #define WM5100_OUT1LMIX_INPUT_4_SOURCE 0x686 | ||
| 240 | #define WM5100_OUT1LMIX_INPUT_4_VOLUME 0x687 | ||
| 241 | #define WM5100_OUT1RMIX_INPUT_1_SOURCE 0x688 | ||
| 242 | #define WM5100_OUT1RMIX_INPUT_1_VOLUME 0x689 | ||
| 243 | #define WM5100_OUT1RMIX_INPUT_2_SOURCE 0x68A | ||
| 244 | #define WM5100_OUT1RMIX_INPUT_2_VOLUME 0x68B | ||
| 245 | #define WM5100_OUT1RMIX_INPUT_3_SOURCE 0x68C | ||
| 246 | #define WM5100_OUT1RMIX_INPUT_3_VOLUME 0x68D | ||
| 247 | #define WM5100_OUT1RMIX_INPUT_4_SOURCE 0x68E | ||
| 248 | #define WM5100_OUT1RMIX_INPUT_4_VOLUME 0x68F | ||
| 249 | #define WM5100_OUT2LMIX_INPUT_1_SOURCE 0x690 | ||
| 250 | #define WM5100_OUT2LMIX_INPUT_1_VOLUME 0x691 | ||
| 251 | #define WM5100_OUT2LMIX_INPUT_2_SOURCE 0x692 | ||
| 252 | #define WM5100_OUT2LMIX_INPUT_2_VOLUME 0x693 | ||
| 253 | #define WM5100_OUT2LMIX_INPUT_3_SOURCE 0x694 | ||
| 254 | #define WM5100_OUT2LMIX_INPUT_3_VOLUME 0x695 | ||
| 255 | #define WM5100_OUT2LMIX_INPUT_4_SOURCE 0x696 | ||
| 256 | #define WM5100_OUT2LMIX_INPUT_4_VOLUME 0x697 | ||
| 257 | #define WM5100_OUT2RMIX_INPUT_1_SOURCE 0x698 | ||
| 258 | #define WM5100_OUT2RMIX_INPUT_1_VOLUME 0x699 | ||
| 259 | #define WM5100_OUT2RMIX_INPUT_2_SOURCE 0x69A | ||
| 260 | #define WM5100_OUT2RMIX_INPUT_2_VOLUME 0x69B | ||
| 261 | #define WM5100_OUT2RMIX_INPUT_3_SOURCE 0x69C | ||
| 262 | #define WM5100_OUT2RMIX_INPUT_3_VOLUME 0x69D | ||
| 263 | #define WM5100_OUT2RMIX_INPUT_4_SOURCE 0x69E | ||
| 264 | #define WM5100_OUT2RMIX_INPUT_4_VOLUME 0x69F | ||
| 265 | #define WM5100_OUT3LMIX_INPUT_1_SOURCE 0x6A0 | ||
| 266 | #define WM5100_OUT3LMIX_INPUT_1_VOLUME 0x6A1 | ||
| 267 | #define WM5100_OUT3LMIX_INPUT_2_SOURCE 0x6A2 | ||
| 268 | #define WM5100_OUT3LMIX_INPUT_2_VOLUME 0x6A3 | ||
| 269 | #define WM5100_OUT3LMIX_INPUT_3_SOURCE 0x6A4 | ||
| 270 | #define WM5100_OUT3LMIX_INPUT_3_VOLUME 0x6A5 | ||
| 271 | #define WM5100_OUT3LMIX_INPUT_4_SOURCE 0x6A6 | ||
| 272 | #define WM5100_OUT3LMIX_INPUT_4_VOLUME 0x6A7 | ||
| 273 | #define WM5100_OUT3RMIX_INPUT_1_SOURCE 0x6A8 | ||
| 274 | #define WM5100_OUT3RMIX_INPUT_1_VOLUME 0x6A9 | ||
| 275 | #define WM5100_OUT3RMIX_INPUT_2_SOURCE 0x6AA | ||
| 276 | #define WM5100_OUT3RMIX_INPUT_2_VOLUME 0x6AB | ||
| 277 | #define WM5100_OUT3RMIX_INPUT_3_SOURCE 0x6AC | ||
| 278 | #define WM5100_OUT3RMIX_INPUT_3_VOLUME 0x6AD | ||
| 279 | #define WM5100_OUT3RMIX_INPUT_4_SOURCE 0x6AE | ||
| 280 | #define WM5100_OUT3RMIX_INPUT_4_VOLUME 0x6AF | ||
| 281 | #define WM5100_OUT4LMIX_INPUT_1_SOURCE 0x6B0 | ||
| 282 | #define WM5100_OUT4LMIX_INPUT_1_VOLUME 0x6B1 | ||
| 283 | #define WM5100_OUT4LMIX_INPUT_2_SOURCE 0x6B2 | ||
| 284 | #define WM5100_OUT4LMIX_INPUT_2_VOLUME 0x6B3 | ||
| 285 | #define WM5100_OUT4LMIX_INPUT_3_SOURCE 0x6B4 | ||
| 286 | #define WM5100_OUT4LMIX_INPUT_3_VOLUME 0x6B5 | ||
| 287 | #define WM5100_OUT4LMIX_INPUT_4_SOURCE 0x6B6 | ||
| 288 | #define WM5100_OUT4LMIX_INPUT_4_VOLUME 0x6B7 | ||
| 289 | #define WM5100_OUT4RMIX_INPUT_1_SOURCE 0x6B8 | ||
| 290 | #define WM5100_OUT4RMIX_INPUT_1_VOLUME 0x6B9 | ||
| 291 | #define WM5100_OUT4RMIX_INPUT_2_SOURCE 0x6BA | ||
| 292 | #define WM5100_OUT4RMIX_INPUT_2_VOLUME 0x6BB | ||
| 293 | #define WM5100_OUT4RMIX_INPUT_3_SOURCE 0x6BC | ||
| 294 | #define WM5100_OUT4RMIX_INPUT_3_VOLUME 0x6BD | ||
| 295 | #define WM5100_OUT4RMIX_INPUT_4_SOURCE 0x6BE | ||
| 296 | #define WM5100_OUT4RMIX_INPUT_4_VOLUME 0x6BF | ||
| 297 | #define WM5100_OUT5LMIX_INPUT_1_SOURCE 0x6C0 | ||
| 298 | #define WM5100_OUT5LMIX_INPUT_1_VOLUME 0x6C1 | ||
| 299 | #define WM5100_OUT5LMIX_INPUT_2_SOURCE 0x6C2 | ||
| 300 | #define WM5100_OUT5LMIX_INPUT_2_VOLUME 0x6C3 | ||
| 301 | #define WM5100_OUT5LMIX_INPUT_3_SOURCE 0x6C4 | ||
| 302 | #define WM5100_OUT5LMIX_INPUT_3_VOLUME 0x6C5 | ||
| 303 | #define WM5100_OUT5LMIX_INPUT_4_SOURCE 0x6C6 | ||
| 304 | #define WM5100_OUT5LMIX_INPUT_4_VOLUME 0x6C7 | ||
| 305 | #define WM5100_OUT5RMIX_INPUT_1_SOURCE 0x6C8 | ||
| 306 | #define WM5100_OUT5RMIX_INPUT_1_VOLUME 0x6C9 | ||
| 307 | #define WM5100_OUT5RMIX_INPUT_2_SOURCE 0x6CA | ||
| 308 | #define WM5100_OUT5RMIX_INPUT_2_VOLUME 0x6CB | ||
| 309 | #define WM5100_OUT5RMIX_INPUT_3_SOURCE 0x6CC | ||
| 310 | #define WM5100_OUT5RMIX_INPUT_3_VOLUME 0x6CD | ||
| 311 | #define WM5100_OUT5RMIX_INPUT_4_SOURCE 0x6CE | ||
| 312 | #define WM5100_OUT5RMIX_INPUT_4_VOLUME 0x6CF | ||
| 313 | #define WM5100_OUT6LMIX_INPUT_1_SOURCE 0x6D0 | ||
| 314 | #define WM5100_OUT6LMIX_INPUT_1_VOLUME 0x6D1 | ||
| 315 | #define WM5100_OUT6LMIX_INPUT_2_SOURCE 0x6D2 | ||
| 316 | #define WM5100_OUT6LMIX_INPUT_2_VOLUME 0x6D3 | ||
| 317 | #define WM5100_OUT6LMIX_INPUT_3_SOURCE 0x6D4 | ||
| 318 | #define WM5100_OUT6LMIX_INPUT_3_VOLUME 0x6D5 | ||
| 319 | #define WM5100_OUT6LMIX_INPUT_4_SOURCE 0x6D6 | ||
| 320 | #define WM5100_OUT6LMIX_INPUT_4_VOLUME 0x6D7 | ||
| 321 | #define WM5100_OUT6RMIX_INPUT_1_SOURCE 0x6D8 | ||
| 322 | #define WM5100_OUT6RMIX_INPUT_1_VOLUME 0x6D9 | ||
| 323 | #define WM5100_OUT6RMIX_INPUT_2_SOURCE 0x6DA | ||
| 324 | #define WM5100_OUT6RMIX_INPUT_2_VOLUME 0x6DB | ||
| 325 | #define WM5100_OUT6RMIX_INPUT_3_SOURCE 0x6DC | ||
| 326 | #define WM5100_OUT6RMIX_INPUT_3_VOLUME 0x6DD | ||
| 327 | #define WM5100_OUT6RMIX_INPUT_4_SOURCE 0x6DE | ||
| 328 | #define WM5100_OUT6RMIX_INPUT_4_VOLUME 0x6DF | ||
| 329 | #define WM5100_AIF1TX1MIX_INPUT_1_SOURCE 0x700 | ||
| 330 | #define WM5100_AIF1TX1MIX_INPUT_1_VOLUME 0x701 | ||
| 331 | #define WM5100_AIF1TX1MIX_INPUT_2_SOURCE 0x702 | ||
| 332 | #define WM5100_AIF1TX1MIX_INPUT_2_VOLUME 0x703 | ||
| 333 | #define WM5100_AIF1TX1MIX_INPUT_3_SOURCE 0x704 | ||
| 334 | #define WM5100_AIF1TX1MIX_INPUT_3_VOLUME 0x705 | ||
| 335 | #define WM5100_AIF1TX1MIX_INPUT_4_SOURCE 0x706 | ||
| 336 | #define WM5100_AIF1TX1MIX_INPUT_4_VOLUME 0x707 | ||
| 337 | #define WM5100_AIF1TX2MIX_INPUT_1_SOURCE 0x708 | ||
| 338 | #define WM5100_AIF1TX2MIX_INPUT_1_VOLUME 0x709 | ||
| 339 | #define WM5100_AIF1TX2MIX_INPUT_2_SOURCE 0x70A | ||
| 340 | #define WM5100_AIF1TX2MIX_INPUT_2_VOLUME 0x70B | ||
| 341 | #define WM5100_AIF1TX2MIX_INPUT_3_SOURCE 0x70C | ||
| 342 | #define WM5100_AIF1TX2MIX_INPUT_3_VOLUME 0x70D | ||
| 343 | #define WM5100_AIF1TX2MIX_INPUT_4_SOURCE 0x70E | ||
| 344 | #define WM5100_AIF1TX2MIX_INPUT_4_VOLUME 0x70F | ||
| 345 | #define WM5100_AIF1TX3MIX_INPUT_1_SOURCE 0x710 | ||
| 346 | #define WM5100_AIF1TX3MIX_INPUT_1_VOLUME 0x711 | ||
| 347 | #define WM5100_AIF1TX3MIX_INPUT_2_SOURCE 0x712 | ||
| 348 | #define WM5100_AIF1TX3MIX_INPUT_2_VOLUME 0x713 | ||
| 349 | #define WM5100_AIF1TX3MIX_INPUT_3_SOURCE 0x714 | ||
| 350 | #define WM5100_AIF1TX3MIX_INPUT_3_VOLUME 0x715 | ||
| 351 | #define WM5100_AIF1TX3MIX_INPUT_4_SOURCE 0x716 | ||
| 352 | #define WM5100_AIF1TX3MIX_INPUT_4_VOLUME 0x717 | ||
| 353 | #define WM5100_AIF1TX4MIX_INPUT_1_SOURCE 0x718 | ||
| 354 | #define WM5100_AIF1TX4MIX_INPUT_1_VOLUME 0x719 | ||
| 355 | #define WM5100_AIF1TX4MIX_INPUT_2_SOURCE 0x71A | ||
| 356 | #define WM5100_AIF1TX4MIX_INPUT_2_VOLUME 0x71B | ||
| 357 | #define WM5100_AIF1TX4MIX_INPUT_3_SOURCE 0x71C | ||
| 358 | #define WM5100_AIF1TX4MIX_INPUT_3_VOLUME 0x71D | ||
| 359 | #define WM5100_AIF1TX4MIX_INPUT_4_SOURCE 0x71E | ||
| 360 | #define WM5100_AIF1TX4MIX_INPUT_4_VOLUME 0x71F | ||
| 361 | #define WM5100_AIF1TX5MIX_INPUT_1_SOURCE 0x720 | ||
| 362 | #define WM5100_AIF1TX5MIX_INPUT_1_VOLUME 0x721 | ||
| 363 | #define WM5100_AIF1TX5MIX_INPUT_2_SOURCE 0x722 | ||
| 364 | #define WM5100_AIF1TX5MIX_INPUT_2_VOLUME 0x723 | ||
| 365 | #define WM5100_AIF1TX5MIX_INPUT_3_SOURCE 0x724 | ||
| 366 | #define WM5100_AIF1TX5MIX_INPUT_3_VOLUME 0x725 | ||
| 367 | #define WM5100_AIF1TX5MIX_INPUT_4_SOURCE 0x726 | ||
| 368 | #define WM5100_AIF1TX5MIX_INPUT_4_VOLUME 0x727 | ||
| 369 | #define WM5100_AIF1TX6MIX_INPUT_1_SOURCE 0x728 | ||
| 370 | #define WM5100_AIF1TX6MIX_INPUT_1_VOLUME 0x729 | ||
| 371 | #define WM5100_AIF1TX6MIX_INPUT_2_SOURCE 0x72A | ||
| 372 | #define WM5100_AIF1TX6MIX_INPUT_2_VOLUME 0x72B | ||
| 373 | #define WM5100_AIF1TX6MIX_INPUT_3_SOURCE 0x72C | ||
| 374 | #define WM5100_AIF1TX6MIX_INPUT_3_VOLUME 0x72D | ||
| 375 | #define WM5100_AIF1TX6MIX_INPUT_4_SOURCE 0x72E | ||
| 376 | #define WM5100_AIF1TX6MIX_INPUT_4_VOLUME 0x72F | ||
| 377 | #define WM5100_AIF1TX7MIX_INPUT_1_SOURCE 0x730 | ||
| 378 | #define WM5100_AIF1TX7MIX_INPUT_1_VOLUME 0x731 | ||
| 379 | #define WM5100_AIF1TX7MIX_INPUT_2_SOURCE 0x732 | ||
| 380 | #define WM5100_AIF1TX7MIX_INPUT_2_VOLUME 0x733 | ||
| 381 | #define WM5100_AIF1TX7MIX_INPUT_3_SOURCE 0x734 | ||
| 382 | #define WM5100_AIF1TX7MIX_INPUT_3_VOLUME 0x735 | ||
| 383 | #define WM5100_AIF1TX7MIX_INPUT_4_SOURCE 0x736 | ||
| 384 | #define WM5100_AIF1TX7MIX_INPUT_4_VOLUME 0x737 | ||
| 385 | #define WM5100_AIF1TX8MIX_INPUT_1_SOURCE 0x738 | ||
| 386 | #define WM5100_AIF1TX8MIX_INPUT_1_VOLUME 0x739 | ||
| 387 | #define WM5100_AIF1TX8MIX_INPUT_2_SOURCE 0x73A | ||
| 388 | #define WM5100_AIF1TX8MIX_INPUT_2_VOLUME 0x73B | ||
| 389 | #define WM5100_AIF1TX8MIX_INPUT_3_SOURCE 0x73C | ||
| 390 | #define WM5100_AIF1TX8MIX_INPUT_3_VOLUME 0x73D | ||
| 391 | #define WM5100_AIF1TX8MIX_INPUT_4_SOURCE 0x73E | ||
| 392 | #define WM5100_AIF1TX8MIX_INPUT_4_VOLUME 0x73F | ||
| 393 | #define WM5100_AIF2TX1MIX_INPUT_1_SOURCE 0x740 | ||
| 394 | #define WM5100_AIF2TX1MIX_INPUT_1_VOLUME 0x741 | ||
| 395 | #define WM5100_AIF2TX1MIX_INPUT_2_SOURCE 0x742 | ||
| 396 | #define WM5100_AIF2TX1MIX_INPUT_2_VOLUME 0x743 | ||
| 397 | #define WM5100_AIF2TX1MIX_INPUT_3_SOURCE 0x744 | ||
| 398 | #define WM5100_AIF2TX1MIX_INPUT_3_VOLUME 0x745 | ||
| 399 | #define WM5100_AIF2TX1MIX_INPUT_4_SOURCE 0x746 | ||
| 400 | #define WM5100_AIF2TX1MIX_INPUT_4_VOLUME 0x747 | ||
| 401 | #define WM5100_AIF2TX2MIX_INPUT_1_SOURCE 0x748 | ||
| 402 | #define WM5100_AIF2TX2MIX_INPUT_1_VOLUME 0x749 | ||
| 403 | #define WM5100_AIF2TX2MIX_INPUT_2_SOURCE 0x74A | ||
| 404 | #define WM5100_AIF2TX2MIX_INPUT_2_VOLUME 0x74B | ||
| 405 | #define WM5100_AIF2TX2MIX_INPUT_3_SOURCE 0x74C | ||
| 406 | #define WM5100_AIF2TX2MIX_INPUT_3_VOLUME 0x74D | ||
| 407 | #define WM5100_AIF2TX2MIX_INPUT_4_SOURCE 0x74E | ||
| 408 | #define WM5100_AIF2TX2MIX_INPUT_4_VOLUME 0x74F | ||
| 409 | #define WM5100_AIF3TX1MIX_INPUT_1_SOURCE 0x780 | ||
| 410 | #define WM5100_AIF3TX1MIX_INPUT_1_VOLUME 0x781 | ||
| 411 | #define WM5100_AIF3TX1MIX_INPUT_2_SOURCE 0x782 | ||
| 412 | #define WM5100_AIF3TX1MIX_INPUT_2_VOLUME 0x783 | ||
| 413 | #define WM5100_AIF3TX1MIX_INPUT_3_SOURCE 0x784 | ||
| 414 | #define WM5100_AIF3TX1MIX_INPUT_3_VOLUME 0x785 | ||
| 415 | #define WM5100_AIF3TX1MIX_INPUT_4_SOURCE 0x786 | ||
| 416 | #define WM5100_AIF3TX1MIX_INPUT_4_VOLUME 0x787 | ||
| 417 | #define WM5100_AIF3TX2MIX_INPUT_1_SOURCE 0x788 | ||
| 418 | #define WM5100_AIF3TX2MIX_INPUT_1_VOLUME 0x789 | ||
| 419 | #define WM5100_AIF3TX2MIX_INPUT_2_SOURCE 0x78A | ||
| 420 | #define WM5100_AIF3TX2MIX_INPUT_2_VOLUME 0x78B | ||
| 421 | #define WM5100_AIF3TX2MIX_INPUT_3_SOURCE 0x78C | ||
| 422 | #define WM5100_AIF3TX2MIX_INPUT_3_VOLUME 0x78D | ||
| 423 | #define WM5100_AIF3TX2MIX_INPUT_4_SOURCE 0x78E | ||
| 424 | #define WM5100_AIF3TX2MIX_INPUT_4_VOLUME 0x78F | ||
| 425 | #define WM5100_EQ1MIX_INPUT_1_SOURCE 0x880 | ||
| 426 | #define WM5100_EQ1MIX_INPUT_1_VOLUME 0x881 | ||
| 427 | #define WM5100_EQ1MIX_INPUT_2_SOURCE 0x882 | ||
| 428 | #define WM5100_EQ1MIX_INPUT_2_VOLUME 0x883 | ||
| 429 | #define WM5100_EQ1MIX_INPUT_3_SOURCE 0x884 | ||
| 430 | #define WM5100_EQ1MIX_INPUT_3_VOLUME 0x885 | ||
| 431 | #define WM5100_EQ1MIX_INPUT_4_SOURCE 0x886 | ||
| 432 | #define WM5100_EQ1MIX_INPUT_4_VOLUME 0x887 | ||
| 433 | #define WM5100_EQ2MIX_INPUT_1_SOURCE 0x888 | ||
| 434 | #define WM5100_EQ2MIX_INPUT_1_VOLUME 0x889 | ||
| 435 | #define WM5100_EQ2MIX_INPUT_2_SOURCE 0x88A | ||
| 436 | #define WM5100_EQ2MIX_INPUT_2_VOLUME 0x88B | ||
| 437 | #define WM5100_EQ2MIX_INPUT_3_SOURCE 0x88C | ||
| 438 | #define WM5100_EQ2MIX_INPUT_3_VOLUME 0x88D | ||
| 439 | #define WM5100_EQ2MIX_INPUT_4_SOURCE 0x88E | ||
| 440 | #define WM5100_EQ2MIX_INPUT_4_VOLUME 0x88F | ||
| 441 | #define WM5100_EQ3MIX_INPUT_1_SOURCE 0x890 | ||
| 442 | #define WM5100_EQ3MIX_INPUT_1_VOLUME 0x891 | ||
| 443 | #define WM5100_EQ3MIX_INPUT_2_SOURCE 0x892 | ||
| 444 | #define WM5100_EQ3MIX_INPUT_2_VOLUME 0x893 | ||
| 445 | #define WM5100_EQ3MIX_INPUT_3_SOURCE 0x894 | ||
| 446 | #define WM5100_EQ3MIX_INPUT_3_VOLUME 0x895 | ||
| 447 | #define WM5100_EQ3MIX_INPUT_4_SOURCE 0x896 | ||
| 448 | #define WM5100_EQ3MIX_INPUT_4_VOLUME 0x897 | ||
| 449 | #define WM5100_EQ4MIX_INPUT_1_SOURCE 0x898 | ||
| 450 | #define WM5100_EQ4MIX_INPUT_1_VOLUME 0x899 | ||
| 451 | #define WM5100_EQ4MIX_INPUT_2_SOURCE 0x89A | ||
| 452 | #define WM5100_EQ4MIX_INPUT_2_VOLUME 0x89B | ||
| 453 | #define WM5100_EQ4MIX_INPUT_3_SOURCE 0x89C | ||
| 454 | #define WM5100_EQ4MIX_INPUT_3_VOLUME 0x89D | ||
| 455 | #define WM5100_EQ4MIX_INPUT_4_SOURCE 0x89E | ||
| 456 | #define WM5100_EQ4MIX_INPUT_4_VOLUME 0x89F | ||
| 457 | #define WM5100_DRC1LMIX_INPUT_1_SOURCE 0x8C0 | ||
| 458 | #define WM5100_DRC1LMIX_INPUT_1_VOLUME 0x8C1 | ||
| 459 | #define WM5100_DRC1LMIX_INPUT_2_SOURCE 0x8C2 | ||
| 460 | #define WM5100_DRC1LMIX_INPUT_2_VOLUME 0x8C3 | ||
| 461 | #define WM5100_DRC1LMIX_INPUT_3_SOURCE 0x8C4 | ||
| 462 | #define WM5100_DRC1LMIX_INPUT_3_VOLUME 0x8C5 | ||
| 463 | #define WM5100_DRC1LMIX_INPUT_4_SOURCE 0x8C6 | ||
| 464 | #define WM5100_DRC1LMIX_INPUT_4_VOLUME 0x8C7 | ||
| 465 | #define WM5100_DRC1RMIX_INPUT_1_SOURCE 0x8C8 | ||
| 466 | #define WM5100_DRC1RMIX_INPUT_1_VOLUME 0x8C9 | ||
| 467 | #define WM5100_DRC1RMIX_INPUT_2_SOURCE 0x8CA | ||
| 468 | #define WM5100_DRC1RMIX_INPUT_2_VOLUME 0x8CB | ||
| 469 | #define WM5100_DRC1RMIX_INPUT_3_SOURCE 0x8CC | ||
| 470 | #define WM5100_DRC1RMIX_INPUT_3_VOLUME 0x8CD | ||
| 471 | #define WM5100_DRC1RMIX_INPUT_4_SOURCE 0x8CE | ||
| 472 | #define WM5100_DRC1RMIX_INPUT_4_VOLUME 0x8CF | ||
| 473 | #define WM5100_HPLP1MIX_INPUT_1_SOURCE 0x900 | ||
| 474 | #define WM5100_HPLP1MIX_INPUT_1_VOLUME 0x901 | ||
| 475 | #define WM5100_HPLP1MIX_INPUT_2_SOURCE 0x902 | ||
| 476 | #define WM5100_HPLP1MIX_INPUT_2_VOLUME 0x903 | ||
| 477 | #define WM5100_HPLP1MIX_INPUT_3_SOURCE 0x904 | ||
| 478 | #define WM5100_HPLP1MIX_INPUT_3_VOLUME 0x905 | ||
| 479 | #define WM5100_HPLP1MIX_INPUT_4_SOURCE 0x906 | ||
| 480 | #define WM5100_HPLP1MIX_INPUT_4_VOLUME 0x907 | ||
| 481 | #define WM5100_HPLP2MIX_INPUT_1_SOURCE 0x908 | ||
| 482 | #define WM5100_HPLP2MIX_INPUT_1_VOLUME 0x909 | ||
| 483 | #define WM5100_HPLP2MIX_INPUT_2_SOURCE 0x90A | ||
| 484 | #define WM5100_HPLP2MIX_INPUT_2_VOLUME 0x90B | ||
| 485 | #define WM5100_HPLP2MIX_INPUT_3_SOURCE 0x90C | ||
| 486 | #define WM5100_HPLP2MIX_INPUT_3_VOLUME 0x90D | ||
| 487 | #define WM5100_HPLP2MIX_INPUT_4_SOURCE 0x90E | ||
| 488 | #define WM5100_HPLP2MIX_INPUT_4_VOLUME 0x90F | ||
| 489 | #define WM5100_HPLP3MIX_INPUT_1_SOURCE 0x910 | ||
| 490 | #define WM5100_HPLP3MIX_INPUT_1_VOLUME 0x911 | ||
| 491 | #define WM5100_HPLP3MIX_INPUT_2_SOURCE 0x912 | ||
| 492 | #define WM5100_HPLP3MIX_INPUT_2_VOLUME 0x913 | ||
| 493 | #define WM5100_HPLP3MIX_INPUT_3_SOURCE 0x914 | ||
| 494 | #define WM5100_HPLP3MIX_INPUT_3_VOLUME 0x915 | ||
| 495 | #define WM5100_HPLP3MIX_INPUT_4_SOURCE 0x916 | ||
| 496 | #define WM5100_HPLP3MIX_INPUT_4_VOLUME 0x917 | ||
| 497 | #define WM5100_HPLP4MIX_INPUT_1_SOURCE 0x918 | ||
| 498 | #define WM5100_HPLP4MIX_INPUT_1_VOLUME 0x919 | ||
| 499 | #define WM5100_HPLP4MIX_INPUT_2_SOURCE 0x91A | ||
| 500 | #define WM5100_HPLP4MIX_INPUT_2_VOLUME 0x91B | ||
| 501 | #define WM5100_HPLP4MIX_INPUT_3_SOURCE 0x91C | ||
| 502 | #define WM5100_HPLP4MIX_INPUT_3_VOLUME 0x91D | ||
| 503 | #define WM5100_HPLP4MIX_INPUT_4_SOURCE 0x91E | ||
| 504 | #define WM5100_HPLP4MIX_INPUT_4_VOLUME 0x91F | ||
| 505 | #define WM5100_DSP1LMIX_INPUT_1_SOURCE 0x940 | ||
| 506 | #define WM5100_DSP1LMIX_INPUT_1_VOLUME 0x941 | ||
| 507 | #define WM5100_DSP1LMIX_INPUT_2_SOURCE 0x942 | ||
| 508 | #define WM5100_DSP1LMIX_INPUT_2_VOLUME 0x943 | ||
| 509 | #define WM5100_DSP1LMIX_INPUT_3_SOURCE 0x944 | ||
| 510 | #define WM5100_DSP1LMIX_INPUT_3_VOLUME 0x945 | ||
| 511 | #define WM5100_DSP1LMIX_INPUT_4_SOURCE 0x946 | ||
| 512 | #define WM5100_DSP1LMIX_INPUT_4_VOLUME 0x947 | ||
| 513 | #define WM5100_DSP1RMIX_INPUT_1_SOURCE 0x948 | ||
| 514 | #define WM5100_DSP1RMIX_INPUT_1_VOLUME 0x949 | ||
| 515 | #define WM5100_DSP1RMIX_INPUT_2_SOURCE 0x94A | ||
| 516 | #define WM5100_DSP1RMIX_INPUT_2_VOLUME 0x94B | ||
| 517 | #define WM5100_DSP1RMIX_INPUT_3_SOURCE 0x94C | ||
| 518 | #define WM5100_DSP1RMIX_INPUT_3_VOLUME 0x94D | ||
| 519 | #define WM5100_DSP1RMIX_INPUT_4_SOURCE 0x94E | ||
| 520 | #define WM5100_DSP1RMIX_INPUT_4_VOLUME 0x94F | ||
| 521 | #define WM5100_DSP1AUX1MIX_INPUT_1_SOURCE 0x950 | ||
| 522 | #define WM5100_DSP1AUX2MIX_INPUT_1_SOURCE 0x958 | ||
| 523 | #define WM5100_DSP1AUX3MIX_INPUT_1_SOURCE 0x960 | ||
| 524 | #define WM5100_DSP1AUX4MIX_INPUT_1_SOURCE 0x968 | ||
| 525 | #define WM5100_DSP1AUX5MIX_INPUT_1_SOURCE 0x970 | ||
| 526 | #define WM5100_DSP1AUX6MIX_INPUT_1_SOURCE 0x978 | ||
| 527 | #define WM5100_DSP2LMIX_INPUT_1_SOURCE 0x980 | ||
| 528 | #define WM5100_DSP2LMIX_INPUT_1_VOLUME 0x981 | ||
| 529 | #define WM5100_DSP2LMIX_INPUT_2_SOURCE 0x982 | ||
| 530 | #define WM5100_DSP2LMIX_INPUT_2_VOLUME 0x983 | ||
| 531 | #define WM5100_DSP2LMIX_INPUT_3_SOURCE 0x984 | ||
| 532 | #define WM5100_DSP2LMIX_INPUT_3_VOLUME 0x985 | ||
| 533 | #define WM5100_DSP2LMIX_INPUT_4_SOURCE 0x986 | ||
| 534 | #define WM5100_DSP2LMIX_INPUT_4_VOLUME 0x987 | ||
| 535 | #define WM5100_DSP2RMIX_INPUT_1_SOURCE 0x988 | ||
| 536 | #define WM5100_DSP2RMIX_INPUT_1_VOLUME 0x989 | ||
| 537 | #define WM5100_DSP2RMIX_INPUT_2_SOURCE 0x98A | ||
| 538 | #define WM5100_DSP2RMIX_INPUT_2_VOLUME 0x98B | ||
| 539 | #define WM5100_DSP2RMIX_INPUT_3_SOURCE 0x98C | ||
| 540 | #define WM5100_DSP2RMIX_INPUT_3_VOLUME 0x98D | ||
| 541 | #define WM5100_DSP2RMIX_INPUT_4_SOURCE 0x98E | ||
| 542 | #define WM5100_DSP2RMIX_INPUT_4_VOLUME 0x98F | ||
| 543 | #define WM5100_DSP2AUX1MIX_INPUT_1_SOURCE 0x990 | ||
| 544 | #define WM5100_DSP2AUX2MIX_INPUT_1_SOURCE 0x998 | ||
| 545 | #define WM5100_DSP2AUX3MIX_INPUT_1_SOURCE 0x9A0 | ||
| 546 | #define WM5100_DSP2AUX4MIX_INPUT_1_SOURCE 0x9A8 | ||
| 547 | #define WM5100_DSP2AUX5MIX_INPUT_1_SOURCE 0x9B0 | ||
| 548 | #define WM5100_DSP2AUX6MIX_INPUT_1_SOURCE 0x9B8 | ||
| 549 | #define WM5100_DSP3LMIX_INPUT_1_SOURCE 0x9C0 | ||
| 550 | #define WM5100_DSP3LMIX_INPUT_1_VOLUME 0x9C1 | ||
| 551 | #define WM5100_DSP3LMIX_INPUT_2_SOURCE 0x9C2 | ||
| 552 | #define WM5100_DSP3LMIX_INPUT_2_VOLUME 0x9C3 | ||
| 553 | #define WM5100_DSP3LMIX_INPUT_3_SOURCE 0x9C4 | ||
| 554 | #define WM5100_DSP3LMIX_INPUT_3_VOLUME 0x9C5 | ||
| 555 | #define WM5100_DSP3LMIX_INPUT_4_SOURCE 0x9C6 | ||
| 556 | #define WM5100_DSP3LMIX_INPUT_4_VOLUME 0x9C7 | ||
| 557 | #define WM5100_DSP3RMIX_INPUT_1_SOURCE 0x9C8 | ||
| 558 | #define WM5100_DSP3RMIX_INPUT_1_VOLUME 0x9C9 | ||
| 559 | #define WM5100_DSP3RMIX_INPUT_2_SOURCE 0x9CA | ||
| 560 | #define WM5100_DSP3RMIX_INPUT_2_VOLUME 0x9CB | ||
| 561 | #define WM5100_DSP3RMIX_INPUT_3_SOURCE 0x9CC | ||
| 562 | #define WM5100_DSP3RMIX_INPUT_3_VOLUME 0x9CD | ||
| 563 | #define WM5100_DSP3RMIX_INPUT_4_SOURCE 0x9CE | ||
| 564 | #define WM5100_DSP3RMIX_INPUT_4_VOLUME 0x9CF | ||
| 565 | #define WM5100_DSP3AUX1MIX_INPUT_1_SOURCE 0x9D0 | ||
| 566 | #define WM5100_DSP3AUX2MIX_INPUT_1_SOURCE 0x9D8 | ||
| 567 | #define WM5100_DSP3AUX3MIX_INPUT_1_SOURCE 0x9E0 | ||
| 568 | #define WM5100_DSP3AUX4MIX_INPUT_1_SOURCE 0x9E8 | ||
| 569 | #define WM5100_DSP3AUX5MIX_INPUT_1_SOURCE 0x9F0 | ||
| 570 | #define WM5100_DSP3AUX6MIX_INPUT_1_SOURCE 0x9F8 | ||
| 571 | #define WM5100_ASRC1LMIX_INPUT_1_SOURCE 0xA80 | ||
| 572 | #define WM5100_ASRC1RMIX_INPUT_1_SOURCE 0xA88 | ||
| 573 | #define WM5100_ASRC2LMIX_INPUT_1_SOURCE 0xA90 | ||
| 574 | #define WM5100_ASRC2RMIX_INPUT_1_SOURCE 0xA98 | ||
| 575 | #define WM5100_ISRC1DEC1MIX_INPUT_1_SOURCE 0xB00 | ||
| 576 | #define WM5100_ISRC1DEC2MIX_INPUT_1_SOURCE 0xB08 | ||
| 577 | #define WM5100_ISRC1DEC3MIX_INPUT_1_SOURCE 0xB10 | ||
| 578 | #define WM5100_ISRC1DEC4MIX_INPUT_1_SOURCE 0xB18 | ||
| 579 | #define WM5100_ISRC1INT1MIX_INPUT_1_SOURCE 0xB20 | ||
| 580 | #define WM5100_ISRC1INT2MIX_INPUT_1_SOURCE 0xB28 | ||
| 581 | #define WM5100_ISRC1INT3MIX_INPUT_1_SOURCE 0xB30 | ||
| 582 | #define WM5100_ISRC1INT4MIX_INPUT_1_SOURCE 0xB38 | ||
| 583 | #define WM5100_ISRC2DEC1MIX_INPUT_1_SOURCE 0xB40 | ||
| 584 | #define WM5100_ISRC2DEC2MIX_INPUT_1_SOURCE 0xB48 | ||
| 585 | #define WM5100_ISRC2DEC3MIX_INPUT_1_SOURCE 0xB50 | ||
| 586 | #define WM5100_ISRC2DEC4MIX_INPUT_1_SOURCE 0xB58 | ||
| 587 | #define WM5100_ISRC2INT1MIX_INPUT_1_SOURCE 0xB60 | ||
| 588 | #define WM5100_ISRC2INT2MIX_INPUT_1_SOURCE 0xB68 | ||
| 589 | #define WM5100_ISRC2INT3MIX_INPUT_1_SOURCE 0xB70 | ||
| 590 | #define WM5100_ISRC2INT4MIX_INPUT_1_SOURCE 0xB78 | ||
| 591 | #define WM5100_GPIO_CTRL_1 0xC00 | ||
| 592 | #define WM5100_GPIO_CTRL_2 0xC01 | ||
| 593 | #define WM5100_GPIO_CTRL_3 0xC02 | ||
| 594 | #define WM5100_GPIO_CTRL_4 0xC03 | ||
| 595 | #define WM5100_GPIO_CTRL_5 0xC04 | ||
| 596 | #define WM5100_GPIO_CTRL_6 0xC05 | ||
| 597 | #define WM5100_MISC_PAD_CTRL_1 0xC23 | ||
| 598 | #define WM5100_MISC_PAD_CTRL_2 0xC24 | ||
| 599 | #define WM5100_MISC_PAD_CTRL_3 0xC25 | ||
| 600 | #define WM5100_MISC_PAD_CTRL_4 0xC26 | ||
| 601 | #define WM5100_MISC_PAD_CTRL_5 0xC27 | ||
| 602 | #define WM5100_MISC_GPIO_1 0xC28 | ||
| 603 | #define WM5100_INTERRUPT_STATUS_1 0xD00 | ||
| 604 | #define WM5100_INTERRUPT_STATUS_2 0xD01 | ||
| 605 | #define WM5100_INTERRUPT_STATUS_3 0xD02 | ||
| 606 | #define WM5100_INTERRUPT_STATUS_4 0xD03 | ||
| 607 | #define WM5100_INTERRUPT_RAW_STATUS_2 0xD04 | ||
| 608 | #define WM5100_INTERRUPT_RAW_STATUS_3 0xD05 | ||
| 609 | #define WM5100_INTERRUPT_RAW_STATUS_4 0xD06 | ||
| 610 | #define WM5100_INTERRUPT_STATUS_1_MASK 0xD07 | ||
| 611 | #define WM5100_INTERRUPT_STATUS_2_MASK 0xD08 | ||
| 612 | #define WM5100_INTERRUPT_STATUS_3_MASK 0xD09 | ||
| 613 | #define WM5100_INTERRUPT_STATUS_4_MASK 0xD0A | ||
| 614 | #define WM5100_INTERRUPT_CONTROL 0xD1F | ||
| 615 | #define WM5100_IRQ_DEBOUNCE_1 0xD20 | ||
| 616 | #define WM5100_IRQ_DEBOUNCE_2 0xD21 | ||
| 617 | #define WM5100_FX_CTRL 0xE00 | ||
| 618 | #define WM5100_EQ1_1 0xE10 | ||
| 619 | #define WM5100_EQ1_2 0xE11 | ||
| 620 | #define WM5100_EQ1_3 0xE12 | ||
| 621 | #define WM5100_EQ1_4 0xE13 | ||
| 622 | #define WM5100_EQ1_5 0xE14 | ||
| 623 | #define WM5100_EQ1_6 0xE15 | ||
| 624 | #define WM5100_EQ1_7 0xE16 | ||
| 625 | #define WM5100_EQ1_8 0xE17 | ||
| 626 | #define WM5100_EQ1_9 0xE18 | ||
| 627 | #define WM5100_EQ1_10 0xE19 | ||
| 628 | #define WM5100_EQ1_11 0xE1A | ||
| 629 | #define WM5100_EQ1_12 0xE1B | ||
| 630 | #define WM5100_EQ1_13 0xE1C | ||
| 631 | #define WM5100_EQ1_14 0xE1D | ||
| 632 | #define WM5100_EQ1_15 0xE1E | ||
| 633 | #define WM5100_EQ1_16 0xE1F | ||
| 634 | #define WM5100_EQ1_17 0xE20 | ||
| 635 | #define WM5100_EQ1_18 0xE21 | ||
| 636 | #define WM5100_EQ1_19 0xE22 | ||
| 637 | #define WM5100_EQ1_20 0xE23 | ||
| 638 | #define WM5100_EQ2_1 0xE26 | ||
| 639 | #define WM5100_EQ2_2 0xE27 | ||
| 640 | #define WM5100_EQ2_3 0xE28 | ||
| 641 | #define WM5100_EQ2_4 0xE29 | ||
| 642 | #define WM5100_EQ2_5 0xE2A | ||
| 643 | #define WM5100_EQ2_6 0xE2B | ||
| 644 | #define WM5100_EQ2_7 0xE2C | ||
| 645 | #define WM5100_EQ2_8 0xE2D | ||
| 646 | #define WM5100_EQ2_9 0xE2E | ||
| 647 | #define WM5100_EQ2_10 0xE2F | ||
| 648 | #define WM5100_EQ2_11 0xE30 | ||
| 649 | #define WM5100_EQ2_12 0xE31 | ||
| 650 | #define WM5100_EQ2_13 0xE32 | ||
| 651 | #define WM5100_EQ2_14 0xE33 | ||
| 652 | #define WM5100_EQ2_15 0xE34 | ||
| 653 | #define WM5100_EQ2_16 0xE35 | ||
| 654 | #define WM5100_EQ2_17 0xE36 | ||
| 655 | #define WM5100_EQ2_18 0xE37 | ||
| 656 | #define WM5100_EQ2_19 0xE38 | ||
| 657 | #define WM5100_EQ2_20 0xE39 | ||
| 658 | #define WM5100_EQ3_1 0xE3C | ||
| 659 | #define WM5100_EQ3_2 0xE3D | ||
| 660 | #define WM5100_EQ3_3 0xE3E | ||
| 661 | #define WM5100_EQ3_4 0xE3F | ||
| 662 | #define WM5100_EQ3_5 0xE40 | ||
| 663 | #define WM5100_EQ3_6 0xE41 | ||
| 664 | #define WM5100_EQ3_7 0xE42 | ||
| 665 | #define WM5100_EQ3_8 0xE43 | ||
| 666 | #define WM5100_EQ3_9 0xE44 | ||
| 667 | #define WM5100_EQ3_10 0xE45 | ||
| 668 | #define WM5100_EQ3_11 0xE46 | ||
| 669 | #define WM5100_EQ3_12 0xE47 | ||
| 670 | #define WM5100_EQ3_13 0xE48 | ||
| 671 | #define WM5100_EQ3_14 0xE49 | ||
| 672 | #define WM5100_EQ3_15 0xE4A | ||
| 673 | #define WM5100_EQ3_16 0xE4B | ||
| 674 | #define WM5100_EQ3_17 0xE4C | ||
| 675 | #define WM5100_EQ3_18 0xE4D | ||
| 676 | #define WM5100_EQ3_19 0xE4E | ||
| 677 | #define WM5100_EQ3_20 0xE4F | ||
| 678 | #define WM5100_EQ4_1 0xE52 | ||
| 679 | #define WM5100_EQ4_2 0xE53 | ||
| 680 | #define WM5100_EQ4_3 0xE54 | ||
| 681 | #define WM5100_EQ4_4 0xE55 | ||
| 682 | #define WM5100_EQ4_5 0xE56 | ||
| 683 | #define WM5100_EQ4_6 0xE57 | ||
| 684 | #define WM5100_EQ4_7 0xE58 | ||
| 685 | #define WM5100_EQ4_8 0xE59 | ||
| 686 | #define WM5100_EQ4_9 0xE5A | ||
| 687 | #define WM5100_EQ4_10 0xE5B | ||
| 688 | #define WM5100_EQ4_11 0xE5C | ||
| 689 | #define WM5100_EQ4_12 0xE5D | ||
| 690 | #define WM5100_EQ4_13 0xE5E | ||
| 691 | #define WM5100_EQ4_14 0xE5F | ||
| 692 | #define WM5100_EQ4_15 0xE60 | ||
| 693 | #define WM5100_EQ4_16 0xE61 | ||
| 694 | #define WM5100_EQ4_17 0xE62 | ||
| 695 | #define WM5100_EQ4_18 0xE63 | ||
| 696 | #define WM5100_EQ4_19 0xE64 | ||
| 697 | #define WM5100_EQ4_20 0xE65 | ||
| 698 | #define WM5100_DRC1_CTRL1 0xE80 | ||
| 699 | #define WM5100_DRC1_CTRL2 0xE81 | ||
| 700 | #define WM5100_DRC1_CTRL3 0xE82 | ||
| 701 | #define WM5100_DRC1_CTRL4 0xE83 | ||
| 702 | #define WM5100_DRC1_CTRL5 0xE84 | ||
| 703 | #define WM5100_HPLPF1_1 0xEC0 | ||
| 704 | #define WM5100_HPLPF1_2 0xEC1 | ||
| 705 | #define WM5100_HPLPF2_1 0xEC4 | ||
| 706 | #define WM5100_HPLPF2_2 0xEC5 | ||
| 707 | #define WM5100_HPLPF3_1 0xEC8 | ||
| 708 | #define WM5100_HPLPF3_2 0xEC9 | ||
| 709 | #define WM5100_HPLPF4_1 0xECC | ||
| 710 | #define WM5100_HPLPF4_2 0xECD | ||
| 711 | #define WM5100_DSP1_DM_0 0x4000 | ||
| 712 | #define WM5100_DSP1_DM_1 0x4001 | ||
| 713 | #define WM5100_DSP1_DM_2 0x4002 | ||
| 714 | #define WM5100_DSP1_DM_3 0x4003 | ||
| 715 | #define WM5100_DSP1_DM_508 0x41FC | ||
| 716 | #define WM5100_DSP1_DM_509 0x41FD | ||
| 717 | #define WM5100_DSP1_DM_510 0x41FE | ||
| 718 | #define WM5100_DSP1_DM_511 0x41FF | ||
| 719 | #define WM5100_DSP1_PM_0 0x4800 | ||
| 720 | #define WM5100_DSP1_PM_1 0x4801 | ||
| 721 | #define WM5100_DSP1_PM_2 0x4802 | ||
| 722 | #define WM5100_DSP1_PM_3 0x4803 | ||
| 723 | #define WM5100_DSP1_PM_4 0x4804 | ||
| 724 | #define WM5100_DSP1_PM_5 0x4805 | ||
| 725 | #define WM5100_DSP1_PM_1530 0x4DFA | ||
| 726 | #define WM5100_DSP1_PM_1531 0x4DFB | ||
| 727 | #define WM5100_DSP1_PM_1532 0x4DFC | ||
| 728 | #define WM5100_DSP1_PM_1533 0x4DFD | ||
| 729 | #define WM5100_DSP1_PM_1534 0x4DFE | ||
| 730 | #define WM5100_DSP1_PM_1535 0x4DFF | ||
| 731 | #define WM5100_DSP1_ZM_0 0x5000 | ||
| 732 | #define WM5100_DSP1_ZM_1 0x5001 | ||
| 733 | #define WM5100_DSP1_ZM_2 0x5002 | ||
| 734 | #define WM5100_DSP1_ZM_3 0x5003 | ||
| 735 | #define WM5100_DSP1_ZM_2044 0x57FC | ||
| 736 | #define WM5100_DSP1_ZM_2045 0x57FD | ||
| 737 | #define WM5100_DSP1_ZM_2046 0x57FE | ||
| 738 | #define WM5100_DSP1_ZM_2047 0x57FF | ||
| 739 | #define WM5100_DSP2_DM_0 0x6000 | ||
| 740 | #define WM5100_DSP2_DM_1 0x6001 | ||
| 741 | #define WM5100_DSP2_DM_2 0x6002 | ||
| 742 | #define WM5100_DSP2_DM_3 0x6003 | ||
| 743 | #define WM5100_DSP2_DM_508 0x61FC | ||
| 744 | #define WM5100_DSP2_DM_509 0x61FD | ||
| 745 | #define WM5100_DSP2_DM_510 0x61FE | ||
| 746 | #define WM5100_DSP2_DM_511 0x61FF | ||
| 747 | #define WM5100_DSP2_PM_0 0x6800 | ||
| 748 | #define WM5100_DSP2_PM_1 0x6801 | ||
| 749 | #define WM5100_DSP2_PM_2 0x6802 | ||
| 750 | #define WM5100_DSP2_PM_3 0x6803 | ||
| 751 | #define WM5100_DSP2_PM_4 0x6804 | ||
| 752 | #define WM5100_DSP2_PM_5 0x6805 | ||
| 753 | #define WM5100_DSP2_PM_1530 0x6DFA | ||
| 754 | #define WM5100_DSP2_PM_1531 0x6DFB | ||
| 755 | #define WM5100_DSP2_PM_1532 0x6DFC | ||
| 756 | #define WM5100_DSP2_PM_1533 0x6DFD | ||
| 757 | #define WM5100_DSP2_PM_1534 0x6DFE | ||
| 758 | #define WM5100_DSP2_PM_1535 0x6DFF | ||
| 759 | #define WM5100_DSP2_ZM_0 0x7000 | ||
| 760 | #define WM5100_DSP2_ZM_1 0x7001 | ||
| 761 | #define WM5100_DSP2_ZM_2 0x7002 | ||
| 762 | #define WM5100_DSP2_ZM_3 0x7003 | ||
| 763 | #define WM5100_DSP2_ZM_2044 0x77FC | ||
| 764 | #define WM5100_DSP2_ZM_2045 0x77FD | ||
| 765 | #define WM5100_DSP2_ZM_2046 0x77FE | ||
| 766 | #define WM5100_DSP2_ZM_2047 0x77FF | ||
| 767 | #define WM5100_DSP3_DM_0 0x8000 | ||
| 768 | #define WM5100_DSP3_DM_1 0x8001 | ||
| 769 | #define WM5100_DSP3_DM_2 0x8002 | ||
| 770 | #define WM5100_DSP3_DM_3 0x8003 | ||
| 771 | #define WM5100_DSP3_DM_508 0x81FC | ||
| 772 | #define WM5100_DSP3_DM_509 0x81FD | ||
| 773 | #define WM5100_DSP3_DM_510 0x81FE | ||
| 774 | #define WM5100_DSP3_DM_511 0x81FF | ||
| 775 | #define WM5100_DSP3_PM_0 0x8800 | ||
| 776 | #define WM5100_DSP3_PM_1 0x8801 | ||
| 777 | #define WM5100_DSP3_PM_2 0x8802 | ||
| 778 | #define WM5100_DSP3_PM_3 0x8803 | ||
| 779 | #define WM5100_DSP3_PM_4 0x8804 | ||
| 780 | #define WM5100_DSP3_PM_5 0x8805 | ||
| 781 | #define WM5100_DSP3_PM_1530 0x8DFA | ||
| 782 | #define WM5100_DSP3_PM_1531 0x8DFB | ||
| 783 | #define WM5100_DSP3_PM_1532 0x8DFC | ||
| 784 | #define WM5100_DSP3_PM_1533 0x8DFD | ||
| 785 | #define WM5100_DSP3_PM_1534 0x8DFE | ||
| 786 | #define WM5100_DSP3_PM_1535 0x8DFF | ||
| 787 | #define WM5100_DSP3_ZM_0 0x9000 | ||
| 788 | #define WM5100_DSP3_ZM_1 0x9001 | ||
| 789 | #define WM5100_DSP3_ZM_2 0x9002 | ||
| 790 | #define WM5100_DSP3_ZM_3 0x9003 | ||
| 791 | #define WM5100_DSP3_ZM_2044 0x97FC | ||
| 792 | #define WM5100_DSP3_ZM_2045 0x97FD | ||
| 793 | #define WM5100_DSP3_ZM_2046 0x97FE | ||
| 794 | #define WM5100_DSP3_ZM_2047 0x97FF | ||
| 795 | |||
| 796 | #define WM5100_REGISTER_COUNT 1435 | ||
| 797 | #define WM5100_MAX_REGISTER 0x97FF | ||
| 798 | |||
| 799 | /* | ||
| 800 | * Field Definitions. | ||
| 801 | */ | ||
| 802 | |||
| 803 | /* | ||
| 804 | * R0 (0x00) - software reset | ||
| 805 | */ | ||
| 806 | #define WM5100_SW_RST_DEV_ID1_MASK 0xFFFF /* SW_RST_DEV_ID1 - [15:0] */ | ||
| 807 | #define WM5100_SW_RST_DEV_ID1_SHIFT 0 /* SW_RST_DEV_ID1 - [15:0] */ | ||
| 808 | #define WM5100_SW_RST_DEV_ID1_WIDTH 16 /* SW_RST_DEV_ID1 - [15:0] */ | ||
| 809 | |||
| 810 | /* | ||
| 811 | * R1 (0x01) - Device Revision | ||
| 812 | */ | ||
| 813 | #define WM5100_DEVICE_REVISION_MASK 0x000F /* DEVICE_REVISION - [3:0] */ | ||
| 814 | #define WM5100_DEVICE_REVISION_SHIFT 0 /* DEVICE_REVISION - [3:0] */ | ||
| 815 | #define WM5100_DEVICE_REVISION_WIDTH 4 /* DEVICE_REVISION - [3:0] */ | ||
| 816 | |||
| 817 | /* | ||
| 818 | * R16 (0x10) - Ctrl IF 1 | ||
| 819 | */ | ||
| 820 | #define WM5100_AUTO_INC 0x0001 /* AUTO_INC */ | ||
| 821 | #define WM5100_AUTO_INC_MASK 0x0001 /* AUTO_INC */ | ||
| 822 | #define WM5100_AUTO_INC_SHIFT 0 /* AUTO_INC */ | ||
| 823 | #define WM5100_AUTO_INC_WIDTH 1 /* AUTO_INC */ | ||
| 824 | |||
| 825 | /* | ||
| 826 | * R32 (0x20) - Tone Generator 1 | ||
| 827 | */ | ||
| 828 | #define WM5100_TONE_RATE_MASK 0x3000 /* TONE_RATE - [13:12] */ | ||
| 829 | #define WM5100_TONE_RATE_SHIFT 12 /* TONE_RATE - [13:12] */ | ||
| 830 | #define WM5100_TONE_RATE_WIDTH 2 /* TONE_RATE - [13:12] */ | ||
| 831 | #define WM5100_TONE_OFFSET_MASK 0x0300 /* TONE_OFFSET - [9:8] */ | ||
| 832 | #define WM5100_TONE_OFFSET_SHIFT 8 /* TONE_OFFSET - [9:8] */ | ||
| 833 | #define WM5100_TONE_OFFSET_WIDTH 2 /* TONE_OFFSET - [9:8] */ | ||
| 834 | #define WM5100_TONE2_ENA 0x0002 /* TONE2_ENA */ | ||
| 835 | #define WM5100_TONE2_ENA_MASK 0x0002 /* TONE2_ENA */ | ||
| 836 | #define WM5100_TONE2_ENA_SHIFT 1 /* TONE2_ENA */ | ||
| 837 | #define WM5100_TONE2_ENA_WIDTH 1 /* TONE2_ENA */ | ||
| 838 | #define WM5100_TONE1_ENA 0x0001 /* TONE1_ENA */ | ||
| 839 | #define WM5100_TONE1_ENA_MASK 0x0001 /* TONE1_ENA */ | ||
| 840 | #define WM5100_TONE1_ENA_SHIFT 0 /* TONE1_ENA */ | ||
| 841 | #define WM5100_TONE1_ENA_WIDTH 1 /* TONE1_ENA */ | ||
| 842 | |||
| 843 | /* | ||
| 844 | * R48 (0x30) - PWM Drive 1 | ||
| 845 | */ | ||
| 846 | #define WM5100_PWM_RATE_MASK 0x3000 /* PWM_RATE - [13:12] */ | ||
| 847 | #define WM5100_PWM_RATE_SHIFT 12 /* PWM_RATE - [13:12] */ | ||
| 848 | #define WM5100_PWM_RATE_WIDTH 2 /* PWM_RATE - [13:12] */ | ||
| 849 | #define WM5100_PWM_CLK_SEL_MASK 0x0300 /* PWM_CLK_SEL - [9:8] */ | ||
| 850 | #define WM5100_PWM_CLK_SEL_SHIFT 8 /* PWM_CLK_SEL - [9:8] */ | ||
| 851 | #define WM5100_PWM_CLK_SEL_WIDTH 2 /* PWM_CLK_SEL - [9:8] */ | ||
| 852 | #define WM5100_PWM2_OVD 0x0020 /* PWM2_OVD */ | ||
| 853 | #define WM5100_PWM2_OVD_MASK 0x0020 /* PWM2_OVD */ | ||
| 854 | #define WM5100_PWM2_OVD_SHIFT 5 /* PWM2_OVD */ | ||
| 855 | #define WM5100_PWM2_OVD_WIDTH 1 /* PWM2_OVD */ | ||
| 856 | #define WM5100_PWM1_OVD 0x0010 /* PWM1_OVD */ | ||
| 857 | #define WM5100_PWM1_OVD_MASK 0x0010 /* PWM1_OVD */ | ||
| 858 | #define WM5100_PWM1_OVD_SHIFT 4 /* PWM1_OVD */ | ||
| 859 | #define WM5100_PWM1_OVD_WIDTH 1 /* PWM1_OVD */ | ||
| 860 | #define WM5100_PWM2_ENA 0x0002 /* PWM2_ENA */ | ||
| 861 | #define WM5100_PWM2_ENA_MASK 0x0002 /* PWM2_ENA */ | ||
| 862 | #define WM5100_PWM2_ENA_SHIFT 1 /* PWM2_ENA */ | ||
| 863 | #define WM5100_PWM2_ENA_WIDTH 1 /* PWM2_ENA */ | ||
| 864 | #define WM5100_PWM1_ENA 0x0001 /* PWM1_ENA */ | ||
| 865 | #define WM5100_PWM1_ENA_MASK 0x0001 /* PWM1_ENA */ | ||
| 866 | #define WM5100_PWM1_ENA_SHIFT 0 /* PWM1_ENA */ | ||
| 867 | #define WM5100_PWM1_ENA_WIDTH 1 /* PWM1_ENA */ | ||
| 868 | |||
| 869 | /* | ||
| 870 | * R49 (0x31) - PWM Drive 2 | ||
| 871 | */ | ||
| 872 | #define WM5100_PWM1_LVL_MASK 0x03FF /* PWM1_LVL - [9:0] */ | ||
| 873 | #define WM5100_PWM1_LVL_SHIFT 0 /* PWM1_LVL - [9:0] */ | ||
| 874 | #define WM5100_PWM1_LVL_WIDTH 10 /* PWM1_LVL - [9:0] */ | ||
| 875 | |||
| 876 | /* | ||
| 877 | * R50 (0x32) - PWM Drive 3 | ||
| 878 | */ | ||
| 879 | #define WM5100_PWM2_LVL_MASK 0x03FF /* PWM2_LVL - [9:0] */ | ||
| 880 | #define WM5100_PWM2_LVL_SHIFT 0 /* PWM2_LVL - [9:0] */ | ||
| 881 | #define WM5100_PWM2_LVL_WIDTH 10 /* PWM2_LVL - [9:0] */ | ||
| 882 | |||
| 883 | /* | ||
| 884 | * R256 (0x100) - Clocking 1 | ||
| 885 | */ | ||
| 886 | #define WM5100_CLK_32K_SRC_MASK 0x000F /* CLK_32K_SRC - [3:0] */ | ||
| 887 | #define WM5100_CLK_32K_SRC_SHIFT 0 /* CLK_32K_SRC - [3:0] */ | ||
| 888 | #define WM5100_CLK_32K_SRC_WIDTH 4 /* CLK_32K_SRC - [3:0] */ | ||
| 889 | |||
| 890 | /* | ||
| 891 | * R257 (0x101) - Clocking 3 | ||
| 892 | */ | ||
| 893 | #define WM5100_SYSCLK_FREQ_MASK 0x0700 /* SYSCLK_FREQ - [10:8] */ | ||
| 894 | #define WM5100_SYSCLK_FREQ_SHIFT 8 /* SYSCLK_FREQ - [10:8] */ | ||
| 895 | #define WM5100_SYSCLK_FREQ_WIDTH 3 /* SYSCLK_FREQ - [10:8] */ | ||
| 896 | #define WM5100_SYSCLK_ENA 0x0040 /* SYSCLK_ENA */ | ||
| 897 | #define WM5100_SYSCLK_ENA_MASK 0x0040 /* SYSCLK_ENA */ | ||
| 898 | #define WM5100_SYSCLK_ENA_SHIFT 6 /* SYSCLK_ENA */ | ||
| 899 | #define WM5100_SYSCLK_ENA_WIDTH 1 /* SYSCLK_ENA */ | ||
| 900 | #define WM5100_SYSCLK_SRC_MASK 0x000F /* SYSCLK_SRC - [3:0] */ | ||
| 901 | #define WM5100_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC - [3:0] */ | ||
| 902 | #define WM5100_SYSCLK_SRC_WIDTH 4 /* SYSCLK_SRC - [3:0] */ | ||
| 903 | |||
| 904 | /* | ||
| 905 | * R258 (0x102) - Clocking 4 | ||
| 906 | */ | ||
| 907 | #define WM5100_SAMPLE_RATE_1_MASK 0x001F /* SAMPLE_RATE_1 - [4:0] */ | ||
| 908 | #define WM5100_SAMPLE_RATE_1_SHIFT 0 /* SAMPLE_RATE_1 - [4:0] */ | ||
| 909 | #define WM5100_SAMPLE_RATE_1_WIDTH 5 /* SAMPLE_RATE_1 - [4:0] */ | ||
| 910 | |||
| 911 | /* | ||
| 912 | * R259 (0x103) - Clocking 5 | ||
| 913 | */ | ||
| 914 | #define WM5100_SAMPLE_RATE_2_MASK 0x001F /* SAMPLE_RATE_2 - [4:0] */ | ||
| 915 | #define WM5100_SAMPLE_RATE_2_SHIFT 0 /* SAMPLE_RATE_2 - [4:0] */ | ||
| 916 | #define WM5100_SAMPLE_RATE_2_WIDTH 5 /* SAMPLE_RATE_2 - [4:0] */ | ||
| 917 | |||
| 918 | /* | ||
| 919 | * R260 (0x104) - Clocking 6 | ||
| 920 | */ | ||
| 921 | #define WM5100_SAMPLE_RATE_3_MASK 0x001F /* SAMPLE_RATE_3 - [4:0] */ | ||
| 922 | #define WM5100_SAMPLE_RATE_3_SHIFT 0 /* SAMPLE_RATE_3 - [4:0] */ | ||
| 923 | #define WM5100_SAMPLE_RATE_3_WIDTH 5 /* SAMPLE_RATE_3 - [4:0] */ | ||
| 924 | |||
| 925 | /* | ||
| 926 | * R263 (0x107) - Clocking 7 | ||
| 927 | */ | ||
| 928 | #define WM5100_ASYNC_CLK_FREQ_MASK 0x0700 /* ASYNC_CLK_FREQ - [10:8] */ | ||
| 929 | #define WM5100_ASYNC_CLK_FREQ_SHIFT 8 /* ASYNC_CLK_FREQ - [10:8] */ | ||
| 930 | #define WM5100_ASYNC_CLK_FREQ_WIDTH 3 /* ASYNC_CLK_FREQ - [10:8] */ | ||
| 931 | #define WM5100_ASYNC_CLK_ENA 0x0040 /* ASYNC_CLK_ENA */ | ||
| 932 | #define WM5100_ASYNC_CLK_ENA_MASK 0x0040 /* ASYNC_CLK_ENA */ | ||
| 933 | #define WM5100_ASYNC_CLK_ENA_SHIFT 6 /* ASYNC_CLK_ENA */ | ||
| 934 | #define WM5100_ASYNC_CLK_ENA_WIDTH 1 /* ASYNC_CLK_ENA */ | ||
| 935 | #define WM5100_ASYNC_CLK_SRC_MASK 0x000F /* ASYNC_CLK_SRC - [3:0] */ | ||
| 936 | #define WM5100_ASYNC_CLK_SRC_SHIFT 0 /* ASYNC_CLK_SRC - [3:0] */ | ||
| 937 | #define WM5100_ASYNC_CLK_SRC_WIDTH 4 /* ASYNC_CLK_SRC - [3:0] */ | ||
| 938 | |||
| 939 | /* | ||
| 940 | * R264 (0x108) - Clocking 8 | ||
| 941 | */ | ||
| 942 | #define WM5100_ASYNC_SAMPLE_RATE_MASK 0x001F /* ASYNC_SAMPLE_RATE - [4:0] */ | ||
| 943 | #define WM5100_ASYNC_SAMPLE_RATE_SHIFT 0 /* ASYNC_SAMPLE_RATE - [4:0] */ | ||
| 944 | #define WM5100_ASYNC_SAMPLE_RATE_WIDTH 5 /* ASYNC_SAMPLE_RATE - [4:0] */ | ||
| 945 | |||
| 946 | /* | ||
| 947 | * R288 (0x120) - ASRC_ENABLE | ||
| 948 | */ | ||
| 949 | #define WM5100_ASRC2L_ENA 0x0008 /* ASRC2L_ENA */ | ||
| 950 | #define WM5100_ASRC2L_ENA_MASK 0x0008 /* ASRC2L_ENA */ | ||
| 951 | #define WM5100_ASRC2L_ENA_SHIFT 3 /* ASRC2L_ENA */ | ||
| 952 | #define WM5100_ASRC2L_ENA_WIDTH 1 /* ASRC2L_ENA */ | ||
| 953 | #define WM5100_ASRC2R_ENA 0x0004 /* ASRC2R_ENA */ | ||
| 954 | #define WM5100_ASRC2R_ENA_MASK 0x0004 /* ASRC2R_ENA */ | ||
| 955 | #define WM5100_ASRC2R_ENA_SHIFT 2 /* ASRC2R_ENA */ | ||
| 956 | #define WM5100_ASRC2R_ENA_WIDTH 1 /* ASRC2R_ENA */ | ||
| 957 | #define WM5100_ASRC1L_ENA 0x0002 /* ASRC1L_ENA */ | ||
| 958 | #define WM5100_ASRC1L_ENA_MASK 0x0002 /* ASRC1L_ENA */ | ||
| 959 | #define WM5100_ASRC1L_ENA_SHIFT 1 /* ASRC1L_ENA */ | ||
| 960 | #define WM5100_ASRC1L_ENA_WIDTH 1 /* ASRC1L_ENA */ | ||
| 961 | #define WM5100_ASRC1R_ENA 0x0001 /* ASRC1R_ENA */ | ||
| 962 | #define WM5100_ASRC1R_ENA_MASK 0x0001 /* ASRC1R_ENA */ | ||
| 963 | #define WM5100_ASRC1R_ENA_SHIFT 0 /* ASRC1R_ENA */ | ||
| 964 | #define WM5100_ASRC1R_ENA_WIDTH 1 /* ASRC1R_ENA */ | ||
| 965 | |||
| 966 | /* | ||
| 967 | * R289 (0x121) - ASRC_STATUS | ||
| 968 | */ | ||
| 969 | #define WM5100_ASRC2L_ENA_STS 0x0008 /* ASRC2L_ENA_STS */ | ||
| 970 | #define WM5100_ASRC2L_ENA_STS_MASK 0x0008 /* ASRC2L_ENA_STS */ | ||
| 971 | #define WM5100_ASRC2L_ENA_STS_SHIFT 3 /* ASRC2L_ENA_STS */ | ||
| 972 | #define WM5100_ASRC2L_ENA_STS_WIDTH 1 /* ASRC2L_ENA_STS */ | ||
| 973 | #define WM5100_ASRC2R_ENA_STS 0x0004 /* ASRC2R_ENA_STS */ | ||
| 974 | #define WM5100_ASRC2R_ENA_STS_MASK 0x0004 /* ASRC2R_ENA_STS */ | ||
| 975 | #define WM5100_ASRC2R_ENA_STS_SHIFT 2 /* ASRC2R_ENA_STS */ | ||
| 976 | #define WM5100_ASRC2R_ENA_STS_WIDTH 1 /* ASRC2R_ENA_STS */ | ||
| 977 | #define WM5100_ASRC1L_ENA_STS 0x0002 /* ASRC1L_ENA_STS */ | ||
| 978 | #define WM5100_ASRC1L_ENA_STS_MASK 0x0002 /* ASRC1L_ENA_STS */ | ||
| 979 | #define WM5100_ASRC1L_ENA_STS_SHIFT 1 /* ASRC1L_ENA_STS */ | ||
| 980 | #define WM5100_ASRC1L_ENA_STS_WIDTH 1 /* ASRC1L_ENA_STS */ | ||
| 981 | #define WM5100_ASRC1R_ENA_STS 0x0001 /* ASRC1R_ENA_STS */ | ||
| 982 | #define WM5100_ASRC1R_ENA_STS_MASK 0x0001 /* ASRC1R_ENA_STS */ | ||
| 983 | #define WM5100_ASRC1R_ENA_STS_SHIFT 0 /* ASRC1R_ENA_STS */ | ||
| 984 | #define WM5100_ASRC1R_ENA_STS_WIDTH 1 /* ASRC1R_ENA_STS */ | ||
| 985 | |||
| 986 | /* | ||
| 987 | * R290 (0x122) - ASRC_RATE1 | ||
| 988 | */ | ||
| 989 | #define WM5100_ASRC_RATE1_MASK 0x0006 /* ASRC_RATE1 - [2:1] */ | ||
| 990 | #define WM5100_ASRC_RATE1_SHIFT 1 /* ASRC_RATE1 - [2:1] */ | ||
| 991 | #define WM5100_ASRC_RATE1_WIDTH 2 /* ASRC_RATE1 - [2:1] */ | ||
| 992 | |||
| 993 | /* | ||
| 994 | * R321 (0x141) - ISRC 1 CTRL 1 | ||
| 995 | */ | ||
| 996 | #define WM5100_ISRC1_DFS_ENA 0x2000 /* ISRC1_DFS_ENA */ | ||
| 997 | #define WM5100_ISRC1_DFS_ENA_MASK 0x2000 /* ISRC1_DFS_ENA */ | ||
| 998 | #define WM5100_ISRC1_DFS_ENA_SHIFT 13 /* ISRC1_DFS_ENA */ | ||
| 999 | #define WM5100_ISRC1_DFS_ENA_WIDTH 1 /* ISRC1_DFS_ENA */ | ||
| 1000 | #define WM5100_ISRC1_CLK_SEL_MASK 0x0300 /* ISRC1_CLK_SEL - [9:8] */ | ||
| 1001 | #define WM5100_ISRC1_CLK_SEL_SHIFT 8 /* ISRC1_CLK_SEL - [9:8] */ | ||
| 1002 | #define WM5100_ISRC1_CLK_SEL_WIDTH 2 /* ISRC1_CLK_SEL - [9:8] */ | ||
| 1003 | #define WM5100_ISRC1_FSH_MASK 0x000C /* ISRC1_FSH - [3:2] */ | ||
| 1004 | #define WM5100_ISRC1_FSH_SHIFT 2 /* ISRC1_FSH - [3:2] */ | ||
| 1005 | #define WM5100_ISRC1_FSH_WIDTH 2 /* ISRC1_FSH - [3:2] */ | ||
| 1006 | #define WM5100_ISRC1_FSL_MASK 0x0003 /* ISRC1_FSL - [1:0] */ | ||
| 1007 | #define WM5100_ISRC1_FSL_SHIFT 0 /* ISRC1_FSL - [1:0] */ | ||
| 1008 | #define WM5100_ISRC1_FSL_WIDTH 2 /* ISRC1_FSL - [1:0] */ | ||
| 1009 | |||
| 1010 | /* | ||
| 1011 | * R322 (0x142) - ISRC 1 CTRL 2 | ||
| 1012 | */ | ||
| 1013 | #define WM5100_ISRC1_INT1_ENA 0x8000 /* ISRC1_INT1_ENA */ | ||
| 1014 | #define WM5100_ISRC1_INT1_ENA_MASK 0x8000 /* ISRC1_INT1_ENA */ | ||
| 1015 | #define WM5100_ISRC1_INT1_ENA_SHIFT 15 /* ISRC1_INT1_ENA */ | ||
| 1016 | #define WM5100_ISRC1_INT1_ENA_WIDTH 1 /* ISRC1_INT1_ENA */ | ||
| 1017 | #define WM5100_ISRC1_INT2_ENA 0x4000 /* ISRC1_INT2_ENA */ | ||
| 1018 | #define WM5100_ISRC1_INT2_ENA_MASK 0x4000 /* ISRC1_INT2_ENA */ | ||
| 1019 | #define WM5100_ISRC1_INT2_ENA_SHIFT 14 /* ISRC1_INT2_ENA */ | ||
| 1020 | #define WM5100_ISRC1_INT2_ENA_WIDTH 1 /* ISRC1_INT2_ENA */ | ||
| 1021 | #define WM5100_ISRC1_INT3_ENA 0x2000 /* ISRC1_INT3_ENA */ | ||
| 1022 | #define WM5100_ISRC1_INT3_ENA_MASK 0x2000 /* ISRC1_INT3_ENA */ | ||
| 1023 | #define WM5100_ISRC1_INT3_ENA_SHIFT 13 /* ISRC1_INT3_ENA */ | ||
| 1024 | #define WM5100_ISRC1_INT3_ENA_WIDTH 1 /* ISRC1_INT3_ENA */ | ||
| 1025 | #define WM5100_ISRC1_INT4_ENA 0x1000 /* ISRC1_INT4_ENA */ | ||
| 1026 | #define WM5100_ISRC1_INT4_ENA_MASK 0x1000 /* ISRC1_INT4_ENA */ | ||
| 1027 | #define WM5100_ISRC1_INT4_ENA_SHIFT 12 /* ISRC1_INT4_ENA */ | ||
| 1028 | #define WM5100_ISRC1_INT4_ENA_WIDTH 1 /* ISRC1_INT4_ENA */ | ||
| 1029 | #define WM5100_ISRC1_DEC1_ENA 0x0200 /* ISRC1_DEC1_ENA */ | ||
| 1030 | #define WM5100_ISRC1_DEC1_ENA_MASK 0x0200 /* ISRC1_DEC1_ENA */ | ||
| 1031 | #define WM5100_ISRC1_DEC1_ENA_SHIFT 9 /* ISRC1_DEC1_ENA */ | ||
| 1032 | #define WM5100_ISRC1_DEC1_ENA_WIDTH 1 /* ISRC1_DEC1_ENA */ | ||
| 1033 | #define WM5100_ISRC1_DEC2_ENA 0x0100 /* ISRC1_DEC2_ENA */ | ||
| 1034 | #define WM5100_ISRC1_DEC2_ENA_MASK 0x0100 /* ISRC1_DEC2_ENA */ | ||
| 1035 | #define WM5100_ISRC1_DEC2_ENA_SHIFT 8 /* ISRC1_DEC2_ENA */ | ||
| 1036 | #define WM5100_ISRC1_DEC2_ENA_WIDTH 1 /* ISRC1_DEC2_ENA */ | ||
| 1037 | #define WM5100_ISRC1_DEC3_ENA 0x0080 /* ISRC1_DEC3_ENA */ | ||
| 1038 | #define WM5100_ISRC1_DEC3_ENA_MASK 0x0080 /* ISRC1_DEC3_ENA */ | ||
| 1039 | #define WM5100_ISRC1_DEC3_ENA_SHIFT 7 /* ISRC1_DEC3_ENA */ | ||
| 1040 | #define WM5100_ISRC1_DEC3_ENA_WIDTH 1 /* ISRC1_DEC3_ENA */ | ||
| 1041 | #define WM5100_ISRC1_DEC4_ENA 0x0040 /* ISRC1_DEC4_ENA */ | ||
| 1042 | #define WM5100_ISRC1_DEC4_ENA_MASK 0x0040 /* ISRC1_DEC4_ENA */ | ||
| 1043 | #define WM5100_ISRC1_DEC4_ENA_SHIFT 6 /* ISRC1_DEC4_ENA */ | ||
| 1044 | #define WM5100_ISRC1_DEC4_ENA_WIDTH 1 /* ISRC1_DEC4_ENA */ | ||
| 1045 | #define WM5100_ISRC1_NOTCH_ENA 0x0001 /* ISRC1_NOTCH_ENA */ | ||
| 1046 | #define WM5100_ISRC1_NOTCH_ENA_MASK 0x0001 /* ISRC1_NOTCH_ENA */ | ||
| 1047 | #define WM5100_ISRC1_NOTCH_ENA_SHIFT 0 /* ISRC1_NOTCH_ENA */ | ||
| 1048 | #define WM5100_ISRC1_NOTCH_ENA_WIDTH 1 /* ISRC1_NOTCH_ENA */ | ||
| 1049 | |||
| 1050 | /* | ||
| 1051 | * R323 (0x143) - ISRC 2 CTRL1 | ||
| 1052 | */ | ||
| 1053 | #define WM5100_ISRC2_DFS_ENA 0x2000 /* ISRC2_DFS_ENA */ | ||
| 1054 | #define WM5100_ISRC2_DFS_ENA_MASK 0x2000 /* ISRC2_DFS_ENA */ | ||
| 1055 | #define WM5100_ISRC2_DFS_ENA_SHIFT 13 /* ISRC2_DFS_ENA */ | ||
| 1056 | #define WM5100_ISRC2_DFS_ENA_WIDTH 1 /* ISRC2_DFS_ENA */ | ||
| 1057 | #define WM5100_ISRC2_CLK_SEL_MASK 0x0300 /* ISRC2_CLK_SEL - [9:8] */ | ||
| 1058 | #define WM5100_ISRC2_CLK_SEL_SHIFT 8 /* ISRC2_CLK_SEL - [9:8] */ | ||
| 1059 | #define WM5100_ISRC2_CLK_SEL_WIDTH 2 /* ISRC2_CLK_SEL - [9:8] */ | ||
| 1060 | #define WM5100_ISRC2_FSH_MASK 0x000C /* ISRC2_FSH - [3:2] */ | ||
| 1061 | #define WM5100_ISRC2_FSH_SHIFT 2 /* ISRC2_FSH - [3:2] */ | ||
| 1062 | #define WM5100_ISRC2_FSH_WIDTH 2 /* ISRC2_FSH - [3:2] */ | ||
| 1063 | #define WM5100_ISRC2_FSL_MASK 0x0003 /* ISRC2_FSL - [1:0] */ | ||
| 1064 | #define WM5100_ISRC2_FSL_SHIFT 0 /* ISRC2_FSL - [1:0] */ | ||
| 1065 | #define WM5100_ISRC2_FSL_WIDTH 2 /* ISRC2_FSL - [1:0] */ | ||
| 1066 | |||
| 1067 | /* | ||
| 1068 | * R324 (0x144) - ISRC 2 CTRL 2 | ||
| 1069 | */ | ||
| 1070 | #define WM5100_ISRC2_INT1_ENA 0x8000 /* ISRC2_INT1_ENA */ | ||
| 1071 | #define WM5100_ISRC2_INT1_ENA_MASK 0x8000 /* ISRC2_INT1_ENA */ | ||
| 1072 | #define WM5100_ISRC2_INT1_ENA_SHIFT 15 /* ISRC2_INT1_ENA */ | ||
| 1073 | #define WM5100_ISRC2_INT1_ENA_WIDTH 1 /* ISRC2_INT1_ENA */ | ||
| 1074 | #define WM5100_ISRC2_INT2_ENA 0x4000 /* ISRC2_INT2_ENA */ | ||
| 1075 | #define WM5100_ISRC2_INT2_ENA_MASK 0x4000 /* ISRC2_INT2_ENA */ | ||
| 1076 | #define WM5100_ISRC2_INT2_ENA_SHIFT 14 /* ISRC2_INT2_ENA */ | ||
| 1077 | #define WM5100_ISRC2_INT2_ENA_WIDTH 1 /* ISRC2_INT2_ENA */ | ||
| 1078 | #define WM5100_ISRC2_INT3_ENA 0x2000 /* ISRC2_INT3_ENA */ | ||
| 1079 | #define WM5100_ISRC2_INT3_ENA_MASK 0x2000 /* ISRC2_INT3_ENA */ | ||
| 1080 | #define WM5100_ISRC2_INT3_ENA_SHIFT 13 /* ISRC2_INT3_ENA */ | ||
| 1081 | #define WM5100_ISRC2_INT3_ENA_WIDTH 1 /* ISRC2_INT3_ENA */ | ||
| 1082 | #define WM5100_ISRC2_INT4_ENA 0x1000 /* ISRC2_INT4_ENA */ | ||
| 1083 | #define WM5100_ISRC2_INT4_ENA_MASK 0x1000 /* ISRC2_INT4_ENA */ | ||
| 1084 | #define WM5100_ISRC2_INT4_ENA_SHIFT 12 /* ISRC2_INT4_ENA */ | ||
| 1085 | #define WM5100_ISRC2_INT4_ENA_WIDTH 1 /* ISRC2_INT4_ENA */ | ||
| 1086 | #define WM5100_ISRC2_DEC1_ENA 0x0200 /* ISRC2_DEC1_ENA */ | ||
| 1087 | #define WM5100_ISRC2_DEC1_ENA_MASK 0x0200 /* ISRC2_DEC1_ENA */ | ||
| 1088 | #define WM5100_ISRC2_DEC1_ENA_SHIFT 9 /* ISRC2_DEC1_ENA */ | ||
| 1089 | #define WM5100_ISRC2_DEC1_ENA_WIDTH 1 /* ISRC2_DEC1_ENA */ | ||
| 1090 | #define WM5100_ISRC2_DEC2_ENA 0x0100 /* ISRC2_DEC2_ENA */ | ||
| 1091 | #define WM5100_ISRC2_DEC2_ENA_MASK 0x0100 /* ISRC2_DEC2_ENA */ | ||
| 1092 | #define WM5100_ISRC2_DEC2_ENA_SHIFT 8 /* ISRC2_DEC2_ENA */ | ||
| 1093 | #define WM5100_ISRC2_DEC2_ENA_WIDTH 1 /* ISRC2_DEC2_ENA */ | ||
| 1094 | #define WM5100_ISRC2_DEC3_ENA 0x0080 /* ISRC2_DEC3_ENA */ | ||
| 1095 | #define WM5100_ISRC2_DEC3_ENA_MASK 0x0080 /* ISRC2_DEC3_ENA */ | ||
| 1096 | #define WM5100_ISRC2_DEC3_ENA_SHIFT 7 /* ISRC2_DEC3_ENA */ | ||
| 1097 | #define WM5100_ISRC2_DEC3_ENA_WIDTH 1 /* ISRC2_DEC3_ENA */ | ||
| 1098 | #define WM5100_ISRC2_DEC4_ENA 0x0040 /* ISRC2_DEC4_ENA */ | ||
| 1099 | #define WM5100_ISRC2_DEC4_ENA_MASK 0x0040 /* ISRC2_DEC4_ENA */ | ||
| 1100 | #define WM5100_ISRC2_DEC4_ENA_SHIFT 6 /* ISRC2_DEC4_ENA */ | ||
| 1101 | #define WM5100_ISRC2_DEC4_ENA_WIDTH 1 /* ISRC2_DEC4_ENA */ | ||
| 1102 | #define WM5100_ISRC2_NOTCH_ENA 0x0001 /* ISRC2_NOTCH_ENA */ | ||
| 1103 | #define WM5100_ISRC2_NOTCH_ENA_MASK 0x0001 /* ISRC2_NOTCH_ENA */ | ||
| 1104 | #define WM5100_ISRC2_NOTCH_ENA_SHIFT 0 /* ISRC2_NOTCH_ENA */ | ||
| 1105 | #define WM5100_ISRC2_NOTCH_ENA_WIDTH 1 /* ISRC2_NOTCH_ENA */ | ||
| 1106 | |||
| 1107 | /* | ||
| 1108 | * R386 (0x182) - FLL1 Control 1 | ||
| 1109 | */ | ||
| 1110 | #define WM5100_FLL1_ENA 0x0001 /* FLL1_ENA */ | ||
| 1111 | #define WM5100_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */ | ||
| 1112 | #define WM5100_FLL1_ENA_SHIFT 0 /* FLL1_ENA */ | ||
| 1113 | #define WM5100_FLL1_ENA_WIDTH 1 /* FLL1_ENA */ | ||
| 1114 | |||
| 1115 | /* | ||
| 1116 | * R387 (0x183) - FLL1 Control 2 | ||
| 1117 | */ | ||
| 1118 | #define WM5100_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */ | ||
| 1119 | #define WM5100_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */ | ||
| 1120 | #define WM5100_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */ | ||
| 1121 | #define WM5100_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */ | ||
| 1122 | #define WM5100_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */ | ||
| 1123 | #define WM5100_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */ | ||
| 1124 | |||
| 1125 | /* | ||
| 1126 | * R388 (0x184) - FLL1 Control 3 | ||
| 1127 | */ | ||
| 1128 | #define WM5100_FLL1_THETA_MASK 0xFFFF /* FLL1_THETA - [15:0] */ | ||
| 1129 | #define WM5100_FLL1_THETA_SHIFT 0 /* FLL1_THETA - [15:0] */ | ||
| 1130 | #define WM5100_FLL1_THETA_WIDTH 16 /* FLL1_THETA - [15:0] */ | ||
| 1131 | |||
| 1132 | /* | ||
| 1133 | * R390 (0x186) - FLL1 Control 5 | ||
| 1134 | */ | ||
| 1135 | #define WM5100_FLL1_N_MASK 0x03FF /* FLL1_N - [9:0] */ | ||
| 1136 | #define WM5100_FLL1_N_SHIFT 0 /* FLL1_N - [9:0] */ | ||
| 1137 | #define WM5100_FLL1_N_WIDTH 10 /* FLL1_N - [9:0] */ | ||
| 1138 | |||
| 1139 | /* | ||
| 1140 | * R391 (0x187) - FLL1 Control 6 | ||
| 1141 | */ | ||
| 1142 | #define WM5100_FLL1_REFCLK_DIV_MASK 0x00C0 /* FLL1_REFCLK_DIV - [7:6] */ | ||
| 1143 | #define WM5100_FLL1_REFCLK_DIV_SHIFT 6 /* FLL1_REFCLK_DIV - [7:6] */ | ||
| 1144 | #define WM5100_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [7:6] */ | ||
| 1145 | #define WM5100_FLL1_REFCLK_SRC_MASK 0x000F /* FLL1_REFCLK_SRC - [3:0] */ | ||
| 1146 | #define WM5100_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [3:0] */ | ||
| 1147 | #define WM5100_FLL1_REFCLK_SRC_WIDTH 4 /* FLL1_REFCLK_SRC - [3:0] */ | ||
| 1148 | |||
| 1149 | /* | ||
| 1150 | * R392 (0x188) - FLL1 EFS 1 | ||
| 1151 | */ | ||
| 1152 | #define WM5100_FLL1_LAMBDA_MASK 0xFFFF /* FLL1_LAMBDA - [15:0] */ | ||
| 1153 | #define WM5100_FLL1_LAMBDA_SHIFT 0 /* FLL1_LAMBDA - [15:0] */ | ||
| 1154 | #define WM5100_FLL1_LAMBDA_WIDTH 16 /* FLL1_LAMBDA - [15:0] */ | ||
| 1155 | |||
| 1156 | /* | ||
| 1157 | * R418 (0x1A2) - FLL2 Control 1 | ||
| 1158 | */ | ||
| 1159 | #define WM5100_FLL2_ENA 0x0001 /* FLL2_ENA */ | ||
| 1160 | #define WM5100_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */ | ||
| 1161 | #define WM5100_FLL2_ENA_SHIFT 0 /* FLL2_ENA */ | ||
| 1162 | #define WM5100_FLL2_ENA_WIDTH 1 /* FLL2_ENA */ | ||
| 1163 | |||
| 1164 | /* | ||
| 1165 | * R419 (0x1A3) - FLL2 Control 2 | ||
| 1166 | */ | ||
| 1167 | #define WM5100_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */ | ||
| 1168 | #define WM5100_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */ | ||
| 1169 | #define WM5100_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */ | ||
| 1170 | #define WM5100_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */ | ||
| 1171 | #define WM5100_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */ | ||
| 1172 | #define WM5100_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */ | ||
| 1173 | |||
| 1174 | /* | ||
| 1175 | * R420 (0x1A4) - FLL2 Control 3 | ||
| 1176 | */ | ||
| 1177 | #define WM5100_FLL2_THETA_MASK 0xFFFF /* FLL2_THETA - [15:0] */ | ||
| 1178 | #define WM5100_FLL2_THETA_SHIFT 0 /* FLL2_THETA - [15:0] */ | ||
| 1179 | #define WM5100_FLL2_THETA_WIDTH 16 /* FLL2_THETA - [15:0] */ | ||
| 1180 | |||
| 1181 | /* | ||
| 1182 | * R422 (0x1A6) - FLL2 Control 5 | ||
| 1183 | */ | ||
| 1184 | #define WM5100_FLL2_N_MASK 0x03FF /* FLL2_N - [9:0] */ | ||
| 1185 | #define WM5100_FLL2_N_SHIFT 0 /* FLL2_N - [9:0] */ | ||
| 1186 | #define WM5100_FLL2_N_WIDTH 10 /* FLL2_N - [9:0] */ | ||
| 1187 | |||
| 1188 | /* | ||
| 1189 | * R423 (0x1A7) - FLL2 Control 6 | ||
| 1190 | */ | ||
| 1191 | #define WM5100_FLL2_REFCLK_DIV_MASK 0x00C0 /* FLL2_REFCLK_DIV - [7:6] */ | ||
| 1192 | #define WM5100_FLL2_REFCLK_DIV_SHIFT 6 /* FLL2_REFCLK_DIV - [7:6] */ | ||
| 1193 | #define WM5100_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [7:6] */ | ||
| 1194 | #define WM5100_FLL2_REFCLK_SRC_MASK 0x000F /* FLL2_REFCLK_SRC - [3:0] */ | ||
| 1195 | #define WM5100_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [3:0] */ | ||
| 1196 | #define WM5100_FLL2_REFCLK_SRC_WIDTH 4 /* FLL2_REFCLK_SRC - [3:0] */ | ||
| 1197 | |||
| 1198 | /* | ||
| 1199 | * R424 (0x1A8) - FLL2 EFS 1 | ||
| 1200 | */ | ||
| 1201 | #define WM5100_FLL2_LAMBDA_MASK 0xFFFF /* FLL2_LAMBDA - [15:0] */ | ||
| 1202 | #define WM5100_FLL2_LAMBDA_SHIFT 0 /* FLL2_LAMBDA - [15:0] */ | ||
| 1203 | #define WM5100_FLL2_LAMBDA_WIDTH 16 /* FLL2_LAMBDA - [15:0] */ | ||
| 1204 | |||
| 1205 | /* | ||
| 1206 | * R512 (0x200) - Mic Charge Pump 1 | ||
| 1207 | */ | ||
| 1208 | #define WM5100_CP2_BYPASS 0x0020 /* CP2_BYPASS */ | ||
| 1209 | #define WM5100_CP2_BYPASS_MASK 0x0020 /* CP2_BYPASS */ | ||
| 1210 | #define WM5100_CP2_BYPASS_SHIFT 5 /* CP2_BYPASS */ | ||
| 1211 | #define WM5100_CP2_BYPASS_WIDTH 1 /* CP2_BYPASS */ | ||
| 1212 | #define WM5100_CP2_ENA 0x0001 /* CP2_ENA */ | ||
| 1213 | #define WM5100_CP2_ENA_MASK 0x0001 /* CP2_ENA */ | ||
| 1214 | #define WM5100_CP2_ENA_SHIFT 0 /* CP2_ENA */ | ||
| 1215 | #define WM5100_CP2_ENA_WIDTH 1 /* CP2_ENA */ | ||
| 1216 | |||
| 1217 | /* | ||
| 1218 | * R513 (0x201) - Mic Charge Pump 2 | ||
| 1219 | */ | ||
| 1220 | #define WM5100_LDO2_VSEL_MASK 0xF800 /* LDO2_VSEL - [15:11] */ | ||
| 1221 | #define WM5100_LDO2_VSEL_SHIFT 11 /* LDO2_VSEL - [15:11] */ | ||
| 1222 | #define WM5100_LDO2_VSEL_WIDTH 5 /* LDO2_VSEL - [15:11] */ | ||
| 1223 | |||
| 1224 | /* | ||
| 1225 | * R514 (0x202) - HP Charge Pump 1 | ||
| 1226 | */ | ||
| 1227 | #define WM5100_CP1_ENA 0x0001 /* CP1_ENA */ | ||
| 1228 | #define WM5100_CP1_ENA_MASK 0x0001 /* CP1_ENA */ | ||
| 1229 | #define WM5100_CP1_ENA_SHIFT 0 /* CP1_ENA */ | ||
| 1230 | #define WM5100_CP1_ENA_WIDTH 1 /* CP1_ENA */ | ||
| 1231 | |||
| 1232 | /* | ||
| 1233 | * R529 (0x211) - LDO1 Control | ||
| 1234 | */ | ||
| 1235 | #define WM5100_LDO1_BYPASS 0x0002 /* LDO1_BYPASS */ | ||
| 1236 | #define WM5100_LDO1_BYPASS_MASK 0x0002 /* LDO1_BYPASS */ | ||
| 1237 | #define WM5100_LDO1_BYPASS_SHIFT 1 /* LDO1_BYPASS */ | ||
| 1238 | #define WM5100_LDO1_BYPASS_WIDTH 1 /* LDO1_BYPASS */ | ||
| 1239 | |||
| 1240 | /* | ||
| 1241 | * R533 (0x215) - Mic Bias Ctrl 1 | ||
| 1242 | */ | ||
| 1243 | #define WM5100_MICB1_DISCH 0x0040 /* MICB1_DISCH */ | ||
| 1244 | #define WM5100_MICB1_DISCH_MASK 0x0040 /* MICB1_DISCH */ | ||
| 1245 | #define WM5100_MICB1_DISCH_SHIFT 6 /* MICB1_DISCH */ | ||
| 1246 | #define WM5100_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ | ||
| 1247 | #define WM5100_MICB1_RATE 0x0020 /* MICB1_RATE */ | ||
| 1248 | #define WM5100_MICB1_RATE_MASK 0x0020 /* MICB1_RATE */ | ||
| 1249 | #define WM5100_MICB1_RATE_SHIFT 5 /* MICB1_RATE */ | ||
| 1250 | #define WM5100_MICB1_RATE_WIDTH 1 /* MICB1_RATE */ | ||
| 1251 | #define WM5100_MICB1_LVL_MASK 0x001C /* MICB1_LVL - [4:2] */ | ||
| 1252 | #define WM5100_MICB1_LVL_SHIFT 2 /* MICB1_LVL - [4:2] */ | ||
| 1253 | #define WM5100_MICB1_LVL_WIDTH 3 /* MICB1_LVL - [4:2] */ | ||
| 1254 | #define WM5100_MICB1_BYPASS 0x0002 /* MICB1_BYPASS */ | ||
| 1255 | #define WM5100_MICB1_BYPASS_MASK 0x0002 /* MICB1_BYPASS */ | ||
| 1256 | #define WM5100_MICB1_BYPASS_SHIFT 1 /* MICB1_BYPASS */ | ||
| 1257 | #define WM5100_MICB1_BYPASS_WIDTH 1 /* MICB1_BYPASS */ | ||
| 1258 | #define WM5100_MICB1_ENA 0x0001 /* MICB1_ENA */ | ||
| 1259 | #define WM5100_MICB1_ENA_MASK 0x0001 /* MICB1_ENA */ | ||
| 1260 | #define WM5100_MICB1_ENA_SHIFT 0 /* MICB1_ENA */ | ||
| 1261 | #define WM5100_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ | ||
| 1262 | |||
| 1263 | /* | ||
| 1264 | * R534 (0x216) - Mic Bias Ctrl 2 | ||
| 1265 | */ | ||
| 1266 | #define WM5100_MICB2_DISCH 0x0040 /* MICB2_DISCH */ | ||
| 1267 | #define WM5100_MICB2_DISCH_MASK 0x0040 /* MICB2_DISCH */ | ||
| 1268 | #define WM5100_MICB2_DISCH_SHIFT 6 /* MICB2_DISCH */ | ||
| 1269 | #define WM5100_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ | ||
| 1270 | #define WM5100_MICB2_RATE 0x0020 /* MICB2_RATE */ | ||
| 1271 | #define WM5100_MICB2_RATE_MASK 0x0020 /* MICB2_RATE */ | ||
| 1272 | #define WM5100_MICB2_RATE_SHIFT 5 /* MICB2_RATE */ | ||
| 1273 | #define WM5100_MICB2_RATE_WIDTH 1 /* MICB2_RATE */ | ||
| 1274 | #define WM5100_MICB2_LVL_MASK 0x001C /* MICB2_LVL - [4:2] */ | ||
| 1275 | #define WM5100_MICB2_LVL_SHIFT 2 /* MICB2_LVL - [4:2] */ | ||
| 1276 | #define WM5100_MICB2_LVL_WIDTH 3 /* MICB2_LVL - [4:2] */ | ||
| 1277 | #define WM5100_MICB2_BYPASS 0x0002 /* MICB2_BYPASS */ | ||
| 1278 | #define WM5100_MICB2_BYPASS_MASK 0x0002 /* MICB2_BYPASS */ | ||
| 1279 | #define WM5100_MICB2_BYPASS_SHIFT 1 /* MICB2_BYPASS */ | ||
| 1280 | #define WM5100_MICB2_BYPASS_WIDTH 1 /* MICB2_BYPASS */ | ||
| 1281 | #define WM5100_MICB2_ENA 0x0001 /* MICB2_ENA */ | ||
| 1282 | #define WM5100_MICB2_ENA_MASK 0x0001 /* MICB2_ENA */ | ||
| 1283 | #define WM5100_MICB2_ENA_SHIFT 0 /* MICB2_ENA */ | ||
| 1284 | #define WM5100_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ | ||
| 1285 | |||
| 1286 | /* | ||
| 1287 | * R535 (0x217) - Mic Bias Ctrl 3 | ||
| 1288 | */ | ||
| 1289 | #define WM5100_MICB3_DISCH 0x0040 /* MICB3_DISCH */ | ||
| 1290 | #define WM5100_MICB3_DISCH_MASK 0x0040 /* MICB3_DISCH */ | ||
| 1291 | #define WM5100_MICB3_DISCH_SHIFT 6 /* MICB3_DISCH */ | ||
| 1292 | #define WM5100_MICB3_DISCH_WIDTH 1 /* MICB3_DISCH */ | ||
| 1293 | #define WM5100_MICB3_RATE 0x0020 /* MICB3_RATE */ | ||
| 1294 | #define WM5100_MICB3_RATE_MASK 0x0020 /* MICB3_RATE */ | ||
| 1295 | #define WM5100_MICB3_RATE_SHIFT 5 /* MICB3_RATE */ | ||
| 1296 | #define WM5100_MICB3_RATE_WIDTH 1 /* MICB3_RATE */ | ||
| 1297 | #define WM5100_MICB3_LVL_MASK 0x001C /* MICB3_LVL - [4:2] */ | ||
| 1298 | #define WM5100_MICB3_LVL_SHIFT 2 /* MICB3_LVL - [4:2] */ | ||
| 1299 | #define WM5100_MICB3_LVL_WIDTH 3 /* MICB3_LVL - [4:2] */ | ||
| 1300 | #define WM5100_MICB3_BYPASS 0x0002 /* MICB3_BYPASS */ | ||
| 1301 | #define WM5100_MICB3_BYPASS_MASK 0x0002 /* MICB3_BYPASS */ | ||
| 1302 | #define WM5100_MICB3_BYPASS_SHIFT 1 /* MICB3_BYPASS */ | ||
| 1303 | #define WM5100_MICB3_BYPASS_WIDTH 1 /* MICB3_BYPASS */ | ||
| 1304 | #define WM5100_MICB3_ENA 0x0001 /* MICB3_ENA */ | ||
| 1305 | #define WM5100_MICB3_ENA_MASK 0x0001 /* MICB3_ENA */ | ||
| 1306 | #define WM5100_MICB3_ENA_SHIFT 0 /* MICB3_ENA */ | ||
| 1307 | #define WM5100_MICB3_ENA_WIDTH 1 /* MICB3_ENA */ | ||
| 1308 | |||
| 1309 | /* | ||
| 1310 | * R640 (0x280) - Accessory Detect Mode 1 | ||
| 1311 | */ | ||
| 1312 | #define WM5100_ACCDET_BIAS_SRC_MASK 0xC000 /* ACCDET_BIAS_SRC - [15:14] */ | ||
| 1313 | #define WM5100_ACCDET_BIAS_SRC_SHIFT 14 /* ACCDET_BIAS_SRC - [15:14] */ | ||
| 1314 | #define WM5100_ACCDET_BIAS_SRC_WIDTH 2 /* ACCDET_BIAS_SRC - [15:14] */ | ||
| 1315 | #define WM5100_ACCDET_SRC 0x2000 /* ACCDET_SRC */ | ||
| 1316 | #define WM5100_ACCDET_SRC_MASK 0x2000 /* ACCDET_SRC */ | ||
| 1317 | #define WM5100_ACCDET_SRC_SHIFT 13 /* ACCDET_SRC */ | ||
| 1318 | #define WM5100_ACCDET_SRC_WIDTH 1 /* ACCDET_SRC */ | ||
| 1319 | #define WM5100_ACCDET_MODE_MASK 0x0003 /* ACCDET_MODE - [1:0] */ | ||
| 1320 | #define WM5100_ACCDET_MODE_SHIFT 0 /* ACCDET_MODE - [1:0] */ | ||
| 1321 | #define WM5100_ACCDET_MODE_WIDTH 2 /* ACCDET_MODE - [1:0] */ | ||
| 1322 | |||
| 1323 | /* | ||
| 1324 | * R648 (0x288) - Headphone Detect 1 | ||
| 1325 | */ | ||
| 1326 | #define WM5100_HP_HOLDTIME_MASK 0x00E0 /* HP_HOLDTIME - [7:5] */ | ||
| 1327 | #define WM5100_HP_HOLDTIME_SHIFT 5 /* HP_HOLDTIME - [7:5] */ | ||
| 1328 | #define WM5100_HP_HOLDTIME_WIDTH 3 /* HP_HOLDTIME - [7:5] */ | ||
| 1329 | #define WM5100_HP_CLK_DIV_MASK 0x0018 /* HP_CLK_DIV - [4:3] */ | ||
| 1330 | #define WM5100_HP_CLK_DIV_SHIFT 3 /* HP_CLK_DIV - [4:3] */ | ||
| 1331 | #define WM5100_HP_CLK_DIV_WIDTH 2 /* HP_CLK_DIV - [4:3] */ | ||
| 1332 | #define WM5100_HP_STEP_SIZE 0x0002 /* HP_STEP_SIZE */ | ||
| 1333 | #define WM5100_HP_STEP_SIZE_MASK 0x0002 /* HP_STEP_SIZE */ | ||
| 1334 | #define WM5100_HP_STEP_SIZE_SHIFT 1 /* HP_STEP_SIZE */ | ||
| 1335 | #define WM5100_HP_STEP_SIZE_WIDTH 1 /* HP_STEP_SIZE */ | ||
| 1336 | #define WM5100_HP_POLL 0x0001 /* HP_POLL */ | ||
| 1337 | #define WM5100_HP_POLL_MASK 0x0001 /* HP_POLL */ | ||
| 1338 | #define WM5100_HP_POLL_SHIFT 0 /* HP_POLL */ | ||
| 1339 | #define WM5100_HP_POLL_WIDTH 1 /* HP_POLL */ | ||
| 1340 | |||
| 1341 | /* | ||
| 1342 | * R649 (0x289) - Headphone Detect 2 | ||
| 1343 | */ | ||
| 1344 | #define WM5100_HP_DONE 0x0080 /* HP_DONE */ | ||
| 1345 | #define WM5100_HP_DONE_MASK 0x0080 /* HP_DONE */ | ||
| 1346 | #define WM5100_HP_DONE_SHIFT 7 /* HP_DONE */ | ||
| 1347 | #define WM5100_HP_DONE_WIDTH 1 /* HP_DONE */ | ||
| 1348 | #define WM5100_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */ | ||
| 1349 | #define WM5100_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */ | ||
| 1350 | #define WM5100_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */ | ||
| 1351 | |||
| 1352 | /* | ||
| 1353 | * R656 (0x290) - Mic Detect 1 | ||
| 1354 | */ | ||
| 1355 | #define WM5100_ACCDET_BIAS_STARTTIME_MASK 0xF000 /* ACCDET_BIAS_STARTTIME - [15:12] */ | ||
| 1356 | #define WM5100_ACCDET_BIAS_STARTTIME_SHIFT 12 /* ACCDET_BIAS_STARTTIME - [15:12] */ | ||
| 1357 | #define WM5100_ACCDET_BIAS_STARTTIME_WIDTH 4 /* ACCDET_BIAS_STARTTIME - [15:12] */ | ||
| 1358 | #define WM5100_ACCDET_RATE_MASK 0x0F00 /* ACCDET_RATE - [11:8] */ | ||
| 1359 | #define WM5100_ACCDET_RATE_SHIFT 8 /* ACCDET_RATE - [11:8] */ | ||
| 1360 | #define WM5100_ACCDET_RATE_WIDTH 4 /* ACCDET_RATE - [11:8] */ | ||
| 1361 | #define WM5100_ACCDET_DBTIME 0x0002 /* ACCDET_DBTIME */ | ||
| 1362 | #define WM5100_ACCDET_DBTIME_MASK 0x0002 /* ACCDET_DBTIME */ | ||
| 1363 | #define WM5100_ACCDET_DBTIME_SHIFT 1 /* ACCDET_DBTIME */ | ||
| 1364 | #define WM5100_ACCDET_DBTIME_WIDTH 1 /* ACCDET_DBTIME */ | ||
| 1365 | #define WM5100_ACCDET_ENA 0x0001 /* ACCDET_ENA */ | ||
| 1366 | #define WM5100_ACCDET_ENA_MASK 0x0001 /* ACCDET_ENA */ | ||
| 1367 | #define WM5100_ACCDET_ENA_SHIFT 0 /* ACCDET_ENA */ | ||
| 1368 | #define WM5100_ACCDET_ENA_WIDTH 1 /* ACCDET_ENA */ | ||
| 1369 | |||
| 1370 | /* | ||
| 1371 | * R657 (0x291) - Mic Detect 2 | ||
| 1372 | */ | ||
| 1373 | #define WM5100_ACCDET_LVL_SEL_MASK 0x00FF /* ACCDET_LVL_SEL - [7:0] */ | ||
| 1374 | #define WM5100_ACCDET_LVL_SEL_SHIFT 0 /* ACCDET_LVL_SEL - [7:0] */ | ||
| 1375 | #define WM5100_ACCDET_LVL_SEL_WIDTH 8 /* ACCDET_LVL_SEL - [7:0] */ | ||
| 1376 | |||
| 1377 | /* | ||
| 1378 | * R658 (0x292) - Mic Detect 3 | ||
| 1379 | */ | ||
| 1380 | #define WM5100_ACCDET_LVL_MASK 0x07FC /* ACCDET_LVL - [10:2] */ | ||
| 1381 | #define WM5100_ACCDET_LVL_SHIFT 2 /* ACCDET_LVL - [10:2] */ | ||
| 1382 | #define WM5100_ACCDET_LVL_WIDTH 9 /* ACCDET_LVL - [10:2] */ | ||
| 1383 | #define WM5100_ACCDET_VALID 0x0002 /* ACCDET_VALID */ | ||
| 1384 | #define WM5100_ACCDET_VALID_MASK 0x0002 /* ACCDET_VALID */ | ||
| 1385 | #define WM5100_ACCDET_VALID_SHIFT 1 /* ACCDET_VALID */ | ||
| 1386 | #define WM5100_ACCDET_VALID_WIDTH 1 /* ACCDET_VALID */ | ||
| 1387 | #define WM5100_ACCDET_STS 0x0001 /* ACCDET_STS */ | ||
| 1388 | #define WM5100_ACCDET_STS_MASK 0x0001 /* ACCDET_STS */ | ||
| 1389 | #define WM5100_ACCDET_STS_SHIFT 0 /* ACCDET_STS */ | ||
| 1390 | #define WM5100_ACCDET_STS_WIDTH 1 /* ACCDET_STS */ | ||
| 1391 | |||
| 1392 | /* | ||
| 1393 | * R699 (0x2BB) - Misc Control | ||
| 1394 | */ | ||
| 1395 | #define WM5100_HPCOM_SRC 0x200 /* HPCOM_SRC */ | ||
| 1396 | #define WM5100_HPCOM_SRC_SHIFT 9 /* HPCOM_SRC */ | ||
| 1397 | |||
| 1398 | /* | ||
| 1399 | * R769 (0x301) - Input Enables | ||
| 1400 | */ | ||
| 1401 | #define WM5100_IN4L_ENA 0x0080 /* IN4L_ENA */ | ||
| 1402 | #define WM5100_IN4L_ENA_MASK 0x0080 /* IN4L_ENA */ | ||
| 1403 | #define WM5100_IN4L_ENA_SHIFT 7 /* IN4L_ENA */ | ||
| 1404 | #define WM5100_IN4L_ENA_WIDTH 1 /* IN4L_ENA */ | ||
| 1405 | #define WM5100_IN4R_ENA 0x0040 /* IN4R_ENA */ | ||
| 1406 | #define WM5100_IN4R_ENA_MASK 0x0040 /* IN4R_ENA */ | ||
| 1407 | #define WM5100_IN4R_ENA_SHIFT 6 /* IN4R_ENA */ | ||
| 1408 | #define WM5100_IN4R_ENA_WIDTH 1 /* IN4R_ENA */ | ||
| 1409 | #define WM5100_IN3L_ENA 0x0020 /* IN3L_ENA */ | ||
| 1410 | #define WM5100_IN3L_ENA_MASK 0x0020 /* IN3L_ENA */ | ||
| 1411 | #define WM5100_IN3L_ENA_SHIFT 5 /* IN3L_ENA */ | ||
| 1412 | #define WM5100_IN3L_ENA_WIDTH 1 /* IN3L_ENA */ | ||
| 1413 | #define WM5100_IN3R_ENA 0x0010 /* IN3R_ENA */ | ||
| 1414 | #define WM5100_IN3R_ENA_MASK 0x0010 /* IN3R_ENA */ | ||
| 1415 | #define WM5100_IN3R_ENA_SHIFT 4 /* IN3R_ENA */ | ||
| 1416 | #define WM5100_IN3R_ENA_WIDTH 1 /* IN3R_ENA */ | ||
| 1417 | #define WM5100_IN2L_ENA 0x0008 /* IN2L_ENA */ | ||
| 1418 | #define WM5100_IN2L_ENA_MASK 0x0008 /* IN2L_ENA */ | ||
| 1419 | #define WM5100_IN2L_ENA_SHIFT 3 /* IN2L_ENA */ | ||
| 1420 | #define WM5100_IN2L_ENA_WIDTH 1 /* IN2L_ENA */ | ||
| 1421 | #define WM5100_IN2R_ENA 0x0004 /* IN2R_ENA */ | ||
| 1422 | #define WM5100_IN2R_ENA_MASK 0x0004 /* IN2R_ENA */ | ||
| 1423 | #define WM5100_IN2R_ENA_SHIFT 2 /* IN2R_ENA */ | ||
| 1424 | #define WM5100_IN2R_ENA_WIDTH 1 /* IN2R_ENA */ | ||
| 1425 | #define WM5100_IN1L_ENA 0x0002 /* IN1L_ENA */ | ||
| 1426 | #define WM5100_IN1L_ENA_MASK 0x0002 /* IN1L_ENA */ | ||
| 1427 | #define WM5100_IN1L_ENA_SHIFT 1 /* IN1L_ENA */ | ||
| 1428 | #define WM5100_IN1L_ENA_WIDTH 1 /* IN1L_ENA */ | ||
| 1429 | #define WM5100_IN1R_ENA 0x0001 /* IN1R_ENA */ | ||
| 1430 | #define WM5100_IN1R_ENA_MASK 0x0001 /* IN1R_ENA */ | ||
| 1431 | #define WM5100_IN1R_ENA_SHIFT 0 /* IN1R_ENA */ | ||
| 1432 | #define WM5100_IN1R_ENA_WIDTH 1 /* IN1R_ENA */ | ||
| 1433 | |||
| 1434 | /* | ||
| 1435 | * R770 (0x302) - Input Enables Status | ||
| 1436 | */ | ||
| 1437 | #define WM5100_IN4L_ENA_STS 0x0080 /* IN4L_ENA_STS */ | ||
| 1438 | #define WM5100_IN4L_ENA_STS_MASK 0x0080 /* IN4L_ENA_STS */ | ||
| 1439 | #define WM5100_IN4L_ENA_STS_SHIFT 7 /* IN4L_ENA_STS */ | ||
| 1440 | #define WM5100_IN4L_ENA_STS_WIDTH 1 /* IN4L_ENA_STS */ | ||
| 1441 | #define WM5100_IN4R_ENA_STS 0x0040 /* IN4R_ENA_STS */ | ||
| 1442 | #define WM5100_IN4R_ENA_STS_MASK 0x0040 /* IN4R_ENA_STS */ | ||
| 1443 | #define WM5100_IN4R_ENA_STS_SHIFT 6 /* IN4R_ENA_STS */ | ||
| 1444 | #define WM5100_IN4R_ENA_STS_WIDTH 1 /* IN4R_ENA_STS */ | ||
| 1445 | #define WM5100_IN3L_ENA_STS 0x0020 /* IN3L_ENA_STS */ | ||
| 1446 | #define WM5100_IN3L_ENA_STS_MASK 0x0020 /* IN3L_ENA_STS */ | ||
| 1447 | #define WM5100_IN3L_ENA_STS_SHIFT 5 /* IN3L_ENA_STS */ | ||
| 1448 | #define WM5100_IN3L_ENA_STS_WIDTH 1 /* IN3L_ENA_STS */ | ||
| 1449 | #define WM5100_IN3R_ENA_STS 0x0010 /* IN3R_ENA_STS */ | ||
| 1450 | #define WM5100_IN3R_ENA_STS_MASK 0x0010 /* IN3R_ENA_STS */ | ||
| 1451 | #define WM5100_IN3R_ENA_STS_SHIFT 4 /* IN3R_ENA_STS */ | ||
| 1452 | #define WM5100_IN3R_ENA_STS_WIDTH 1 /* IN3R_ENA_STS */ | ||
| 1453 | #define WM5100_IN2L_ENA_STS 0x0008 /* IN2L_ENA_STS */ | ||
| 1454 | #define WM5100_IN2L_ENA_STS_MASK 0x0008 /* IN2L_ENA_STS */ | ||
| 1455 | #define WM5100_IN2L_ENA_STS_SHIFT 3 /* IN2L_ENA_STS */ | ||
| 1456 | #define WM5100_IN2L_ENA_STS_WIDTH 1 /* IN2L_ENA_STS */ | ||
| 1457 | #define WM5100_IN2R_ENA_STS 0x0004 /* IN2R_ENA_STS */ | ||
| 1458 | #define WM5100_IN2R_ENA_STS_MASK 0x0004 /* IN2R_ENA_STS */ | ||
| 1459 | #define WM5100_IN2R_ENA_STS_SHIFT 2 /* IN2R_ENA_STS */ | ||
| 1460 | #define WM5100_IN2R_ENA_STS_WIDTH 1 /* IN2R_ENA_STS */ | ||
| 1461 | #define WM5100_IN1L_ENA_STS 0x0002 /* IN1L_ENA_STS */ | ||
| 1462 | #define WM5100_IN1L_ENA_STS_MASK 0x0002 /* IN1L_ENA_STS */ | ||
| 1463 | #define WM5100_IN1L_ENA_STS_SHIFT 1 /* IN1L_ENA_STS */ | ||
| 1464 | #define WM5100_IN1L_ENA_STS_WIDTH 1 /* IN1L_ENA_STS */ | ||
| 1465 | #define WM5100_IN1R_ENA_STS 0x0001 /* IN1R_ENA_STS */ | ||
| 1466 | #define WM5100_IN1R_ENA_STS_MASK 0x0001 /* IN1R_ENA_STS */ | ||
| 1467 | #define WM5100_IN1R_ENA_STS_SHIFT 0 /* IN1R_ENA_STS */ | ||
| 1468 | #define WM5100_IN1R_ENA_STS_WIDTH 1 /* IN1R_ENA_STS */ | ||
| 1469 | |||
| 1470 | /* | ||
| 1471 | * R784 (0x310) - IN1L Control | ||
| 1472 | */ | ||
| 1473 | #define WM5100_IN_RATE_MASK 0xC000 /* IN_RATE - [15:14] */ | ||
| 1474 | #define WM5100_IN_RATE_SHIFT 14 /* IN_RATE - [15:14] */ | ||
| 1475 | #define WM5100_IN_RATE_WIDTH 2 /* IN_RATE - [15:14] */ | ||
| 1476 | #define WM5100_IN1_OSR 0x2000 /* IN1_OSR */ | ||
| 1477 | #define WM5100_IN1_OSR_MASK 0x2000 /* IN1_OSR */ | ||
| 1478 | #define WM5100_IN1_OSR_SHIFT 13 /* IN1_OSR */ | ||
| 1479 | #define WM5100_IN1_OSR_WIDTH 1 /* IN1_OSR */ | ||
| 1480 | #define WM5100_IN1_DMIC_SUP_MASK 0x1800 /* IN1_DMIC_SUP - [12:11] */ | ||
| 1481 | #define WM5100_IN1_DMIC_SUP_SHIFT 11 /* IN1_DMIC_SUP - [12:11] */ | ||
| 1482 | #define WM5100_IN1_DMIC_SUP_WIDTH 2 /* IN1_DMIC_SUP - [12:11] */ | ||
| 1483 | #define WM5100_IN1_MODE_MASK 0x0600 /* IN1_MODE - [10:9] */ | ||
| 1484 | #define WM5100_IN1_MODE_SHIFT 9 /* IN1_MODE - [10:9] */ | ||
| 1485 | #define WM5100_IN1_MODE_WIDTH 2 /* IN1_MODE - [10:9] */ | ||
| 1486 | #define WM5100_IN1L_PGA_VOL_MASK 0x00FE /* IN1L_PGA_VOL - [7:1] */ | ||
| 1487 | #define WM5100_IN1L_PGA_VOL_SHIFT 1 /* IN1L_PGA_VOL - [7:1] */ | ||
| 1488 | #define WM5100_IN1L_PGA_VOL_WIDTH 7 /* IN1L_PGA_VOL - [7:1] */ | ||
| 1489 | |||
| 1490 | /* | ||
| 1491 | * R785 (0x311) - IN1R Control | ||
| 1492 | */ | ||
| 1493 | #define WM5100_IN1R_PGA_VOL_MASK 0x00FE /* IN1R_PGA_VOL - [7:1] */ | ||
| 1494 | #define WM5100_IN1R_PGA_VOL_SHIFT 1 /* IN1R_PGA_VOL - [7:1] */ | ||
| 1495 | #define WM5100_IN1R_PGA_VOL_WIDTH 7 /* IN1R_PGA_VOL - [7:1] */ | ||
| 1496 | |||
| 1497 | /* | ||
| 1498 | * R786 (0x312) - IN2L Control | ||
| 1499 | */ | ||
| 1500 | #define WM5100_IN2_OSR 0x2000 /* IN2_OSR */ | ||
| 1501 | #define WM5100_IN2_OSR_MASK 0x2000 /* IN2_OSR */ | ||
| 1502 | #define WM5100_IN2_OSR_SHIFT 13 /* IN2_OSR */ | ||
| 1503 | #define WM5100_IN2_OSR_WIDTH 1 /* IN2_OSR */ | ||
| 1504 | #define WM5100_IN2_DMIC_SUP_MASK 0x1800 /* IN2_DMIC_SUP - [12:11] */ | ||
| 1505 | #define WM5100_IN2_DMIC_SUP_SHIFT 11 /* IN2_DMIC_SUP - [12:11] */ | ||
| 1506 | #define WM5100_IN2_DMIC_SUP_WIDTH 2 /* IN2_DMIC_SUP - [12:11] */ | ||
| 1507 | #define WM5100_IN2_MODE_MASK 0x0600 /* IN2_MODE - [10:9] */ | ||
| 1508 | #define WM5100_IN2_MODE_SHIFT 9 /* IN2_MODE - [10:9] */ | ||
| 1509 | #define WM5100_IN2_MODE_WIDTH 2 /* IN2_MODE - [10:9] */ | ||
| 1510 | #define WM5100_IN2L_PGA_VOL_MASK 0x00FE /* IN2L_PGA_VOL - [7:1] */ | ||
| 1511 | #define WM5100_IN2L_PGA_VOL_SHIFT 1 /* IN2L_PGA_VOL - [7:1] */ | ||
| 1512 | #define WM5100_IN2L_PGA_VOL_WIDTH 7 /* IN2L_PGA_VOL - [7:1] */ | ||
| 1513 | |||
| 1514 | /* | ||
| 1515 | * R787 (0x313) - IN2R Control | ||
| 1516 | */ | ||
| 1517 | #define WM5100_IN2R_PGA_VOL_MASK 0x00FE /* IN2R_PGA_VOL - [7:1] */ | ||
| 1518 | #define WM5100_IN2R_PGA_VOL_SHIFT 1 /* IN2R_PGA_VOL - [7:1] */ | ||
| 1519 | #define WM5100_IN2R_PGA_VOL_WIDTH 7 /* IN2R_PGA_VOL - [7:1] */ | ||
| 1520 | |||
| 1521 | /* | ||
| 1522 | * R788 (0x314) - IN3L Control | ||
| 1523 | */ | ||
| 1524 | #define WM5100_IN3_OSR 0x2000 /* IN3_OSR */ | ||
| 1525 | #define WM5100_IN3_OSR_MASK 0x2000 /* IN3_OSR */ | ||
| 1526 | #define WM5100_IN3_OSR_SHIFT 13 /* IN3_OSR */ | ||
| 1527 | #define WM5100_IN3_OSR_WIDTH 1 /* IN3_OSR */ | ||
| 1528 | #define WM5100_IN3_DMIC_SUP_MASK 0x1800 /* IN3_DMIC_SUP - [12:11] */ | ||
| 1529 | #define WM5100_IN3_DMIC_SUP_SHIFT 11 /* IN3_DMIC_SUP - [12:11] */ | ||
| 1530 | #define WM5100_IN3_DMIC_SUP_WIDTH 2 /* IN3_DMIC_SUP - [12:11] */ | ||
| 1531 | #define WM5100_IN3_MODE_MASK 0x0600 /* IN3_MODE - [10:9] */ | ||
| 1532 | #define WM5100_IN3_MODE_SHIFT 9 /* IN3_MODE - [10:9] */ | ||
| 1533 | #define WM5100_IN3_MODE_WIDTH 2 /* IN3_MODE - [10:9] */ | ||
| 1534 | #define WM5100_IN3L_PGA_VOL_MASK 0x00FE /* IN3L_PGA_VOL - [7:1] */ | ||
| 1535 | #define WM5100_IN3L_PGA_VOL_SHIFT 1 /* IN3L_PGA_VOL - [7:1] */ | ||
| 1536 | #define WM5100_IN3L_PGA_VOL_WIDTH 7 /* IN3L_PGA_VOL - [7:1] */ | ||
| 1537 | |||
| 1538 | /* | ||
| 1539 | * R789 (0x315) - IN3R Control | ||
| 1540 | */ | ||
| 1541 | #define WM5100_IN3R_PGA_VOL_MASK 0x00FE /* IN3R_PGA_VOL - [7:1] */ | ||
| 1542 | #define WM5100_IN3R_PGA_VOL_SHIFT 1 /* IN3R_PGA_VOL - [7:1] */ | ||
| 1543 | #define WM5100_IN3R_PGA_VOL_WIDTH 7 /* IN3R_PGA_VOL - [7:1] */ | ||
| 1544 | |||
| 1545 | /* | ||
| 1546 | * R790 (0x316) - IN4L Control | ||
| 1547 | */ | ||
| 1548 | #define WM5100_IN4_OSR 0x2000 /* IN4_OSR */ | ||
| 1549 | #define WM5100_IN4_OSR_MASK 0x2000 /* IN4_OSR */ | ||
| 1550 | #define WM5100_IN4_OSR_SHIFT 13 /* IN4_OSR */ | ||
| 1551 | #define WM5100_IN4_OSR_WIDTH 1 /* IN4_OSR */ | ||
| 1552 | #define WM5100_IN4_DMIC_SUP_MASK 0x1800 /* IN4_DMIC_SUP - [12:11] */ | ||
| 1553 | #define WM5100_IN4_DMIC_SUP_SHIFT 11 /* IN4_DMIC_SUP - [12:11] */ | ||
| 1554 | #define WM5100_IN4_DMIC_SUP_WIDTH 2 /* IN4_DMIC_SUP - [12:11] */ | ||
| 1555 | #define WM5100_IN4_MODE_MASK 0x0600 /* IN4_MODE - [10:9] */ | ||
| 1556 | #define WM5100_IN4_MODE_SHIFT 9 /* IN4_MODE - [10:9] */ | ||
| 1557 | #define WM5100_IN4_MODE_WIDTH 2 /* IN4_MODE - [10:9] */ | ||
| 1558 | #define WM5100_IN4L_PGA_VOL_MASK 0x00FE /* IN4L_PGA_VOL - [7:1] */ | ||
| 1559 | #define WM5100_IN4L_PGA_VOL_SHIFT 1 /* IN4L_PGA_VOL - [7:1] */ | ||
| 1560 | #define WM5100_IN4L_PGA_VOL_WIDTH 7 /* IN4L_PGA_VOL - [7:1] */ | ||
| 1561 | |||
| 1562 | /* | ||
| 1563 | * R791 (0x317) - IN4R Control | ||
| 1564 | */ | ||
| 1565 | #define WM5100_IN4R_PGA_VOL_MASK 0x00FE /* IN4R_PGA_VOL - [7:1] */ | ||
| 1566 | #define WM5100_IN4R_PGA_VOL_SHIFT 1 /* IN4R_PGA_VOL - [7:1] */ | ||
| 1567 | #define WM5100_IN4R_PGA_VOL_WIDTH 7 /* IN4R_PGA_VOL - [7:1] */ | ||
| 1568 | |||
| 1569 | /* | ||
| 1570 | * R792 (0x318) - RXANC_SRC | ||
| 1571 | */ | ||
| 1572 | #define WM5100_IN_RXANC_SEL_MASK 0x0007 /* IN_RXANC_SEL - [2:0] */ | ||
| 1573 | #define WM5100_IN_RXANC_SEL_SHIFT 0 /* IN_RXANC_SEL - [2:0] */ | ||
| 1574 | #define WM5100_IN_RXANC_SEL_WIDTH 3 /* IN_RXANC_SEL - [2:0] */ | ||
| 1575 | |||
| 1576 | /* | ||
| 1577 | * R793 (0x319) - Input Volume Ramp | ||
| 1578 | */ | ||
| 1579 | #define WM5100_IN_VD_RAMP_MASK 0x0070 /* IN_VD_RAMP - [6:4] */ | ||
| 1580 | #define WM5100_IN_VD_RAMP_SHIFT 4 /* IN_VD_RAMP - [6:4] */ | ||
| 1581 | #define WM5100_IN_VD_RAMP_WIDTH 3 /* IN_VD_RAMP - [6:4] */ | ||
| 1582 | #define WM5100_IN_VI_RAMP_MASK 0x0007 /* IN_VI_RAMP - [2:0] */ | ||
| 1583 | #define WM5100_IN_VI_RAMP_SHIFT 0 /* IN_VI_RAMP - [2:0] */ | ||
| 1584 | #define WM5100_IN_VI_RAMP_WIDTH 3 /* IN_VI_RAMP - [2:0] */ | ||
| 1585 | |||
| 1586 | /* | ||
| 1587 | * R800 (0x320) - ADC Digital Volume 1L | ||
| 1588 | */ | ||
| 1589 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1590 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1591 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1592 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1593 | #define WM5100_IN1L_MUTE 0x0100 /* IN1L_MUTE */ | ||
| 1594 | #define WM5100_IN1L_MUTE_MASK 0x0100 /* IN1L_MUTE */ | ||
| 1595 | #define WM5100_IN1L_MUTE_SHIFT 8 /* IN1L_MUTE */ | ||
| 1596 | #define WM5100_IN1L_MUTE_WIDTH 1 /* IN1L_MUTE */ | ||
| 1597 | #define WM5100_IN1L_VOL_MASK 0x00FF /* IN1L_VOL - [7:0] */ | ||
| 1598 | #define WM5100_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [7:0] */ | ||
| 1599 | #define WM5100_IN1L_VOL_WIDTH 8 /* IN1L_VOL - [7:0] */ | ||
| 1600 | |||
| 1601 | /* | ||
| 1602 | * R801 (0x321) - ADC Digital Volume 1R | ||
| 1603 | */ | ||
| 1604 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1605 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1606 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1607 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1608 | #define WM5100_IN1R_MUTE 0x0100 /* IN1R_MUTE */ | ||
| 1609 | #define WM5100_IN1R_MUTE_MASK 0x0100 /* IN1R_MUTE */ | ||
| 1610 | #define WM5100_IN1R_MUTE_SHIFT 8 /* IN1R_MUTE */ | ||
| 1611 | #define WM5100_IN1R_MUTE_WIDTH 1 /* IN1R_MUTE */ | ||
| 1612 | #define WM5100_IN1R_VOL_MASK 0x00FF /* IN1R_VOL - [7:0] */ | ||
| 1613 | #define WM5100_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [7:0] */ | ||
| 1614 | #define WM5100_IN1R_VOL_WIDTH 8 /* IN1R_VOL - [7:0] */ | ||
| 1615 | |||
| 1616 | /* | ||
| 1617 | * R802 (0x322) - ADC Digital Volume 2L | ||
| 1618 | */ | ||
| 1619 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1620 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1621 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1622 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1623 | #define WM5100_IN2L_MUTE 0x0100 /* IN2L_MUTE */ | ||
| 1624 | #define WM5100_IN2L_MUTE_MASK 0x0100 /* IN2L_MUTE */ | ||
| 1625 | #define WM5100_IN2L_MUTE_SHIFT 8 /* IN2L_MUTE */ | ||
| 1626 | #define WM5100_IN2L_MUTE_WIDTH 1 /* IN2L_MUTE */ | ||
| 1627 | #define WM5100_IN2L_VOL_MASK 0x00FF /* IN2L_VOL - [7:0] */ | ||
| 1628 | #define WM5100_IN2L_VOL_SHIFT 0 /* IN2L_VOL - [7:0] */ | ||
| 1629 | #define WM5100_IN2L_VOL_WIDTH 8 /* IN2L_VOL - [7:0] */ | ||
| 1630 | |||
| 1631 | /* | ||
| 1632 | * R803 (0x323) - ADC Digital Volume 2R | ||
| 1633 | */ | ||
| 1634 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1635 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1636 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1637 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1638 | #define WM5100_IN2R_MUTE 0x0100 /* IN2R_MUTE */ | ||
| 1639 | #define WM5100_IN2R_MUTE_MASK 0x0100 /* IN2R_MUTE */ | ||
| 1640 | #define WM5100_IN2R_MUTE_SHIFT 8 /* IN2R_MUTE */ | ||
| 1641 | #define WM5100_IN2R_MUTE_WIDTH 1 /* IN2R_MUTE */ | ||
| 1642 | #define WM5100_IN2R_VOL_MASK 0x00FF /* IN2R_VOL - [7:0] */ | ||
| 1643 | #define WM5100_IN2R_VOL_SHIFT 0 /* IN2R_VOL - [7:0] */ | ||
| 1644 | #define WM5100_IN2R_VOL_WIDTH 8 /* IN2R_VOL - [7:0] */ | ||
| 1645 | |||
| 1646 | /* | ||
| 1647 | * R804 (0x324) - ADC Digital Volume 3L | ||
| 1648 | */ | ||
| 1649 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1650 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1651 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1652 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1653 | #define WM5100_IN3L_MUTE 0x0100 /* IN3L_MUTE */ | ||
| 1654 | #define WM5100_IN3L_MUTE_MASK 0x0100 /* IN3L_MUTE */ | ||
| 1655 | #define WM5100_IN3L_MUTE_SHIFT 8 /* IN3L_MUTE */ | ||
| 1656 | #define WM5100_IN3L_MUTE_WIDTH 1 /* IN3L_MUTE */ | ||
| 1657 | #define WM5100_IN3L_VOL_MASK 0x00FF /* IN3L_VOL - [7:0] */ | ||
| 1658 | #define WM5100_IN3L_VOL_SHIFT 0 /* IN3L_VOL - [7:0] */ | ||
| 1659 | #define WM5100_IN3L_VOL_WIDTH 8 /* IN3L_VOL - [7:0] */ | ||
| 1660 | |||
| 1661 | /* | ||
| 1662 | * R805 (0x325) - ADC Digital Volume 3R | ||
| 1663 | */ | ||
| 1664 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1665 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1666 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1667 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1668 | #define WM5100_IN3R_MUTE 0x0100 /* IN3R_MUTE */ | ||
| 1669 | #define WM5100_IN3R_MUTE_MASK 0x0100 /* IN3R_MUTE */ | ||
| 1670 | #define WM5100_IN3R_MUTE_SHIFT 8 /* IN3R_MUTE */ | ||
| 1671 | #define WM5100_IN3R_MUTE_WIDTH 1 /* IN3R_MUTE */ | ||
| 1672 | #define WM5100_IN3R_VOL_MASK 0x00FF /* IN3R_VOL - [7:0] */ | ||
| 1673 | #define WM5100_IN3R_VOL_SHIFT 0 /* IN3R_VOL - [7:0] */ | ||
| 1674 | #define WM5100_IN3R_VOL_WIDTH 8 /* IN3R_VOL - [7:0] */ | ||
| 1675 | |||
| 1676 | /* | ||
| 1677 | * R806 (0x326) - ADC Digital Volume 4L | ||
| 1678 | */ | ||
| 1679 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1680 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1681 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1682 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1683 | #define WM5100_IN4L_MUTE 0x0100 /* IN4L_MUTE */ | ||
| 1684 | #define WM5100_IN4L_MUTE_MASK 0x0100 /* IN4L_MUTE */ | ||
| 1685 | #define WM5100_IN4L_MUTE_SHIFT 8 /* IN4L_MUTE */ | ||
| 1686 | #define WM5100_IN4L_MUTE_WIDTH 1 /* IN4L_MUTE */ | ||
| 1687 | #define WM5100_IN4L_VOL_MASK 0x00FF /* IN4L_VOL - [7:0] */ | ||
| 1688 | #define WM5100_IN4L_VOL_SHIFT 0 /* IN4L_VOL - [7:0] */ | ||
| 1689 | #define WM5100_IN4L_VOL_WIDTH 8 /* IN4L_VOL - [7:0] */ | ||
| 1690 | |||
| 1691 | /* | ||
| 1692 | * R807 (0x327) - ADC Digital Volume 4R | ||
| 1693 | */ | ||
| 1694 | #define WM5100_IN_VU 0x0200 /* IN_VU */ | ||
| 1695 | #define WM5100_IN_VU_MASK 0x0200 /* IN_VU */ | ||
| 1696 | #define WM5100_IN_VU_SHIFT 9 /* IN_VU */ | ||
| 1697 | #define WM5100_IN_VU_WIDTH 1 /* IN_VU */ | ||
| 1698 | #define WM5100_IN4R_MUTE 0x0100 /* IN4R_MUTE */ | ||
| 1699 | #define WM5100_IN4R_MUTE_MASK 0x0100 /* IN4R_MUTE */ | ||
| 1700 | #define WM5100_IN4R_MUTE_SHIFT 8 /* IN4R_MUTE */ | ||
| 1701 | #define WM5100_IN4R_MUTE_WIDTH 1 /* IN4R_MUTE */ | ||
| 1702 | #define WM5100_IN4R_VOL_MASK 0x00FF /* IN4R_VOL - [7:0] */ | ||
| 1703 | #define WM5100_IN4R_VOL_SHIFT 0 /* IN4R_VOL - [7:0] */ | ||
| 1704 | #define WM5100_IN4R_VOL_WIDTH 8 /* IN4R_VOL - [7:0] */ | ||
| 1705 | |||
| 1706 | /* | ||
| 1707 | * R1025 (0x401) - Output Enables 2 | ||
| 1708 | */ | ||
| 1709 | #define WM5100_OUT6L_ENA 0x0800 /* OUT6L_ENA */ | ||
| 1710 | #define WM5100_OUT6L_ENA_MASK 0x0800 /* OUT6L_ENA */ | ||
| 1711 | #define WM5100_OUT6L_ENA_SHIFT 11 /* OUT6L_ENA */ | ||
| 1712 | #define WM5100_OUT6L_ENA_WIDTH 1 /* OUT6L_ENA */ | ||
| 1713 | #define WM5100_OUT6R_ENA 0x0400 /* OUT6R_ENA */ | ||
| 1714 | #define WM5100_OUT6R_ENA_MASK 0x0400 /* OUT6R_ENA */ | ||
| 1715 | #define WM5100_OUT6R_ENA_SHIFT 10 /* OUT6R_ENA */ | ||
| 1716 | #define WM5100_OUT6R_ENA_WIDTH 1 /* OUT6R_ENA */ | ||
| 1717 | #define WM5100_OUT5L_ENA 0x0200 /* OUT5L_ENA */ | ||
| 1718 | #define WM5100_OUT5L_ENA_MASK 0x0200 /* OUT5L_ENA */ | ||
| 1719 | #define WM5100_OUT5L_ENA_SHIFT 9 /* OUT5L_ENA */ | ||
| 1720 | #define WM5100_OUT5L_ENA_WIDTH 1 /* OUT5L_ENA */ | ||
| 1721 | #define WM5100_OUT5R_ENA 0x0100 /* OUT5R_ENA */ | ||
| 1722 | #define WM5100_OUT5R_ENA_MASK 0x0100 /* OUT5R_ENA */ | ||
| 1723 | #define WM5100_OUT5R_ENA_SHIFT 8 /* OUT5R_ENA */ | ||
| 1724 | #define WM5100_OUT5R_ENA_WIDTH 1 /* OUT5R_ENA */ | ||
| 1725 | #define WM5100_OUT4L_ENA 0x0080 /* OUT4L_ENA */ | ||
| 1726 | #define WM5100_OUT4L_ENA_MASK 0x0080 /* OUT4L_ENA */ | ||
| 1727 | #define WM5100_OUT4L_ENA_SHIFT 7 /* OUT4L_ENA */ | ||
| 1728 | #define WM5100_OUT4L_ENA_WIDTH 1 /* OUT4L_ENA */ | ||
| 1729 | #define WM5100_OUT4R_ENA 0x0040 /* OUT4R_ENA */ | ||
| 1730 | #define WM5100_OUT4R_ENA_MASK 0x0040 /* OUT4R_ENA */ | ||
| 1731 | #define WM5100_OUT4R_ENA_SHIFT 6 /* OUT4R_ENA */ | ||
| 1732 | #define WM5100_OUT4R_ENA_WIDTH 1 /* OUT4R_ENA */ | ||
| 1733 | |||
| 1734 | /* | ||
| 1735 | * R1026 (0x402) - Output Status 1 | ||
| 1736 | */ | ||
| 1737 | #define WM5100_OUT3L_ENA_STS 0x0020 /* OUT3L_ENA_STS */ | ||
| 1738 | #define WM5100_OUT3L_ENA_STS_MASK 0x0020 /* OUT3L_ENA_STS */ | ||
| 1739 | #define WM5100_OUT3L_ENA_STS_SHIFT 5 /* OUT3L_ENA_STS */ | ||
| 1740 | #define WM5100_OUT3L_ENA_STS_WIDTH 1 /* OUT3L_ENA_STS */ | ||
| 1741 | #define WM5100_OUT3R_ENA_STS 0x0010 /* OUT3R_ENA_STS */ | ||
| 1742 | #define WM5100_OUT3R_ENA_STS_MASK 0x0010 /* OUT3R_ENA_STS */ | ||
| 1743 | #define WM5100_OUT3R_ENA_STS_SHIFT 4 /* OUT3R_ENA_STS */ | ||
| 1744 | #define WM5100_OUT3R_ENA_STS_WIDTH 1 /* OUT3R_ENA_STS */ | ||
| 1745 | #define WM5100_OUT2L_ENA_STS 0x0008 /* OUT2L_ENA_STS */ | ||
| 1746 | #define WM5100_OUT2L_ENA_STS_MASK 0x0008 /* OUT2L_ENA_STS */ | ||
| 1747 | #define WM5100_OUT2L_ENA_STS_SHIFT 3 /* OUT2L_ENA_STS */ | ||
| 1748 | #define WM5100_OUT2L_ENA_STS_WIDTH 1 /* OUT2L_ENA_STS */ | ||
| 1749 | #define WM5100_OUT2R_ENA_STS 0x0004 /* OUT2R_ENA_STS */ | ||
| 1750 | #define WM5100_OUT2R_ENA_STS_MASK 0x0004 /* OUT2R_ENA_STS */ | ||
| 1751 | #define WM5100_OUT2R_ENA_STS_SHIFT 2 /* OUT2R_ENA_STS */ | ||
| 1752 | #define WM5100_OUT2R_ENA_STS_WIDTH 1 /* OUT2R_ENA_STS */ | ||
| 1753 | #define WM5100_OUT1L_ENA_STS 0x0002 /* OUT1L_ENA_STS */ | ||
| 1754 | #define WM5100_OUT1L_ENA_STS_MASK 0x0002 /* OUT1L_ENA_STS */ | ||
| 1755 | #define WM5100_OUT1L_ENA_STS_SHIFT 1 /* OUT1L_ENA_STS */ | ||
| 1756 | #define WM5100_OUT1L_ENA_STS_WIDTH 1 /* OUT1L_ENA_STS */ | ||
| 1757 | #define WM5100_OUT1R_ENA_STS 0x0001 /* OUT1R_ENA_STS */ | ||
| 1758 | #define WM5100_OUT1R_ENA_STS_MASK 0x0001 /* OUT1R_ENA_STS */ | ||
| 1759 | #define WM5100_OUT1R_ENA_STS_SHIFT 0 /* OUT1R_ENA_STS */ | ||
| 1760 | #define WM5100_OUT1R_ENA_STS_WIDTH 1 /* OUT1R_ENA_STS */ | ||
| 1761 | |||
| 1762 | /* | ||
| 1763 | * R1027 (0x403) - Output Status 2 | ||
| 1764 | */ | ||
| 1765 | #define WM5100_OUT6L_ENA_STS 0x0800 /* OUT6L_ENA_STS */ | ||
| 1766 | #define WM5100_OUT6L_ENA_STS_MASK 0x0800 /* OUT6L_ENA_STS */ | ||
| 1767 | #define WM5100_OUT6L_ENA_STS_SHIFT 11 /* OUT6L_ENA_STS */ | ||
| 1768 | #define WM5100_OUT6L_ENA_STS_WIDTH 1 /* OUT6L_ENA_STS */ | ||
| 1769 | #define WM5100_OUT6R_ENA_STS 0x0400 /* OUT6R_ENA_STS */ | ||
| 1770 | #define WM5100_OUT6R_ENA_STS_MASK 0x0400 /* OUT6R_ENA_STS */ | ||
| 1771 | #define WM5100_OUT6R_ENA_STS_SHIFT 10 /* OUT6R_ENA_STS */ | ||
| 1772 | #define WM5100_OUT6R_ENA_STS_WIDTH 1 /* OUT6R_ENA_STS */ | ||
| 1773 | #define WM5100_OUT5L_ENA_STS 0x0200 /* OUT5L_ENA_STS */ | ||
| 1774 | #define WM5100_OUT5L_ENA_STS_MASK 0x0200 /* OUT5L_ENA_STS */ | ||
| 1775 | #define WM5100_OUT5L_ENA_STS_SHIFT 9 /* OUT5L_ENA_STS */ | ||
| 1776 | #define WM5100_OUT5L_ENA_STS_WIDTH 1 /* OUT5L_ENA_STS */ | ||
| 1777 | #define WM5100_OUT5R_ENA_STS 0x0100 /* OUT5R_ENA_STS */ | ||
| 1778 | #define WM5100_OUT5R_ENA_STS_MASK 0x0100 /* OUT5R_ENA_STS */ | ||
| 1779 | #define WM5100_OUT5R_ENA_STS_SHIFT 8 /* OUT5R_ENA_STS */ | ||
| 1780 | #define WM5100_OUT5R_ENA_STS_WIDTH 1 /* OUT5R_ENA_STS */ | ||
| 1781 | #define WM5100_OUT4L_ENA_STS 0x0080 /* OUT4L_ENA_STS */ | ||
| 1782 | #define WM5100_OUT4L_ENA_STS_MASK 0x0080 /* OUT4L_ENA_STS */ | ||
| 1783 | #define WM5100_OUT4L_ENA_STS_SHIFT 7 /* OUT4L_ENA_STS */ | ||
| 1784 | #define WM5100_OUT4L_ENA_STS_WIDTH 1 /* OUT4L_ENA_STS */ | ||
| 1785 | #define WM5100_OUT4R_ENA_STS 0x0040 /* OUT4R_ENA_STS */ | ||
| 1786 | #define WM5100_OUT4R_ENA_STS_MASK 0x0040 /* OUT4R_ENA_STS */ | ||
| 1787 | #define WM5100_OUT4R_ENA_STS_SHIFT 6 /* OUT4R_ENA_STS */ | ||
| 1788 | #define WM5100_OUT4R_ENA_STS_WIDTH 1 /* OUT4R_ENA_STS */ | ||
| 1789 | |||
| 1790 | /* | ||
| 1791 | * R1032 (0x408) - Channel Enables 1 | ||
| 1792 | */ | ||
| 1793 | #define WM5100_HP3L_ENA 0x0020 /* HP3L_ENA */ | ||
| 1794 | #define WM5100_HP3L_ENA_MASK 0x0020 /* HP3L_ENA */ | ||
| 1795 | #define WM5100_HP3L_ENA_SHIFT 5 /* HP3L_ENA */ | ||
| 1796 | #define WM5100_HP3L_ENA_WIDTH 1 /* HP3L_ENA */ | ||
| 1797 | #define WM5100_HP3R_ENA 0x0010 /* HP3R_ENA */ | ||
| 1798 | #define WM5100_HP3R_ENA_MASK 0x0010 /* HP3R_ENA */ | ||
| 1799 | #define WM5100_HP3R_ENA_SHIFT 4 /* HP3R_ENA */ | ||
| 1800 | #define WM5100_HP3R_ENA_WIDTH 1 /* HP3R_ENA */ | ||
| 1801 | #define WM5100_HP2L_ENA 0x0008 /* HP2L_ENA */ | ||
| 1802 | #define WM5100_HP2L_ENA_MASK 0x0008 /* HP2L_ENA */ | ||
| 1803 | #define WM5100_HP2L_ENA_SHIFT 3 /* HP2L_ENA */ | ||
| 1804 | #define WM5100_HP2L_ENA_WIDTH 1 /* HP2L_ENA */ | ||
| 1805 | #define WM5100_HP2R_ENA 0x0004 /* HP2R_ENA */ | ||
| 1806 | #define WM5100_HP2R_ENA_MASK 0x0004 /* HP2R_ENA */ | ||
| 1807 | #define WM5100_HP2R_ENA_SHIFT 2 /* HP2R_ENA */ | ||
| 1808 | #define WM5100_HP2R_ENA_WIDTH 1 /* HP2R_ENA */ | ||
| 1809 | #define WM5100_HP1L_ENA 0x0002 /* HP1L_ENA */ | ||
| 1810 | #define WM5100_HP1L_ENA_MASK 0x0002 /* HP1L_ENA */ | ||
| 1811 | #define WM5100_HP1L_ENA_SHIFT 1 /* HP1L_ENA */ | ||
| 1812 | #define WM5100_HP1L_ENA_WIDTH 1 /* HP1L_ENA */ | ||
| 1813 | #define WM5100_HP1R_ENA 0x0001 /* HP1R_ENA */ | ||
| 1814 | #define WM5100_HP1R_ENA_MASK 0x0001 /* HP1R_ENA */ | ||
| 1815 | #define WM5100_HP1R_ENA_SHIFT 0 /* HP1R_ENA */ | ||
| 1816 | #define WM5100_HP1R_ENA_WIDTH 1 /* HP1R_ENA */ | ||
| 1817 | |||
| 1818 | /* | ||
| 1819 | * R1040 (0x410) - Out Volume 1L | ||
| 1820 | */ | ||
| 1821 | #define WM5100_OUT_RATE_MASK 0xC000 /* OUT_RATE - [15:14] */ | ||
| 1822 | #define WM5100_OUT_RATE_SHIFT 14 /* OUT_RATE - [15:14] */ | ||
| 1823 | #define WM5100_OUT_RATE_WIDTH 2 /* OUT_RATE - [15:14] */ | ||
| 1824 | #define WM5100_OUT1_OSR 0x2000 /* OUT1_OSR */ | ||
| 1825 | #define WM5100_OUT1_OSR_MASK 0x2000 /* OUT1_OSR */ | ||
| 1826 | #define WM5100_OUT1_OSR_SHIFT 13 /* OUT1_OSR */ | ||
| 1827 | #define WM5100_OUT1_OSR_WIDTH 1 /* OUT1_OSR */ | ||
| 1828 | #define WM5100_OUT1_MONO 0x1000 /* OUT1_MONO */ | ||
| 1829 | #define WM5100_OUT1_MONO_MASK 0x1000 /* OUT1_MONO */ | ||
| 1830 | #define WM5100_OUT1_MONO_SHIFT 12 /* OUT1_MONO */ | ||
| 1831 | #define WM5100_OUT1_MONO_WIDTH 1 /* OUT1_MONO */ | ||
| 1832 | #define WM5100_OUT1L_ANC_SRC 0x0800 /* OUT1L_ANC_SRC */ | ||
| 1833 | #define WM5100_OUT1L_ANC_SRC_MASK 0x0800 /* OUT1L_ANC_SRC */ | ||
| 1834 | #define WM5100_OUT1L_ANC_SRC_SHIFT 11 /* OUT1L_ANC_SRC */ | ||
| 1835 | #define WM5100_OUT1L_ANC_SRC_WIDTH 1 /* OUT1L_ANC_SRC */ | ||
| 1836 | #define WM5100_OUT1L_PGA_VOL_MASK 0x00FE /* OUT1L_PGA_VOL - [7:1] */ | ||
| 1837 | #define WM5100_OUT1L_PGA_VOL_SHIFT 1 /* OUT1L_PGA_VOL - [7:1] */ | ||
| 1838 | #define WM5100_OUT1L_PGA_VOL_WIDTH 7 /* OUT1L_PGA_VOL - [7:1] */ | ||
| 1839 | |||
| 1840 | /* | ||
| 1841 | * R1041 (0x411) - Out Volume 1R | ||
| 1842 | */ | ||
| 1843 | #define WM5100_OUT1R_ANC_SRC 0x0800 /* OUT1R_ANC_SRC */ | ||
| 1844 | #define WM5100_OUT1R_ANC_SRC_MASK 0x0800 /* OUT1R_ANC_SRC */ | ||
| 1845 | #define WM5100_OUT1R_ANC_SRC_SHIFT 11 /* OUT1R_ANC_SRC */ | ||
| 1846 | #define WM5100_OUT1R_ANC_SRC_WIDTH 1 /* OUT1R_ANC_SRC */ | ||
| 1847 | #define WM5100_OUT1R_PGA_VOL_MASK 0x00FE /* OUT1R_PGA_VOL - [7:1] */ | ||
| 1848 | #define WM5100_OUT1R_PGA_VOL_SHIFT 1 /* OUT1R_PGA_VOL - [7:1] */ | ||
| 1849 | #define WM5100_OUT1R_PGA_VOL_WIDTH 7 /* OUT1R_PGA_VOL - [7:1] */ | ||
| 1850 | |||
| 1851 | /* | ||
| 1852 | * R1042 (0x412) - DAC Volume Limit 1L | ||
| 1853 | */ | ||
| 1854 | #define WM5100_OUT1L_VOL_LIM_MASK 0x00FF /* OUT1L_VOL_LIM - [7:0] */ | ||
| 1855 | #define WM5100_OUT1L_VOL_LIM_SHIFT 0 /* OUT1L_VOL_LIM - [7:0] */ | ||
| 1856 | #define WM5100_OUT1L_VOL_LIM_WIDTH 8 /* OUT1L_VOL_LIM - [7:0] */ | ||
| 1857 | |||
| 1858 | /* | ||
| 1859 | * R1043 (0x413) - DAC Volume Limit 1R | ||
| 1860 | */ | ||
| 1861 | #define WM5100_OUT1R_VOL_LIM_MASK 0x00FF /* OUT1R_VOL_LIM - [7:0] */ | ||
| 1862 | #define WM5100_OUT1R_VOL_LIM_SHIFT 0 /* OUT1R_VOL_LIM - [7:0] */ | ||
| 1863 | #define WM5100_OUT1R_VOL_LIM_WIDTH 8 /* OUT1R_VOL_LIM - [7:0] */ | ||
| 1864 | |||
| 1865 | /* | ||
| 1866 | * R1044 (0x414) - Out Volume 2L | ||
| 1867 | */ | ||
| 1868 | #define WM5100_OUT2_OSR 0x2000 /* OUT2_OSR */ | ||
| 1869 | #define WM5100_OUT2_OSR_MASK 0x2000 /* OUT2_OSR */ | ||
| 1870 | #define WM5100_OUT2_OSR_SHIFT 13 /* OUT2_OSR */ | ||
| 1871 | #define WM5100_OUT2_OSR_WIDTH 1 /* OUT2_OSR */ | ||
| 1872 | #define WM5100_OUT2_MONO 0x1000 /* OUT2_MONO */ | ||
| 1873 | #define WM5100_OUT2_MONO_MASK 0x1000 /* OUT2_MONO */ | ||
| 1874 | #define WM5100_OUT2_MONO_SHIFT 12 /* OUT2_MONO */ | ||
| 1875 | #define WM5100_OUT2_MONO_WIDTH 1 /* OUT2_MONO */ | ||
| 1876 | #define WM5100_OUT2L_ANC_SRC 0x0800 /* OUT2L_ANC_SRC */ | ||
| 1877 | #define WM5100_OUT2L_ANC_SRC_MASK 0x0800 /* OUT2L_ANC_SRC */ | ||
| 1878 | #define WM5100_OUT2L_ANC_SRC_SHIFT 11 /* OUT2L_ANC_SRC */ | ||
| 1879 | #define WM5100_OUT2L_ANC_SRC_WIDTH 1 /* OUT2L_ANC_SRC */ | ||
| 1880 | #define WM5100_OUT2L_PGA_VOL_MASK 0x00FE /* OUT2L_PGA_VOL - [7:1] */ | ||
| 1881 | #define WM5100_OUT2L_PGA_VOL_SHIFT 1 /* OUT2L_PGA_VOL - [7:1] */ | ||
| 1882 | #define WM5100_OUT2L_PGA_VOL_WIDTH 7 /* OUT2L_PGA_VOL - [7:1] */ | ||
| 1883 | |||
| 1884 | /* | ||
| 1885 | * R1045 (0x415) - Out Volume 2R | ||
| 1886 | */ | ||
| 1887 | #define WM5100_OUT2R_ANC_SRC 0x0800 /* OUT2R_ANC_SRC */ | ||
| 1888 | #define WM5100_OUT2R_ANC_SRC_MASK 0x0800 /* OUT2R_ANC_SRC */ | ||
| 1889 | #define WM5100_OUT2R_ANC_SRC_SHIFT 11 /* OUT2R_ANC_SRC */ | ||
| 1890 | #define WM5100_OUT2R_ANC_SRC_WIDTH 1 /* OUT2R_ANC_SRC */ | ||
| 1891 | #define WM5100_OUT2R_PGA_VOL_MASK 0x00FE /* OUT2R_PGA_VOL - [7:1] */ | ||
| 1892 | #define WM5100_OUT2R_PGA_VOL_SHIFT 1 /* OUT2R_PGA_VOL - [7:1] */ | ||
| 1893 | #define WM5100_OUT2R_PGA_VOL_WIDTH 7 /* OUT2R_PGA_VOL - [7:1] */ | ||
| 1894 | |||
| 1895 | /* | ||
| 1896 | * R1046 (0x416) - DAC Volume Limit 2L | ||
| 1897 | */ | ||
| 1898 | #define WM5100_OUT2L_VOL_LIM_MASK 0x00FF /* OUT2L_VOL_LIM - [7:0] */ | ||
| 1899 | #define WM5100_OUT2L_VOL_LIM_SHIFT 0 /* OUT2L_VOL_LIM - [7:0] */ | ||
| 1900 | #define WM5100_OUT2L_VOL_LIM_WIDTH 8 /* OUT2L_VOL_LIM - [7:0] */ | ||
| 1901 | |||
| 1902 | /* | ||
| 1903 | * R1047 (0x417) - DAC Volume Limit 2R | ||
| 1904 | */ | ||
| 1905 | #define WM5100_OUT2R_VOL_LIM_MASK 0x00FF /* OUT2R_VOL_LIM - [7:0] */ | ||
| 1906 | #define WM5100_OUT2R_VOL_LIM_SHIFT 0 /* OUT2R_VOL_LIM - [7:0] */ | ||
| 1907 | #define WM5100_OUT2R_VOL_LIM_WIDTH 8 /* OUT2R_VOL_LIM - [7:0] */ | ||
| 1908 | |||
| 1909 | /* | ||
| 1910 | * R1048 (0x418) - Out Volume 3L | ||
| 1911 | */ | ||
| 1912 | #define WM5100_OUT3_OSR 0x2000 /* OUT3_OSR */ | ||
| 1913 | #define WM5100_OUT3_OSR_MASK 0x2000 /* OUT3_OSR */ | ||
| 1914 | #define WM5100_OUT3_OSR_SHIFT 13 /* OUT3_OSR */ | ||
| 1915 | #define WM5100_OUT3_OSR_WIDTH 1 /* OUT3_OSR */ | ||
| 1916 | #define WM5100_OUT3_MONO 0x1000 /* OUT3_MONO */ | ||
| 1917 | #define WM5100_OUT3_MONO_MASK 0x1000 /* OUT3_MONO */ | ||
| 1918 | #define WM5100_OUT3_MONO_SHIFT 12 /* OUT3_MONO */ | ||
| 1919 | #define WM5100_OUT3_MONO_WIDTH 1 /* OUT3_MONO */ | ||
| 1920 | #define WM5100_OUT3L_ANC_SRC 0x0800 /* OUT3L_ANC_SRC */ | ||
| 1921 | #define WM5100_OUT3L_ANC_SRC_MASK 0x0800 /* OUT3L_ANC_SRC */ | ||
| 1922 | #define WM5100_OUT3L_ANC_SRC_SHIFT 11 /* OUT3L_ANC_SRC */ | ||
| 1923 | #define WM5100_OUT3L_ANC_SRC_WIDTH 1 /* OUT3L_ANC_SRC */ | ||
| 1924 | #define WM5100_OUT3L_PGA_VOL_MASK 0x00FE /* OUT3L_PGA_VOL - [7:1] */ | ||
| 1925 | #define WM5100_OUT3L_PGA_VOL_SHIFT 1 /* OUT3L_PGA_VOL - [7:1] */ | ||
| 1926 | #define WM5100_OUT3L_PGA_VOL_WIDTH 7 /* OUT3L_PGA_VOL - [7:1] */ | ||
| 1927 | |||
| 1928 | /* | ||
| 1929 | * R1049 (0x419) - Out Volume 3R | ||
| 1930 | */ | ||
| 1931 | #define WM5100_OUT3R_ANC_SRC 0x0800 /* OUT3R_ANC_SRC */ | ||
| 1932 | #define WM5100_OUT3R_ANC_SRC_MASK 0x0800 /* OUT3R_ANC_SRC */ | ||
| 1933 | #define WM5100_OUT3R_ANC_SRC_SHIFT 11 /* OUT3R_ANC_SRC */ | ||
| 1934 | #define WM5100_OUT3R_ANC_SRC_WIDTH 1 /* OUT3R_ANC_SRC */ | ||
| 1935 | #define WM5100_OUT3R_PGA_VOL_MASK 0x00FE /* OUT3R_PGA_VOL - [7:1] */ | ||
| 1936 | #define WM5100_OUT3R_PGA_VOL_SHIFT 1 /* OUT3R_PGA_VOL - [7:1] */ | ||
| 1937 | #define WM5100_OUT3R_PGA_VOL_WIDTH 7 /* OUT3R_PGA_VOL - [7:1] */ | ||
| 1938 | |||
| 1939 | /* | ||
| 1940 | * R1050 (0x41A) - DAC Volume Limit 3L | ||
| 1941 | */ | ||
| 1942 | #define WM5100_OUT3L_VOL_LIM_MASK 0x00FF /* OUT3L_VOL_LIM - [7:0] */ | ||
| 1943 | #define WM5100_OUT3L_VOL_LIM_SHIFT 0 /* OUT3L_VOL_LIM - [7:0] */ | ||
| 1944 | #define WM5100_OUT3L_VOL_LIM_WIDTH 8 /* OUT3L_VOL_LIM - [7:0] */ | ||
| 1945 | |||
| 1946 | /* | ||
| 1947 | * R1051 (0x41B) - DAC Volume Limit 3R | ||
| 1948 | */ | ||
| 1949 | #define WM5100_OUT3R_VOL_LIM_MASK 0x00FF /* OUT3R_VOL_LIM - [7:0] */ | ||
| 1950 | #define WM5100_OUT3R_VOL_LIM_SHIFT 0 /* OUT3R_VOL_LIM - [7:0] */ | ||
| 1951 | #define WM5100_OUT3R_VOL_LIM_WIDTH 8 /* OUT3R_VOL_LIM - [7:0] */ | ||
| 1952 | |||
| 1953 | /* | ||
| 1954 | * R1052 (0x41C) - Out Volume 4L | ||
| 1955 | */ | ||
| 1956 | #define WM5100_OUT4_OSR 0x2000 /* OUT4_OSR */ | ||
| 1957 | #define WM5100_OUT4_OSR_MASK 0x2000 /* OUT4_OSR */ | ||
| 1958 | #define WM5100_OUT4_OSR_SHIFT 13 /* OUT4_OSR */ | ||
| 1959 | #define WM5100_OUT4_OSR_WIDTH 1 /* OUT4_OSR */ | ||
| 1960 | #define WM5100_OUT4L_ANC_SRC 0x0800 /* OUT4L_ANC_SRC */ | ||
| 1961 | #define WM5100_OUT4L_ANC_SRC_MASK 0x0800 /* OUT4L_ANC_SRC */ | ||
| 1962 | #define WM5100_OUT4L_ANC_SRC_SHIFT 11 /* OUT4L_ANC_SRC */ | ||
| 1963 | #define WM5100_OUT4L_ANC_SRC_WIDTH 1 /* OUT4L_ANC_SRC */ | ||
| 1964 | #define WM5100_OUT4L_VOL_LIM_MASK 0x00FF /* OUT4L_VOL_LIM - [7:0] */ | ||
| 1965 | #define WM5100_OUT4L_VOL_LIM_SHIFT 0 /* OUT4L_VOL_LIM - [7:0] */ | ||
| 1966 | #define WM5100_OUT4L_VOL_LIM_WIDTH 8 /* OUT4L_VOL_LIM - [7:0] */ | ||
| 1967 | |||
| 1968 | /* | ||
| 1969 | * R1053 (0x41D) - Out Volume 4R | ||
| 1970 | */ | ||
| 1971 | #define WM5100_OUT4R_ANC_SRC 0x0800 /* OUT4R_ANC_SRC */ | ||
| 1972 | #define WM5100_OUT4R_ANC_SRC_MASK 0x0800 /* OUT4R_ANC_SRC */ | ||
| 1973 | #define WM5100_OUT4R_ANC_SRC_SHIFT 11 /* OUT4R_ANC_SRC */ | ||
| 1974 | #define WM5100_OUT4R_ANC_SRC_WIDTH 1 /* OUT4R_ANC_SRC */ | ||
| 1975 | #define WM5100_OUT4R_VOL_LIM_MASK 0x00FF /* OUT4R_VOL_LIM - [7:0] */ | ||
| 1976 | #define WM5100_OUT4R_VOL_LIM_SHIFT 0 /* OUT4R_VOL_LIM - [7:0] */ | ||
| 1977 | #define WM5100_OUT4R_VOL_LIM_WIDTH 8 /* OUT4R_VOL_LIM - [7:0] */ | ||
| 1978 | |||
| 1979 | /* | ||
| 1980 | * R1054 (0x41E) - DAC Volume Limit 5L | ||
| 1981 | */ | ||
| 1982 | #define WM5100_OUT5_OSR 0x2000 /* OUT5_OSR */ | ||
| 1983 | #define WM5100_OUT5_OSR_MASK 0x2000 /* OUT5_OSR */ | ||
| 1984 | #define WM5100_OUT5_OSR_SHIFT 13 /* OUT5_OSR */ | ||
| 1985 | #define WM5100_OUT5_OSR_WIDTH 1 /* OUT5_OSR */ | ||
| 1986 | #define WM5100_OUT5L_ANC_SRC 0x0800 /* OUT5L_ANC_SRC */ | ||
| 1987 | #define WM5100_OUT5L_ANC_SRC_MASK 0x0800 /* OUT5L_ANC_SRC */ | ||
| 1988 | #define WM5100_OUT5L_ANC_SRC_SHIFT 11 /* OUT5L_ANC_SRC */ | ||
| 1989 | #define WM5100_OUT5L_ANC_SRC_WIDTH 1 /* OUT5L_ANC_SRC */ | ||
| 1990 | #define WM5100_OUT5L_VOL_LIM_MASK 0x00FF /* OUT5L_VOL_LIM - [7:0] */ | ||
| 1991 | #define WM5100_OUT5L_VOL_LIM_SHIFT 0 /* OUT5L_VOL_LIM - [7:0] */ | ||
| 1992 | #define WM5100_OUT5L_VOL_LIM_WIDTH 8 /* OUT5L_VOL_LIM - [7:0] */ | ||
| 1993 | |||
| 1994 | /* | ||
| 1995 | * R1055 (0x41F) - DAC Volume Limit 5R | ||
| 1996 | */ | ||
| 1997 | #define WM5100_OUT5R_ANC_SRC 0x0800 /* OUT5R_ANC_SRC */ | ||
| 1998 | #define WM5100_OUT5R_ANC_SRC_MASK 0x0800 /* OUT5R_ANC_SRC */ | ||
| 1999 | #define WM5100_OUT5R_ANC_SRC_SHIFT 11 /* OUT5R_ANC_SRC */ | ||
| 2000 | #define WM5100_OUT5R_ANC_SRC_WIDTH 1 /* OUT5R_ANC_SRC */ | ||
| 2001 | #define WM5100_OUT5R_VOL_LIM_MASK 0x00FF /* OUT5R_VOL_LIM - [7:0] */ | ||
| 2002 | #define WM5100_OUT5R_VOL_LIM_SHIFT 0 /* OUT5R_VOL_LIM - [7:0] */ | ||
| 2003 | #define WM5100_OUT5R_VOL_LIM_WIDTH 8 /* OUT5R_VOL_LIM - [7:0] */ | ||
| 2004 | |||
| 2005 | /* | ||
| 2006 | * R1056 (0x420) - DAC Volume Limit 6L | ||
| 2007 | */ | ||
| 2008 | #define WM5100_OUT6_OSR 0x2000 /* OUT6_OSR */ | ||
| 2009 | #define WM5100_OUT6_OSR_MASK 0x2000 /* OUT6_OSR */ | ||
| 2010 | #define WM5100_OUT6_OSR_SHIFT 13 /* OUT6_OSR */ | ||
| 2011 | #define WM5100_OUT6_OSR_WIDTH 1 /* OUT6_OSR */ | ||
| 2012 | #define WM5100_OUT6L_ANC_SRC 0x0800 /* OUT6L_ANC_SRC */ | ||
| 2013 | #define WM5100_OUT6L_ANC_SRC_MASK 0x0800 /* OUT6L_ANC_SRC */ | ||
| 2014 | #define WM5100_OUT6L_ANC_SRC_SHIFT 11 /* OUT6L_ANC_SRC */ | ||
| 2015 | #define WM5100_OUT6L_ANC_SRC_WIDTH 1 /* OUT6L_ANC_SRC */ | ||
| 2016 | #define WM5100_OUT6L_VOL_LIM_MASK 0x00FF /* OUT6L_VOL_LIM - [7:0] */ | ||
| 2017 | #define WM5100_OUT6L_VOL_LIM_SHIFT 0 /* OUT6L_VOL_LIM - [7:0] */ | ||
| 2018 | #define WM5100_OUT6L_VOL_LIM_WIDTH 8 /* OUT6L_VOL_LIM - [7:0] */ | ||
| 2019 | |||
| 2020 | /* | ||
| 2021 | * R1057 (0x421) - DAC Volume Limit 6R | ||
| 2022 | */ | ||
| 2023 | #define WM5100_OUT6R_ANC_SRC 0x0800 /* OUT6R_ANC_SRC */ | ||
| 2024 | #define WM5100_OUT6R_ANC_SRC_MASK 0x0800 /* OUT6R_ANC_SRC */ | ||
| 2025 | #define WM5100_OUT6R_ANC_SRC_SHIFT 11 /* OUT6R_ANC_SRC */ | ||
| 2026 | #define WM5100_OUT6R_ANC_SRC_WIDTH 1 /* OUT6R_ANC_SRC */ | ||
| 2027 | #define WM5100_OUT6R_VOL_LIM_MASK 0x00FF /* OUT6R_VOL_LIM - [7:0] */ | ||
| 2028 | #define WM5100_OUT6R_VOL_LIM_SHIFT 0 /* OUT6R_VOL_LIM - [7:0] */ | ||
| 2029 | #define WM5100_OUT6R_VOL_LIM_WIDTH 8 /* OUT6R_VOL_LIM - [7:0] */ | ||
| 2030 | |||
| 2031 | /* | ||
| 2032 | * R1088 (0x440) - DAC AEC Control 1 | ||
| 2033 | */ | ||
| 2034 | #define WM5100_AEC_LOOPBACK_SRC_MASK 0x003C /* AEC_LOOPBACK_SRC - [5:2] */ | ||
| 2035 | #define WM5100_AEC_LOOPBACK_SRC_SHIFT 2 /* AEC_LOOPBACK_SRC - [5:2] */ | ||
| 2036 | #define WM5100_AEC_LOOPBACK_SRC_WIDTH 4 /* AEC_LOOPBACK_SRC - [5:2] */ | ||
| 2037 | #define WM5100_AEC_ENA_STS 0x0002 /* AEC_ENA_STS */ | ||
| 2038 | #define WM5100_AEC_ENA_STS_MASK 0x0002 /* AEC_ENA_STS */ | ||
| 2039 | #define WM5100_AEC_ENA_STS_SHIFT 1 /* AEC_ENA_STS */ | ||
| 2040 | #define WM5100_AEC_ENA_STS_WIDTH 1 /* AEC_ENA_STS */ | ||
| 2041 | #define WM5100_AEC_LOOPBACK_ENA 0x0001 /* AEC_LOOPBACK_ENA */ | ||
| 2042 | #define WM5100_AEC_LOOPBACK_ENA_MASK 0x0001 /* AEC_LOOPBACK_ENA */ | ||
| 2043 | #define WM5100_AEC_LOOPBACK_ENA_SHIFT 0 /* AEC_LOOPBACK_ENA */ | ||
| 2044 | #define WM5100_AEC_LOOPBACK_ENA_WIDTH 1 /* AEC_LOOPBACK_ENA */ | ||
| 2045 | |||
| 2046 | /* | ||
| 2047 | * R1089 (0x441) - Output Volume Ramp | ||
| 2048 | */ | ||
| 2049 | #define WM5100_OUT_VD_RAMP_MASK 0x0070 /* OUT_VD_RAMP - [6:4] */ | ||
| 2050 | #define WM5100_OUT_VD_RAMP_SHIFT 4 /* OUT_VD_RAMP - [6:4] */ | ||
| 2051 | #define WM5100_OUT_VD_RAMP_WIDTH 3 /* OUT_VD_RAMP - [6:4] */ | ||
| 2052 | #define WM5100_OUT_VI_RAMP_MASK 0x0007 /* OUT_VI_RAMP - [2:0] */ | ||
| 2053 | #define WM5100_OUT_VI_RAMP_SHIFT 0 /* OUT_VI_RAMP - [2:0] */ | ||
| 2054 | #define WM5100_OUT_VI_RAMP_WIDTH 3 /* OUT_VI_RAMP - [2:0] */ | ||
| 2055 | |||
| 2056 | /* | ||
| 2057 | * R1152 (0x480) - DAC Digital Volume 1L | ||
| 2058 | */ | ||
| 2059 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2060 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2061 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2062 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2063 | #define WM5100_OUT1L_MUTE 0x0100 /* OUT1L_MUTE */ | ||
| 2064 | #define WM5100_OUT1L_MUTE_MASK 0x0100 /* OUT1L_MUTE */ | ||
| 2065 | #define WM5100_OUT1L_MUTE_SHIFT 8 /* OUT1L_MUTE */ | ||
| 2066 | #define WM5100_OUT1L_MUTE_WIDTH 1 /* OUT1L_MUTE */ | ||
| 2067 | #define WM5100_OUT1L_VOL_MASK 0x00FF /* OUT1L_VOL - [7:0] */ | ||
| 2068 | #define WM5100_OUT1L_VOL_SHIFT 0 /* OUT1L_VOL - [7:0] */ | ||
| 2069 | #define WM5100_OUT1L_VOL_WIDTH 8 /* OUT1L_VOL - [7:0] */ | ||
| 2070 | |||
| 2071 | /* | ||
| 2072 | * R1153 (0x481) - DAC Digital Volume 1R | ||
| 2073 | */ | ||
| 2074 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2075 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2076 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2077 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2078 | #define WM5100_OUT1R_MUTE 0x0100 /* OUT1R_MUTE */ | ||
| 2079 | #define WM5100_OUT1R_MUTE_MASK 0x0100 /* OUT1R_MUTE */ | ||
| 2080 | #define WM5100_OUT1R_MUTE_SHIFT 8 /* OUT1R_MUTE */ | ||
| 2081 | #define WM5100_OUT1R_MUTE_WIDTH 1 /* OUT1R_MUTE */ | ||
| 2082 | #define WM5100_OUT1R_VOL_MASK 0x00FF /* OUT1R_VOL - [7:0] */ | ||
| 2083 | #define WM5100_OUT1R_VOL_SHIFT 0 /* OUT1R_VOL - [7:0] */ | ||
| 2084 | #define WM5100_OUT1R_VOL_WIDTH 8 /* OUT1R_VOL - [7:0] */ | ||
| 2085 | |||
| 2086 | /* | ||
| 2087 | * R1154 (0x482) - DAC Digital Volume 2L | ||
| 2088 | */ | ||
| 2089 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2090 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2091 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2092 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2093 | #define WM5100_OUT2L_MUTE 0x0100 /* OUT2L_MUTE */ | ||
| 2094 | #define WM5100_OUT2L_MUTE_MASK 0x0100 /* OUT2L_MUTE */ | ||
| 2095 | #define WM5100_OUT2L_MUTE_SHIFT 8 /* OUT2L_MUTE */ | ||
| 2096 | #define WM5100_OUT2L_MUTE_WIDTH 1 /* OUT2L_MUTE */ | ||
| 2097 | #define WM5100_OUT2L_VOL_MASK 0x00FF /* OUT2L_VOL - [7:0] */ | ||
| 2098 | #define WM5100_OUT2L_VOL_SHIFT 0 /* OUT2L_VOL - [7:0] */ | ||
| 2099 | #define WM5100_OUT2L_VOL_WIDTH 8 /* OUT2L_VOL - [7:0] */ | ||
| 2100 | |||
| 2101 | /* | ||
| 2102 | * R1155 (0x483) - DAC Digital Volume 2R | ||
| 2103 | */ | ||
| 2104 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2105 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2106 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2107 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2108 | #define WM5100_OUT2R_MUTE 0x0100 /* OUT2R_MUTE */ | ||
| 2109 | #define WM5100_OUT2R_MUTE_MASK 0x0100 /* OUT2R_MUTE */ | ||
| 2110 | #define WM5100_OUT2R_MUTE_SHIFT 8 /* OUT2R_MUTE */ | ||
| 2111 | #define WM5100_OUT2R_MUTE_WIDTH 1 /* OUT2R_MUTE */ | ||
| 2112 | #define WM5100_OUT2R_VOL_MASK 0x00FF /* OUT2R_VOL - [7:0] */ | ||
| 2113 | #define WM5100_OUT2R_VOL_SHIFT 0 /* OUT2R_VOL - [7:0] */ | ||
| 2114 | #define WM5100_OUT2R_VOL_WIDTH 8 /* OUT2R_VOL - [7:0] */ | ||
| 2115 | |||
| 2116 | /* | ||
| 2117 | * R1156 (0x484) - DAC Digital Volume 3L | ||
| 2118 | */ | ||
| 2119 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2120 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2121 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2122 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2123 | #define WM5100_OUT3L_MUTE 0x0100 /* OUT3L_MUTE */ | ||
| 2124 | #define WM5100_OUT3L_MUTE_MASK 0x0100 /* OUT3L_MUTE */ | ||
| 2125 | #define WM5100_OUT3L_MUTE_SHIFT 8 /* OUT3L_MUTE */ | ||
| 2126 | #define WM5100_OUT3L_MUTE_WIDTH 1 /* OUT3L_MUTE */ | ||
| 2127 | #define WM5100_OUT3L_VOL_MASK 0x00FF /* OUT3L_VOL - [7:0] */ | ||
| 2128 | #define WM5100_OUT3L_VOL_SHIFT 0 /* OUT3L_VOL - [7:0] */ | ||
| 2129 | #define WM5100_OUT3L_VOL_WIDTH 8 /* OUT3L_VOL - [7:0] */ | ||
| 2130 | |||
| 2131 | /* | ||
| 2132 | * R1157 (0x485) - DAC Digital Volume 3R | ||
| 2133 | */ | ||
| 2134 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2135 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2136 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2137 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2138 | #define WM5100_OUT3R_MUTE 0x0100 /* OUT3R_MUTE */ | ||
| 2139 | #define WM5100_OUT3R_MUTE_MASK 0x0100 /* OUT3R_MUTE */ | ||
| 2140 | #define WM5100_OUT3R_MUTE_SHIFT 8 /* OUT3R_MUTE */ | ||
| 2141 | #define WM5100_OUT3R_MUTE_WIDTH 1 /* OUT3R_MUTE */ | ||
| 2142 | #define WM5100_OUT3R_VOL_MASK 0x00FF /* OUT3R_VOL - [7:0] */ | ||
| 2143 | #define WM5100_OUT3R_VOL_SHIFT 0 /* OUT3R_VOL - [7:0] */ | ||
| 2144 | #define WM5100_OUT3R_VOL_WIDTH 8 /* OUT3R_VOL - [7:0] */ | ||
| 2145 | |||
| 2146 | /* | ||
| 2147 | * R1158 (0x486) - DAC Digital Volume 4L | ||
| 2148 | */ | ||
| 2149 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2150 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2151 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2152 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2153 | #define WM5100_OUT4L_MUTE 0x0100 /* OUT4L_MUTE */ | ||
| 2154 | #define WM5100_OUT4L_MUTE_MASK 0x0100 /* OUT4L_MUTE */ | ||
| 2155 | #define WM5100_OUT4L_MUTE_SHIFT 8 /* OUT4L_MUTE */ | ||
| 2156 | #define WM5100_OUT4L_MUTE_WIDTH 1 /* OUT4L_MUTE */ | ||
| 2157 | #define WM5100_OUT4L_VOL_MASK 0x00FF /* OUT4L_VOL - [7:0] */ | ||
| 2158 | #define WM5100_OUT4L_VOL_SHIFT 0 /* OUT4L_VOL - [7:0] */ | ||
| 2159 | #define WM5100_OUT4L_VOL_WIDTH 8 /* OUT4L_VOL - [7:0] */ | ||
| 2160 | |||
| 2161 | /* | ||
| 2162 | * R1159 (0x487) - DAC Digital Volume 4R | ||
| 2163 | */ | ||
| 2164 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2165 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2166 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2167 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2168 | #define WM5100_OUT4R_MUTE 0x0100 /* OUT4R_MUTE */ | ||
| 2169 | #define WM5100_OUT4R_MUTE_MASK 0x0100 /* OUT4R_MUTE */ | ||
| 2170 | #define WM5100_OUT4R_MUTE_SHIFT 8 /* OUT4R_MUTE */ | ||
| 2171 | #define WM5100_OUT4R_MUTE_WIDTH 1 /* OUT4R_MUTE */ | ||
| 2172 | #define WM5100_OUT4R_VOL_MASK 0x00FF /* OUT4R_VOL - [7:0] */ | ||
| 2173 | #define WM5100_OUT4R_VOL_SHIFT 0 /* OUT4R_VOL - [7:0] */ | ||
| 2174 | #define WM5100_OUT4R_VOL_WIDTH 8 /* OUT4R_VOL - [7:0] */ | ||
| 2175 | |||
| 2176 | /* | ||
| 2177 | * R1160 (0x488) - DAC Digital Volume 5L | ||
| 2178 | */ | ||
| 2179 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2180 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2181 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2182 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2183 | #define WM5100_OUT5L_MUTE 0x0100 /* OUT5L_MUTE */ | ||
| 2184 | #define WM5100_OUT5L_MUTE_MASK 0x0100 /* OUT5L_MUTE */ | ||
| 2185 | #define WM5100_OUT5L_MUTE_SHIFT 8 /* OUT5L_MUTE */ | ||
| 2186 | #define WM5100_OUT5L_MUTE_WIDTH 1 /* OUT5L_MUTE */ | ||
| 2187 | #define WM5100_OUT5L_VOL_MASK 0x00FF /* OUT5L_VOL - [7:0] */ | ||
| 2188 | #define WM5100_OUT5L_VOL_SHIFT 0 /* OUT5L_VOL - [7:0] */ | ||
| 2189 | #define WM5100_OUT5L_VOL_WIDTH 8 /* OUT5L_VOL - [7:0] */ | ||
| 2190 | |||
| 2191 | /* | ||
| 2192 | * R1161 (0x489) - DAC Digital Volume 5R | ||
| 2193 | */ | ||
| 2194 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2195 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2196 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2197 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2198 | #define WM5100_OUT5R_MUTE 0x0100 /* OUT5R_MUTE */ | ||
| 2199 | #define WM5100_OUT5R_MUTE_MASK 0x0100 /* OUT5R_MUTE */ | ||
| 2200 | #define WM5100_OUT5R_MUTE_SHIFT 8 /* OUT5R_MUTE */ | ||
| 2201 | #define WM5100_OUT5R_MUTE_WIDTH 1 /* OUT5R_MUTE */ | ||
| 2202 | #define WM5100_OUT5R_VOL_MASK 0x00FF /* OUT5R_VOL - [7:0] */ | ||
| 2203 | #define WM5100_OUT5R_VOL_SHIFT 0 /* OUT5R_VOL - [7:0] */ | ||
| 2204 | #define WM5100_OUT5R_VOL_WIDTH 8 /* OUT5R_VOL - [7:0] */ | ||
| 2205 | |||
| 2206 | /* | ||
| 2207 | * R1162 (0x48A) - DAC Digital Volume 6L | ||
| 2208 | */ | ||
| 2209 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2210 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2211 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2212 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2213 | #define WM5100_OUT6L_MUTE 0x0100 /* OUT6L_MUTE */ | ||
| 2214 | #define WM5100_OUT6L_MUTE_MASK 0x0100 /* OUT6L_MUTE */ | ||
| 2215 | #define WM5100_OUT6L_MUTE_SHIFT 8 /* OUT6L_MUTE */ | ||
| 2216 | #define WM5100_OUT6L_MUTE_WIDTH 1 /* OUT6L_MUTE */ | ||
| 2217 | #define WM5100_OUT6L_VOL_MASK 0x00FF /* OUT6L_VOL - [7:0] */ | ||
| 2218 | #define WM5100_OUT6L_VOL_SHIFT 0 /* OUT6L_VOL - [7:0] */ | ||
| 2219 | #define WM5100_OUT6L_VOL_WIDTH 8 /* OUT6L_VOL - [7:0] */ | ||
| 2220 | |||
| 2221 | /* | ||
| 2222 | * R1163 (0x48B) - DAC Digital Volume 6R | ||
| 2223 | */ | ||
| 2224 | #define WM5100_OUT_VU 0x0200 /* OUT_VU */ | ||
| 2225 | #define WM5100_OUT_VU_MASK 0x0200 /* OUT_VU */ | ||
| 2226 | #define WM5100_OUT_VU_SHIFT 9 /* OUT_VU */ | ||
| 2227 | #define WM5100_OUT_VU_WIDTH 1 /* OUT_VU */ | ||
| 2228 | #define WM5100_OUT6R_MUTE 0x0100 /* OUT6R_MUTE */ | ||
| 2229 | #define WM5100_OUT6R_MUTE_MASK 0x0100 /* OUT6R_MUTE */ | ||
| 2230 | #define WM5100_OUT6R_MUTE_SHIFT 8 /* OUT6R_MUTE */ | ||
| 2231 | #define WM5100_OUT6R_MUTE_WIDTH 1 /* OUT6R_MUTE */ | ||
| 2232 | #define WM5100_OUT6R_VOL_MASK 0x00FF /* OUT6R_VOL - [7:0] */ | ||
| 2233 | #define WM5100_OUT6R_VOL_SHIFT 0 /* OUT6R_VOL - [7:0] */ | ||
| 2234 | #define WM5100_OUT6R_VOL_WIDTH 8 /* OUT6R_VOL - [7:0] */ | ||
| 2235 | |||
| 2236 | /* | ||
| 2237 | * R1216 (0x4C0) - PDM SPK1 CTRL 1 | ||
| 2238 | */ | ||
| 2239 | #define WM5100_SPK1R_MUTE 0x2000 /* SPK1R_MUTE */ | ||
| 2240 | #define WM5100_SPK1R_MUTE_MASK 0x2000 /* SPK1R_MUTE */ | ||
| 2241 | #define WM5100_SPK1R_MUTE_SHIFT 13 /* SPK1R_MUTE */ | ||
| 2242 | #define WM5100_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */ | ||
| 2243 | #define WM5100_SPK1L_MUTE 0x1000 /* SPK1L_MUTE */ | ||
| 2244 | #define WM5100_SPK1L_MUTE_MASK 0x1000 /* SPK1L_MUTE */ | ||
| 2245 | #define WM5100_SPK1L_MUTE_SHIFT 12 /* SPK1L_MUTE */ | ||
| 2246 | #define WM5100_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */ | ||
| 2247 | #define WM5100_SPK1_MUTE_ENDIAN 0x0100 /* SPK1_MUTE_ENDIAN */ | ||
| 2248 | #define WM5100_SPK1_MUTE_ENDIAN_MASK 0x0100 /* SPK1_MUTE_ENDIAN */ | ||
| 2249 | #define WM5100_SPK1_MUTE_ENDIAN_SHIFT 8 /* SPK1_MUTE_ENDIAN */ | ||
| 2250 | #define WM5100_SPK1_MUTE_ENDIAN_WIDTH 1 /* SPK1_MUTE_ENDIAN */ | ||
| 2251 | #define WM5100_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */ | ||
| 2252 | #define WM5100_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */ | ||
| 2253 | #define WM5100_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */ | ||
| 2254 | |||
| 2255 | /* | ||
| 2256 | * R1217 (0x4C1) - PDM SPK1 CTRL 2 | ||
| 2257 | */ | ||
| 2258 | #define WM5100_SPK1_FMT 0x0001 /* SPK1_FMT */ | ||
| 2259 | #define WM5100_SPK1_FMT_MASK 0x0001 /* SPK1_FMT */ | ||
| 2260 | #define WM5100_SPK1_FMT_SHIFT 0 /* SPK1_FMT */ | ||
| 2261 | #define WM5100_SPK1_FMT_WIDTH 1 /* SPK1_FMT */ | ||
| 2262 | |||
| 2263 | /* | ||
| 2264 | * R1218 (0x4C2) - PDM SPK2 CTRL 1 | ||
| 2265 | */ | ||
| 2266 | #define WM5100_SPK2R_MUTE 0x2000 /* SPK2R_MUTE */ | ||
| 2267 | #define WM5100_SPK2R_MUTE_MASK 0x2000 /* SPK2R_MUTE */ | ||
| 2268 | #define WM5100_SPK2R_MUTE_SHIFT 13 /* SPK2R_MUTE */ | ||
| 2269 | #define WM5100_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */ | ||
| 2270 | #define WM5100_SPK2L_MUTE 0x1000 /* SPK2L_MUTE */ | ||
| 2271 | #define WM5100_SPK2L_MUTE_MASK 0x1000 /* SPK2L_MUTE */ | ||
| 2272 | #define WM5100_SPK2L_MUTE_SHIFT 12 /* SPK2L_MUTE */ | ||
| 2273 | #define WM5100_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */ | ||
| 2274 | #define WM5100_SPK2_MUTE_ENDIAN 0x0100 /* SPK2_MUTE_ENDIAN */ | ||
| 2275 | #define WM5100_SPK2_MUTE_ENDIAN_MASK 0x0100 /* SPK2_MUTE_ENDIAN */ | ||
| 2276 | #define WM5100_SPK2_MUTE_ENDIAN_SHIFT 8 /* SPK2_MUTE_ENDIAN */ | ||
| 2277 | #define WM5100_SPK2_MUTE_ENDIAN_WIDTH 1 /* SPK2_MUTE_ENDIAN */ | ||
| 2278 | #define WM5100_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */ | ||
| 2279 | #define WM5100_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */ | ||
| 2280 | #define WM5100_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */ | ||
| 2281 | |||
| 2282 | /* | ||
| 2283 | * R1219 (0x4C3) - PDM SPK2 CTRL 2 | ||
| 2284 | */ | ||
| 2285 | #define WM5100_SPK2_FMT 0x0001 /* SPK2_FMT */ | ||
| 2286 | #define WM5100_SPK2_FMT_MASK 0x0001 /* SPK2_FMT */ | ||
| 2287 | #define WM5100_SPK2_FMT_SHIFT 0 /* SPK2_FMT */ | ||
| 2288 | #define WM5100_SPK2_FMT_WIDTH 1 /* SPK2_FMT */ | ||
| 2289 | |||
| 2290 | /* | ||
| 2291 | * R1280 (0x500) - Audio IF 1_1 | ||
| 2292 | */ | ||
| 2293 | #define WM5100_AIF1_BCLK_INV 0x0080 /* AIF1_BCLK_INV */ | ||
| 2294 | #define WM5100_AIF1_BCLK_INV_MASK 0x0080 /* AIF1_BCLK_INV */ | ||
| 2295 | #define WM5100_AIF1_BCLK_INV_SHIFT 7 /* AIF1_BCLK_INV */ | ||
| 2296 | #define WM5100_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ | ||
| 2297 | #define WM5100_AIF1_BCLK_FRC 0x0040 /* AIF1_BCLK_FRC */ | ||
| 2298 | #define WM5100_AIF1_BCLK_FRC_MASK 0x0040 /* AIF1_BCLK_FRC */ | ||
| 2299 | #define WM5100_AIF1_BCLK_FRC_SHIFT 6 /* AIF1_BCLK_FRC */ | ||
| 2300 | #define WM5100_AIF1_BCLK_FRC_WIDTH 1 /* AIF1_BCLK_FRC */ | ||
| 2301 | #define WM5100_AIF1_BCLK_MSTR 0x0020 /* AIF1_BCLK_MSTR */ | ||
| 2302 | #define WM5100_AIF1_BCLK_MSTR_MASK 0x0020 /* AIF1_BCLK_MSTR */ | ||
| 2303 | #define WM5100_AIF1_BCLK_MSTR_SHIFT 5 /* AIF1_BCLK_MSTR */ | ||
| 2304 | #define WM5100_AIF1_BCLK_MSTR_WIDTH 1 /* AIF1_BCLK_MSTR */ | ||
| 2305 | #define WM5100_AIF1_BCLK_FREQ_MASK 0x001F /* AIF1_BCLK_FREQ - [4:0] */ | ||
| 2306 | #define WM5100_AIF1_BCLK_FREQ_SHIFT 0 /* AIF1_BCLK_FREQ - [4:0] */ | ||
| 2307 | #define WM5100_AIF1_BCLK_FREQ_WIDTH 5 /* AIF1_BCLK_FREQ - [4:0] */ | ||
| 2308 | |||
| 2309 | /* | ||
| 2310 | * R1281 (0x501) - Audio IF 1_2 | ||
| 2311 | */ | ||
| 2312 | #define WM5100_AIF1TX_DAT_TRI 0x0020 /* AIF1TX_DAT_TRI */ | ||
| 2313 | #define WM5100_AIF1TX_DAT_TRI_MASK 0x0020 /* AIF1TX_DAT_TRI */ | ||
| 2314 | #define WM5100_AIF1TX_DAT_TRI_SHIFT 5 /* AIF1TX_DAT_TRI */ | ||
| 2315 | #define WM5100_AIF1TX_DAT_TRI_WIDTH 1 /* AIF1TX_DAT_TRI */ | ||
| 2316 | #define WM5100_AIF1TX_LRCLK_SRC 0x0008 /* AIF1TX_LRCLK_SRC */ | ||
| 2317 | #define WM5100_AIF1TX_LRCLK_SRC_MASK 0x0008 /* AIF1TX_LRCLK_SRC */ | ||
| 2318 | #define WM5100_AIF1TX_LRCLK_SRC_SHIFT 3 /* AIF1TX_LRCLK_SRC */ | ||
| 2319 | #define WM5100_AIF1TX_LRCLK_SRC_WIDTH 1 /* AIF1TX_LRCLK_SRC */ | ||
| 2320 | #define WM5100_AIF1TX_LRCLK_INV 0x0004 /* AIF1TX_LRCLK_INV */ | ||
| 2321 | #define WM5100_AIF1TX_LRCLK_INV_MASK 0x0004 /* AIF1TX_LRCLK_INV */ | ||
| 2322 | #define WM5100_AIF1TX_LRCLK_INV_SHIFT 2 /* AIF1TX_LRCLK_INV */ | ||
| 2323 | #define WM5100_AIF1TX_LRCLK_INV_WIDTH 1 /* AIF1TX_LRCLK_INV */ | ||
| 2324 | #define WM5100_AIF1TX_LRCLK_FRC 0x0002 /* AIF1TX_LRCLK_FRC */ | ||
| 2325 | #define WM5100_AIF1TX_LRCLK_FRC_MASK 0x0002 /* AIF1TX_LRCLK_FRC */ | ||
| 2326 | #define WM5100_AIF1TX_LRCLK_FRC_SHIFT 1 /* AIF1TX_LRCLK_FRC */ | ||
| 2327 | #define WM5100_AIF1TX_LRCLK_FRC_WIDTH 1 /* AIF1TX_LRCLK_FRC */ | ||
| 2328 | #define WM5100_AIF1TX_LRCLK_MSTR 0x0001 /* AIF1TX_LRCLK_MSTR */ | ||
| 2329 | #define WM5100_AIF1TX_LRCLK_MSTR_MASK 0x0001 /* AIF1TX_LRCLK_MSTR */ | ||
| 2330 | #define WM5100_AIF1TX_LRCLK_MSTR_SHIFT 0 /* AIF1TX_LRCLK_MSTR */ | ||
| 2331 | #define WM5100_AIF1TX_LRCLK_MSTR_WIDTH 1 /* AIF1TX_LRCLK_MSTR */ | ||
| 2332 | |||
| 2333 | /* | ||
| 2334 | * R1282 (0x502) - Audio IF 1_3 | ||
| 2335 | */ | ||
| 2336 | #define WM5100_AIF1RX_LRCLK_INV 0x0004 /* AIF1RX_LRCLK_INV */ | ||
| 2337 | #define WM5100_AIF1RX_LRCLK_INV_MASK 0x0004 /* AIF1RX_LRCLK_INV */ | ||
| 2338 | #define WM5100_AIF1RX_LRCLK_INV_SHIFT 2 /* AIF1RX_LRCLK_INV */ | ||
| 2339 | #define WM5100_AIF1RX_LRCLK_INV_WIDTH 1 /* AIF1RX_LRCLK_INV */ | ||
| 2340 | #define WM5100_AIF1RX_LRCLK_FRC 0x0002 /* AIF1RX_LRCLK_FRC */ | ||
| 2341 | #define WM5100_AIF1RX_LRCLK_FRC_MASK 0x0002 /* AIF1RX_LRCLK_FRC */ | ||
| 2342 | #define WM5100_AIF1RX_LRCLK_FRC_SHIFT 1 /* AIF1RX_LRCLK_FRC */ | ||
| 2343 | #define WM5100_AIF1RX_LRCLK_FRC_WIDTH 1 /* AIF1RX_LRCLK_FRC */ | ||
| 2344 | #define WM5100_AIF1RX_LRCLK_MSTR 0x0001 /* AIF1RX_LRCLK_MSTR */ | ||
| 2345 | #define WM5100_AIF1RX_LRCLK_MSTR_MASK 0x0001 /* AIF1RX_LRCLK_MSTR */ | ||
| 2346 | #define WM5100_AIF1RX_LRCLK_MSTR_SHIFT 0 /* AIF1RX_LRCLK_MSTR */ | ||
| 2347 | #define WM5100_AIF1RX_LRCLK_MSTR_WIDTH 1 /* AIF1RX_LRCLK_MSTR */ | ||
| 2348 | |||
| 2349 | /* | ||
| 2350 | * R1283 (0x503) - Audio IF 1_4 | ||
| 2351 | */ | ||
| 2352 | #define WM5100_AIF1_TRI 0x0040 /* AIF1_TRI */ | ||
| 2353 | #define WM5100_AIF1_TRI_MASK 0x0040 /* AIF1_TRI */ | ||
| 2354 | #define WM5100_AIF1_TRI_SHIFT 6 /* AIF1_TRI */ | ||
| 2355 | #define WM5100_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ | ||
| 2356 | #define WM5100_AIF1_RATE_MASK 0x0003 /* AIF1_RATE - [1:0] */ | ||
| 2357 | #define WM5100_AIF1_RATE_SHIFT 0 /* AIF1_RATE - [1:0] */ | ||
| 2358 | #define WM5100_AIF1_RATE_WIDTH 2 /* AIF1_RATE - [1:0] */ | ||
| 2359 | |||
| 2360 | /* | ||
| 2361 | * R1284 (0x504) - Audio IF 1_5 | ||
| 2362 | */ | ||
| 2363 | #define WM5100_AIF1_FMT_MASK 0x0007 /* AIF1_FMT - [2:0] */ | ||
| 2364 | #define WM5100_AIF1_FMT_SHIFT 0 /* AIF1_FMT - [2:0] */ | ||
| 2365 | #define WM5100_AIF1_FMT_WIDTH 3 /* AIF1_FMT - [2:0] */ | ||
| 2366 | |||
| 2367 | /* | ||
| 2368 | * R1285 (0x505) - Audio IF 1_6 | ||
| 2369 | */ | ||
| 2370 | #define WM5100_AIF1TX_BCPF_MASK 0x1FFF /* AIF1TX_BCPF - [12:0] */ | ||
| 2371 | #define WM5100_AIF1TX_BCPF_SHIFT 0 /* AIF1TX_BCPF - [12:0] */ | ||
| 2372 | #define WM5100_AIF1TX_BCPF_WIDTH 13 /* AIF1TX_BCPF - [12:0] */ | ||
| 2373 | |||
| 2374 | /* | ||
| 2375 | * R1286 (0x506) - Audio IF 1_7 | ||
| 2376 | */ | ||
| 2377 | #define WM5100_AIF1RX_BCPF_MASK 0x1FFF /* AIF1RX_BCPF - [12:0] */ | ||
| 2378 | #define WM5100_AIF1RX_BCPF_SHIFT 0 /* AIF1RX_BCPF - [12:0] */ | ||
| 2379 | #define WM5100_AIF1RX_BCPF_WIDTH 13 /* AIF1RX_BCPF - [12:0] */ | ||
| 2380 | |||
| 2381 | /* | ||
| 2382 | * R1287 (0x507) - Audio IF 1_8 | ||
| 2383 | */ | ||
| 2384 | #define WM5100_AIF1TX_WL_MASK 0x3F00 /* AIF1TX_WL - [13:8] */ | ||
| 2385 | #define WM5100_AIF1TX_WL_SHIFT 8 /* AIF1TX_WL - [13:8] */ | ||
| 2386 | #define WM5100_AIF1TX_WL_WIDTH 6 /* AIF1TX_WL - [13:8] */ | ||
| 2387 | #define WM5100_AIF1TX_SLOT_LEN_MASK 0x00FF /* AIF1TX_SLOT_LEN - [7:0] */ | ||
| 2388 | #define WM5100_AIF1TX_SLOT_LEN_SHIFT 0 /* AIF1TX_SLOT_LEN - [7:0] */ | ||
| 2389 | #define WM5100_AIF1TX_SLOT_LEN_WIDTH 8 /* AIF1TX_SLOT_LEN - [7:0] */ | ||
| 2390 | |||
| 2391 | /* | ||
| 2392 | * R1288 (0x508) - Audio IF 1_9 | ||
| 2393 | */ | ||
| 2394 | #define WM5100_AIF1RX_WL_MASK 0x3F00 /* AIF1RX_WL - [13:8] */ | ||
| 2395 | #define WM5100_AIF1RX_WL_SHIFT 8 /* AIF1RX_WL - [13:8] */ | ||
| 2396 | #define WM5100_AIF1RX_WL_WIDTH 6 /* AIF1RX_WL - [13:8] */ | ||
| 2397 | #define WM5100_AIF1RX_SLOT_LEN_MASK 0x00FF /* AIF1RX_SLOT_LEN - [7:0] */ | ||
| 2398 | #define WM5100_AIF1RX_SLOT_LEN_SHIFT 0 /* AIF1RX_SLOT_LEN - [7:0] */ | ||
| 2399 | #define WM5100_AIF1RX_SLOT_LEN_WIDTH 8 /* AIF1RX_SLOT_LEN - [7:0] */ | ||
| 2400 | |||
| 2401 | /* | ||
| 2402 | * R1289 (0x509) - Audio IF 1_10 | ||
| 2403 | */ | ||
| 2404 | #define WM5100_AIF1TX1_SLOT_MASK 0x003F /* AIF1TX1_SLOT - [5:0] */ | ||
| 2405 | #define WM5100_AIF1TX1_SLOT_SHIFT 0 /* AIF1TX1_SLOT - [5:0] */ | ||
| 2406 | #define WM5100_AIF1TX1_SLOT_WIDTH 6 /* AIF1TX1_SLOT - [5:0] */ | ||
| 2407 | |||
| 2408 | /* | ||
| 2409 | * R1290 (0x50A) - Audio IF 1_11 | ||
| 2410 | */ | ||
| 2411 | #define WM5100_AIF1TX2_SLOT_MASK 0x003F /* AIF1TX2_SLOT - [5:0] */ | ||
| 2412 | #define WM5100_AIF1TX2_SLOT_SHIFT 0 /* AIF1TX2_SLOT - [5:0] */ | ||
| 2413 | #define WM5100_AIF1TX2_SLOT_WIDTH 6 /* AIF1TX2_SLOT - [5:0] */ | ||
| 2414 | |||
| 2415 | /* | ||
| 2416 | * R1291 (0x50B) - Audio IF 1_12 | ||
| 2417 | */ | ||
| 2418 | #define WM5100_AIF1TX3_SLOT_MASK 0x003F /* AIF1TX3_SLOT - [5:0] */ | ||
| 2419 | #define WM5100_AIF1TX3_SLOT_SHIFT 0 /* AIF1TX3_SLOT - [5:0] */ | ||
| 2420 | #define WM5100_AIF1TX3_SLOT_WIDTH 6 /* AIF1TX3_SLOT - [5:0] */ | ||
| 2421 | |||
| 2422 | /* | ||
| 2423 | * R1292 (0x50C) - Audio IF 1_13 | ||
| 2424 | */ | ||
| 2425 | #define WM5100_AIF1TX4_SLOT_MASK 0x003F /* AIF1TX4_SLOT - [5:0] */ | ||
| 2426 | #define WM5100_AIF1TX4_SLOT_SHIFT 0 /* AIF1TX4_SLOT - [5:0] */ | ||
| 2427 | #define WM5100_AIF1TX4_SLOT_WIDTH 6 /* AIF1TX4_SLOT - [5:0] */ | ||
| 2428 | |||
| 2429 | /* | ||
| 2430 | * R1293 (0x50D) - Audio IF 1_14 | ||
| 2431 | */ | ||
| 2432 | #define WM5100_AIF1TX5_SLOT_MASK 0x003F /* AIF1TX5_SLOT - [5:0] */ | ||
| 2433 | #define WM5100_AIF1TX5_SLOT_SHIFT 0 /* AIF1TX5_SLOT - [5:0] */ | ||
| 2434 | #define WM5100_AIF1TX5_SLOT_WIDTH 6 /* AIF1TX5_SLOT - [5:0] */ | ||
| 2435 | |||
| 2436 | /* | ||
| 2437 | * R1294 (0x50E) - Audio IF 1_15 | ||
| 2438 | */ | ||
| 2439 | #define WM5100_AIF1TX6_SLOT_MASK 0x003F /* AIF1TX6_SLOT - [5:0] */ | ||
| 2440 | #define WM5100_AIF1TX6_SLOT_SHIFT 0 /* AIF1TX6_SLOT - [5:0] */ | ||
| 2441 | #define WM5100_AIF1TX6_SLOT_WIDTH 6 /* AIF1TX6_SLOT - [5:0] */ | ||
| 2442 | |||
| 2443 | /* | ||
| 2444 | * R1295 (0x50F) - Audio IF 1_16 | ||
| 2445 | */ | ||
| 2446 | #define WM5100_AIF1TX7_SLOT_MASK 0x003F /* AIF1TX7_SLOT - [5:0] */ | ||
| 2447 | #define WM5100_AIF1TX7_SLOT_SHIFT 0 /* AIF1TX7_SLOT - [5:0] */ | ||
| 2448 | #define WM5100_AIF1TX7_SLOT_WIDTH 6 /* AIF1TX7_SLOT - [5:0] */ | ||
| 2449 | |||
| 2450 | /* | ||
| 2451 | * R1296 (0x510) - Audio IF 1_17 | ||
| 2452 | */ | ||
| 2453 | #define WM5100_AIF1TX8_SLOT_MASK 0x003F /* AIF1TX8_SLOT - [5:0] */ | ||
| 2454 | #define WM5100_AIF1TX8_SLOT_SHIFT 0 /* AIF1TX8_SLOT - [5:0] */ | ||
| 2455 | #define WM5100_AIF1TX8_SLOT_WIDTH 6 /* AIF1TX8_SLOT - [5:0] */ | ||
| 2456 | |||
| 2457 | /* | ||
| 2458 | * R1297 (0x511) - Audio IF 1_18 | ||
| 2459 | */ | ||
| 2460 | #define WM5100_AIF1RX1_SLOT_MASK 0x003F /* AIF1RX1_SLOT - [5:0] */ | ||
| 2461 | #define WM5100_AIF1RX1_SLOT_SHIFT 0 /* AIF1RX1_SLOT - [5:0] */ | ||
| 2462 | #define WM5100_AIF1RX1_SLOT_WIDTH 6 /* AIF1RX1_SLOT - [5:0] */ | ||
| 2463 | |||
| 2464 | /* | ||
| 2465 | * R1298 (0x512) - Audio IF 1_19 | ||
| 2466 | */ | ||
| 2467 | #define WM5100_AIF1RX2_SLOT_MASK 0x003F /* AIF1RX2_SLOT - [5:0] */ | ||
| 2468 | #define WM5100_AIF1RX2_SLOT_SHIFT 0 /* AIF1RX2_SLOT - [5:0] */ | ||
| 2469 | #define WM5100_AIF1RX2_SLOT_WIDTH 6 /* AIF1RX2_SLOT - [5:0] */ | ||
| 2470 | |||
| 2471 | /* | ||
| 2472 | * R1299 (0x513) - Audio IF 1_20 | ||
| 2473 | */ | ||
| 2474 | #define WM5100_AIF1RX3_SLOT_MASK 0x003F /* AIF1RX3_SLOT - [5:0] */ | ||
| 2475 | #define WM5100_AIF1RX3_SLOT_SHIFT 0 /* AIF1RX3_SLOT - [5:0] */ | ||
| 2476 | #define WM5100_AIF1RX3_SLOT_WIDTH 6 /* AIF1RX3_SLOT - [5:0] */ | ||
| 2477 | |||
| 2478 | /* | ||
| 2479 | * R1300 (0x514) - Audio IF 1_21 | ||
| 2480 | */ | ||
| 2481 | #define WM5100_AIF1RX4_SLOT_MASK 0x003F /* AIF1RX4_SLOT - [5:0] */ | ||
| 2482 | #define WM5100_AIF1RX4_SLOT_SHIFT 0 /* AIF1RX4_SLOT - [5:0] */ | ||
| 2483 | #define WM5100_AIF1RX4_SLOT_WIDTH 6 /* AIF1RX4_SLOT - [5:0] */ | ||
| 2484 | |||
| 2485 | /* | ||
| 2486 | * R1301 (0x515) - Audio IF 1_22 | ||
| 2487 | */ | ||
| 2488 | #define WM5100_AIF1RX5_SLOT_MASK 0x003F /* AIF1RX5_SLOT - [5:0] */ | ||
| 2489 | #define WM5100_AIF1RX5_SLOT_SHIFT 0 /* AIF1RX5_SLOT - [5:0] */ | ||
| 2490 | #define WM5100_AIF1RX5_SLOT_WIDTH 6 /* AIF1RX5_SLOT - [5:0] */ | ||
| 2491 | |||
| 2492 | /* | ||
| 2493 | * R1302 (0x516) - Audio IF 1_23 | ||
| 2494 | */ | ||
| 2495 | #define WM5100_AIF1RX6_SLOT_MASK 0x003F /* AIF1RX6_SLOT - [5:0] */ | ||
| 2496 | #define WM5100_AIF1RX6_SLOT_SHIFT 0 /* AIF1RX6_SLOT - [5:0] */ | ||
| 2497 | #define WM5100_AIF1RX6_SLOT_WIDTH 6 /* AIF1RX6_SLOT - [5:0] */ | ||
| 2498 | |||
| 2499 | /* | ||
| 2500 | * R1303 (0x517) - Audio IF 1_24 | ||
| 2501 | */ | ||
| 2502 | #define WM5100_AIF1RX7_SLOT_MASK 0x003F /* AIF1RX7_SLOT - [5:0] */ | ||
| 2503 | #define WM5100_AIF1RX7_SLOT_SHIFT 0 /* AIF1RX7_SLOT - [5:0] */ | ||
| 2504 | #define WM5100_AIF1RX7_SLOT_WIDTH 6 /* AIF1RX7_SLOT - [5:0] */ | ||
| 2505 | |||
| 2506 | /* | ||
| 2507 | * R1304 (0x518) - Audio IF 1_25 | ||
| 2508 | */ | ||
| 2509 | #define WM5100_AIF1RX8_SLOT_MASK 0x003F /* AIF1RX8_SLOT - [5:0] */ | ||
| 2510 | #define WM5100_AIF1RX8_SLOT_SHIFT 0 /* AIF1RX8_SLOT - [5:0] */ | ||
| 2511 | #define WM5100_AIF1RX8_SLOT_WIDTH 6 /* AIF1RX8_SLOT - [5:0] */ | ||
| 2512 | |||
| 2513 | /* | ||
| 2514 | * R1305 (0x519) - Audio IF 1_26 | ||
| 2515 | */ | ||
| 2516 | #define WM5100_AIF1TX8_ENA 0x0080 /* AIF1TX8_ENA */ | ||
| 2517 | #define WM5100_AIF1TX8_ENA_MASK 0x0080 /* AIF1TX8_ENA */ | ||
| 2518 | #define WM5100_AIF1TX8_ENA_SHIFT 7 /* AIF1TX8_ENA */ | ||
| 2519 | #define WM5100_AIF1TX8_ENA_WIDTH 1 /* AIF1TX8_ENA */ | ||
| 2520 | #define WM5100_AIF1TX7_ENA 0x0040 /* AIF1TX7_ENA */ | ||
| 2521 | #define WM5100_AIF1TX7_ENA_MASK 0x0040 /* AIF1TX7_ENA */ | ||
| 2522 | #define WM5100_AIF1TX7_ENA_SHIFT 6 /* AIF1TX7_ENA */ | ||
| 2523 | #define WM5100_AIF1TX7_ENA_WIDTH 1 /* AIF1TX7_ENA */ | ||
| 2524 | #define WM5100_AIF1TX6_ENA 0x0020 /* AIF1TX6_ENA */ | ||
| 2525 | #define WM5100_AIF1TX6_ENA_MASK 0x0020 /* AIF1TX6_ENA */ | ||
| 2526 | #define WM5100_AIF1TX6_ENA_SHIFT 5 /* AIF1TX6_ENA */ | ||
| 2527 | #define WM5100_AIF1TX6_ENA_WIDTH 1 /* AIF1TX6_ENA */ | ||
| 2528 | #define WM5100_AIF1TX5_ENA 0x0010 /* AIF1TX5_ENA */ | ||
| 2529 | #define WM5100_AIF1TX5_ENA_MASK 0x0010 /* AIF1TX5_ENA */ | ||
| 2530 | #define WM5100_AIF1TX5_ENA_SHIFT 4 /* AIF1TX5_ENA */ | ||
| 2531 | #define WM5100_AIF1TX5_ENA_WIDTH 1 /* AIF1TX5_ENA */ | ||
| 2532 | #define WM5100_AIF1TX4_ENA 0x0008 /* AIF1TX4_ENA */ | ||
| 2533 | #define WM5100_AIF1TX4_ENA_MASK 0x0008 /* AIF1TX4_ENA */ | ||
| 2534 | #define WM5100_AIF1TX4_ENA_SHIFT 3 /* AIF1TX4_ENA */ | ||
| 2535 | #define WM5100_AIF1TX4_ENA_WIDTH 1 /* AIF1TX4_ENA */ | ||
| 2536 | #define WM5100_AIF1TX3_ENA 0x0004 /* AIF1TX3_ENA */ | ||
| 2537 | #define WM5100_AIF1TX3_ENA_MASK 0x0004 /* AIF1TX3_ENA */ | ||
| 2538 | #define WM5100_AIF1TX3_ENA_SHIFT 2 /* AIF1TX3_ENA */ | ||
| 2539 | #define WM5100_AIF1TX3_ENA_WIDTH 1 /* AIF1TX3_ENA */ | ||
| 2540 | #define WM5100_AIF1TX2_ENA 0x0002 /* AIF1TX2_ENA */ | ||
| 2541 | #define WM5100_AIF1TX2_ENA_MASK 0x0002 /* AIF1TX2_ENA */ | ||
| 2542 | #define WM5100_AIF1TX2_ENA_SHIFT 1 /* AIF1TX2_ENA */ | ||
| 2543 | #define WM5100_AIF1TX2_ENA_WIDTH 1 /* AIF1TX2_ENA */ | ||
| 2544 | #define WM5100_AIF1TX1_ENA 0x0001 /* AIF1TX1_ENA */ | ||
| 2545 | #define WM5100_AIF1TX1_ENA_MASK 0x0001 /* AIF1TX1_ENA */ | ||
| 2546 | #define WM5100_AIF1TX1_ENA_SHIFT 0 /* AIF1TX1_ENA */ | ||
| 2547 | #define WM5100_AIF1TX1_ENA_WIDTH 1 /* AIF1TX1_ENA */ | ||
| 2548 | |||
| 2549 | /* | ||
| 2550 | * R1306 (0x51A) - Audio IF 1_27 | ||
| 2551 | */ | ||
| 2552 | #define WM5100_AIF1RX8_ENA 0x0080 /* AIF1RX8_ENA */ | ||
| 2553 | #define WM5100_AIF1RX8_ENA_MASK 0x0080 /* AIF1RX8_ENA */ | ||
| 2554 | #define WM5100_AIF1RX8_ENA_SHIFT 7 /* AIF1RX8_ENA */ | ||
| 2555 | #define WM5100_AIF1RX8_ENA_WIDTH 1 /* AIF1RX8_ENA */ | ||
| 2556 | #define WM5100_AIF1RX7_ENA 0x0040 /* AIF1RX7_ENA */ | ||
| 2557 | #define WM5100_AIF1RX7_ENA_MASK 0x0040 /* AIF1RX7_ENA */ | ||
| 2558 | #define WM5100_AIF1RX7_ENA_SHIFT 6 /* AIF1RX7_ENA */ | ||
| 2559 | #define WM5100_AIF1RX7_ENA_WIDTH 1 /* AIF1RX7_ENA */ | ||
| 2560 | #define WM5100_AIF1RX6_ENA 0x0020 /* AIF1RX6_ENA */ | ||
| 2561 | #define WM5100_AIF1RX6_ENA_MASK 0x0020 /* AIF1RX6_ENA */ | ||
| 2562 | #define WM5100_AIF1RX6_ENA_SHIFT 5 /* AIF1RX6_ENA */ | ||
| 2563 | #define WM5100_AIF1RX6_ENA_WIDTH 1 /* AIF1RX6_ENA */ | ||
| 2564 | #define WM5100_AIF1RX5_ENA 0x0010 /* AIF1RX5_ENA */ | ||
| 2565 | #define WM5100_AIF1RX5_ENA_MASK 0x0010 /* AIF1RX5_ENA */ | ||
| 2566 | #define WM5100_AIF1RX5_ENA_SHIFT 4 /* AIF1RX5_ENA */ | ||
| 2567 | #define WM5100_AIF1RX5_ENA_WIDTH 1 /* AIF1RX5_ENA */ | ||
| 2568 | #define WM5100_AIF1RX4_ENA 0x0008 /* AIF1RX4_ENA */ | ||
| 2569 | #define WM5100_AIF1RX4_ENA_MASK 0x0008 /* AIF1RX4_ENA */ | ||
| 2570 | #define WM5100_AIF1RX4_ENA_SHIFT 3 /* AIF1RX4_ENA */ | ||
| 2571 | #define WM5100_AIF1RX4_ENA_WIDTH 1 /* AIF1RX4_ENA */ | ||
| 2572 | #define WM5100_AIF1RX3_ENA 0x0004 /* AIF1RX3_ENA */ | ||
| 2573 | #define WM5100_AIF1RX3_ENA_MASK 0x0004 /* AIF1RX3_ENA */ | ||
| 2574 | #define WM5100_AIF1RX3_ENA_SHIFT 2 /* AIF1RX3_ENA */ | ||
| 2575 | #define WM5100_AIF1RX3_ENA_WIDTH 1 /* AIF1RX3_ENA */ | ||
| 2576 | #define WM5100_AIF1RX2_ENA 0x0002 /* AIF1RX2_ENA */ | ||
| 2577 | #define WM5100_AIF1RX2_ENA_MASK 0x0002 /* AIF1RX2_ENA */ | ||
| 2578 | #define WM5100_AIF1RX2_ENA_SHIFT 1 /* AIF1RX2_ENA */ | ||
| 2579 | #define WM5100_AIF1RX2_ENA_WIDTH 1 /* AIF1RX2_ENA */ | ||
| 2580 | #define WM5100_AIF1RX1_ENA 0x0001 /* AIF1RX1_ENA */ | ||
| 2581 | #define WM5100_AIF1RX1_ENA_MASK 0x0001 /* AIF1RX1_ENA */ | ||
| 2582 | #define WM5100_AIF1RX1_ENA_SHIFT 0 /* AIF1RX1_ENA */ | ||
| 2583 | #define WM5100_AIF1RX1_ENA_WIDTH 1 /* AIF1RX1_ENA */ | ||
| 2584 | |||
| 2585 | /* | ||
| 2586 | * R1344 (0x540) - Audio IF 2_1 | ||
| 2587 | */ | ||
| 2588 | #define WM5100_AIF2_BCLK_INV 0x0080 /* AIF2_BCLK_INV */ | ||
| 2589 | #define WM5100_AIF2_BCLK_INV_MASK 0x0080 /* AIF2_BCLK_INV */ | ||
| 2590 | #define WM5100_AIF2_BCLK_INV_SHIFT 7 /* AIF2_BCLK_INV */ | ||
| 2591 | #define WM5100_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */ | ||
| 2592 | #define WM5100_AIF2_BCLK_FRC 0x0040 /* AIF2_BCLK_FRC */ | ||
| 2593 | #define WM5100_AIF2_BCLK_FRC_MASK 0x0040 /* AIF2_BCLK_FRC */ | ||
| 2594 | #define WM5100_AIF2_BCLK_FRC_SHIFT 6 /* AIF2_BCLK_FRC */ | ||
| 2595 | #define WM5100_AIF2_BCLK_FRC_WIDTH 1 /* AIF2_BCLK_FRC */ | ||
| 2596 | #define WM5100_AIF2_BCLK_MSTR 0x0020 /* AIF2_BCLK_MSTR */ | ||
| 2597 | #define WM5100_AIF2_BCLK_MSTR_MASK 0x0020 /* AIF2_BCLK_MSTR */ | ||
| 2598 | #define WM5100_AIF2_BCLK_MSTR_SHIFT 5 /* AIF2_BCLK_MSTR */ | ||
| 2599 | #define WM5100_AIF2_BCLK_MSTR_WIDTH 1 /* AIF2_BCLK_MSTR */ | ||
| 2600 | #define WM5100_AIF2_BCLK_FREQ_MASK 0x001F /* AIF2_BCLK_FREQ - [4:0] */ | ||
| 2601 | #define WM5100_AIF2_BCLK_FREQ_SHIFT 0 /* AIF2_BCLK_FREQ - [4:0] */ | ||
| 2602 | #define WM5100_AIF2_BCLK_FREQ_WIDTH 5 /* AIF2_BCLK_FREQ - [4:0] */ | ||
| 2603 | |||
| 2604 | /* | ||
| 2605 | * R1345 (0x541) - Audio IF 2_2 | ||
| 2606 | */ | ||
| 2607 | #define WM5100_AIF2TX_DAT_TRI 0x0020 /* AIF2TX_DAT_TRI */ | ||
| 2608 | #define WM5100_AIF2TX_DAT_TRI_MASK 0x0020 /* AIF2TX_DAT_TRI */ | ||
| 2609 | #define WM5100_AIF2TX_DAT_TRI_SHIFT 5 /* AIF2TX_DAT_TRI */ | ||
| 2610 | #define WM5100_AIF2TX_DAT_TRI_WIDTH 1 /* AIF2TX_DAT_TRI */ | ||
| 2611 | #define WM5100_AIF2TX_LRCLK_SRC 0x0008 /* AIF2TX_LRCLK_SRC */ | ||
| 2612 | #define WM5100_AIF2TX_LRCLK_SRC_MASK 0x0008 /* AIF2TX_LRCLK_SRC */ | ||
| 2613 | #define WM5100_AIF2TX_LRCLK_SRC_SHIFT 3 /* AIF2TX_LRCLK_SRC */ | ||
| 2614 | #define WM5100_AIF2TX_LRCLK_SRC_WIDTH 1 /* AIF2TX_LRCLK_SRC */ | ||
| 2615 | #define WM5100_AIF2TX_LRCLK_INV 0x0004 /* AIF2TX_LRCLK_INV */ | ||
| 2616 | #define WM5100_AIF2TX_LRCLK_INV_MASK 0x0004 /* AIF2TX_LRCLK_INV */ | ||
| 2617 | #define WM5100_AIF2TX_LRCLK_INV_SHIFT 2 /* AIF2TX_LRCLK_INV */ | ||
| 2618 | #define WM5100_AIF2TX_LRCLK_INV_WIDTH 1 /* AIF2TX_LRCLK_INV */ | ||
| 2619 | #define WM5100_AIF2TX_LRCLK_FRC 0x0002 /* AIF2TX_LRCLK_FRC */ | ||
| 2620 | #define WM5100_AIF2TX_LRCLK_FRC_MASK 0x0002 /* AIF2TX_LRCLK_FRC */ | ||
| 2621 | #define WM5100_AIF2TX_LRCLK_FRC_SHIFT 1 /* AIF2TX_LRCLK_FRC */ | ||
| 2622 | #define WM5100_AIF2TX_LRCLK_FRC_WIDTH 1 /* AIF2TX_LRCLK_FRC */ | ||
| 2623 | #define WM5100_AIF2TX_LRCLK_MSTR 0x0001 /* AIF2TX_LRCLK_MSTR */ | ||
| 2624 | #define WM5100_AIF2TX_LRCLK_MSTR_MASK 0x0001 /* AIF2TX_LRCLK_MSTR */ | ||
| 2625 | #define WM5100_AIF2TX_LRCLK_MSTR_SHIFT 0 /* AIF2TX_LRCLK_MSTR */ | ||
| 2626 | #define WM5100_AIF2TX_LRCLK_MSTR_WIDTH 1 /* AIF2TX_LRCLK_MSTR */ | ||
| 2627 | |||
| 2628 | /* | ||
| 2629 | * R1346 (0x542) - Audio IF 2_3 | ||
| 2630 | */ | ||
| 2631 | #define WM5100_AIF2RX_LRCLK_INV 0x0004 /* AIF2RX_LRCLK_INV */ | ||
| 2632 | #define WM5100_AIF2RX_LRCLK_INV_MASK 0x0004 /* AIF2RX_LRCLK_INV */ | ||
| 2633 | #define WM5100_AIF2RX_LRCLK_INV_SHIFT 2 /* AIF2RX_LRCLK_INV */ | ||
| 2634 | #define WM5100_AIF2RX_LRCLK_INV_WIDTH 1 /* AIF2RX_LRCLK_INV */ | ||
| 2635 | #define WM5100_AIF2RX_LRCLK_FRC 0x0002 /* AIF2RX_LRCLK_FRC */ | ||
| 2636 | #define WM5100_AIF2RX_LRCLK_FRC_MASK 0x0002 /* AIF2RX_LRCLK_FRC */ | ||
| 2637 | #define WM5100_AIF2RX_LRCLK_FRC_SHIFT 1 /* AIF2RX_LRCLK_FRC */ | ||
| 2638 | #define WM5100_AIF2RX_LRCLK_FRC_WIDTH 1 /* AIF2RX_LRCLK_FRC */ | ||
| 2639 | #define WM5100_AIF2RX_LRCLK_MSTR 0x0001 /* AIF2RX_LRCLK_MSTR */ | ||
| 2640 | #define WM5100_AIF2RX_LRCLK_MSTR_MASK 0x0001 /* AIF2RX_LRCLK_MSTR */ | ||
| 2641 | #define WM5100_AIF2RX_LRCLK_MSTR_SHIFT 0 /* AIF2RX_LRCLK_MSTR */ | ||
| 2642 | #define WM5100_AIF2RX_LRCLK_MSTR_WIDTH 1 /* AIF2RX_LRCLK_MSTR */ | ||
| 2643 | |||
| 2644 | /* | ||
| 2645 | * R1347 (0x543) - Audio IF 2_4 | ||
| 2646 | */ | ||
| 2647 | #define WM5100_AIF2_TRI 0x0040 /* AIF2_TRI */ | ||
| 2648 | #define WM5100_AIF2_TRI_MASK 0x0040 /* AIF2_TRI */ | ||
| 2649 | #define WM5100_AIF2_TRI_SHIFT 6 /* AIF2_TRI */ | ||
| 2650 | #define WM5100_AIF2_TRI_WIDTH 1 /* AIF2_TRI */ | ||
| 2651 | #define WM5100_AIF2_RATE_MASK 0x0003 /* AIF2_RATE - [1:0] */ | ||
| 2652 | #define WM5100_AIF2_RATE_SHIFT 0 /* AIF2_RATE - [1:0] */ | ||
| 2653 | #define WM5100_AIF2_RATE_WIDTH 2 /* AIF2_RATE - [1:0] */ | ||
| 2654 | |||
| 2655 | /* | ||
| 2656 | * R1348 (0x544) - Audio IF 2_5 | ||
| 2657 | */ | ||
| 2658 | #define WM5100_AIF2_FMT_MASK 0x0007 /* AIF2_FMT - [2:0] */ | ||
| 2659 | #define WM5100_AIF2_FMT_SHIFT 0 /* AIF2_FMT - [2:0] */ | ||
| 2660 | #define WM5100_AIF2_FMT_WIDTH 3 /* AIF2_FMT - [2:0] */ | ||
| 2661 | |||
| 2662 | /* | ||
| 2663 | * R1349 (0x545) - Audio IF 2_6 | ||
| 2664 | */ | ||
| 2665 | #define WM5100_AIF2TX_BCPF_MASK 0x1FFF /* AIF2TX_BCPF - [12:0] */ | ||
| 2666 | #define WM5100_AIF2TX_BCPF_SHIFT 0 /* AIF2TX_BCPF - [12:0] */ | ||
| 2667 | #define WM5100_AIF2TX_BCPF_WIDTH 13 /* AIF2TX_BCPF - [12:0] */ | ||
| 2668 | |||
| 2669 | /* | ||
| 2670 | * R1350 (0x546) - Audio IF 2_7 | ||
| 2671 | */ | ||
| 2672 | #define WM5100_AIF2RX_BCPF_MASK 0x1FFF /* AIF2RX_BCPF - [12:0] */ | ||
| 2673 | #define WM5100_AIF2RX_BCPF_SHIFT 0 /* AIF2RX_BCPF - [12:0] */ | ||
| 2674 | #define WM5100_AIF2RX_BCPF_WIDTH 13 /* AIF2RX_BCPF - [12:0] */ | ||
| 2675 | |||
| 2676 | /* | ||
| 2677 | * R1351 (0x547) - Audio IF 2_8 | ||
| 2678 | */ | ||
| 2679 | #define WM5100_AIF2TX_WL_MASK 0x3F00 /* AIF2TX_WL - [13:8] */ | ||
| 2680 | #define WM5100_AIF2TX_WL_SHIFT 8 /* AIF2TX_WL - [13:8] */ | ||
| 2681 | #define WM5100_AIF2TX_WL_WIDTH 6 /* AIF2TX_WL - [13:8] */ | ||
| 2682 | #define WM5100_AIF2TX_SLOT_LEN_MASK 0x00FF /* AIF2TX_SLOT_LEN - [7:0] */ | ||
| 2683 | #define WM5100_AIF2TX_SLOT_LEN_SHIFT 0 /* AIF2TX_SLOT_LEN - [7:0] */ | ||
| 2684 | #define WM5100_AIF2TX_SLOT_LEN_WIDTH 8 /* AIF2TX_SLOT_LEN - [7:0] */ | ||
| 2685 | |||
| 2686 | /* | ||
| 2687 | * R1352 (0x548) - Audio IF 2_9 | ||
| 2688 | */ | ||
| 2689 | #define WM5100_AIF2RX_WL_MASK 0x3F00 /* AIF2RX_WL - [13:8] */ | ||
| 2690 | #define WM5100_AIF2RX_WL_SHIFT 8 /* AIF2RX_WL - [13:8] */ | ||
| 2691 | #define WM5100_AIF2RX_WL_WIDTH 6 /* AIF2RX_WL - [13:8] */ | ||
| 2692 | #define WM5100_AIF2RX_SLOT_LEN_MASK 0x00FF /* AIF2RX_SLOT_LEN - [7:0] */ | ||
| 2693 | #define WM5100_AIF2RX_SLOT_LEN_SHIFT 0 /* AIF2RX_SLOT_LEN - [7:0] */ | ||
| 2694 | #define WM5100_AIF2RX_SLOT_LEN_WIDTH 8 /* AIF2RX_SLOT_LEN - [7:0] */ | ||
| 2695 | |||
| 2696 | /* | ||
| 2697 | * R1353 (0x549) - Audio IF 2_10 | ||
| 2698 | */ | ||
| 2699 | #define WM5100_AIF2TX1_SLOT_MASK 0x003F /* AIF2TX1_SLOT - [5:0] */ | ||
| 2700 | #define WM5100_AIF2TX1_SLOT_SHIFT 0 /* AIF2TX1_SLOT - [5:0] */ | ||
| 2701 | #define WM5100_AIF2TX1_SLOT_WIDTH 6 /* AIF2TX1_SLOT - [5:0] */ | ||
| 2702 | |||
| 2703 | /* | ||
| 2704 | * R1354 (0x54A) - Audio IF 2_11 | ||
| 2705 | */ | ||
| 2706 | #define WM5100_AIF2TX2_SLOT_MASK 0x003F /* AIF2TX2_SLOT - [5:0] */ | ||
| 2707 | #define WM5100_AIF2TX2_SLOT_SHIFT 0 /* AIF2TX2_SLOT - [5:0] */ | ||
| 2708 | #define WM5100_AIF2TX2_SLOT_WIDTH 6 /* AIF2TX2_SLOT - [5:0] */ | ||
| 2709 | |||
| 2710 | /* | ||
| 2711 | * R1361 (0x551) - Audio IF 2_18 | ||
| 2712 | */ | ||
| 2713 | #define WM5100_AIF2RX1_SLOT_MASK 0x003F /* AIF2RX1_SLOT - [5:0] */ | ||
| 2714 | #define WM5100_AIF2RX1_SLOT_SHIFT 0 /* AIF2RX1_SLOT - [5:0] */ | ||
| 2715 | #define WM5100_AIF2RX1_SLOT_WIDTH 6 /* AIF2RX1_SLOT - [5:0] */ | ||
| 2716 | |||
| 2717 | /* | ||
| 2718 | * R1362 (0x552) - Audio IF 2_19 | ||
| 2719 | */ | ||
| 2720 | #define WM5100_AIF2RX2_SLOT_MASK 0x003F /* AIF2RX2_SLOT - [5:0] */ | ||
| 2721 | #define WM5100_AIF2RX2_SLOT_SHIFT 0 /* AIF2RX2_SLOT - [5:0] */ | ||
| 2722 | #define WM5100_AIF2RX2_SLOT_WIDTH 6 /* AIF2RX2_SLOT - [5:0] */ | ||
| 2723 | |||
| 2724 | /* | ||
| 2725 | * R1369 (0x559) - Audio IF 2_26 | ||
| 2726 | */ | ||
| 2727 | #define WM5100_AIF2TX2_ENA 0x0002 /* AIF2TX2_ENA */ | ||
| 2728 | #define WM5100_AIF2TX2_ENA_MASK 0x0002 /* AIF2TX2_ENA */ | ||
| 2729 | #define WM5100_AIF2TX2_ENA_SHIFT 1 /* AIF2TX2_ENA */ | ||
| 2730 | #define WM5100_AIF2TX2_ENA_WIDTH 1 /* AIF2TX2_ENA */ | ||
| 2731 | #define WM5100_AIF2TX1_ENA 0x0001 /* AIF2TX1_ENA */ | ||
| 2732 | #define WM5100_AIF2TX1_ENA_MASK 0x0001 /* AIF2TX1_ENA */ | ||
| 2733 | #define WM5100_AIF2TX1_ENA_SHIFT 0 /* AIF2TX1_ENA */ | ||
| 2734 | #define WM5100_AIF2TX1_ENA_WIDTH 1 /* AIF2TX1_ENA */ | ||
| 2735 | |||
| 2736 | /* | ||
| 2737 | * R1370 (0x55A) - Audio IF 2_27 | ||
| 2738 | */ | ||
| 2739 | #define WM5100_AIF2RX2_ENA 0x0002 /* AIF2RX2_ENA */ | ||
| 2740 | #define WM5100_AIF2RX2_ENA_MASK 0x0002 /* AIF2RX2_ENA */ | ||
| 2741 | #define WM5100_AIF2RX2_ENA_SHIFT 1 /* AIF2RX2_ENA */ | ||
| 2742 | #define WM5100_AIF2RX2_ENA_WIDTH 1 /* AIF2RX2_ENA */ | ||
| 2743 | #define WM5100_AIF2RX1_ENA 0x0001 /* AIF2RX1_ENA */ | ||
| 2744 | #define WM5100_AIF2RX1_ENA_MASK 0x0001 /* AIF2RX1_ENA */ | ||
| 2745 | #define WM5100_AIF2RX1_ENA_SHIFT 0 /* AIF2RX1_ENA */ | ||
| 2746 | #define WM5100_AIF2RX1_ENA_WIDTH 1 /* AIF2RX1_ENA */ | ||
| 2747 | |||
| 2748 | /* | ||
| 2749 | * R1408 (0x580) - Audio IF 3_1 | ||
| 2750 | */ | ||
| 2751 | #define WM5100_AIF3_BCLK_INV 0x0080 /* AIF3_BCLK_INV */ | ||
| 2752 | #define WM5100_AIF3_BCLK_INV_MASK 0x0080 /* AIF3_BCLK_INV */ | ||
| 2753 | #define WM5100_AIF3_BCLK_INV_SHIFT 7 /* AIF3_BCLK_INV */ | ||
| 2754 | #define WM5100_AIF3_BCLK_INV_WIDTH 1 /* AIF3_BCLK_INV */ | ||
| 2755 | #define WM5100_AIF3_BCLK_FRC 0x0040 /* AIF3_BCLK_FRC */ | ||
| 2756 | #define WM5100_AIF3_BCLK_FRC_MASK 0x0040 /* AIF3_BCLK_FRC */ | ||
| 2757 | #define WM5100_AIF3_BCLK_FRC_SHIFT 6 /* AIF3_BCLK_FRC */ | ||
| 2758 | #define WM5100_AIF3_BCLK_FRC_WIDTH 1 /* AIF3_BCLK_FRC */ | ||
| 2759 | #define WM5100_AIF3_BCLK_MSTR 0x0020 /* AIF3_BCLK_MSTR */ | ||
| 2760 | #define WM5100_AIF3_BCLK_MSTR_MASK 0x0020 /* AIF3_BCLK_MSTR */ | ||
| 2761 | #define WM5100_AIF3_BCLK_MSTR_SHIFT 5 /* AIF3_BCLK_MSTR */ | ||
| 2762 | #define WM5100_AIF3_BCLK_MSTR_WIDTH 1 /* AIF3_BCLK_MSTR */ | ||
| 2763 | #define WM5100_AIF3_BCLK_FREQ_MASK 0x001F /* AIF3_BCLK_FREQ - [4:0] */ | ||
| 2764 | #define WM5100_AIF3_BCLK_FREQ_SHIFT 0 /* AIF3_BCLK_FREQ - [4:0] */ | ||
| 2765 | #define WM5100_AIF3_BCLK_FREQ_WIDTH 5 /* AIF3_BCLK_FREQ - [4:0] */ | ||
| 2766 | |||
| 2767 | /* | ||
| 2768 | * R1409 (0x581) - Audio IF 3_2 | ||
| 2769 | */ | ||
| 2770 | #define WM5100_AIF3TX_DAT_TRI 0x0020 /* AIF3TX_DAT_TRI */ | ||
| 2771 | #define WM5100_AIF3TX_DAT_TRI_MASK 0x0020 /* AIF3TX_DAT_TRI */ | ||
| 2772 | #define WM5100_AIF3TX_DAT_TRI_SHIFT 5 /* AIF3TX_DAT_TRI */ | ||
| 2773 | #define WM5100_AIF3TX_DAT_TRI_WIDTH 1 /* AIF3TX_DAT_TRI */ | ||
| 2774 | #define WM5100_AIF3TX_LRCLK_SRC 0x0008 /* AIF3TX_LRCLK_SRC */ | ||
| 2775 | #define WM5100_AIF3TX_LRCLK_SRC_MASK 0x0008 /* AIF3TX_LRCLK_SRC */ | ||
| 2776 | #define WM5100_AIF3TX_LRCLK_SRC_SHIFT 3 /* AIF3TX_LRCLK_SRC */ | ||
| 2777 | #define WM5100_AIF3TX_LRCLK_SRC_WIDTH 1 /* AIF3TX_LRCLK_SRC */ | ||
| 2778 | #define WM5100_AIF3TX_LRCLK_INV 0x0004 /* AIF3TX_LRCLK_INV */ | ||
| 2779 | #define WM5100_AIF3TX_LRCLK_INV_MASK 0x0004 /* AIF3TX_LRCLK_INV */ | ||
| 2780 | #define WM5100_AIF3TX_LRCLK_INV_SHIFT 2 /* AIF3TX_LRCLK_INV */ | ||
| 2781 | #define WM5100_AIF3TX_LRCLK_INV_WIDTH 1 /* AIF3TX_LRCLK_INV */ | ||
| 2782 | #define WM5100_AIF3TX_LRCLK_FRC 0x0002 /* AIF3TX_LRCLK_FRC */ | ||
| 2783 | #define WM5100_AIF3TX_LRCLK_FRC_MASK 0x0002 /* AIF3TX_LRCLK_FRC */ | ||
| 2784 | #define WM5100_AIF3TX_LRCLK_FRC_SHIFT 1 /* AIF3TX_LRCLK_FRC */ | ||
| 2785 | #define WM5100_AIF3TX_LRCLK_FRC_WIDTH 1 /* AIF3TX_LRCLK_FRC */ | ||
| 2786 | #define WM5100_AIF3TX_LRCLK_MSTR 0x0001 /* AIF3TX_LRCLK_MSTR */ | ||
| 2787 | #define WM5100_AIF3TX_LRCLK_MSTR_MASK 0x0001 /* AIF3TX_LRCLK_MSTR */ | ||
| 2788 | #define WM5100_AIF3TX_LRCLK_MSTR_SHIFT 0 /* AIF3TX_LRCLK_MSTR */ | ||
| 2789 | #define WM5100_AIF3TX_LRCLK_MSTR_WIDTH 1 /* AIF3TX_LRCLK_MSTR */ | ||
| 2790 | |||
| 2791 | /* | ||
| 2792 | * R1410 (0x582) - Audio IF 3_3 | ||
| 2793 | */ | ||
| 2794 | #define WM5100_AIF3RX_LRCLK_INV 0x0004 /* AIF3RX_LRCLK_INV */ | ||
| 2795 | #define WM5100_AIF3RX_LRCLK_INV_MASK 0x0004 /* AIF3RX_LRCLK_INV */ | ||
| 2796 | #define WM5100_AIF3RX_LRCLK_INV_SHIFT 2 /* AIF3RX_LRCLK_INV */ | ||
| 2797 | #define WM5100_AIF3RX_LRCLK_INV_WIDTH 1 /* AIF3RX_LRCLK_INV */ | ||
| 2798 | #define WM5100_AIF3RX_LRCLK_FRC 0x0002 /* AIF3RX_LRCLK_FRC */ | ||
| 2799 | #define WM5100_AIF3RX_LRCLK_FRC_MASK 0x0002 /* AIF3RX_LRCLK_FRC */ | ||
| 2800 | #define WM5100_AIF3RX_LRCLK_FRC_SHIFT 1 /* AIF3RX_LRCLK_FRC */ | ||
| 2801 | #define WM5100_AIF3RX_LRCLK_FRC_WIDTH 1 /* AIF3RX_LRCLK_FRC */ | ||
| 2802 | #define WM5100_AIF3RX_LRCLK_MSTR 0x0001 /* AIF3RX_LRCLK_MSTR */ | ||
| 2803 | #define WM5100_AIF3RX_LRCLK_MSTR_MASK 0x0001 /* AIF3RX_LRCLK_MSTR */ | ||
| 2804 | #define WM5100_AIF3RX_LRCLK_MSTR_SHIFT 0 /* AIF3RX_LRCLK_MSTR */ | ||
| 2805 | #define WM5100_AIF3RX_LRCLK_MSTR_WIDTH 1 /* AIF3RX_LRCLK_MSTR */ | ||
| 2806 | |||
| 2807 | /* | ||
| 2808 | * R1411 (0x583) - Audio IF 3_4 | ||
| 2809 | */ | ||
| 2810 | #define WM5100_AIF3_TRI 0x0040 /* AIF3_TRI */ | ||
| 2811 | #define WM5100_AIF3_TRI_MASK 0x0040 /* AIF3_TRI */ | ||
| 2812 | #define WM5100_AIF3_TRI_SHIFT 6 /* AIF3_TRI */ | ||
| 2813 | #define WM5100_AIF3_TRI_WIDTH 1 /* AIF3_TRI */ | ||
| 2814 | #define WM5100_AIF3_RATE_MASK 0x0003 /* AIF3_RATE - [1:0] */ | ||
| 2815 | #define WM5100_AIF3_RATE_SHIFT 0 /* AIF3_RATE - [1:0] */ | ||
| 2816 | #define WM5100_AIF3_RATE_WIDTH 2 /* AIF3_RATE - [1:0] */ | ||
| 2817 | |||
| 2818 | /* | ||
| 2819 | * R1412 (0x584) - Audio IF 3_5 | ||
| 2820 | */ | ||
| 2821 | #define WM5100_AIF3_FMT_MASK 0x0007 /* AIF3_FMT - [2:0] */ | ||
| 2822 | #define WM5100_AIF3_FMT_SHIFT 0 /* AIF3_FMT - [2:0] */ | ||
| 2823 | #define WM5100_AIF3_FMT_WIDTH 3 /* AIF3_FMT - [2:0] */ | ||
| 2824 | |||
| 2825 | /* | ||
| 2826 | * R1413 (0x585) - Audio IF 3_6 | ||
| 2827 | */ | ||
| 2828 | #define WM5100_AIF3TX_BCPF_MASK 0x1FFF /* AIF3TX_BCPF - [12:0] */ | ||
| 2829 | #define WM5100_AIF3TX_BCPF_SHIFT 0 /* AIF3TX_BCPF - [12:0] */ | ||
| 2830 | #define WM5100_AIF3TX_BCPF_WIDTH 13 /* AIF3TX_BCPF - [12:0] */ | ||
| 2831 | |||
| 2832 | /* | ||
| 2833 | * R1414 (0x586) - Audio IF 3_7 | ||
| 2834 | */ | ||
| 2835 | #define WM5100_AIF3RX_BCPF_MASK 0x1FFF /* AIF3RX_BCPF - [12:0] */ | ||
| 2836 | #define WM5100_AIF3RX_BCPF_SHIFT 0 /* AIF3RX_BCPF - [12:0] */ | ||
| 2837 | #define WM5100_AIF3RX_BCPF_WIDTH 13 /* AIF3RX_BCPF - [12:0] */ | ||
| 2838 | |||
| 2839 | /* | ||
| 2840 | * R1415 (0x587) - Audio IF 3_8 | ||
| 2841 | */ | ||
| 2842 | #define WM5100_AIF3TX_WL_MASK 0x3F00 /* AIF3TX_WL - [13:8] */ | ||
| 2843 | #define WM5100_AIF3TX_WL_SHIFT 8 /* AIF3TX_WL - [13:8] */ | ||
| 2844 | #define WM5100_AIF3TX_WL_WIDTH 6 /* AIF3TX_WL - [13:8] */ | ||
| 2845 | #define WM5100_AIF3TX_SLOT_LEN_MASK 0x00FF /* AIF3TX_SLOT_LEN - [7:0] */ | ||
| 2846 | #define WM5100_AIF3TX_SLOT_LEN_SHIFT 0 /* AIF3TX_SLOT_LEN - [7:0] */ | ||
| 2847 | #define WM5100_AIF3TX_SLOT_LEN_WIDTH 8 /* AIF3TX_SLOT_LEN - [7:0] */ | ||
| 2848 | |||
| 2849 | /* | ||
| 2850 | * R1416 (0x588) - Audio IF 3_9 | ||
| 2851 | */ | ||
| 2852 | #define WM5100_AIF3RX_WL_MASK 0x3F00 /* AIF3RX_WL - [13:8] */ | ||
| 2853 | #define WM5100_AIF3RX_WL_SHIFT 8 /* AIF3RX_WL - [13:8] */ | ||
| 2854 | #define WM5100_AIF3RX_WL_WIDTH 6 /* AIF3RX_WL - [13:8] */ | ||
| 2855 | #define WM5100_AIF3RX_SLOT_LEN_MASK 0x00FF /* AIF3RX_SLOT_LEN - [7:0] */ | ||
| 2856 | #define WM5100_AIF3RX_SLOT_LEN_SHIFT 0 /* AIF3RX_SLOT_LEN - [7:0] */ | ||
| 2857 | #define WM5100_AIF3RX_SLOT_LEN_WIDTH 8 /* AIF3RX_SLOT_LEN - [7:0] */ | ||
| 2858 | |||
| 2859 | /* | ||
| 2860 | * R1417 (0x589) - Audio IF 3_10 | ||
| 2861 | */ | ||
| 2862 | #define WM5100_AIF3TX1_SLOT_MASK 0x003F /* AIF3TX1_SLOT - [5:0] */ | ||
| 2863 | #define WM5100_AIF3TX1_SLOT_SHIFT 0 /* AIF3TX1_SLOT - [5:0] */ | ||
| 2864 | #define WM5100_AIF3TX1_SLOT_WIDTH 6 /* AIF3TX1_SLOT - [5:0] */ | ||
| 2865 | |||
| 2866 | /* | ||
| 2867 | * R1418 (0x58A) - Audio IF 3_11 | ||
| 2868 | */ | ||
| 2869 | #define WM5100_AIF3TX2_SLOT_MASK 0x003F /* AIF3TX2_SLOT - [5:0] */ | ||
| 2870 | #define WM5100_AIF3TX2_SLOT_SHIFT 0 /* AIF3TX2_SLOT - [5:0] */ | ||
| 2871 | #define WM5100_AIF3TX2_SLOT_WIDTH 6 /* AIF3TX2_SLOT - [5:0] */ | ||
| 2872 | |||
| 2873 | /* | ||
| 2874 | * R1425 (0x591) - Audio IF 3_18 | ||
| 2875 | */ | ||
| 2876 | #define WM5100_AIF3RX1_SLOT_MASK 0x003F /* AIF3RX1_SLOT - [5:0] */ | ||
| 2877 | #define WM5100_AIF3RX1_SLOT_SHIFT 0 /* AIF3RX1_SLOT - [5:0] */ | ||
| 2878 | #define WM5100_AIF3RX1_SLOT_WIDTH 6 /* AIF3RX1_SLOT - [5:0] */ | ||
| 2879 | |||
| 2880 | /* | ||
| 2881 | * R1426 (0x592) - Audio IF 3_19 | ||
| 2882 | */ | ||
| 2883 | #define WM5100_AIF3RX2_SLOT_MASK 0x003F /* AIF3RX2_SLOT - [5:0] */ | ||
| 2884 | #define WM5100_AIF3RX2_SLOT_SHIFT 0 /* AIF3RX2_SLOT - [5:0] */ | ||
| 2885 | #define WM5100_AIF3RX2_SLOT_WIDTH 6 /* AIF3RX2_SLOT - [5:0] */ | ||
| 2886 | |||
| 2887 | /* | ||
| 2888 | * R1433 (0x599) - Audio IF 3_26 | ||
| 2889 | */ | ||
| 2890 | #define WM5100_AIF3TX2_ENA 0x0002 /* AIF3TX2_ENA */ | ||
| 2891 | #define WM5100_AIF3TX2_ENA_MASK 0x0002 /* AIF3TX2_ENA */ | ||
| 2892 | #define WM5100_AIF3TX2_ENA_SHIFT 1 /* AIF3TX2_ENA */ | ||
| 2893 | #define WM5100_AIF3TX2_ENA_WIDTH 1 /* AIF3TX2_ENA */ | ||
| 2894 | #define WM5100_AIF3TX1_ENA 0x0001 /* AIF3TX1_ENA */ | ||
| 2895 | #define WM5100_AIF3TX1_ENA_MASK 0x0001 /* AIF3TX1_ENA */ | ||
| 2896 | #define WM5100_AIF3TX1_ENA_SHIFT 0 /* AIF3TX1_ENA */ | ||
| 2897 | #define WM5100_AIF3TX1_ENA_WIDTH 1 /* AIF3TX1_ENA */ | ||
| 2898 | |||
| 2899 | /* | ||
| 2900 | * R1434 (0x59A) - Audio IF 3_27 | ||
| 2901 | */ | ||
| 2902 | #define WM5100_AIF3RX2_ENA 0x0002 /* AIF3RX2_ENA */ | ||
| 2903 | #define WM5100_AIF3RX2_ENA_MASK 0x0002 /* AIF3RX2_ENA */ | ||
| 2904 | #define WM5100_AIF3RX2_ENA_SHIFT 1 /* AIF3RX2_ENA */ | ||
| 2905 | #define WM5100_AIF3RX2_ENA_WIDTH 1 /* AIF3RX2_ENA */ | ||
| 2906 | #define WM5100_AIF3RX1_ENA 0x0001 /* AIF3RX1_ENA */ | ||
| 2907 | #define WM5100_AIF3RX1_ENA_MASK 0x0001 /* AIF3RX1_ENA */ | ||
| 2908 | #define WM5100_AIF3RX1_ENA_SHIFT 0 /* AIF3RX1_ENA */ | ||
| 2909 | #define WM5100_AIF3RX1_ENA_WIDTH 1 /* AIF3RX1_ENA */ | ||
| 2910 | |||
| 2911 | #define WM5100_MIXER_VOL_MASK 0x00FE /* MIXER_VOL - [7:1] */ | ||
| 2912 | #define WM5100_MIXER_VOL_SHIFT 1 /* MIXER_VOL - [7:1] */ | ||
| 2913 | #define WM5100_MIXER_VOL_WIDTH 7 /* MIXER_VOL - [7:1] */ | ||
| 2914 | |||
| 2915 | /* | ||
| 2916 | * R3072 (0xC00) - GPIO CTRL 1 | ||
| 2917 | */ | ||
| 2918 | #define WM5100_GP1_DIR 0x8000 /* GP1_DIR */ | ||
| 2919 | #define WM5100_GP1_DIR_MASK 0x8000 /* GP1_DIR */ | ||
| 2920 | #define WM5100_GP1_DIR_SHIFT 15 /* GP1_DIR */ | ||
| 2921 | #define WM5100_GP1_DIR_WIDTH 1 /* GP1_DIR */ | ||
| 2922 | #define WM5100_GP1_PU 0x4000 /* GP1_PU */ | ||
| 2923 | #define WM5100_GP1_PU_MASK 0x4000 /* GP1_PU */ | ||
| 2924 | #define WM5100_GP1_PU_SHIFT 14 /* GP1_PU */ | ||
| 2925 | #define WM5100_GP1_PU_WIDTH 1 /* GP1_PU */ | ||
| 2926 | #define WM5100_GP1_PD 0x2000 /* GP1_PD */ | ||
| 2927 | #define WM5100_GP1_PD_MASK 0x2000 /* GP1_PD */ | ||
| 2928 | #define WM5100_GP1_PD_SHIFT 13 /* GP1_PD */ | ||
| 2929 | #define WM5100_GP1_PD_WIDTH 1 /* GP1_PD */ | ||
| 2930 | #define WM5100_GP1_POL 0x0400 /* GP1_POL */ | ||
| 2931 | #define WM5100_GP1_POL_MASK 0x0400 /* GP1_POL */ | ||
| 2932 | #define WM5100_GP1_POL_SHIFT 10 /* GP1_POL */ | ||
| 2933 | #define WM5100_GP1_POL_WIDTH 1 /* GP1_POL */ | ||
| 2934 | #define WM5100_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ | ||
| 2935 | #define WM5100_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ | ||
| 2936 | #define WM5100_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ | ||
| 2937 | #define WM5100_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ | ||
| 2938 | #define WM5100_GP1_DB 0x0100 /* GP1_DB */ | ||
| 2939 | #define WM5100_GP1_DB_MASK 0x0100 /* GP1_DB */ | ||
| 2940 | #define WM5100_GP1_DB_SHIFT 8 /* GP1_DB */ | ||
| 2941 | #define WM5100_GP1_DB_WIDTH 1 /* GP1_DB */ | ||
| 2942 | #define WM5100_GP1_LVL 0x0040 /* GP1_LVL */ | ||
| 2943 | #define WM5100_GP1_LVL_MASK 0x0040 /* GP1_LVL */ | ||
| 2944 | #define WM5100_GP1_LVL_SHIFT 6 /* GP1_LVL */ | ||
| 2945 | #define WM5100_GP1_LVL_WIDTH 1 /* GP1_LVL */ | ||
| 2946 | #define WM5100_GP1_FN_MASK 0x003F /* GP1_FN - [5:0] */ | ||
| 2947 | #define WM5100_GP1_FN_SHIFT 0 /* GP1_FN - [5:0] */ | ||
| 2948 | #define WM5100_GP1_FN_WIDTH 6 /* GP1_FN - [5:0] */ | ||
| 2949 | |||
| 2950 | /* | ||
| 2951 | * R3073 (0xC01) - GPIO CTRL 2 | ||
| 2952 | */ | ||
| 2953 | #define WM5100_GP2_DIR 0x8000 /* GP2_DIR */ | ||
| 2954 | #define WM5100_GP2_DIR_MASK 0x8000 /* GP2_DIR */ | ||
| 2955 | #define WM5100_GP2_DIR_SHIFT 15 /* GP2_DIR */ | ||
| 2956 | #define WM5100_GP2_DIR_WIDTH 1 /* GP2_DIR */ | ||
| 2957 | #define WM5100_GP2_PU 0x4000 /* GP2_PU */ | ||
| 2958 | #define WM5100_GP2_PU_MASK 0x4000 /* GP2_PU */ | ||
| 2959 | #define WM5100_GP2_PU_SHIFT 14 /* GP2_PU */ | ||
| 2960 | #define WM5100_GP2_PU_WIDTH 1 /* GP2_PU */ | ||
| 2961 | #define WM5100_GP2_PD 0x2000 /* GP2_PD */ | ||
| 2962 | #define WM5100_GP2_PD_MASK 0x2000 /* GP2_PD */ | ||
| 2963 | #define WM5100_GP2_PD_SHIFT 13 /* GP2_PD */ | ||
| 2964 | #define WM5100_GP2_PD_WIDTH 1 /* GP2_PD */ | ||
| 2965 | #define WM5100_GP2_POL 0x0400 /* GP2_POL */ | ||
| 2966 | #define WM5100_GP2_POL_MASK 0x0400 /* GP2_POL */ | ||
| 2967 | #define WM5100_GP2_POL_SHIFT 10 /* GP2_POL */ | ||
| 2968 | #define WM5100_GP2_POL_WIDTH 1 /* GP2_POL */ | ||
| 2969 | #define WM5100_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ | ||
| 2970 | #define WM5100_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ | ||
| 2971 | #define WM5100_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ | ||
| 2972 | #define WM5100_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ | ||
| 2973 | #define WM5100_GP2_DB 0x0100 /* GP2_DB */ | ||
| 2974 | #define WM5100_GP2_DB_MASK 0x0100 /* GP2_DB */ | ||
| 2975 | #define WM5100_GP2_DB_SHIFT 8 /* GP2_DB */ | ||
| 2976 | #define WM5100_GP2_DB_WIDTH 1 /* GP2_DB */ | ||
| 2977 | #define WM5100_GP2_LVL 0x0040 /* GP2_LVL */ | ||
| 2978 | #define WM5100_GP2_LVL_MASK 0x0040 /* GP2_LVL */ | ||
| 2979 | #define WM5100_GP2_LVL_SHIFT 6 /* GP2_LVL */ | ||
| 2980 | #define WM5100_GP2_LVL_WIDTH 1 /* GP2_LVL */ | ||
| 2981 | #define WM5100_GP2_FN_MASK 0x003F /* GP2_FN - [5:0] */ | ||
| 2982 | #define WM5100_GP2_FN_SHIFT 0 /* GP2_FN - [5:0] */ | ||
| 2983 | #define WM5100_GP2_FN_WIDTH 6 /* GP2_FN - [5:0] */ | ||
| 2984 | |||
| 2985 | /* | ||
| 2986 | * R3074 (0xC02) - GPIO CTRL 3 | ||
| 2987 | */ | ||
| 2988 | #define WM5100_GP3_DIR 0x8000 /* GP3_DIR */ | ||
| 2989 | #define WM5100_GP3_DIR_MASK 0x8000 /* GP3_DIR */ | ||
| 2990 | #define WM5100_GP3_DIR_SHIFT 15 /* GP3_DIR */ | ||
| 2991 | #define WM5100_GP3_DIR_WIDTH 1 /* GP3_DIR */ | ||
| 2992 | #define WM5100_GP3_PU 0x4000 /* GP3_PU */ | ||
| 2993 | #define WM5100_GP3_PU_MASK 0x4000 /* GP3_PU */ | ||
| 2994 | #define WM5100_GP3_PU_SHIFT 14 /* GP3_PU */ | ||
| 2995 | #define WM5100_GP3_PU_WIDTH 1 /* GP3_PU */ | ||
| 2996 | #define WM5100_GP3_PD 0x2000 /* GP3_PD */ | ||
| 2997 | #define WM5100_GP3_PD_MASK 0x2000 /* GP3_PD */ | ||
| 2998 | #define WM5100_GP3_PD_SHIFT 13 /* GP3_PD */ | ||
| 2999 | #define WM5100_GP3_PD_WIDTH 1 /* GP3_PD */ | ||
| 3000 | #define WM5100_GP3_POL 0x0400 /* GP3_POL */ | ||
| 3001 | #define WM5100_GP3_POL_MASK 0x0400 /* GP3_POL */ | ||
| 3002 | #define WM5100_GP3_POL_SHIFT 10 /* GP3_POL */ | ||
| 3003 | #define WM5100_GP3_POL_WIDTH 1 /* GP3_POL */ | ||
| 3004 | #define WM5100_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ | ||
| 3005 | #define WM5100_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ | ||
| 3006 | #define WM5100_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ | ||
| 3007 | #define WM5100_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ | ||
| 3008 | #define WM5100_GP3_DB 0x0100 /* GP3_DB */ | ||
| 3009 | #define WM5100_GP3_DB_MASK 0x0100 /* GP3_DB */ | ||
| 3010 | #define WM5100_GP3_DB_SHIFT 8 /* GP3_DB */ | ||
| 3011 | #define WM5100_GP3_DB_WIDTH 1 /* GP3_DB */ | ||
| 3012 | #define WM5100_GP3_LVL 0x0040 /* GP3_LVL */ | ||
| 3013 | #define WM5100_GP3_LVL_MASK 0x0040 /* GP3_LVL */ | ||
| 3014 | #define WM5100_GP3_LVL_SHIFT 6 /* GP3_LVL */ | ||
| 3015 | #define WM5100_GP3_LVL_WIDTH 1 /* GP3_LVL */ | ||
| 3016 | #define WM5100_GP3_FN_MASK 0x003F /* GP3_FN - [5:0] */ | ||
| 3017 | #define WM5100_GP3_FN_SHIFT 0 /* GP3_FN - [5:0] */ | ||
| 3018 | #define WM5100_GP3_FN_WIDTH 6 /* GP3_FN - [5:0] */ | ||
| 3019 | |||
| 3020 | /* | ||
| 3021 | * R3075 (0xC03) - GPIO CTRL 4 | ||
| 3022 | */ | ||
| 3023 | #define WM5100_GP4_DIR 0x8000 /* GP4_DIR */ | ||
| 3024 | #define WM5100_GP4_DIR_MASK 0x8000 /* GP4_DIR */ | ||
| 3025 | #define WM5100_GP4_DIR_SHIFT 15 /* GP4_DIR */ | ||
| 3026 | #define WM5100_GP4_DIR_WIDTH 1 /* GP4_DIR */ | ||
| 3027 | #define WM5100_GP4_PU 0x4000 /* GP4_PU */ | ||
| 3028 | #define WM5100_GP4_PU_MASK 0x4000 /* GP4_PU */ | ||
| 3029 | #define WM5100_GP4_PU_SHIFT 14 /* GP4_PU */ | ||
| 3030 | #define WM5100_GP4_PU_WIDTH 1 /* GP4_PU */ | ||
| 3031 | #define WM5100_GP4_PD 0x2000 /* GP4_PD */ | ||
| 3032 | #define WM5100_GP4_PD_MASK 0x2000 /* GP4_PD */ | ||
| 3033 | #define WM5100_GP4_PD_SHIFT 13 /* GP4_PD */ | ||
| 3034 | #define WM5100_GP4_PD_WIDTH 1 /* GP4_PD */ | ||
| 3035 | #define WM5100_GP4_POL 0x0400 /* GP4_POL */ | ||
| 3036 | #define WM5100_GP4_POL_MASK 0x0400 /* GP4_POL */ | ||
| 3037 | #define WM5100_GP4_POL_SHIFT 10 /* GP4_POL */ | ||
| 3038 | #define WM5100_GP4_POL_WIDTH 1 /* GP4_POL */ | ||
| 3039 | #define WM5100_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ | ||
| 3040 | #define WM5100_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ | ||
| 3041 | #define WM5100_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ | ||
| 3042 | #define WM5100_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ | ||
| 3043 | #define WM5100_GP4_DB 0x0100 /* GP4_DB */ | ||
| 3044 | #define WM5100_GP4_DB_MASK 0x0100 /* GP4_DB */ | ||
| 3045 | #define WM5100_GP4_DB_SHIFT 8 /* GP4_DB */ | ||
| 3046 | #define WM5100_GP4_DB_WIDTH 1 /* GP4_DB */ | ||
| 3047 | #define WM5100_GP4_LVL 0x0040 /* GP4_LVL */ | ||
| 3048 | #define WM5100_GP4_LVL_MASK 0x0040 /* GP4_LVL */ | ||
| 3049 | #define WM5100_GP4_LVL_SHIFT 6 /* GP4_LVL */ | ||
| 3050 | #define WM5100_GP4_LVL_WIDTH 1 /* GP4_LVL */ | ||
| 3051 | #define WM5100_GP4_FN_MASK 0x003F /* GP4_FN - [5:0] */ | ||
| 3052 | #define WM5100_GP4_FN_SHIFT 0 /* GP4_FN - [5:0] */ | ||
| 3053 | #define WM5100_GP4_FN_WIDTH 6 /* GP4_FN - [5:0] */ | ||
| 3054 | |||
| 3055 | /* | ||
| 3056 | * R3076 (0xC04) - GPIO CTRL 5 | ||
| 3057 | */ | ||
| 3058 | #define WM5100_GP5_DIR 0x8000 /* GP5_DIR */ | ||
| 3059 | #define WM5100_GP5_DIR_MASK 0x8000 /* GP5_DIR */ | ||
| 3060 | #define WM5100_GP5_DIR_SHIFT 15 /* GP5_DIR */ | ||
| 3061 | #define WM5100_GP5_DIR_WIDTH 1 /* GP5_DIR */ | ||
| 3062 | #define WM5100_GP5_PU 0x4000 /* GP5_PU */ | ||
| 3063 | #define WM5100_GP5_PU_MASK 0x4000 /* GP5_PU */ | ||
| 3064 | #define WM5100_GP5_PU_SHIFT 14 /* GP5_PU */ | ||
| 3065 | #define WM5100_GP5_PU_WIDTH 1 /* GP5_PU */ | ||
| 3066 | #define WM5100_GP5_PD 0x2000 /* GP5_PD */ | ||
| 3067 | #define WM5100_GP5_PD_MASK 0x2000 /* GP5_PD */ | ||
| 3068 | #define WM5100_GP5_PD_SHIFT 13 /* GP5_PD */ | ||
| 3069 | #define WM5100_GP5_PD_WIDTH 1 /* GP5_PD */ | ||
| 3070 | #define WM5100_GP5_POL 0x0400 /* GP5_POL */ | ||
| 3071 | #define WM5100_GP5_POL_MASK 0x0400 /* GP5_POL */ | ||
| 3072 | #define WM5100_GP5_POL_SHIFT 10 /* GP5_POL */ | ||
| 3073 | #define WM5100_GP5_POL_WIDTH 1 /* GP5_POL */ | ||
| 3074 | #define WM5100_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */ | ||
| 3075 | #define WM5100_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */ | ||
| 3076 | #define WM5100_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */ | ||
| 3077 | #define WM5100_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */ | ||
| 3078 | #define WM5100_GP5_DB 0x0100 /* GP5_DB */ | ||
| 3079 | #define WM5100_GP5_DB_MASK 0x0100 /* GP5_DB */ | ||
| 3080 | #define WM5100_GP5_DB_SHIFT 8 /* GP5_DB */ | ||
| 3081 | #define WM5100_GP5_DB_WIDTH 1 /* GP5_DB */ | ||
| 3082 | #define WM5100_GP5_LVL 0x0040 /* GP5_LVL */ | ||
| 3083 | #define WM5100_GP5_LVL_MASK 0x0040 /* GP5_LVL */ | ||
| 3084 | #define WM5100_GP5_LVL_SHIFT 6 /* GP5_LVL */ | ||
| 3085 | #define WM5100_GP5_LVL_WIDTH 1 /* GP5_LVL */ | ||
| 3086 | #define WM5100_GP5_FN_MASK 0x003F /* GP5_FN - [5:0] */ | ||
| 3087 | #define WM5100_GP5_FN_SHIFT 0 /* GP5_FN - [5:0] */ | ||
| 3088 | #define WM5100_GP5_FN_WIDTH 6 /* GP5_FN - [5:0] */ | ||
| 3089 | |||
| 3090 | /* | ||
| 3091 | * R3077 (0xC05) - GPIO CTRL 6 | ||
| 3092 | */ | ||
| 3093 | #define WM5100_GP6_DIR 0x8000 /* GP6_DIR */ | ||
| 3094 | #define WM5100_GP6_DIR_MASK 0x8000 /* GP6_DIR */ | ||
| 3095 | #define WM5100_GP6_DIR_SHIFT 15 /* GP6_DIR */ | ||
| 3096 | #define WM5100_GP6_DIR_WIDTH 1 /* GP6_DIR */ | ||
| 3097 | #define WM5100_GP6_PU 0x4000 /* GP6_PU */ | ||
| 3098 | #define WM5100_GP6_PU_MASK 0x4000 /* GP6_PU */ | ||
| 3099 | #define WM5100_GP6_PU_SHIFT 14 /* GP6_PU */ | ||
| 3100 | #define WM5100_GP6_PU_WIDTH 1 /* GP6_PU */ | ||
| 3101 | #define WM5100_GP6_PD 0x2000 /* GP6_PD */ | ||
| 3102 | #define WM5100_GP6_PD_MASK 0x2000 /* GP6_PD */ | ||
| 3103 | #define WM5100_GP6_PD_SHIFT 13 /* GP6_PD */ | ||
| 3104 | #define WM5100_GP6_PD_WIDTH 1 /* GP6_PD */ | ||
| 3105 | #define WM5100_GP6_POL 0x0400 /* GP6_POL */ | ||
| 3106 | #define WM5100_GP6_POL_MASK 0x0400 /* GP6_POL */ | ||
| 3107 | #define WM5100_GP6_POL_SHIFT 10 /* GP6_POL */ | ||
| 3108 | #define WM5100_GP6_POL_WIDTH 1 /* GP6_POL */ | ||
| 3109 | #define WM5100_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */ | ||
| 3110 | #define WM5100_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */ | ||
| 3111 | #define WM5100_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */ | ||
| 3112 | #define WM5100_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */ | ||
| 3113 | #define WM5100_GP6_DB 0x0100 /* GP6_DB */ | ||
| 3114 | #define WM5100_GP6_DB_MASK 0x0100 /* GP6_DB */ | ||
| 3115 | #define WM5100_GP6_DB_SHIFT 8 /* GP6_DB */ | ||
| 3116 | #define WM5100_GP6_DB_WIDTH 1 /* GP6_DB */ | ||
| 3117 | #define WM5100_GP6_LVL 0x0040 /* GP6_LVL */ | ||
| 3118 | #define WM5100_GP6_LVL_MASK 0x0040 /* GP6_LVL */ | ||
| 3119 | #define WM5100_GP6_LVL_SHIFT 6 /* GP6_LVL */ | ||
| 3120 | #define WM5100_GP6_LVL_WIDTH 1 /* GP6_LVL */ | ||
| 3121 | #define WM5100_GP6_FN_MASK 0x003F /* GP6_FN - [5:0] */ | ||
| 3122 | #define WM5100_GP6_FN_SHIFT 0 /* GP6_FN - [5:0] */ | ||
| 3123 | #define WM5100_GP6_FN_WIDTH 6 /* GP6_FN - [5:0] */ | ||
| 3124 | |||
| 3125 | /* | ||
| 3126 | * R3107 (0xC23) - Misc Pad Ctrl 1 | ||
| 3127 | */ | ||
| 3128 | #define WM5100_LDO1ENA_PD 0x8000 /* LDO1ENA_PD */ | ||
| 3129 | #define WM5100_LDO1ENA_PD_MASK 0x8000 /* LDO1ENA_PD */ | ||
| 3130 | #define WM5100_LDO1ENA_PD_SHIFT 15 /* LDO1ENA_PD */ | ||
| 3131 | #define WM5100_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ | ||
| 3132 | #define WM5100_MCLK2_PD 0x2000 /* MCLK2_PD */ | ||
| 3133 | #define WM5100_MCLK2_PD_MASK 0x2000 /* MCLK2_PD */ | ||
| 3134 | #define WM5100_MCLK2_PD_SHIFT 13 /* MCLK2_PD */ | ||
| 3135 | #define WM5100_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ | ||
| 3136 | #define WM5100_MCLK1_PD 0x1000 /* MCLK1_PD */ | ||
| 3137 | #define WM5100_MCLK1_PD_MASK 0x1000 /* MCLK1_PD */ | ||
| 3138 | #define WM5100_MCLK1_PD_SHIFT 12 /* MCLK1_PD */ | ||
| 3139 | #define WM5100_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ | ||
| 3140 | #define WM5100_RESET_PU 0x0002 /* RESET_PU */ | ||
| 3141 | #define WM5100_RESET_PU_MASK 0x0002 /* RESET_PU */ | ||
| 3142 | #define WM5100_RESET_PU_SHIFT 1 /* RESET_PU */ | ||
| 3143 | #define WM5100_RESET_PU_WIDTH 1 /* RESET_PU */ | ||
| 3144 | #define WM5100_ADDR_PD 0x0001 /* ADDR_PD */ | ||
| 3145 | #define WM5100_ADDR_PD_MASK 0x0001 /* ADDR_PD */ | ||
| 3146 | #define WM5100_ADDR_PD_SHIFT 0 /* ADDR_PD */ | ||
| 3147 | #define WM5100_ADDR_PD_WIDTH 1 /* ADDR_PD */ | ||
| 3148 | |||
| 3149 | /* | ||
| 3150 | * R3108 (0xC24) - Misc Pad Ctrl 2 | ||
| 3151 | */ | ||
| 3152 | #define WM5100_DMICDAT4_PD 0x0008 /* DMICDAT4_PD */ | ||
| 3153 | #define WM5100_DMICDAT4_PD_MASK 0x0008 /* DMICDAT4_PD */ | ||
| 3154 | #define WM5100_DMICDAT4_PD_SHIFT 3 /* DMICDAT4_PD */ | ||
| 3155 | #define WM5100_DMICDAT4_PD_WIDTH 1 /* DMICDAT4_PD */ | ||
| 3156 | #define WM5100_DMICDAT3_PD 0x0004 /* DMICDAT3_PD */ | ||
| 3157 | #define WM5100_DMICDAT3_PD_MASK 0x0004 /* DMICDAT3_PD */ | ||
| 3158 | #define WM5100_DMICDAT3_PD_SHIFT 2 /* DMICDAT3_PD */ | ||
| 3159 | #define WM5100_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */ | ||
| 3160 | #define WM5100_DMICDAT2_PD 0x0002 /* DMICDAT2_PD */ | ||
| 3161 | #define WM5100_DMICDAT2_PD_MASK 0x0002 /* DMICDAT2_PD */ | ||
| 3162 | #define WM5100_DMICDAT2_PD_SHIFT 1 /* DMICDAT2_PD */ | ||
| 3163 | #define WM5100_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ | ||
| 3164 | #define WM5100_DMICDAT1_PD 0x0001 /* DMICDAT1_PD */ | ||
| 3165 | #define WM5100_DMICDAT1_PD_MASK 0x0001 /* DMICDAT1_PD */ | ||
| 3166 | #define WM5100_DMICDAT1_PD_SHIFT 0 /* DMICDAT1_PD */ | ||
| 3167 | #define WM5100_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ | ||
| 3168 | |||
| 3169 | /* | ||
| 3170 | * R3109 (0xC25) - Misc Pad Ctrl 3 | ||
| 3171 | */ | ||
| 3172 | #define WM5100_AIF1RXLRCLK_PU 0x0020 /* AIF1RXLRCLK_PU */ | ||
| 3173 | #define WM5100_AIF1RXLRCLK_PU_MASK 0x0020 /* AIF1RXLRCLK_PU */ | ||
| 3174 | #define WM5100_AIF1RXLRCLK_PU_SHIFT 5 /* AIF1RXLRCLK_PU */ | ||
| 3175 | #define WM5100_AIF1RXLRCLK_PU_WIDTH 1 /* AIF1RXLRCLK_PU */ | ||
| 3176 | #define WM5100_AIF1RXLRCLK_PD 0x0010 /* AIF1RXLRCLK_PD */ | ||
| 3177 | #define WM5100_AIF1RXLRCLK_PD_MASK 0x0010 /* AIF1RXLRCLK_PD */ | ||
| 3178 | #define WM5100_AIF1RXLRCLK_PD_SHIFT 4 /* AIF1RXLRCLK_PD */ | ||
| 3179 | #define WM5100_AIF1RXLRCLK_PD_WIDTH 1 /* AIF1RXLRCLK_PD */ | ||
| 3180 | #define WM5100_AIF1BCLK_PU 0x0008 /* AIF1BCLK_PU */ | ||
| 3181 | #define WM5100_AIF1BCLK_PU_MASK 0x0008 /* AIF1BCLK_PU */ | ||
| 3182 | #define WM5100_AIF1BCLK_PU_SHIFT 3 /* AIF1BCLK_PU */ | ||
| 3183 | #define WM5100_AIF1BCLK_PU_WIDTH 1 /* AIF1BCLK_PU */ | ||
| 3184 | #define WM5100_AIF1BCLK_PD 0x0004 /* AIF1BCLK_PD */ | ||
| 3185 | #define WM5100_AIF1BCLK_PD_MASK 0x0004 /* AIF1BCLK_PD */ | ||
| 3186 | #define WM5100_AIF1BCLK_PD_SHIFT 2 /* AIF1BCLK_PD */ | ||
| 3187 | #define WM5100_AIF1BCLK_PD_WIDTH 1 /* AIF1BCLK_PD */ | ||
| 3188 | #define WM5100_AIF1RXDAT_PU 0x0002 /* AIF1RXDAT_PU */ | ||
| 3189 | #define WM5100_AIF1RXDAT_PU_MASK 0x0002 /* AIF1RXDAT_PU */ | ||
| 3190 | #define WM5100_AIF1RXDAT_PU_SHIFT 1 /* AIF1RXDAT_PU */ | ||
| 3191 | #define WM5100_AIF1RXDAT_PU_WIDTH 1 /* AIF1RXDAT_PU */ | ||
| 3192 | #define WM5100_AIF1RXDAT_PD 0x0001 /* AIF1RXDAT_PD */ | ||
| 3193 | #define WM5100_AIF1RXDAT_PD_MASK 0x0001 /* AIF1RXDAT_PD */ | ||
| 3194 | #define WM5100_AIF1RXDAT_PD_SHIFT 0 /* AIF1RXDAT_PD */ | ||
| 3195 | #define WM5100_AIF1RXDAT_PD_WIDTH 1 /* AIF1RXDAT_PD */ | ||
| 3196 | |||
| 3197 | /* | ||
| 3198 | * R3110 (0xC26) - Misc Pad Ctrl 4 | ||
| 3199 | */ | ||
| 3200 | #define WM5100_AIF2RXLRCLK_PU 0x0020 /* AIF2RXLRCLK_PU */ | ||
| 3201 | #define WM5100_AIF2RXLRCLK_PU_MASK 0x0020 /* AIF2RXLRCLK_PU */ | ||
| 3202 | #define WM5100_AIF2RXLRCLK_PU_SHIFT 5 /* AIF2RXLRCLK_PU */ | ||
| 3203 | #define WM5100_AIF2RXLRCLK_PU_WIDTH 1 /* AIF2RXLRCLK_PU */ | ||
| 3204 | #define WM5100_AIF2RXLRCLK_PD 0x0010 /* AIF2RXLRCLK_PD */ | ||
| 3205 | #define WM5100_AIF2RXLRCLK_PD_MASK 0x0010 /* AIF2RXLRCLK_PD */ | ||
| 3206 | #define WM5100_AIF2RXLRCLK_PD_SHIFT 4 /* AIF2RXLRCLK_PD */ | ||
| 3207 | #define WM5100_AIF2RXLRCLK_PD_WIDTH 1 /* AIF2RXLRCLK_PD */ | ||
| 3208 | #define WM5100_AIF2BCLK_PU 0x0008 /* AIF2BCLK_PU */ | ||
| 3209 | #define WM5100_AIF2BCLK_PU_MASK 0x0008 /* AIF2BCLK_PU */ | ||
| 3210 | #define WM5100_AIF2BCLK_PU_SHIFT 3 /* AIF2BCLK_PU */ | ||
| 3211 | #define WM5100_AIF2BCLK_PU_WIDTH 1 /* AIF2BCLK_PU */ | ||
| 3212 | #define WM5100_AIF2BCLK_PD 0x0004 /* AIF2BCLK_PD */ | ||
| 3213 | #define WM5100_AIF2BCLK_PD_MASK 0x0004 /* AIF2BCLK_PD */ | ||
| 3214 | #define WM5100_AIF2BCLK_PD_SHIFT 2 /* AIF2BCLK_PD */ | ||
| 3215 | #define WM5100_AIF2BCLK_PD_WIDTH 1 /* AIF2BCLK_PD */ | ||
| 3216 | #define WM5100_AIF2RXDAT_PU 0x0002 /* AIF2RXDAT_PU */ | ||
| 3217 | #define WM5100_AIF2RXDAT_PU_MASK 0x0002 /* AIF2RXDAT_PU */ | ||
| 3218 | #define WM5100_AIF2RXDAT_PU_SHIFT 1 /* AIF2RXDAT_PU */ | ||
| 3219 | #define WM5100_AIF2RXDAT_PU_WIDTH 1 /* AIF2RXDAT_PU */ | ||
| 3220 | #define WM5100_AIF2RXDAT_PD 0x0001 /* AIF2RXDAT_PD */ | ||
| 3221 | #define WM5100_AIF2RXDAT_PD_MASK 0x0001 /* AIF2RXDAT_PD */ | ||
| 3222 | #define WM5100_AIF2RXDAT_PD_SHIFT 0 /* AIF2RXDAT_PD */ | ||
| 3223 | #define WM5100_AIF2RXDAT_PD_WIDTH 1 /* AIF2RXDAT_PD */ | ||
| 3224 | |||
| 3225 | /* | ||
| 3226 | * R3111 (0xC27) - Misc Pad Ctrl 5 | ||
| 3227 | */ | ||
| 3228 | #define WM5100_AIF3RXLRCLK_PU 0x0020 /* AIF3RXLRCLK_PU */ | ||
| 3229 | #define WM5100_AIF3RXLRCLK_PU_MASK 0x0020 /* AIF3RXLRCLK_PU */ | ||
| 3230 | #define WM5100_AIF3RXLRCLK_PU_SHIFT 5 /* AIF3RXLRCLK_PU */ | ||
| 3231 | #define WM5100_AIF3RXLRCLK_PU_WIDTH 1 /* AIF3RXLRCLK_PU */ | ||
| 3232 | #define WM5100_AIF3RXLRCLK_PD 0x0010 /* AIF3RXLRCLK_PD */ | ||
| 3233 | #define WM5100_AIF3RXLRCLK_PD_MASK 0x0010 /* AIF3RXLRCLK_PD */ | ||
| 3234 | #define WM5100_AIF3RXLRCLK_PD_SHIFT 4 /* AIF3RXLRCLK_PD */ | ||
| 3235 | #define WM5100_AIF3RXLRCLK_PD_WIDTH 1 /* AIF3RXLRCLK_PD */ | ||
| 3236 | #define WM5100_AIF3BCLK_PU 0x0008 /* AIF3BCLK_PU */ | ||
| 3237 | #define WM5100_AIF3BCLK_PU_MASK 0x0008 /* AIF3BCLK_PU */ | ||
| 3238 | #define WM5100_AIF3BCLK_PU_SHIFT 3 /* AIF3BCLK_PU */ | ||
| 3239 | #define WM5100_AIF3BCLK_PU_WIDTH 1 /* AIF3BCLK_PU */ | ||
| 3240 | #define WM5100_AIF3BCLK_PD 0x0004 /* AIF3BCLK_PD */ | ||
| 3241 | #define WM5100_AIF3BCLK_PD_MASK 0x0004 /* AIF3BCLK_PD */ | ||
| 3242 | #define WM5100_AIF3BCLK_PD_SHIFT 2 /* AIF3BCLK_PD */ | ||
| 3243 | #define WM5100_AIF3BCLK_PD_WIDTH 1 /* AIF3BCLK_PD */ | ||
| 3244 | #define WM5100_AIF3RXDAT_PU 0x0002 /* AIF3RXDAT_PU */ | ||
| 3245 | #define WM5100_AIF3RXDAT_PU_MASK 0x0002 /* AIF3RXDAT_PU */ | ||
| 3246 | #define WM5100_AIF3RXDAT_PU_SHIFT 1 /* AIF3RXDAT_PU */ | ||
| 3247 | #define WM5100_AIF3RXDAT_PU_WIDTH 1 /* AIF3RXDAT_PU */ | ||
| 3248 | #define WM5100_AIF3RXDAT_PD 0x0001 /* AIF3RXDAT_PD */ | ||
| 3249 | #define WM5100_AIF3RXDAT_PD_MASK 0x0001 /* AIF3RXDAT_PD */ | ||
| 3250 | #define WM5100_AIF3RXDAT_PD_SHIFT 0 /* AIF3RXDAT_PD */ | ||
| 3251 | #define WM5100_AIF3RXDAT_PD_WIDTH 1 /* AIF3RXDAT_PD */ | ||
| 3252 | |||
| 3253 | /* | ||
| 3254 | * R3112 (0xC28) - Misc GPIO 1 | ||
| 3255 | */ | ||
| 3256 | #define WM5100_OPCLK_SEL_MASK 0x0003 /* OPCLK_SEL - [1:0] */ | ||
| 3257 | #define WM5100_OPCLK_SEL_SHIFT 0 /* OPCLK_SEL - [1:0] */ | ||
| 3258 | #define WM5100_OPCLK_SEL_WIDTH 2 /* OPCLK_SEL - [1:0] */ | ||
| 3259 | |||
| 3260 | /* | ||
| 3261 | * R3328 (0xD00) - Interrupt Status 1 | ||
| 3262 | */ | ||
| 3263 | #define WM5100_GP6_EINT 0x0020 /* GP6_EINT */ | ||
| 3264 | #define WM5100_GP6_EINT_MASK 0x0020 /* GP6_EINT */ | ||
| 3265 | #define WM5100_GP6_EINT_SHIFT 5 /* GP6_EINT */ | ||
| 3266 | #define WM5100_GP6_EINT_WIDTH 1 /* GP6_EINT */ | ||
| 3267 | #define WM5100_GP5_EINT 0x0010 /* GP5_EINT */ | ||
| 3268 | #define WM5100_GP5_EINT_MASK 0x0010 /* GP5_EINT */ | ||
| 3269 | #define WM5100_GP5_EINT_SHIFT 4 /* GP5_EINT */ | ||
| 3270 | #define WM5100_GP5_EINT_WIDTH 1 /* GP5_EINT */ | ||
| 3271 | #define WM5100_GP4_EINT 0x0008 /* GP4_EINT */ | ||
| 3272 | #define WM5100_GP4_EINT_MASK 0x0008 /* GP4_EINT */ | ||
| 3273 | #define WM5100_GP4_EINT_SHIFT 3 /* GP4_EINT */ | ||
| 3274 | #define WM5100_GP4_EINT_WIDTH 1 /* GP4_EINT */ | ||
| 3275 | #define WM5100_GP3_EINT 0x0004 /* GP3_EINT */ | ||
| 3276 | #define WM5100_GP3_EINT_MASK 0x0004 /* GP3_EINT */ | ||
| 3277 | #define WM5100_GP3_EINT_SHIFT 2 /* GP3_EINT */ | ||
| 3278 | #define WM5100_GP3_EINT_WIDTH 1 /* GP3_EINT */ | ||
| 3279 | #define WM5100_GP2_EINT 0x0002 /* GP2_EINT */ | ||
| 3280 | #define WM5100_GP2_EINT_MASK 0x0002 /* GP2_EINT */ | ||
| 3281 | #define WM5100_GP2_EINT_SHIFT 1 /* GP2_EINT */ | ||
| 3282 | #define WM5100_GP2_EINT_WIDTH 1 /* GP2_EINT */ | ||
| 3283 | #define WM5100_GP1_EINT 0x0001 /* GP1_EINT */ | ||
| 3284 | #define WM5100_GP1_EINT_MASK 0x0001 /* GP1_EINT */ | ||
| 3285 | #define WM5100_GP1_EINT_SHIFT 0 /* GP1_EINT */ | ||
| 3286 | #define WM5100_GP1_EINT_WIDTH 1 /* GP1_EINT */ | ||
| 3287 | |||
| 3288 | /* | ||
| 3289 | * R3329 (0xD01) - Interrupt Status 2 | ||
| 3290 | */ | ||
| 3291 | #define WM5100_DSP_IRQ6_EINT 0x0020 /* DSP_IRQ6_EINT */ | ||
| 3292 | #define WM5100_DSP_IRQ6_EINT_MASK 0x0020 /* DSP_IRQ6_EINT */ | ||
| 3293 | #define WM5100_DSP_IRQ6_EINT_SHIFT 5 /* DSP_IRQ6_EINT */ | ||
| 3294 | #define WM5100_DSP_IRQ6_EINT_WIDTH 1 /* DSP_IRQ6_EINT */ | ||
| 3295 | #define WM5100_DSP_IRQ5_EINT 0x0010 /* DSP_IRQ5_EINT */ | ||
| 3296 | #define WM5100_DSP_IRQ5_EINT_MASK 0x0010 /* DSP_IRQ5_EINT */ | ||
| 3297 | #define WM5100_DSP_IRQ5_EINT_SHIFT 4 /* DSP_IRQ5_EINT */ | ||
| 3298 | #define WM5100_DSP_IRQ5_EINT_WIDTH 1 /* DSP_IRQ5_EINT */ | ||
| 3299 | #define WM5100_DSP_IRQ4_EINT 0x0008 /* DSP_IRQ4_EINT */ | ||
| 3300 | #define WM5100_DSP_IRQ4_EINT_MASK 0x0008 /* DSP_IRQ4_EINT */ | ||
| 3301 | #define WM5100_DSP_IRQ4_EINT_SHIFT 3 /* DSP_IRQ4_EINT */ | ||
| 3302 | #define WM5100_DSP_IRQ4_EINT_WIDTH 1 /* DSP_IRQ4_EINT */ | ||
| 3303 | #define WM5100_DSP_IRQ3_EINT 0x0004 /* DSP_IRQ3_EINT */ | ||
| 3304 | #define WM5100_DSP_IRQ3_EINT_MASK 0x0004 /* DSP_IRQ3_EINT */ | ||
| 3305 | #define WM5100_DSP_IRQ3_EINT_SHIFT 2 /* DSP_IRQ3_EINT */ | ||
| 3306 | #define WM5100_DSP_IRQ3_EINT_WIDTH 1 /* DSP_IRQ3_EINT */ | ||
| 3307 | #define WM5100_DSP_IRQ2_EINT 0x0002 /* DSP_IRQ2_EINT */ | ||
| 3308 | #define WM5100_DSP_IRQ2_EINT_MASK 0x0002 /* DSP_IRQ2_EINT */ | ||
| 3309 | #define WM5100_DSP_IRQ2_EINT_SHIFT 1 /* DSP_IRQ2_EINT */ | ||
| 3310 | #define WM5100_DSP_IRQ2_EINT_WIDTH 1 /* DSP_IRQ2_EINT */ | ||
| 3311 | #define WM5100_DSP_IRQ1_EINT 0x0001 /* DSP_IRQ1_EINT */ | ||
| 3312 | #define WM5100_DSP_IRQ1_EINT_MASK 0x0001 /* DSP_IRQ1_EINT */ | ||
| 3313 | #define WM5100_DSP_IRQ1_EINT_SHIFT 0 /* DSP_IRQ1_EINT */ | ||
| 3314 | #define WM5100_DSP_IRQ1_EINT_WIDTH 1 /* DSP_IRQ1_EINT */ | ||
| 3315 | |||
| 3316 | /* | ||
| 3317 | * R3330 (0xD02) - Interrupt Status 3 | ||
| 3318 | */ | ||
| 3319 | #define WM5100_SPK_SHUTDOWN_WARN_EINT 0x8000 /* SPK_SHUTDOWN_WARN_EINT */ | ||
| 3320 | #define WM5100_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* SPK_SHUTDOWN_WARN_EINT */ | ||
| 3321 | #define WM5100_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* SPK_SHUTDOWN_WARN_EINT */ | ||
| 3322 | #define WM5100_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* SPK_SHUTDOWN_WARN_EINT */ | ||
| 3323 | #define WM5100_SPK_SHUTDOWN_EINT 0x4000 /* SPK_SHUTDOWN_EINT */ | ||
| 3324 | #define WM5100_SPK_SHUTDOWN_EINT_MASK 0x4000 /* SPK_SHUTDOWN_EINT */ | ||
| 3325 | #define WM5100_SPK_SHUTDOWN_EINT_SHIFT 14 /* SPK_SHUTDOWN_EINT */ | ||
| 3326 | #define WM5100_SPK_SHUTDOWN_EINT_WIDTH 1 /* SPK_SHUTDOWN_EINT */ | ||
| 3327 | #define WM5100_HPDET_EINT 0x2000 /* HPDET_EINT */ | ||
| 3328 | #define WM5100_HPDET_EINT_MASK 0x2000 /* HPDET_EINT */ | ||
| 3329 | #define WM5100_HPDET_EINT_SHIFT 13 /* HPDET_EINT */ | ||
| 3330 | #define WM5100_HPDET_EINT_WIDTH 1 /* HPDET_EINT */ | ||
| 3331 | #define WM5100_ACCDET_EINT 0x1000 /* ACCDET_EINT */ | ||
| 3332 | #define WM5100_ACCDET_EINT_MASK 0x1000 /* ACCDET_EINT */ | ||
| 3333 | #define WM5100_ACCDET_EINT_SHIFT 12 /* ACCDET_EINT */ | ||
| 3334 | #define WM5100_ACCDET_EINT_WIDTH 1 /* ACCDET_EINT */ | ||
| 3335 | #define WM5100_DRC_SIG_DET_EINT 0x0200 /* DRC_SIG_DET_EINT */ | ||
| 3336 | #define WM5100_DRC_SIG_DET_EINT_MASK 0x0200 /* DRC_SIG_DET_EINT */ | ||
| 3337 | #define WM5100_DRC_SIG_DET_EINT_SHIFT 9 /* DRC_SIG_DET_EINT */ | ||
| 3338 | #define WM5100_DRC_SIG_DET_EINT_WIDTH 1 /* DRC_SIG_DET_EINT */ | ||
| 3339 | #define WM5100_ASRC2_LOCK_EINT 0x0100 /* ASRC2_LOCK_EINT */ | ||
| 3340 | #define WM5100_ASRC2_LOCK_EINT_MASK 0x0100 /* ASRC2_LOCK_EINT */ | ||
| 3341 | #define WM5100_ASRC2_LOCK_EINT_SHIFT 8 /* ASRC2_LOCK_EINT */ | ||
| 3342 | #define WM5100_ASRC2_LOCK_EINT_WIDTH 1 /* ASRC2_LOCK_EINT */ | ||
| 3343 | #define WM5100_ASRC1_LOCK_EINT 0x0080 /* ASRC1_LOCK_EINT */ | ||
| 3344 | #define WM5100_ASRC1_LOCK_EINT_MASK 0x0080 /* ASRC1_LOCK_EINT */ | ||
| 3345 | #define WM5100_ASRC1_LOCK_EINT_SHIFT 7 /* ASRC1_LOCK_EINT */ | ||
| 3346 | #define WM5100_ASRC1_LOCK_EINT_WIDTH 1 /* ASRC1_LOCK_EINT */ | ||
| 3347 | #define WM5100_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */ | ||
| 3348 | #define WM5100_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */ | ||
| 3349 | #define WM5100_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */ | ||
| 3350 | #define WM5100_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */ | ||
| 3351 | #define WM5100_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */ | ||
| 3352 | #define WM5100_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */ | ||
| 3353 | #define WM5100_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */ | ||
| 3354 | #define WM5100_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */ | ||
| 3355 | #define WM5100_CLKGEN_ERR_EINT 0x0002 /* CLKGEN_ERR_EINT */ | ||
| 3356 | #define WM5100_CLKGEN_ERR_EINT_MASK 0x0002 /* CLKGEN_ERR_EINT */ | ||
| 3357 | #define WM5100_CLKGEN_ERR_EINT_SHIFT 1 /* CLKGEN_ERR_EINT */ | ||
| 3358 | #define WM5100_CLKGEN_ERR_EINT_WIDTH 1 /* CLKGEN_ERR_EINT */ | ||
| 3359 | #define WM5100_CLKGEN_ERR_ASYNC_EINT 0x0001 /* CLKGEN_ERR_ASYNC_EINT */ | ||
| 3360 | #define WM5100_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* CLKGEN_ERR_ASYNC_EINT */ | ||
| 3361 | #define WM5100_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* CLKGEN_ERR_ASYNC_EINT */ | ||
| 3362 | #define WM5100_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* CLKGEN_ERR_ASYNC_EINT */ | ||
| 3363 | |||
| 3364 | /* | ||
| 3365 | * R3331 (0xD03) - Interrupt Status 4 | ||
| 3366 | */ | ||
| 3367 | #define WM5100_AIF3_ERR_EINT 0x2000 /* AIF3_ERR_EINT */ | ||
| 3368 | #define WM5100_AIF3_ERR_EINT_MASK 0x2000 /* AIF3_ERR_EINT */ | ||
| 3369 | #define WM5100_AIF3_ERR_EINT_SHIFT 13 /* AIF3_ERR_EINT */ | ||
| 3370 | #define WM5100_AIF3_ERR_EINT_WIDTH 1 /* AIF3_ERR_EINT */ | ||
| 3371 | #define WM5100_AIF2_ERR_EINT 0x1000 /* AIF2_ERR_EINT */ | ||
| 3372 | #define WM5100_AIF2_ERR_EINT_MASK 0x1000 /* AIF2_ERR_EINT */ | ||
| 3373 | #define WM5100_AIF2_ERR_EINT_SHIFT 12 /* AIF2_ERR_EINT */ | ||
| 3374 | #define WM5100_AIF2_ERR_EINT_WIDTH 1 /* AIF2_ERR_EINT */ | ||
| 3375 | #define WM5100_AIF1_ERR_EINT 0x0800 /* AIF1_ERR_EINT */ | ||
| 3376 | #define WM5100_AIF1_ERR_EINT_MASK 0x0800 /* AIF1_ERR_EINT */ | ||
| 3377 | #define WM5100_AIF1_ERR_EINT_SHIFT 11 /* AIF1_ERR_EINT */ | ||
| 3378 | #define WM5100_AIF1_ERR_EINT_WIDTH 1 /* AIF1_ERR_EINT */ | ||
| 3379 | #define WM5100_CTRLIF_ERR_EINT 0x0400 /* CTRLIF_ERR_EINT */ | ||
| 3380 | #define WM5100_CTRLIF_ERR_EINT_MASK 0x0400 /* CTRLIF_ERR_EINT */ | ||
| 3381 | #define WM5100_CTRLIF_ERR_EINT_SHIFT 10 /* CTRLIF_ERR_EINT */ | ||
| 3382 | #define WM5100_CTRLIF_ERR_EINT_WIDTH 1 /* CTRLIF_ERR_EINT */ | ||
| 3383 | #define WM5100_ISRC2_UNDERCLOCKED_EINT 0x0200 /* ISRC2_UNDERCLOCKED_EINT */ | ||
| 3384 | #define WM5100_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* ISRC2_UNDERCLOCKED_EINT */ | ||
| 3385 | #define WM5100_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* ISRC2_UNDERCLOCKED_EINT */ | ||
| 3386 | #define WM5100_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC2_UNDERCLOCKED_EINT */ | ||
| 3387 | #define WM5100_ISRC1_UNDERCLOCKED_EINT 0x0100 /* ISRC1_UNDERCLOCKED_EINT */ | ||
| 3388 | #define WM5100_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* ISRC1_UNDERCLOCKED_EINT */ | ||
| 3389 | #define WM5100_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* ISRC1_UNDERCLOCKED_EINT */ | ||
| 3390 | #define WM5100_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* ISRC1_UNDERCLOCKED_EINT */ | ||
| 3391 | #define WM5100_FX_UNDERCLOCKED_EINT 0x0080 /* FX_UNDERCLOCKED_EINT */ | ||
| 3392 | #define WM5100_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* FX_UNDERCLOCKED_EINT */ | ||
| 3393 | #define WM5100_FX_UNDERCLOCKED_EINT_SHIFT 7 /* FX_UNDERCLOCKED_EINT */ | ||
| 3394 | #define WM5100_FX_UNDERCLOCKED_EINT_WIDTH 1 /* FX_UNDERCLOCKED_EINT */ | ||
| 3395 | #define WM5100_AIF3_UNDERCLOCKED_EINT 0x0040 /* AIF3_UNDERCLOCKED_EINT */ | ||
| 3396 | #define WM5100_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* AIF3_UNDERCLOCKED_EINT */ | ||
| 3397 | #define WM5100_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* AIF3_UNDERCLOCKED_EINT */ | ||
| 3398 | #define WM5100_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* AIF3_UNDERCLOCKED_EINT */ | ||
| 3399 | #define WM5100_AIF2_UNDERCLOCKED_EINT 0x0020 /* AIF2_UNDERCLOCKED_EINT */ | ||
| 3400 | #define WM5100_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* AIF2_UNDERCLOCKED_EINT */ | ||
| 3401 | #define WM5100_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* AIF2_UNDERCLOCKED_EINT */ | ||
| 3402 | #define WM5100_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* AIF2_UNDERCLOCKED_EINT */ | ||
| 3403 | #define WM5100_AIF1_UNDERCLOCKED_EINT 0x0010 /* AIF1_UNDERCLOCKED_EINT */ | ||
| 3404 | #define WM5100_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* AIF1_UNDERCLOCKED_EINT */ | ||
| 3405 | #define WM5100_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* AIF1_UNDERCLOCKED_EINT */ | ||
| 3406 | #define WM5100_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* AIF1_UNDERCLOCKED_EINT */ | ||
| 3407 | #define WM5100_ASRC_UNDERCLOCKED_EINT 0x0008 /* ASRC_UNDERCLOCKED_EINT */ | ||
| 3408 | #define WM5100_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* ASRC_UNDERCLOCKED_EINT */ | ||
| 3409 | #define WM5100_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* ASRC_UNDERCLOCKED_EINT */ | ||
| 3410 | #define WM5100_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* ASRC_UNDERCLOCKED_EINT */ | ||
| 3411 | #define WM5100_DAC_UNDERCLOCKED_EINT 0x0004 /* DAC_UNDERCLOCKED_EINT */ | ||
| 3412 | #define WM5100_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* DAC_UNDERCLOCKED_EINT */ | ||
| 3413 | #define WM5100_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* DAC_UNDERCLOCKED_EINT */ | ||
| 3414 | #define WM5100_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* DAC_UNDERCLOCKED_EINT */ | ||
| 3415 | #define WM5100_ADC_UNDERCLOCKED_EINT 0x0002 /* ADC_UNDERCLOCKED_EINT */ | ||
| 3416 | #define WM5100_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* ADC_UNDERCLOCKED_EINT */ | ||
| 3417 | #define WM5100_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* ADC_UNDERCLOCKED_EINT */ | ||
| 3418 | #define WM5100_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* ADC_UNDERCLOCKED_EINT */ | ||
| 3419 | #define WM5100_MIXER_UNDERCLOCKED_EINT 0x0001 /* MIXER_UNDERCLOCKED_EINT */ | ||
| 3420 | #define WM5100_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* MIXER_UNDERCLOCKED_EINT */ | ||
| 3421 | #define WM5100_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* MIXER_UNDERCLOCKED_EINT */ | ||
| 3422 | #define WM5100_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* MIXER_UNDERCLOCKED_EINT */ | ||
| 3423 | |||
| 3424 | /* | ||
| 3425 | * R3332 (0xD04) - Interrupt Raw Status 2 | ||
| 3426 | */ | ||
| 3427 | #define WM5100_DSP_IRQ6_STS 0x0020 /* DSP_IRQ6_STS */ | ||
| 3428 | #define WM5100_DSP_IRQ6_STS_MASK 0x0020 /* DSP_IRQ6_STS */ | ||
| 3429 | #define WM5100_DSP_IRQ6_STS_SHIFT 5 /* DSP_IRQ6_STS */ | ||
| 3430 | #define WM5100_DSP_IRQ6_STS_WIDTH 1 /* DSP_IRQ6_STS */ | ||
| 3431 | #define WM5100_DSP_IRQ5_STS 0x0010 /* DSP_IRQ5_STS */ | ||
| 3432 | #define WM5100_DSP_IRQ5_STS_MASK 0x0010 /* DSP_IRQ5_STS */ | ||
| 3433 | #define WM5100_DSP_IRQ5_STS_SHIFT 4 /* DSP_IRQ5_STS */ | ||
| 3434 | #define WM5100_DSP_IRQ5_STS_WIDTH 1 /* DSP_IRQ5_STS */ | ||
| 3435 | #define WM5100_DSP_IRQ4_STS 0x0008 /* DSP_IRQ4_STS */ | ||
| 3436 | #define WM5100_DSP_IRQ4_STS_MASK 0x0008 /* DSP_IRQ4_STS */ | ||
| 3437 | #define WM5100_DSP_IRQ4_STS_SHIFT 3 /* DSP_IRQ4_STS */ | ||
| 3438 | #define WM5100_DSP_IRQ4_STS_WIDTH 1 /* DSP_IRQ4_STS */ | ||
| 3439 | #define WM5100_DSP_IRQ3_STS 0x0004 /* DSP_IRQ3_STS */ | ||
| 3440 | #define WM5100_DSP_IRQ3_STS_MASK 0x0004 /* DSP_IRQ3_STS */ | ||
| 3441 | #define WM5100_DSP_IRQ3_STS_SHIFT 2 /* DSP_IRQ3_STS */ | ||
| 3442 | #define WM5100_DSP_IRQ3_STS_WIDTH 1 /* DSP_IRQ3_STS */ | ||
| 3443 | #define WM5100_DSP_IRQ2_STS 0x0002 /* DSP_IRQ2_STS */ | ||
| 3444 | #define WM5100_DSP_IRQ2_STS_MASK 0x0002 /* DSP_IRQ2_STS */ | ||
| 3445 | #define WM5100_DSP_IRQ2_STS_SHIFT 1 /* DSP_IRQ2_STS */ | ||
| 3446 | #define WM5100_DSP_IRQ2_STS_WIDTH 1 /* DSP_IRQ2_STS */ | ||
| 3447 | #define WM5100_DSP_IRQ1_STS 0x0001 /* DSP_IRQ1_STS */ | ||
| 3448 | #define WM5100_DSP_IRQ1_STS_MASK 0x0001 /* DSP_IRQ1_STS */ | ||
| 3449 | #define WM5100_DSP_IRQ1_STS_SHIFT 0 /* DSP_IRQ1_STS */ | ||
| 3450 | #define WM5100_DSP_IRQ1_STS_WIDTH 1 /* DSP_IRQ1_STS */ | ||
| 3451 | |||
| 3452 | /* | ||
| 3453 | * R3333 (0xD05) - Interrupt Raw Status 3 | ||
| 3454 | */ | ||
| 3455 | #define WM5100_SPK_SHUTDOWN_WARN_STS 0x8000 /* SPK_SHUTDOWN_WARN_STS */ | ||
| 3456 | #define WM5100_SPK_SHUTDOWN_WARN_STS_MASK 0x8000 /* SPK_SHUTDOWN_WARN_STS */ | ||
| 3457 | #define WM5100_SPK_SHUTDOWN_WARN_STS_SHIFT 15 /* SPK_SHUTDOWN_WARN_STS */ | ||
| 3458 | #define WM5100_SPK_SHUTDOWN_WARN_STS_WIDTH 1 /* SPK_SHUTDOWN_WARN_STS */ | ||
| 3459 | #define WM5100_SPK_SHUTDOWN_STS 0x4000 /* SPK_SHUTDOWN_STS */ | ||
| 3460 | #define WM5100_SPK_SHUTDOWN_STS_MASK 0x4000 /* SPK_SHUTDOWN_STS */ | ||
| 3461 | #define WM5100_SPK_SHUTDOWN_STS_SHIFT 14 /* SPK_SHUTDOWN_STS */ | ||
| 3462 | #define WM5100_SPK_SHUTDOWN_STS_WIDTH 1 /* SPK_SHUTDOWN_STS */ | ||
| 3463 | #define WM5100_HPDET_STS 0x2000 /* HPDET_STS */ | ||
| 3464 | #define WM5100_HPDET_STS_MASK 0x2000 /* HPDET_STS */ | ||
| 3465 | #define WM5100_HPDET_STS_SHIFT 13 /* HPDET_STS */ | ||
| 3466 | #define WM5100_HPDET_STS_WIDTH 1 /* HPDET_STS */ | ||
| 3467 | #define WM5100_DRC_SID_DET_STS 0x0200 /* DRC_SID_DET_STS */ | ||
| 3468 | #define WM5100_DRC_SID_DET_STS_MASK 0x0200 /* DRC_SID_DET_STS */ | ||
| 3469 | #define WM5100_DRC_SID_DET_STS_SHIFT 9 /* DRC_SID_DET_STS */ | ||
| 3470 | #define WM5100_DRC_SID_DET_STS_WIDTH 1 /* DRC_SID_DET_STS */ | ||
| 3471 | #define WM5100_ASRC2_LOCK_STS 0x0100 /* ASRC2_LOCK_STS */ | ||
| 3472 | #define WM5100_ASRC2_LOCK_STS_MASK 0x0100 /* ASRC2_LOCK_STS */ | ||
| 3473 | #define WM5100_ASRC2_LOCK_STS_SHIFT 8 /* ASRC2_LOCK_STS */ | ||
| 3474 | #define WM5100_ASRC2_LOCK_STS_WIDTH 1 /* ASRC2_LOCK_STS */ | ||
| 3475 | #define WM5100_ASRC1_LOCK_STS 0x0080 /* ASRC1_LOCK_STS */ | ||
| 3476 | #define WM5100_ASRC1_LOCK_STS_MASK 0x0080 /* ASRC1_LOCK_STS */ | ||
| 3477 | #define WM5100_ASRC1_LOCK_STS_SHIFT 7 /* ASRC1_LOCK_STS */ | ||
| 3478 | #define WM5100_ASRC1_LOCK_STS_WIDTH 1 /* ASRC1_LOCK_STS */ | ||
| 3479 | #define WM5100_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */ | ||
| 3480 | #define WM5100_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */ | ||
| 3481 | #define WM5100_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */ | ||
| 3482 | #define WM5100_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */ | ||
| 3483 | #define WM5100_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */ | ||
| 3484 | #define WM5100_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */ | ||
| 3485 | #define WM5100_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */ | ||
| 3486 | #define WM5100_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */ | ||
| 3487 | #define WM5100_CLKGEN_ERR_STS 0x0002 /* CLKGEN_ERR_STS */ | ||
| 3488 | #define WM5100_CLKGEN_ERR_STS_MASK 0x0002 /* CLKGEN_ERR_STS */ | ||
| 3489 | #define WM5100_CLKGEN_ERR_STS_SHIFT 1 /* CLKGEN_ERR_STS */ | ||
| 3490 | #define WM5100_CLKGEN_ERR_STS_WIDTH 1 /* CLKGEN_ERR_STS */ | ||
| 3491 | #define WM5100_CLKGEN_ERR_ASYNC_STS 0x0001 /* CLKGEN_ERR_ASYNC_STS */ | ||
| 3492 | #define WM5100_CLKGEN_ERR_ASYNC_STS_MASK 0x0001 /* CLKGEN_ERR_ASYNC_STS */ | ||
| 3493 | #define WM5100_CLKGEN_ERR_ASYNC_STS_SHIFT 0 /* CLKGEN_ERR_ASYNC_STS */ | ||
| 3494 | #define WM5100_CLKGEN_ERR_ASYNC_STS_WIDTH 1 /* CLKGEN_ERR_ASYNC_STS */ | ||
| 3495 | |||
| 3496 | /* | ||
| 3497 | * R3334 (0xD06) - Interrupt Raw Status 4 | ||
| 3498 | */ | ||
| 3499 | #define WM5100_AIF3_ERR_STS 0x2000 /* AIF3_ERR_STS */ | ||
| 3500 | #define WM5100_AIF3_ERR_STS_MASK 0x2000 /* AIF3_ERR_STS */ | ||
| 3501 | #define WM5100_AIF3_ERR_STS_SHIFT 13 /* AIF3_ERR_STS */ | ||
| 3502 | #define WM5100_AIF3_ERR_STS_WIDTH 1 /* AIF3_ERR_STS */ | ||
| 3503 | #define WM5100_AIF2_ERR_STS 0x1000 /* AIF2_ERR_STS */ | ||
| 3504 | #define WM5100_AIF2_ERR_STS_MASK 0x1000 /* AIF2_ERR_STS */ | ||
| 3505 | #define WM5100_AIF2_ERR_STS_SHIFT 12 /* AIF2_ERR_STS */ | ||
| 3506 | #define WM5100_AIF2_ERR_STS_WIDTH 1 /* AIF2_ERR_STS */ | ||
| 3507 | #define WM5100_AIF1_ERR_STS 0x0800 /* AIF1_ERR_STS */ | ||
| 3508 | #define WM5100_AIF1_ERR_STS_MASK 0x0800 /* AIF1_ERR_STS */ | ||
| 3509 | #define WM5100_AIF1_ERR_STS_SHIFT 11 /* AIF1_ERR_STS */ | ||
| 3510 | #define WM5100_AIF1_ERR_STS_WIDTH 1 /* AIF1_ERR_STS */ | ||
| 3511 | #define WM5100_CTRLIF_ERR_STS 0x0400 /* CTRLIF_ERR_STS */ | ||
| 3512 | #define WM5100_CTRLIF_ERR_STS_MASK 0x0400 /* CTRLIF_ERR_STS */ | ||
| 3513 | #define WM5100_CTRLIF_ERR_STS_SHIFT 10 /* CTRLIF_ERR_STS */ | ||
| 3514 | #define WM5100_CTRLIF_ERR_STS_WIDTH 1 /* CTRLIF_ERR_STS */ | ||
| 3515 | #define WM5100_ISRC2_UNDERCLOCKED_STS 0x0200 /* ISRC2_UNDERCLOCKED_STS */ | ||
| 3516 | #define WM5100_ISRC2_UNDERCLOCKED_STS_MASK 0x0200 /* ISRC2_UNDERCLOCKED_STS */ | ||
| 3517 | #define WM5100_ISRC2_UNDERCLOCKED_STS_SHIFT 9 /* ISRC2_UNDERCLOCKED_STS */ | ||
| 3518 | #define WM5100_ISRC2_UNDERCLOCKED_STS_WIDTH 1 /* ISRC2_UNDERCLOCKED_STS */ | ||
| 3519 | #define WM5100_ISRC1_UNDERCLOCKED_STS 0x0100 /* ISRC1_UNDERCLOCKED_STS */ | ||
| 3520 | #define WM5100_ISRC1_UNDERCLOCKED_STS_MASK 0x0100 /* ISRC1_UNDERCLOCKED_STS */ | ||
| 3521 | #define WM5100_ISRC1_UNDERCLOCKED_STS_SHIFT 8 /* ISRC1_UNDERCLOCKED_STS */ | ||
| 3522 | #define WM5100_ISRC1_UNDERCLOCKED_STS_WIDTH 1 /* ISRC1_UNDERCLOCKED_STS */ | ||
| 3523 | #define WM5100_FX_UNDERCLOCKED_STS 0x0080 /* FX_UNDERCLOCKED_STS */ | ||
| 3524 | #define WM5100_FX_UNDERCLOCKED_STS_MASK 0x0080 /* FX_UNDERCLOCKED_STS */ | ||
| 3525 | #define WM5100_FX_UNDERCLOCKED_STS_SHIFT 7 /* FX_UNDERCLOCKED_STS */ | ||
| 3526 | #define WM5100_FX_UNDERCLOCKED_STS_WIDTH 1 /* FX_UNDERCLOCKED_STS */ | ||
| 3527 | #define WM5100_AIF3_UNDERCLOCKED_STS 0x0040 /* AIF3_UNDERCLOCKED_STS */ | ||
| 3528 | #define WM5100_AIF3_UNDERCLOCKED_STS_MASK 0x0040 /* AIF3_UNDERCLOCKED_STS */ | ||
| 3529 | #define WM5100_AIF3_UNDERCLOCKED_STS_SHIFT 6 /* AIF3_UNDERCLOCKED_STS */ | ||
| 3530 | #define WM5100_AIF3_UNDERCLOCKED_STS_WIDTH 1 /* AIF3_UNDERCLOCKED_STS */ | ||
| 3531 | #define WM5100_AIF2_UNDERCLOCKED_STS 0x0020 /* AIF2_UNDERCLOCKED_STS */ | ||
| 3532 | #define WM5100_AIF2_UNDERCLOCKED_STS_MASK 0x0020 /* AIF2_UNDERCLOCKED_STS */ | ||
| 3533 | #define WM5100_AIF2_UNDERCLOCKED_STS_SHIFT 5 /* AIF2_UNDERCLOCKED_STS */ | ||
| 3534 | #define WM5100_AIF2_UNDERCLOCKED_STS_WIDTH 1 /* AIF2_UNDERCLOCKED_STS */ | ||
| 3535 | #define WM5100_AIF1_UNDERCLOCKED_STS 0x0010 /* AIF1_UNDERCLOCKED_STS */ | ||
| 3536 | #define WM5100_AIF1_UNDERCLOCKED_STS_MASK 0x0010 /* AIF1_UNDERCLOCKED_STS */ | ||
| 3537 | #define WM5100_AIF1_UNDERCLOCKED_STS_SHIFT 4 /* AIF1_UNDERCLOCKED_STS */ | ||
| 3538 | #define WM5100_AIF1_UNDERCLOCKED_STS_WIDTH 1 /* AIF1_UNDERCLOCKED_STS */ | ||
| 3539 | #define WM5100_ASRC_UNDERCLOCKED_STS 0x0008 /* ASRC_UNDERCLOCKED_STS */ | ||
| 3540 | #define WM5100_ASRC_UNDERCLOCKED_STS_MASK 0x0008 /* ASRC_UNDERCLOCKED_STS */ | ||
| 3541 | #define WM5100_ASRC_UNDERCLOCKED_STS_SHIFT 3 /* ASRC_UNDERCLOCKED_STS */ | ||
| 3542 | #define WM5100_ASRC_UNDERCLOCKED_STS_WIDTH 1 /* ASRC_UNDERCLOCKED_STS */ | ||
| 3543 | #define WM5100_DAC_UNDERCLOCKED_STS 0x0004 /* DAC_UNDERCLOCKED_STS */ | ||
| 3544 | #define WM5100_DAC_UNDERCLOCKED_STS_MASK 0x0004 /* DAC_UNDERCLOCKED_STS */ | ||
| 3545 | #define WM5100_DAC_UNDERCLOCKED_STS_SHIFT 2 /* DAC_UNDERCLOCKED_STS */ | ||
| 3546 | #define WM5100_DAC_UNDERCLOCKED_STS_WIDTH 1 /* DAC_UNDERCLOCKED_STS */ | ||
| 3547 | #define WM5100_ADC_UNDERCLOCKED_STS 0x0002 /* ADC_UNDERCLOCKED_STS */ | ||
| 3548 | #define WM5100_ADC_UNDERCLOCKED_STS_MASK 0x0002 /* ADC_UNDERCLOCKED_STS */ | ||
| 3549 | #define WM5100_ADC_UNDERCLOCKED_STS_SHIFT 1 /* ADC_UNDERCLOCKED_STS */ | ||
| 3550 | #define WM5100_ADC_UNDERCLOCKED_STS_WIDTH 1 /* ADC_UNDERCLOCKED_STS */ | ||
| 3551 | #define WM5100_MIXER_UNDERCLOCKED_STS 0x0001 /* MIXER_UNDERCLOCKED_STS */ | ||
| 3552 | #define WM5100_MIXER_UNDERCLOCKED_STS_MASK 0x0001 /* MIXER_UNDERCLOCKED_STS */ | ||
| 3553 | #define WM5100_MIXER_UNDERCLOCKED_STS_SHIFT 0 /* MIXER_UNDERCLOCKED_STS */ | ||
| 3554 | #define WM5100_MIXER_UNDERCLOCKED_STS_WIDTH 1 /* MIXER_UNDERCLOCKED_STS */ | ||
| 3555 | |||
| 3556 | /* | ||
| 3557 | * R3335 (0xD07) - Interrupt Status 1 Mask | ||
| 3558 | */ | ||
| 3559 | #define WM5100_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */ | ||
| 3560 | #define WM5100_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */ | ||
| 3561 | #define WM5100_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */ | ||
| 3562 | #define WM5100_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */ | ||
| 3563 | #define WM5100_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */ | ||
| 3564 | #define WM5100_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */ | ||
| 3565 | #define WM5100_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */ | ||
| 3566 | #define WM5100_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */ | ||
| 3567 | #define WM5100_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ | ||
| 3568 | #define WM5100_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ | ||
| 3569 | #define WM5100_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ | ||
| 3570 | #define WM5100_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ | ||
| 3571 | #define WM5100_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ | ||
| 3572 | #define WM5100_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ | ||
| 3573 | #define WM5100_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ | ||
| 3574 | #define WM5100_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ | ||
| 3575 | #define WM5100_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ | ||
| 3576 | #define WM5100_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ | ||
| 3577 | #define WM5100_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ | ||
| 3578 | #define WM5100_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ | ||
| 3579 | #define WM5100_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ | ||
| 3580 | #define WM5100_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ | ||
| 3581 | #define WM5100_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ | ||
| 3582 | #define WM5100_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ | ||
| 3583 | |||
| 3584 | /* | ||
| 3585 | * R3336 (0xD08) - Interrupt Status 2 Mask | ||
| 3586 | */ | ||
| 3587 | #define WM5100_IM_DSP_IRQ6_EINT 0x0020 /* IM_DSP_IRQ6_EINT */ | ||
| 3588 | #define WM5100_IM_DSP_IRQ6_EINT_MASK 0x0020 /* IM_DSP_IRQ6_EINT */ | ||
| 3589 | #define WM5100_IM_DSP_IRQ6_EINT_SHIFT 5 /* IM_DSP_IRQ6_EINT */ | ||
| 3590 | #define WM5100_IM_DSP_IRQ6_EINT_WIDTH 1 /* IM_DSP_IRQ6_EINT */ | ||
| 3591 | #define WM5100_IM_DSP_IRQ5_EINT 0x0010 /* IM_DSP_IRQ5_EINT */ | ||
| 3592 | #define WM5100_IM_DSP_IRQ5_EINT_MASK 0x0010 /* IM_DSP_IRQ5_EINT */ | ||
| 3593 | #define WM5100_IM_DSP_IRQ5_EINT_SHIFT 4 /* IM_DSP_IRQ5_EINT */ | ||
| 3594 | #define WM5100_IM_DSP_IRQ5_EINT_WIDTH 1 /* IM_DSP_IRQ5_EINT */ | ||
| 3595 | #define WM5100_IM_DSP_IRQ4_EINT 0x0008 /* IM_DSP_IRQ4_EINT */ | ||
| 3596 | #define WM5100_IM_DSP_IRQ4_EINT_MASK 0x0008 /* IM_DSP_IRQ4_EINT */ | ||
| 3597 | #define WM5100_IM_DSP_IRQ4_EINT_SHIFT 3 /* IM_DSP_IRQ4_EINT */ | ||
| 3598 | #define WM5100_IM_DSP_IRQ4_EINT_WIDTH 1 /* IM_DSP_IRQ4_EINT */ | ||
| 3599 | #define WM5100_IM_DSP_IRQ3_EINT 0x0004 /* IM_DSP_IRQ3_EINT */ | ||
| 3600 | #define WM5100_IM_DSP_IRQ3_EINT_MASK 0x0004 /* IM_DSP_IRQ3_EINT */ | ||
| 3601 | #define WM5100_IM_DSP_IRQ3_EINT_SHIFT 2 /* IM_DSP_IRQ3_EINT */ | ||
| 3602 | #define WM5100_IM_DSP_IRQ3_EINT_WIDTH 1 /* IM_DSP_IRQ3_EINT */ | ||
| 3603 | #define WM5100_IM_DSP_IRQ2_EINT 0x0002 /* IM_DSP_IRQ2_EINT */ | ||
| 3604 | #define WM5100_IM_DSP_IRQ2_EINT_MASK 0x0002 /* IM_DSP_IRQ2_EINT */ | ||
| 3605 | #define WM5100_IM_DSP_IRQ2_EINT_SHIFT 1 /* IM_DSP_IRQ2_EINT */ | ||
| 3606 | #define WM5100_IM_DSP_IRQ2_EINT_WIDTH 1 /* IM_DSP_IRQ2_EINT */ | ||
| 3607 | #define WM5100_IM_DSP_IRQ1_EINT 0x0001 /* IM_DSP_IRQ1_EINT */ | ||
| 3608 | #define WM5100_IM_DSP_IRQ1_EINT_MASK 0x0001 /* IM_DSP_IRQ1_EINT */ | ||
| 3609 | #define WM5100_IM_DSP_IRQ1_EINT_SHIFT 0 /* IM_DSP_IRQ1_EINT */ | ||
| 3610 | #define WM5100_IM_DSP_IRQ1_EINT_WIDTH 1 /* IM_DSP_IRQ1_EINT */ | ||
| 3611 | |||
| 3612 | /* | ||
| 3613 | * R3337 (0xD09) - Interrupt Status 3 Mask | ||
| 3614 | */ | ||
| 3615 | #define WM5100_IM_SPK_SHUTDOWN_WARN_EINT 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */ | ||
| 3616 | #define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_MASK 0x8000 /* IM_SPK_SHUTDOWN_WARN_EINT */ | ||
| 3617 | #define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_SHIFT 15 /* IM_SPK_SHUTDOWN_WARN_EINT */ | ||
| 3618 | #define WM5100_IM_SPK_SHUTDOWN_WARN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_WARN_EINT */ | ||
| 3619 | #define WM5100_IM_SPK_SHUTDOWN_EINT 0x4000 /* IM_SPK_SHUTDOWN_EINT */ | ||
| 3620 | #define WM5100_IM_SPK_SHUTDOWN_EINT_MASK 0x4000 /* IM_SPK_SHUTDOWN_EINT */ | ||
| 3621 | #define WM5100_IM_SPK_SHUTDOWN_EINT_SHIFT 14 /* IM_SPK_SHUTDOWN_EINT */ | ||
| 3622 | #define WM5100_IM_SPK_SHUTDOWN_EINT_WIDTH 1 /* IM_SPK_SHUTDOWN_EINT */ | ||
| 3623 | #define WM5100_IM_HPDET_EINT 0x2000 /* IM_HPDET_EINT */ | ||
| 3624 | #define WM5100_IM_HPDET_EINT_MASK 0x2000 /* IM_HPDET_EINT */ | ||
| 3625 | #define WM5100_IM_HPDET_EINT_SHIFT 13 /* IM_HPDET_EINT */ | ||
| 3626 | #define WM5100_IM_HPDET_EINT_WIDTH 1 /* IM_HPDET_EINT */ | ||
| 3627 | #define WM5100_IM_ACCDET_EINT 0x1000 /* IM_ACCDET_EINT */ | ||
| 3628 | #define WM5100_IM_ACCDET_EINT_MASK 0x1000 /* IM_ACCDET_EINT */ | ||
| 3629 | #define WM5100_IM_ACCDET_EINT_SHIFT 12 /* IM_ACCDET_EINT */ | ||
| 3630 | #define WM5100_IM_ACCDET_EINT_WIDTH 1 /* IM_ACCDET_EINT */ | ||
| 3631 | #define WM5100_IM_DRC_SIG_DET_EINT 0x0200 /* IM_DRC_SIG_DET_EINT */ | ||
| 3632 | #define WM5100_IM_DRC_SIG_DET_EINT_MASK 0x0200 /* IM_DRC_SIG_DET_EINT */ | ||
| 3633 | #define WM5100_IM_DRC_SIG_DET_EINT_SHIFT 9 /* IM_DRC_SIG_DET_EINT */ | ||
| 3634 | #define WM5100_IM_DRC_SIG_DET_EINT_WIDTH 1 /* IM_DRC_SIG_DET_EINT */ | ||
| 3635 | #define WM5100_IM_ASRC2_LOCK_EINT 0x0100 /* IM_ASRC2_LOCK_EINT */ | ||
| 3636 | #define WM5100_IM_ASRC2_LOCK_EINT_MASK 0x0100 /* IM_ASRC2_LOCK_EINT */ | ||
| 3637 | #define WM5100_IM_ASRC2_LOCK_EINT_SHIFT 8 /* IM_ASRC2_LOCK_EINT */ | ||
| 3638 | #define WM5100_IM_ASRC2_LOCK_EINT_WIDTH 1 /* IM_ASRC2_LOCK_EINT */ | ||
| 3639 | #define WM5100_IM_ASRC1_LOCK_EINT 0x0080 /* IM_ASRC1_LOCK_EINT */ | ||
| 3640 | #define WM5100_IM_ASRC1_LOCK_EINT_MASK 0x0080 /* IM_ASRC1_LOCK_EINT */ | ||
| 3641 | #define WM5100_IM_ASRC1_LOCK_EINT_SHIFT 7 /* IM_ASRC1_LOCK_EINT */ | ||
| 3642 | #define WM5100_IM_ASRC1_LOCK_EINT_WIDTH 1 /* IM_ASRC1_LOCK_EINT */ | ||
| 3643 | #define WM5100_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */ | ||
| 3644 | #define WM5100_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */ | ||
| 3645 | #define WM5100_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */ | ||
| 3646 | #define WM5100_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */ | ||
| 3647 | #define WM5100_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */ | ||
| 3648 | #define WM5100_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */ | ||
| 3649 | #define WM5100_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */ | ||
| 3650 | #define WM5100_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */ | ||
| 3651 | #define WM5100_IM_CLKGEN_ERR_EINT 0x0002 /* IM_CLKGEN_ERR_EINT */ | ||
| 3652 | #define WM5100_IM_CLKGEN_ERR_EINT_MASK 0x0002 /* IM_CLKGEN_ERR_EINT */ | ||
| 3653 | #define WM5100_IM_CLKGEN_ERR_EINT_SHIFT 1 /* IM_CLKGEN_ERR_EINT */ | ||
| 3654 | #define WM5100_IM_CLKGEN_ERR_EINT_WIDTH 1 /* IM_CLKGEN_ERR_EINT */ | ||
| 3655 | #define WM5100_IM_CLKGEN_ERR_ASYNC_EINT 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */ | ||
| 3656 | #define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_MASK 0x0001 /* IM_CLKGEN_ERR_ASYNC_EINT */ | ||
| 3657 | #define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_SHIFT 0 /* IM_CLKGEN_ERR_ASYNC_EINT */ | ||
| 3658 | #define WM5100_IM_CLKGEN_ERR_ASYNC_EINT_WIDTH 1 /* IM_CLKGEN_ERR_ASYNC_EINT */ | ||
| 3659 | |||
| 3660 | /* | ||
| 3661 | * R3338 (0xD0A) - Interrupt Status 4 Mask | ||
| 3662 | */ | ||
| 3663 | #define WM5100_IM_AIF3_ERR_EINT 0x2000 /* IM_AIF3_ERR_EINT */ | ||
| 3664 | #define WM5100_IM_AIF3_ERR_EINT_MASK 0x2000 /* IM_AIF3_ERR_EINT */ | ||
| 3665 | #define WM5100_IM_AIF3_ERR_EINT_SHIFT 13 /* IM_AIF3_ERR_EINT */ | ||
| 3666 | #define WM5100_IM_AIF3_ERR_EINT_WIDTH 1 /* IM_AIF3_ERR_EINT */ | ||
| 3667 | #define WM5100_IM_AIF2_ERR_EINT 0x1000 /* IM_AIF2_ERR_EINT */ | ||
| 3668 | #define WM5100_IM_AIF2_ERR_EINT_MASK 0x1000 /* IM_AIF2_ERR_EINT */ | ||
| 3669 | #define WM5100_IM_AIF2_ERR_EINT_SHIFT 12 /* IM_AIF2_ERR_EINT */ | ||
| 3670 | #define WM5100_IM_AIF2_ERR_EINT_WIDTH 1 /* IM_AIF2_ERR_EINT */ | ||
| 3671 | #define WM5100_IM_AIF1_ERR_EINT 0x0800 /* IM_AIF1_ERR_EINT */ | ||
| 3672 | #define WM5100_IM_AIF1_ERR_EINT_MASK 0x0800 /* IM_AIF1_ERR_EINT */ | ||
| 3673 | #define WM5100_IM_AIF1_ERR_EINT_SHIFT 11 /* IM_AIF1_ERR_EINT */ | ||
| 3674 | #define WM5100_IM_AIF1_ERR_EINT_WIDTH 1 /* IM_AIF1_ERR_EINT */ | ||
| 3675 | #define WM5100_IM_CTRLIF_ERR_EINT 0x0400 /* IM_CTRLIF_ERR_EINT */ | ||
| 3676 | #define WM5100_IM_CTRLIF_ERR_EINT_MASK 0x0400 /* IM_CTRLIF_ERR_EINT */ | ||
| 3677 | #define WM5100_IM_CTRLIF_ERR_EINT_SHIFT 10 /* IM_CTRLIF_ERR_EINT */ | ||
| 3678 | #define WM5100_IM_CTRLIF_ERR_EINT_WIDTH 1 /* IM_CTRLIF_ERR_EINT */ | ||
| 3679 | #define WM5100_IM_ISRC2_UNDERCLOCKED_EINT 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */ | ||
| 3680 | #define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_MASK 0x0200 /* IM_ISRC2_UNDERCLOCKED_EINT */ | ||
| 3681 | #define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_SHIFT 9 /* IM_ISRC2_UNDERCLOCKED_EINT */ | ||
| 3682 | #define WM5100_IM_ISRC2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC2_UNDERCLOCKED_EINT */ | ||
| 3683 | #define WM5100_IM_ISRC1_UNDERCLOCKED_EINT 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */ | ||
| 3684 | #define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_MASK 0x0100 /* IM_ISRC1_UNDERCLOCKED_EINT */ | ||
| 3685 | #define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_SHIFT 8 /* IM_ISRC1_UNDERCLOCKED_EINT */ | ||
| 3686 | #define WM5100_IM_ISRC1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ISRC1_UNDERCLOCKED_EINT */ | ||
| 3687 | #define WM5100_IM_FX_UNDERCLOCKED_EINT 0x0080 /* IM_FX_UNDERCLOCKED_EINT */ | ||
| 3688 | #define WM5100_IM_FX_UNDERCLOCKED_EINT_MASK 0x0080 /* IM_FX_UNDERCLOCKED_EINT */ | ||
| 3689 | #define WM5100_IM_FX_UNDERCLOCKED_EINT_SHIFT 7 /* IM_FX_UNDERCLOCKED_EINT */ | ||
| 3690 | #define WM5100_IM_FX_UNDERCLOCKED_EINT_WIDTH 1 /* IM_FX_UNDERCLOCKED_EINT */ | ||
| 3691 | #define WM5100_IM_AIF3_UNDERCLOCKED_EINT 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */ | ||
| 3692 | #define WM5100_IM_AIF3_UNDERCLOCKED_EINT_MASK 0x0040 /* IM_AIF3_UNDERCLOCKED_EINT */ | ||
| 3693 | #define WM5100_IM_AIF3_UNDERCLOCKED_EINT_SHIFT 6 /* IM_AIF3_UNDERCLOCKED_EINT */ | ||
| 3694 | #define WM5100_IM_AIF3_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF3_UNDERCLOCKED_EINT */ | ||
| 3695 | #define WM5100_IM_AIF2_UNDERCLOCKED_EINT 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */ | ||
| 3696 | #define WM5100_IM_AIF2_UNDERCLOCKED_EINT_MASK 0x0020 /* IM_AIF2_UNDERCLOCKED_EINT */ | ||
| 3697 | #define WM5100_IM_AIF2_UNDERCLOCKED_EINT_SHIFT 5 /* IM_AIF2_UNDERCLOCKED_EINT */ | ||
| 3698 | #define WM5100_IM_AIF2_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF2_UNDERCLOCKED_EINT */ | ||
| 3699 | #define WM5100_IM_AIF1_UNDERCLOCKED_EINT 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */ | ||
| 3700 | #define WM5100_IM_AIF1_UNDERCLOCKED_EINT_MASK 0x0010 /* IM_AIF1_UNDERCLOCKED_EINT */ | ||
| 3701 | #define WM5100_IM_AIF1_UNDERCLOCKED_EINT_SHIFT 4 /* IM_AIF1_UNDERCLOCKED_EINT */ | ||
| 3702 | #define WM5100_IM_AIF1_UNDERCLOCKED_EINT_WIDTH 1 /* IM_AIF1_UNDERCLOCKED_EINT */ | ||
| 3703 | #define WM5100_IM_ASRC_UNDERCLOCKED_EINT 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */ | ||
| 3704 | #define WM5100_IM_ASRC_UNDERCLOCKED_EINT_MASK 0x0008 /* IM_ASRC_UNDERCLOCKED_EINT */ | ||
| 3705 | #define WM5100_IM_ASRC_UNDERCLOCKED_EINT_SHIFT 3 /* IM_ASRC_UNDERCLOCKED_EINT */ | ||
| 3706 | #define WM5100_IM_ASRC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ASRC_UNDERCLOCKED_EINT */ | ||
| 3707 | #define WM5100_IM_DAC_UNDERCLOCKED_EINT 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */ | ||
| 3708 | #define WM5100_IM_DAC_UNDERCLOCKED_EINT_MASK 0x0004 /* IM_DAC_UNDERCLOCKED_EINT */ | ||
| 3709 | #define WM5100_IM_DAC_UNDERCLOCKED_EINT_SHIFT 2 /* IM_DAC_UNDERCLOCKED_EINT */ | ||
| 3710 | #define WM5100_IM_DAC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_DAC_UNDERCLOCKED_EINT */ | ||
| 3711 | #define WM5100_IM_ADC_UNDERCLOCKED_EINT 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */ | ||
| 3712 | #define WM5100_IM_ADC_UNDERCLOCKED_EINT_MASK 0x0002 /* IM_ADC_UNDERCLOCKED_EINT */ | ||
| 3713 | #define WM5100_IM_ADC_UNDERCLOCKED_EINT_SHIFT 1 /* IM_ADC_UNDERCLOCKED_EINT */ | ||
| 3714 | #define WM5100_IM_ADC_UNDERCLOCKED_EINT_WIDTH 1 /* IM_ADC_UNDERCLOCKED_EINT */ | ||
| 3715 | #define WM5100_IM_MIXER_UNDERCLOCKED_EINT 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */ | ||
| 3716 | #define WM5100_IM_MIXER_UNDERCLOCKED_EINT_MASK 0x0001 /* IM_MIXER_UNDERCLOCKED_EINT */ | ||
| 3717 | #define WM5100_IM_MIXER_UNDERCLOCKED_EINT_SHIFT 0 /* IM_MIXER_UNDERCLOCKED_EINT */ | ||
| 3718 | #define WM5100_IM_MIXER_UNDERCLOCKED_EINT_WIDTH 1 /* IM_MIXER_UNDERCLOCKED_EINT */ | ||
| 3719 | |||
| 3720 | /* | ||
| 3721 | * R3359 (0xD1F) - Interrupt Control | ||
| 3722 | */ | ||
| 3723 | #define WM5100_IM_IRQ 0x0001 /* IM_IRQ */ | ||
| 3724 | #define WM5100_IM_IRQ_MASK 0x0001 /* IM_IRQ */ | ||
| 3725 | #define WM5100_IM_IRQ_SHIFT 0 /* IM_IRQ */ | ||
| 3726 | #define WM5100_IM_IRQ_WIDTH 1 /* IM_IRQ */ | ||
| 3727 | |||
| 3728 | /* | ||
| 3729 | * R3360 (0xD20) - IRQ Debounce 1 | ||
| 3730 | */ | ||
| 3731 | #define WM5100_SPK_SHUTDOWN_WARN_DB 0x0200 /* SPK_SHUTDOWN_WARN_DB */ | ||
| 3732 | #define WM5100_SPK_SHUTDOWN_WARN_DB_MASK 0x0200 /* SPK_SHUTDOWN_WARN_DB */ | ||
| 3733 | #define WM5100_SPK_SHUTDOWN_WARN_DB_SHIFT 9 /* SPK_SHUTDOWN_WARN_DB */ | ||
| 3734 | #define WM5100_SPK_SHUTDOWN_WARN_DB_WIDTH 1 /* SPK_SHUTDOWN_WARN_DB */ | ||
| 3735 | #define WM5100_SPK_SHUTDOWN_DB 0x0100 /* SPK_SHUTDOWN_DB */ | ||
| 3736 | #define WM5100_SPK_SHUTDOWN_DB_MASK 0x0100 /* SPK_SHUTDOWN_DB */ | ||
| 3737 | #define WM5100_SPK_SHUTDOWN_DB_SHIFT 8 /* SPK_SHUTDOWN_DB */ | ||
| 3738 | #define WM5100_SPK_SHUTDOWN_DB_WIDTH 1 /* SPK_SHUTDOWN_DB */ | ||
| 3739 | #define WM5100_FLL1_LOCK_IRQ_DB 0x0008 /* FLL1_LOCK_IRQ_DB */ | ||
| 3740 | #define WM5100_FLL1_LOCK_IRQ_DB_MASK 0x0008 /* FLL1_LOCK_IRQ_DB */ | ||
| 3741 | #define WM5100_FLL1_LOCK_IRQ_DB_SHIFT 3 /* FLL1_LOCK_IRQ_DB */ | ||
| 3742 | #define WM5100_FLL1_LOCK_IRQ_DB_WIDTH 1 /* FLL1_LOCK_IRQ_DB */ | ||
| 3743 | #define WM5100_FLL2_LOCK_IRQ_DB 0x0004 /* FLL2_LOCK_IRQ_DB */ | ||
| 3744 | #define WM5100_FLL2_LOCK_IRQ_DB_MASK 0x0004 /* FLL2_LOCK_IRQ_DB */ | ||
| 3745 | #define WM5100_FLL2_LOCK_IRQ_DB_SHIFT 2 /* FLL2_LOCK_IRQ_DB */ | ||
| 3746 | #define WM5100_FLL2_LOCK_IRQ_DB_WIDTH 1 /* FLL2_LOCK_IRQ_DB */ | ||
| 3747 | #define WM5100_CLKGEN_ERR_IRQ_DB 0x0002 /* CLKGEN_ERR_IRQ_DB */ | ||
| 3748 | #define WM5100_CLKGEN_ERR_IRQ_DB_MASK 0x0002 /* CLKGEN_ERR_IRQ_DB */ | ||
| 3749 | #define WM5100_CLKGEN_ERR_IRQ_DB_SHIFT 1 /* CLKGEN_ERR_IRQ_DB */ | ||
| 3750 | #define WM5100_CLKGEN_ERR_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_IRQ_DB */ | ||
| 3751 | #define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */ | ||
| 3752 | #define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_MASK 0x0001 /* CLKGEN_ERR_ASYNC_IRQ_DB */ | ||
| 3753 | #define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_SHIFT 0 /* CLKGEN_ERR_ASYNC_IRQ_DB */ | ||
| 3754 | #define WM5100_CLKGEN_ERR_ASYNC_IRQ_DB_WIDTH 1 /* CLKGEN_ERR_ASYNC_IRQ_DB */ | ||
| 3755 | |||
| 3756 | /* | ||
| 3757 | * R3361 (0xD21) - IRQ Debounce 2 | ||
| 3758 | */ | ||
| 3759 | #define WM5100_AIF_ERR_DB 0x0001 /* AIF_ERR_DB */ | ||
| 3760 | #define WM5100_AIF_ERR_DB_MASK 0x0001 /* AIF_ERR_DB */ | ||
| 3761 | #define WM5100_AIF_ERR_DB_SHIFT 0 /* AIF_ERR_DB */ | ||
| 3762 | #define WM5100_AIF_ERR_DB_WIDTH 1 /* AIF_ERR_DB */ | ||
| 3763 | |||
| 3764 | /* | ||
| 3765 | * R3584 (0xE00) - FX_Ctrl | ||
| 3766 | */ | ||
| 3767 | #define WM5100_FX_STS_MASK 0xFFC0 /* FX_STS - [15:6] */ | ||
| 3768 | #define WM5100_FX_STS_SHIFT 6 /* FX_STS - [15:6] */ | ||
| 3769 | #define WM5100_FX_STS_WIDTH 10 /* FX_STS - [15:6] */ | ||
| 3770 | #define WM5100_FX_RATE_MASK 0x0003 /* FX_RATE - [1:0] */ | ||
| 3771 | #define WM5100_FX_RATE_SHIFT 0 /* FX_RATE - [1:0] */ | ||
| 3772 | #define WM5100_FX_RATE_WIDTH 2 /* FX_RATE - [1:0] */ | ||
| 3773 | |||
| 3774 | /* | ||
| 3775 | * R3600 (0xE10) - EQ1_1 | ||
| 3776 | */ | ||
| 3777 | #define WM5100_EQ1_B1_GAIN_MASK 0xF800 /* EQ1_B1_GAIN - [15:11] */ | ||
| 3778 | #define WM5100_EQ1_B1_GAIN_SHIFT 11 /* EQ1_B1_GAIN - [15:11] */ | ||
| 3779 | #define WM5100_EQ1_B1_GAIN_WIDTH 5 /* EQ1_B1_GAIN - [15:11] */ | ||
| 3780 | #define WM5100_EQ1_B2_GAIN_MASK 0x07C0 /* EQ1_B2_GAIN - [10:6] */ | ||
| 3781 | #define WM5100_EQ1_B2_GAIN_SHIFT 6 /* EQ1_B2_GAIN - [10:6] */ | ||
| 3782 | #define WM5100_EQ1_B2_GAIN_WIDTH 5 /* EQ1_B2_GAIN - [10:6] */ | ||
| 3783 | #define WM5100_EQ1_B3_GAIN_MASK 0x003E /* EQ1_B3_GAIN - [5:1] */ | ||
| 3784 | #define WM5100_EQ1_B3_GAIN_SHIFT 1 /* EQ1_B3_GAIN - [5:1] */ | ||
| 3785 | #define WM5100_EQ1_B3_GAIN_WIDTH 5 /* EQ1_B3_GAIN - [5:1] */ | ||
| 3786 | #define WM5100_EQ1_ENA 0x0001 /* EQ1_ENA */ | ||
| 3787 | #define WM5100_EQ1_ENA_MASK 0x0001 /* EQ1_ENA */ | ||
| 3788 | #define WM5100_EQ1_ENA_SHIFT 0 /* EQ1_ENA */ | ||
| 3789 | #define WM5100_EQ1_ENA_WIDTH 1 /* EQ1_ENA */ | ||
| 3790 | |||
| 3791 | /* | ||
| 3792 | * R3601 (0xE11) - EQ1_2 | ||
| 3793 | */ | ||
| 3794 | #define WM5100_EQ1_B4_GAIN_MASK 0xF800 /* EQ1_B4_GAIN - [15:11] */ | ||
| 3795 | #define WM5100_EQ1_B4_GAIN_SHIFT 11 /* EQ1_B4_GAIN - [15:11] */ | ||
| 3796 | #define WM5100_EQ1_B4_GAIN_WIDTH 5 /* EQ1_B4_GAIN - [15:11] */ | ||
| 3797 | #define WM5100_EQ1_B5_GAIN_MASK 0x07C0 /* EQ1_B5_GAIN - [10:6] */ | ||
| 3798 | #define WM5100_EQ1_B5_GAIN_SHIFT 6 /* EQ1_B5_GAIN - [10:6] */ | ||
| 3799 | #define WM5100_EQ1_B5_GAIN_WIDTH 5 /* EQ1_B5_GAIN - [10:6] */ | ||
| 3800 | |||
| 3801 | /* | ||
| 3802 | * R3602 (0xE12) - EQ1_3 | ||
| 3803 | */ | ||
| 3804 | #define WM5100_EQ1_B1_A_MASK 0xFFFF /* EQ1_B1_A - [15:0] */ | ||
| 3805 | #define WM5100_EQ1_B1_A_SHIFT 0 /* EQ1_B1_A - [15:0] */ | ||
| 3806 | #define WM5100_EQ1_B1_A_WIDTH 16 /* EQ1_B1_A - [15:0] */ | ||
| 3807 | |||
| 3808 | /* | ||
| 3809 | * R3603 (0xE13) - EQ1_4 | ||
| 3810 | */ | ||
| 3811 | #define WM5100_EQ1_B1_B_MASK 0xFFFF /* EQ1_B1_B - [15:0] */ | ||
| 3812 | #define WM5100_EQ1_B1_B_SHIFT 0 /* EQ1_B1_B - [15:0] */ | ||
| 3813 | #define WM5100_EQ1_B1_B_WIDTH 16 /* EQ1_B1_B - [15:0] */ | ||
| 3814 | |||
| 3815 | /* | ||
| 3816 | * R3604 (0xE14) - EQ1_5 | ||
| 3817 | */ | ||
| 3818 | #define WM5100_EQ1_B1_PG_MASK 0xFFFF /* EQ1_B1_PG - [15:0] */ | ||
| 3819 | #define WM5100_EQ1_B1_PG_SHIFT 0 /* EQ1_B1_PG - [15:0] */ | ||
| 3820 | #define WM5100_EQ1_B1_PG_WIDTH 16 /* EQ1_B1_PG - [15:0] */ | ||
| 3821 | |||
| 3822 | /* | ||
| 3823 | * R3605 (0xE15) - EQ1_6 | ||
| 3824 | */ | ||
| 3825 | #define WM5100_EQ1_B2_A_MASK 0xFFFF /* EQ1_B2_A - [15:0] */ | ||
| 3826 | #define WM5100_EQ1_B2_A_SHIFT 0 /* EQ1_B2_A - [15:0] */ | ||
| 3827 | #define WM5100_EQ1_B2_A_WIDTH 16 /* EQ1_B2_A - [15:0] */ | ||
| 3828 | |||
| 3829 | /* | ||
| 3830 | * R3606 (0xE16) - EQ1_7 | ||
| 3831 | */ | ||
| 3832 | #define WM5100_EQ1_B2_B_MASK 0xFFFF /* EQ1_B2_B - [15:0] */ | ||
| 3833 | #define WM5100_EQ1_B2_B_SHIFT 0 /* EQ1_B2_B - [15:0] */ | ||
| 3834 | #define WM5100_EQ1_B2_B_WIDTH 16 /* EQ1_B2_B - [15:0] */ | ||
| 3835 | |||
| 3836 | /* | ||
| 3837 | * R3607 (0xE17) - EQ1_8 | ||
| 3838 | */ | ||
| 3839 | #define WM5100_EQ1_B2_C_MASK 0xFFFF /* EQ1_B2_C - [15:0] */ | ||
| 3840 | #define WM5100_EQ1_B2_C_SHIFT 0 /* EQ1_B2_C - [15:0] */ | ||
| 3841 | #define WM5100_EQ1_B2_C_WIDTH 16 /* EQ1_B2_C - [15:0] */ | ||
| 3842 | |||
| 3843 | /* | ||
| 3844 | * R3608 (0xE18) - EQ1_9 | ||
| 3845 | */ | ||
| 3846 | #define WM5100_EQ1_B2_PG_MASK 0xFFFF /* EQ1_B2_PG - [15:0] */ | ||
| 3847 | #define WM5100_EQ1_B2_PG_SHIFT 0 /* EQ1_B2_PG - [15:0] */ | ||
| 3848 | #define WM5100_EQ1_B2_PG_WIDTH 16 /* EQ1_B2_PG - [15:0] */ | ||
| 3849 | |||
| 3850 | /* | ||
| 3851 | * R3609 (0xE19) - EQ1_10 | ||
| 3852 | */ | ||
| 3853 | #define WM5100_EQ1_B3_A_MASK 0xFFFF /* EQ1_B3_A - [15:0] */ | ||
| 3854 | #define WM5100_EQ1_B3_A_SHIFT 0 /* EQ1_B3_A - [15:0] */ | ||
| 3855 | #define WM5100_EQ1_B3_A_WIDTH 16 /* EQ1_B3_A - [15:0] */ | ||
| 3856 | |||
| 3857 | /* | ||
| 3858 | * R3610 (0xE1A) - EQ1_11 | ||
| 3859 | */ | ||
| 3860 | #define WM5100_EQ1_B3_B_MASK 0xFFFF /* EQ1_B3_B - [15:0] */ | ||
| 3861 | #define WM5100_EQ1_B3_B_SHIFT 0 /* EQ1_B3_B - [15:0] */ | ||
| 3862 | #define WM5100_EQ1_B3_B_WIDTH 16 /* EQ1_B3_B - [15:0] */ | ||
| 3863 | |||
| 3864 | /* | ||
| 3865 | * R3611 (0xE1B) - EQ1_12 | ||
| 3866 | */ | ||
| 3867 | #define WM5100_EQ1_B3_C_MASK 0xFFFF /* EQ1_B3_C - [15:0] */ | ||
| 3868 | #define WM5100_EQ1_B3_C_SHIFT 0 /* EQ1_B3_C - [15:0] */ | ||
| 3869 | #define WM5100_EQ1_B3_C_WIDTH 16 /* EQ1_B3_C - [15:0] */ | ||
| 3870 | |||
| 3871 | /* | ||
| 3872 | * R3612 (0xE1C) - EQ1_13 | ||
| 3873 | */ | ||
| 3874 | #define WM5100_EQ1_B3_PG_MASK 0xFFFF /* EQ1_B3_PG - [15:0] */ | ||
| 3875 | #define WM5100_EQ1_B3_PG_SHIFT 0 /* EQ1_B3_PG - [15:0] */ | ||
| 3876 | #define WM5100_EQ1_B3_PG_WIDTH 16 /* EQ1_B3_PG - [15:0] */ | ||
| 3877 | |||
| 3878 | /* | ||
| 3879 | * R3613 (0xE1D) - EQ1_14 | ||
| 3880 | */ | ||
| 3881 | #define WM5100_EQ1_B4_A_MASK 0xFFFF /* EQ1_B4_A - [15:0] */ | ||
| 3882 | #define WM5100_EQ1_B4_A_SHIFT 0 /* EQ1_B4_A - [15:0] */ | ||
| 3883 | #define WM5100_EQ1_B4_A_WIDTH 16 /* EQ1_B4_A - [15:0] */ | ||
| 3884 | |||
| 3885 | /* | ||
| 3886 | * R3614 (0xE1E) - EQ1_15 | ||
| 3887 | */ | ||
| 3888 | #define WM5100_EQ1_B4_B_MASK 0xFFFF /* EQ1_B4_B - [15:0] */ | ||
| 3889 | #define WM5100_EQ1_B4_B_SHIFT 0 /* EQ1_B4_B - [15:0] */ | ||
| 3890 | #define WM5100_EQ1_B4_B_WIDTH 16 /* EQ1_B4_B - [15:0] */ | ||
| 3891 | |||
| 3892 | /* | ||
| 3893 | * R3615 (0xE1F) - EQ1_16 | ||
| 3894 | */ | ||
| 3895 | #define WM5100_EQ1_B4_C_MASK 0xFFFF /* EQ1_B4_C - [15:0] */ | ||
| 3896 | #define WM5100_EQ1_B4_C_SHIFT 0 /* EQ1_B4_C - [15:0] */ | ||
| 3897 | #define WM5100_EQ1_B4_C_WIDTH 16 /* EQ1_B4_C - [15:0] */ | ||
| 3898 | |||
| 3899 | /* | ||
| 3900 | * R3616 (0xE20) - EQ1_17 | ||
| 3901 | */ | ||
| 3902 | #define WM5100_EQ1_B4_PG_MASK 0xFFFF /* EQ1_B4_PG - [15:0] */ | ||
| 3903 | #define WM5100_EQ1_B4_PG_SHIFT 0 /* EQ1_B4_PG - [15:0] */ | ||
| 3904 | #define WM5100_EQ1_B4_PG_WIDTH 16 /* EQ1_B4_PG - [15:0] */ | ||
| 3905 | |||
| 3906 | /* | ||
| 3907 | * R3617 (0xE21) - EQ1_18 | ||
| 3908 | */ | ||
| 3909 | #define WM5100_EQ1_B5_A_MASK 0xFFFF /* EQ1_B5_A - [15:0] */ | ||
| 3910 | #define WM5100_EQ1_B5_A_SHIFT 0 /* EQ1_B5_A - [15:0] */ | ||
| 3911 | #define WM5100_EQ1_B5_A_WIDTH 16 /* EQ1_B5_A - [15:0] */ | ||
| 3912 | |||
| 3913 | /* | ||
| 3914 | * R3618 (0xE22) - EQ1_19 | ||
| 3915 | */ | ||
| 3916 | #define WM5100_EQ1_B5_B_MASK 0xFFFF /* EQ1_B5_B - [15:0] */ | ||
| 3917 | #define WM5100_EQ1_B5_B_SHIFT 0 /* EQ1_B5_B - [15:0] */ | ||
| 3918 | #define WM5100_EQ1_B5_B_WIDTH 16 /* EQ1_B5_B - [15:0] */ | ||
| 3919 | |||
| 3920 | /* | ||
| 3921 | * R3619 (0xE23) - EQ1_20 | ||
| 3922 | */ | ||
| 3923 | #define WM5100_EQ1_B5_PG_MASK 0xFFFF /* EQ1_B5_PG - [15:0] */ | ||
| 3924 | #define WM5100_EQ1_B5_PG_SHIFT 0 /* EQ1_B5_PG - [15:0] */ | ||
| 3925 | #define WM5100_EQ1_B5_PG_WIDTH 16 /* EQ1_B5_PG - [15:0] */ | ||
| 3926 | |||
| 3927 | /* | ||
| 3928 | * R3622 (0xE26) - EQ2_1 | ||
| 3929 | */ | ||
| 3930 | #define WM5100_EQ2_B1_GAIN_MASK 0xF800 /* EQ2_B1_GAIN - [15:11] */ | ||
| 3931 | #define WM5100_EQ2_B1_GAIN_SHIFT 11 /* EQ2_B1_GAIN - [15:11] */ | ||
| 3932 | #define WM5100_EQ2_B1_GAIN_WIDTH 5 /* EQ2_B1_GAIN - [15:11] */ | ||
| 3933 | #define WM5100_EQ2_B2_GAIN_MASK 0x07C0 /* EQ2_B2_GAIN - [10:6] */ | ||
| 3934 | #define WM5100_EQ2_B2_GAIN_SHIFT 6 /* EQ2_B2_GAIN - [10:6] */ | ||
| 3935 | #define WM5100_EQ2_B2_GAIN_WIDTH 5 /* EQ2_B2_GAIN - [10:6] */ | ||
| 3936 | #define WM5100_EQ2_B3_GAIN_MASK 0x003E /* EQ2_B3_GAIN - [5:1] */ | ||
| 3937 | #define WM5100_EQ2_B3_GAIN_SHIFT 1 /* EQ2_B3_GAIN - [5:1] */ | ||
| 3938 | #define WM5100_EQ2_B3_GAIN_WIDTH 5 /* EQ2_B3_GAIN - [5:1] */ | ||
| 3939 | #define WM5100_EQ2_ENA 0x0001 /* EQ2_ENA */ | ||
| 3940 | #define WM5100_EQ2_ENA_MASK 0x0001 /* EQ2_ENA */ | ||
| 3941 | #define WM5100_EQ2_ENA_SHIFT 0 /* EQ2_ENA */ | ||
| 3942 | #define WM5100_EQ2_ENA_WIDTH 1 /* EQ2_ENA */ | ||
| 3943 | |||
| 3944 | /* | ||
| 3945 | * R3623 (0xE27) - EQ2_2 | ||
| 3946 | */ | ||
| 3947 | #define WM5100_EQ2_B4_GAIN_MASK 0xF800 /* EQ2_B4_GAIN - [15:11] */ | ||
| 3948 | #define WM5100_EQ2_B4_GAIN_SHIFT 11 /* EQ2_B4_GAIN - [15:11] */ | ||
| 3949 | #define WM5100_EQ2_B4_GAIN_WIDTH 5 /* EQ2_B4_GAIN - [15:11] */ | ||
| 3950 | #define WM5100_EQ2_B5_GAIN_MASK 0x07C0 /* EQ2_B5_GAIN - [10:6] */ | ||
| 3951 | #define WM5100_EQ2_B5_GAIN_SHIFT 6 /* EQ2_B5_GAIN - [10:6] */ | ||
| 3952 | #define WM5100_EQ2_B5_GAIN_WIDTH 5 /* EQ2_B5_GAIN - [10:6] */ | ||
| 3953 | |||
| 3954 | /* | ||
| 3955 | * R3624 (0xE28) - EQ2_3 | ||
| 3956 | */ | ||
| 3957 | #define WM5100_EQ2_B1_A_MASK 0xFFFF /* EQ2_B1_A - [15:0] */ | ||
| 3958 | #define WM5100_EQ2_B1_A_SHIFT 0 /* EQ2_B1_A - [15:0] */ | ||
| 3959 | #define WM5100_EQ2_B1_A_WIDTH 16 /* EQ2_B1_A - [15:0] */ | ||
| 3960 | |||
| 3961 | /* | ||
| 3962 | * R3625 (0xE29) - EQ2_4 | ||
| 3963 | */ | ||
| 3964 | #define WM5100_EQ2_B1_B_MASK 0xFFFF /* EQ2_B1_B - [15:0] */ | ||
| 3965 | #define WM5100_EQ2_B1_B_SHIFT 0 /* EQ2_B1_B - [15:0] */ | ||
| 3966 | #define WM5100_EQ2_B1_B_WIDTH 16 /* EQ2_B1_B - [15:0] */ | ||
| 3967 | |||
| 3968 | /* | ||
| 3969 | * R3626 (0xE2A) - EQ2_5 | ||
| 3970 | */ | ||
| 3971 | #define WM5100_EQ2_B1_PG_MASK 0xFFFF /* EQ2_B1_PG - [15:0] */ | ||
| 3972 | #define WM5100_EQ2_B1_PG_SHIFT 0 /* EQ2_B1_PG - [15:0] */ | ||
| 3973 | #define WM5100_EQ2_B1_PG_WIDTH 16 /* EQ2_B1_PG - [15:0] */ | ||
| 3974 | |||
| 3975 | /* | ||
| 3976 | * R3627 (0xE2B) - EQ2_6 | ||
| 3977 | */ | ||
| 3978 | #define WM5100_EQ2_B2_A_MASK 0xFFFF /* EQ2_B2_A - [15:0] */ | ||
| 3979 | #define WM5100_EQ2_B2_A_SHIFT 0 /* EQ2_B2_A - [15:0] */ | ||
| 3980 | #define WM5100_EQ2_B2_A_WIDTH 16 /* EQ2_B2_A - [15:0] */ | ||
| 3981 | |||
| 3982 | /* | ||
| 3983 | * R3628 (0xE2C) - EQ2_7 | ||
| 3984 | */ | ||
| 3985 | #define WM5100_EQ2_B2_B_MASK 0xFFFF /* EQ2_B2_B - [15:0] */ | ||
| 3986 | #define WM5100_EQ2_B2_B_SHIFT 0 /* EQ2_B2_B - [15:0] */ | ||
| 3987 | #define WM5100_EQ2_B2_B_WIDTH 16 /* EQ2_B2_B - [15:0] */ | ||
| 3988 | |||
| 3989 | /* | ||
| 3990 | * R3629 (0xE2D) - EQ2_8 | ||
| 3991 | */ | ||
| 3992 | #define WM5100_EQ2_B2_C_MASK 0xFFFF /* EQ2_B2_C - [15:0] */ | ||
| 3993 | #define WM5100_EQ2_B2_C_SHIFT 0 /* EQ2_B2_C - [15:0] */ | ||
| 3994 | #define WM5100_EQ2_B2_C_WIDTH 16 /* EQ2_B2_C - [15:0] */ | ||
| 3995 | |||
| 3996 | /* | ||
| 3997 | * R3630 (0xE2E) - EQ2_9 | ||
| 3998 | */ | ||
| 3999 | #define WM5100_EQ2_B2_PG_MASK 0xFFFF /* EQ2_B2_PG - [15:0] */ | ||
| 4000 | #define WM5100_EQ2_B2_PG_SHIFT 0 /* EQ2_B2_PG - [15:0] */ | ||
| 4001 | #define WM5100_EQ2_B2_PG_WIDTH 16 /* EQ2_B2_PG - [15:0] */ | ||
| 4002 | |||
| 4003 | /* | ||
| 4004 | * R3631 (0xE2F) - EQ2_10 | ||
| 4005 | */ | ||
| 4006 | #define WM5100_EQ2_B3_A_MASK 0xFFFF /* EQ2_B3_A - [15:0] */ | ||
| 4007 | #define WM5100_EQ2_B3_A_SHIFT 0 /* EQ2_B3_A - [15:0] */ | ||
| 4008 | #define WM5100_EQ2_B3_A_WIDTH 16 /* EQ2_B3_A - [15:0] */ | ||
| 4009 | |||
| 4010 | /* | ||
| 4011 | * R3632 (0xE30) - EQ2_11 | ||
| 4012 | */ | ||
| 4013 | #define WM5100_EQ2_B3_B_MASK 0xFFFF /* EQ2_B3_B - [15:0] */ | ||
| 4014 | #define WM5100_EQ2_B3_B_SHIFT 0 /* EQ2_B3_B - [15:0] */ | ||
| 4015 | #define WM5100_EQ2_B3_B_WIDTH 16 /* EQ2_B3_B - [15:0] */ | ||
| 4016 | |||
| 4017 | /* | ||
| 4018 | * R3633 (0xE31) - EQ2_12 | ||
| 4019 | */ | ||
| 4020 | #define WM5100_EQ2_B3_C_MASK 0xFFFF /* EQ2_B3_C - [15:0] */ | ||
| 4021 | #define WM5100_EQ2_B3_C_SHIFT 0 /* EQ2_B3_C - [15:0] */ | ||
| 4022 | #define WM5100_EQ2_B3_C_WIDTH 16 /* EQ2_B3_C - [15:0] */ | ||
| 4023 | |||
| 4024 | /* | ||
| 4025 | * R3634 (0xE32) - EQ2_13 | ||
| 4026 | */ | ||
| 4027 | #define WM5100_EQ2_B3_PG_MASK 0xFFFF /* EQ2_B3_PG - [15:0] */ | ||
| 4028 | #define WM5100_EQ2_B3_PG_SHIFT 0 /* EQ2_B3_PG - [15:0] */ | ||
| 4029 | #define WM5100_EQ2_B3_PG_WIDTH 16 /* EQ2_B3_PG - [15:0] */ | ||
| 4030 | |||
| 4031 | /* | ||
| 4032 | * R3635 (0xE33) - EQ2_14 | ||
| 4033 | */ | ||
| 4034 | #define WM5100_EQ2_B4_A_MASK 0xFFFF /* EQ2_B4_A - [15:0] */ | ||
| 4035 | #define WM5100_EQ2_B4_A_SHIFT 0 /* EQ2_B4_A - [15:0] */ | ||
| 4036 | #define WM5100_EQ2_B4_A_WIDTH 16 /* EQ2_B4_A - [15:0] */ | ||
| 4037 | |||
| 4038 | /* | ||
| 4039 | * R3636 (0xE34) - EQ2_15 | ||
| 4040 | */ | ||
| 4041 | #define WM5100_EQ2_B4_B_MASK 0xFFFF /* EQ2_B4_B - [15:0] */ | ||
| 4042 | #define WM5100_EQ2_B4_B_SHIFT 0 /* EQ2_B4_B - [15:0] */ | ||
| 4043 | #define WM5100_EQ2_B4_B_WIDTH 16 /* EQ2_B4_B - [15:0] */ | ||
| 4044 | |||
| 4045 | /* | ||
| 4046 | * R3637 (0xE35) - EQ2_16 | ||
| 4047 | */ | ||
| 4048 | #define WM5100_EQ2_B4_C_MASK 0xFFFF /* EQ2_B4_C - [15:0] */ | ||
| 4049 | #define WM5100_EQ2_B4_C_SHIFT 0 /* EQ2_B4_C - [15:0] */ | ||
| 4050 | #define WM5100_EQ2_B4_C_WIDTH 16 /* EQ2_B4_C - [15:0] */ | ||
| 4051 | |||
| 4052 | /* | ||
| 4053 | * R3638 (0xE36) - EQ2_17 | ||
| 4054 | */ | ||
| 4055 | #define WM5100_EQ2_B4_PG_MASK 0xFFFF /* EQ2_B4_PG - [15:0] */ | ||
| 4056 | #define WM5100_EQ2_B4_PG_SHIFT 0 /* EQ2_B4_PG - [15:0] */ | ||
| 4057 | #define WM5100_EQ2_B4_PG_WIDTH 16 /* EQ2_B4_PG - [15:0] */ | ||
| 4058 | |||
| 4059 | /* | ||
| 4060 | * R3639 (0xE37) - EQ2_18 | ||
| 4061 | */ | ||
| 4062 | #define WM5100_EQ2_B5_A_MASK 0xFFFF /* EQ2_B5_A - [15:0] */ | ||
| 4063 | #define WM5100_EQ2_B5_A_SHIFT 0 /* EQ2_B5_A - [15:0] */ | ||
| 4064 | #define WM5100_EQ2_B5_A_WIDTH 16 /* EQ2_B5_A - [15:0] */ | ||
| 4065 | |||
| 4066 | /* | ||
| 4067 | * R3640 (0xE38) - EQ2_19 | ||
| 4068 | */ | ||
| 4069 | #define WM5100_EQ2_B5_B_MASK 0xFFFF /* EQ2_B5_B - [15:0] */ | ||
| 4070 | #define WM5100_EQ2_B5_B_SHIFT 0 /* EQ2_B5_B - [15:0] */ | ||
| 4071 | #define WM5100_EQ2_B5_B_WIDTH 16 /* EQ2_B5_B - [15:0] */ | ||
| 4072 | |||
| 4073 | /* | ||
| 4074 | * R3641 (0xE39) - EQ2_20 | ||
| 4075 | */ | ||
| 4076 | #define WM5100_EQ2_B5_PG_MASK 0xFFFF /* EQ2_B5_PG - [15:0] */ | ||
| 4077 | #define WM5100_EQ2_B5_PG_SHIFT 0 /* EQ2_B5_PG - [15:0] */ | ||
| 4078 | #define WM5100_EQ2_B5_PG_WIDTH 16 /* EQ2_B5_PG - [15:0] */ | ||
| 4079 | |||
| 4080 | /* | ||
| 4081 | * R3644 (0xE3C) - EQ3_1 | ||
| 4082 | */ | ||
| 4083 | #define WM5100_EQ3_B1_GAIN_MASK 0xF800 /* EQ3_B1_GAIN - [15:11] */ | ||
| 4084 | #define WM5100_EQ3_B1_GAIN_SHIFT 11 /* EQ3_B1_GAIN - [15:11] */ | ||
| 4085 | #define WM5100_EQ3_B1_GAIN_WIDTH 5 /* EQ3_B1_GAIN - [15:11] */ | ||
| 4086 | #define WM5100_EQ3_B2_GAIN_MASK 0x07C0 /* EQ3_B2_GAIN - [10:6] */ | ||
| 4087 | #define WM5100_EQ3_B2_GAIN_SHIFT 6 /* EQ3_B2_GAIN - [10:6] */ | ||
| 4088 | #define WM5100_EQ3_B2_GAIN_WIDTH 5 /* EQ3_B2_GAIN - [10:6] */ | ||
| 4089 | #define WM5100_EQ3_B3_GAIN_MASK 0x003E /* EQ3_B3_GAIN - [5:1] */ | ||
| 4090 | #define WM5100_EQ3_B3_GAIN_SHIFT 1 /* EQ3_B3_GAIN - [5:1] */ | ||
| 4091 | #define WM5100_EQ3_B3_GAIN_WIDTH 5 /* EQ3_B3_GAIN - [5:1] */ | ||
| 4092 | #define WM5100_EQ3_ENA 0x0001 /* EQ3_ENA */ | ||
| 4093 | #define WM5100_EQ3_ENA_MASK 0x0001 /* EQ3_ENA */ | ||
| 4094 | #define WM5100_EQ3_ENA_SHIFT 0 /* EQ3_ENA */ | ||
| 4095 | #define WM5100_EQ3_ENA_WIDTH 1 /* EQ3_ENA */ | ||
| 4096 | |||
| 4097 | /* | ||
| 4098 | * R3645 (0xE3D) - EQ3_2 | ||
| 4099 | */ | ||
| 4100 | #define WM5100_EQ3_B4_GAIN_MASK 0xF800 /* EQ3_B4_GAIN - [15:11] */ | ||
| 4101 | #define WM5100_EQ3_B4_GAIN_SHIFT 11 /* EQ3_B4_GAIN - [15:11] */ | ||
| 4102 | #define WM5100_EQ3_B4_GAIN_WIDTH 5 /* EQ3_B4_GAIN - [15:11] */ | ||
| 4103 | #define WM5100_EQ3_B5_GAIN_MASK 0x07C0 /* EQ3_B5_GAIN - [10:6] */ | ||
| 4104 | #define WM5100_EQ3_B5_GAIN_SHIFT 6 /* EQ3_B5_GAIN - [10:6] */ | ||
| 4105 | #define WM5100_EQ3_B5_GAIN_WIDTH 5 /* EQ3_B5_GAIN - [10:6] */ | ||
| 4106 | |||
| 4107 | /* | ||
| 4108 | * R3646 (0xE3E) - EQ3_3 | ||
| 4109 | */ | ||
| 4110 | #define WM5100_EQ3_B1_A_MASK 0xFFFF /* EQ3_B1_A - [15:0] */ | ||
| 4111 | #define WM5100_EQ3_B1_A_SHIFT 0 /* EQ3_B1_A - [15:0] */ | ||
| 4112 | #define WM5100_EQ3_B1_A_WIDTH 16 /* EQ3_B1_A - [15:0] */ | ||
| 4113 | |||
| 4114 | /* | ||
| 4115 | * R3647 (0xE3F) - EQ3_4 | ||
| 4116 | */ | ||
| 4117 | #define WM5100_EQ3_B1_B_MASK 0xFFFF /* EQ3_B1_B - [15:0] */ | ||
| 4118 | #define WM5100_EQ3_B1_B_SHIFT 0 /* EQ3_B1_B - [15:0] */ | ||
| 4119 | #define WM5100_EQ3_B1_B_WIDTH 16 /* EQ3_B1_B - [15:0] */ | ||
| 4120 | |||
| 4121 | /* | ||
| 4122 | * R3648 (0xE40) - EQ3_5 | ||
| 4123 | */ | ||
| 4124 | #define WM5100_EQ3_B1_PG_MASK 0xFFFF /* EQ3_B1_PG - [15:0] */ | ||
| 4125 | #define WM5100_EQ3_B1_PG_SHIFT 0 /* EQ3_B1_PG - [15:0] */ | ||
| 4126 | #define WM5100_EQ3_B1_PG_WIDTH 16 /* EQ3_B1_PG - [15:0] */ | ||
| 4127 | |||
| 4128 | /* | ||
| 4129 | * R3649 (0xE41) - EQ3_6 | ||
| 4130 | */ | ||
| 4131 | #define WM5100_EQ3_B2_A_MASK 0xFFFF /* EQ3_B2_A - [15:0] */ | ||
| 4132 | #define WM5100_EQ3_B2_A_SHIFT 0 /* EQ3_B2_A - [15:0] */ | ||
| 4133 | #define WM5100_EQ3_B2_A_WIDTH 16 /* EQ3_B2_A - [15:0] */ | ||
| 4134 | |||
| 4135 | /* | ||
| 4136 | * R3650 (0xE42) - EQ3_7 | ||
| 4137 | */ | ||
| 4138 | #define WM5100_EQ3_B2_B_MASK 0xFFFF /* EQ3_B2_B - [15:0] */ | ||
| 4139 | #define WM5100_EQ3_B2_B_SHIFT 0 /* EQ3_B2_B - [15:0] */ | ||
| 4140 | #define WM5100_EQ3_B2_B_WIDTH 16 /* EQ3_B2_B - [15:0] */ | ||
| 4141 | |||
| 4142 | /* | ||
| 4143 | * R3651 (0xE43) - EQ3_8 | ||
| 4144 | */ | ||
| 4145 | #define WM5100_EQ3_B2_C_MASK 0xFFFF /* EQ3_B2_C - [15:0] */ | ||
| 4146 | #define WM5100_EQ3_B2_C_SHIFT 0 /* EQ3_B2_C - [15:0] */ | ||
| 4147 | #define WM5100_EQ3_B2_C_WIDTH 16 /* EQ3_B2_C - [15:0] */ | ||
| 4148 | |||
| 4149 | /* | ||
| 4150 | * R3652 (0xE44) - EQ3_9 | ||
| 4151 | */ | ||
| 4152 | #define WM5100_EQ3_B2_PG_MASK 0xFFFF /* EQ3_B2_PG - [15:0] */ | ||
| 4153 | #define WM5100_EQ3_B2_PG_SHIFT 0 /* EQ3_B2_PG - [15:0] */ | ||
| 4154 | #define WM5100_EQ3_B2_PG_WIDTH 16 /* EQ3_B2_PG - [15:0] */ | ||
| 4155 | |||
| 4156 | /* | ||
| 4157 | * R3653 (0xE45) - EQ3_10 | ||
| 4158 | */ | ||
| 4159 | #define WM5100_EQ3_B3_A_MASK 0xFFFF /* EQ3_B3_A - [15:0] */ | ||
| 4160 | #define WM5100_EQ3_B3_A_SHIFT 0 /* EQ3_B3_A - [15:0] */ | ||
| 4161 | #define WM5100_EQ3_B3_A_WIDTH 16 /* EQ3_B3_A - [15:0] */ | ||
| 4162 | |||
| 4163 | /* | ||
| 4164 | * R3654 (0xE46) - EQ3_11 | ||
| 4165 | */ | ||
| 4166 | #define WM5100_EQ3_B3_B_MASK 0xFFFF /* EQ3_B3_B - [15:0] */ | ||
| 4167 | #define WM5100_EQ3_B3_B_SHIFT 0 /* EQ3_B3_B - [15:0] */ | ||
| 4168 | #define WM5100_EQ3_B3_B_WIDTH 16 /* EQ3_B3_B - [15:0] */ | ||
| 4169 | |||
| 4170 | /* | ||
| 4171 | * R3655 (0xE47) - EQ3_12 | ||
| 4172 | */ | ||
| 4173 | #define WM5100_EQ3_B3_C_MASK 0xFFFF /* EQ3_B3_C - [15:0] */ | ||
| 4174 | #define WM5100_EQ3_B3_C_SHIFT 0 /* EQ3_B3_C - [15:0] */ | ||
| 4175 | #define WM5100_EQ3_B3_C_WIDTH 16 /* EQ3_B3_C - [15:0] */ | ||
| 4176 | |||
| 4177 | /* | ||
| 4178 | * R3656 (0xE48) - EQ3_13 | ||
| 4179 | */ | ||
| 4180 | #define WM5100_EQ3_B3_PG_MASK 0xFFFF /* EQ3_B3_PG - [15:0] */ | ||
| 4181 | #define WM5100_EQ3_B3_PG_SHIFT 0 /* EQ3_B3_PG - [15:0] */ | ||
| 4182 | #define WM5100_EQ3_B3_PG_WIDTH 16 /* EQ3_B3_PG - [15:0] */ | ||
| 4183 | |||
| 4184 | /* | ||
| 4185 | * R3657 (0xE49) - EQ3_14 | ||
| 4186 | */ | ||
| 4187 | #define WM5100_EQ3_B4_A_MASK 0xFFFF /* EQ3_B4_A - [15:0] */ | ||
| 4188 | #define WM5100_EQ3_B4_A_SHIFT 0 /* EQ3_B4_A - [15:0] */ | ||
| 4189 | #define WM5100_EQ3_B4_A_WIDTH 16 /* EQ3_B4_A - [15:0] */ | ||
| 4190 | |||
| 4191 | /* | ||
| 4192 | * R3658 (0xE4A) - EQ3_15 | ||
| 4193 | */ | ||
| 4194 | #define WM5100_EQ3_B4_B_MASK 0xFFFF /* EQ3_B4_B - [15:0] */ | ||
| 4195 | #define WM5100_EQ3_B4_B_SHIFT 0 /* EQ3_B4_B - [15:0] */ | ||
| 4196 | #define WM5100_EQ3_B4_B_WIDTH 16 /* EQ3_B4_B - [15:0] */ | ||
| 4197 | |||
| 4198 | /* | ||
| 4199 | * R3659 (0xE4B) - EQ3_16 | ||
| 4200 | */ | ||
| 4201 | #define WM5100_EQ3_B4_C_MASK 0xFFFF /* EQ3_B4_C - [15:0] */ | ||
| 4202 | #define WM5100_EQ3_B4_C_SHIFT 0 /* EQ3_B4_C - [15:0] */ | ||
| 4203 | #define WM5100_EQ3_B4_C_WIDTH 16 /* EQ3_B4_C - [15:0] */ | ||
| 4204 | |||
| 4205 | /* | ||
| 4206 | * R3660 (0xE4C) - EQ3_17 | ||
| 4207 | */ | ||
| 4208 | #define WM5100_EQ3_B4_PG_MASK 0xFFFF /* EQ3_B4_PG - [15:0] */ | ||
| 4209 | #define WM5100_EQ3_B4_PG_SHIFT 0 /* EQ3_B4_PG - [15:0] */ | ||
| 4210 | #define WM5100_EQ3_B4_PG_WIDTH 16 /* EQ3_B4_PG - [15:0] */ | ||
| 4211 | |||
| 4212 | /* | ||
| 4213 | * R3661 (0xE4D) - EQ3_18 | ||
| 4214 | */ | ||
| 4215 | #define WM5100_EQ3_B5_A_MASK 0xFFFF /* EQ3_B5_A - [15:0] */ | ||
| 4216 | #define WM5100_EQ3_B5_A_SHIFT 0 /* EQ3_B5_A - [15:0] */ | ||
| 4217 | #define WM5100_EQ3_B5_A_WIDTH 16 /* EQ3_B5_A - [15:0] */ | ||
| 4218 | |||
| 4219 | /* | ||
| 4220 | * R3662 (0xE4E) - EQ3_19 | ||
| 4221 | */ | ||
| 4222 | #define WM5100_EQ3_B5_B_MASK 0xFFFF /* EQ3_B5_B - [15:0] */ | ||
| 4223 | #define WM5100_EQ3_B5_B_SHIFT 0 /* EQ3_B5_B - [15:0] */ | ||
| 4224 | #define WM5100_EQ3_B5_B_WIDTH 16 /* EQ3_B5_B - [15:0] */ | ||
| 4225 | |||
| 4226 | /* | ||
| 4227 | * R3663 (0xE4F) - EQ3_20 | ||
| 4228 | */ | ||
| 4229 | #define WM5100_EQ3_B5_PG_MASK 0xFFFF /* EQ3_B5_PG - [15:0] */ | ||
| 4230 | #define WM5100_EQ3_B5_PG_SHIFT 0 /* EQ3_B5_PG - [15:0] */ | ||
| 4231 | #define WM5100_EQ3_B5_PG_WIDTH 16 /* EQ3_B5_PG - [15:0] */ | ||
| 4232 | |||
| 4233 | /* | ||
| 4234 | * R3666 (0xE52) - EQ4_1 | ||
| 4235 | */ | ||
| 4236 | #define WM5100_EQ4_B1_GAIN_MASK 0xF800 /* EQ4_B1_GAIN - [15:11] */ | ||
| 4237 | #define WM5100_EQ4_B1_GAIN_SHIFT 11 /* EQ4_B1_GAIN - [15:11] */ | ||
| 4238 | #define WM5100_EQ4_B1_GAIN_WIDTH 5 /* EQ4_B1_GAIN - [15:11] */ | ||
| 4239 | #define WM5100_EQ4_B2_GAIN_MASK 0x07C0 /* EQ4_B2_GAIN - [10:6] */ | ||
| 4240 | #define WM5100_EQ4_B2_GAIN_SHIFT 6 /* EQ4_B2_GAIN - [10:6] */ | ||
| 4241 | #define WM5100_EQ4_B2_GAIN_WIDTH 5 /* EQ4_B2_GAIN - [10:6] */ | ||
| 4242 | #define WM5100_EQ4_B3_GAIN_MASK 0x003E /* EQ4_B3_GAIN - [5:1] */ | ||
| 4243 | #define WM5100_EQ4_B3_GAIN_SHIFT 1 /* EQ4_B3_GAIN - [5:1] */ | ||
| 4244 | #define WM5100_EQ4_B3_GAIN_WIDTH 5 /* EQ4_B3_GAIN - [5:1] */ | ||
| 4245 | #define WM5100_EQ4_ENA 0x0001 /* EQ4_ENA */ | ||
| 4246 | #define WM5100_EQ4_ENA_MASK 0x0001 /* EQ4_ENA */ | ||
| 4247 | #define WM5100_EQ4_ENA_SHIFT 0 /* EQ4_ENA */ | ||
| 4248 | #define WM5100_EQ4_ENA_WIDTH 1 /* EQ4_ENA */ | ||
| 4249 | |||
| 4250 | /* | ||
| 4251 | * R3667 (0xE53) - EQ4_2 | ||
| 4252 | */ | ||
| 4253 | #define WM5100_EQ4_B4_GAIN_MASK 0xF800 /* EQ4_B4_GAIN - [15:11] */ | ||
| 4254 | #define WM5100_EQ4_B4_GAIN_SHIFT 11 /* EQ4_B4_GAIN - [15:11] */ | ||
| 4255 | #define WM5100_EQ4_B4_GAIN_WIDTH 5 /* EQ4_B4_GAIN - [15:11] */ | ||
| 4256 | #define WM5100_EQ4_B5_GAIN_MASK 0x07C0 /* EQ4_B5_GAIN - [10:6] */ | ||
| 4257 | #define WM5100_EQ4_B5_GAIN_SHIFT 6 /* EQ4_B5_GAIN - [10:6] */ | ||
| 4258 | #define WM5100_EQ4_B5_GAIN_WIDTH 5 /* EQ4_B5_GAIN - [10:6] */ | ||
| 4259 | |||
| 4260 | /* | ||
| 4261 | * R3668 (0xE54) - EQ4_3 | ||
| 4262 | */ | ||
| 4263 | #define WM5100_EQ4_B1_A_MASK 0xFFFF /* EQ4_B1_A - [15:0] */ | ||
| 4264 | #define WM5100_EQ4_B1_A_SHIFT 0 /* EQ4_B1_A - [15:0] */ | ||
| 4265 | #define WM5100_EQ4_B1_A_WIDTH 16 /* EQ4_B1_A - [15:0] */ | ||
| 4266 | |||
| 4267 | /* | ||
| 4268 | * R3669 (0xE55) - EQ4_4 | ||
| 4269 | */ | ||
| 4270 | #define WM5100_EQ4_B1_B_MASK 0xFFFF /* EQ4_B1_B - [15:0] */ | ||
| 4271 | #define WM5100_EQ4_B1_B_SHIFT 0 /* EQ4_B1_B - [15:0] */ | ||
| 4272 | #define WM5100_EQ4_B1_B_WIDTH 16 /* EQ4_B1_B - [15:0] */ | ||
| 4273 | |||
| 4274 | /* | ||
| 4275 | * R3670 (0xE56) - EQ4_5 | ||
| 4276 | */ | ||
| 4277 | #define WM5100_EQ4_B1_PG_MASK 0xFFFF /* EQ4_B1_PG - [15:0] */ | ||
| 4278 | #define WM5100_EQ4_B1_PG_SHIFT 0 /* EQ4_B1_PG - [15:0] */ | ||
| 4279 | #define WM5100_EQ4_B1_PG_WIDTH 16 /* EQ4_B1_PG - [15:0] */ | ||
| 4280 | |||
| 4281 | /* | ||
| 4282 | * R3671 (0xE57) - EQ4_6 | ||
| 4283 | */ | ||
| 4284 | #define WM5100_EQ4_B2_A_MASK 0xFFFF /* EQ4_B2_A - [15:0] */ | ||
| 4285 | #define WM5100_EQ4_B2_A_SHIFT 0 /* EQ4_B2_A - [15:0] */ | ||
| 4286 | #define WM5100_EQ4_B2_A_WIDTH 16 /* EQ4_B2_A - [15:0] */ | ||
| 4287 | |||
| 4288 | /* | ||
| 4289 | * R3672 (0xE58) - EQ4_7 | ||
| 4290 | */ | ||
| 4291 | #define WM5100_EQ4_B2_B_MASK 0xFFFF /* EQ4_B2_B - [15:0] */ | ||
| 4292 | #define WM5100_EQ4_B2_B_SHIFT 0 /* EQ4_B2_B - [15:0] */ | ||
| 4293 | #define WM5100_EQ4_B2_B_WIDTH 16 /* EQ4_B2_B - [15:0] */ | ||
| 4294 | |||
| 4295 | /* | ||
| 4296 | * R3673 (0xE59) - EQ4_8 | ||
| 4297 | */ | ||
| 4298 | #define WM5100_EQ4_B2_C_MASK 0xFFFF /* EQ4_B2_C - [15:0] */ | ||
| 4299 | #define WM5100_EQ4_B2_C_SHIFT 0 /* EQ4_B2_C - [15:0] */ | ||
| 4300 | #define WM5100_EQ4_B2_C_WIDTH 16 /* EQ4_B2_C - [15:0] */ | ||
| 4301 | |||
| 4302 | /* | ||
| 4303 | * R3674 (0xE5A) - EQ4_9 | ||
| 4304 | */ | ||
| 4305 | #define WM5100_EQ4_B2_PG_MASK 0xFFFF /* EQ4_B2_PG - [15:0] */ | ||
| 4306 | #define WM5100_EQ4_B2_PG_SHIFT 0 /* EQ4_B2_PG - [15:0] */ | ||
| 4307 | #define WM5100_EQ4_B2_PG_WIDTH 16 /* EQ4_B2_PG - [15:0] */ | ||
| 4308 | |||
| 4309 | /* | ||
| 4310 | * R3675 (0xE5B) - EQ4_10 | ||
| 4311 | */ | ||
| 4312 | #define WM5100_EQ4_B3_A_MASK 0xFFFF /* EQ4_B3_A - [15:0] */ | ||
| 4313 | #define WM5100_EQ4_B3_A_SHIFT 0 /* EQ4_B3_A - [15:0] */ | ||
| 4314 | #define WM5100_EQ4_B3_A_WIDTH 16 /* EQ4_B3_A - [15:0] */ | ||
| 4315 | |||
| 4316 | /* | ||
| 4317 | * R3676 (0xE5C) - EQ4_11 | ||
| 4318 | */ | ||
| 4319 | #define WM5100_EQ4_B3_B_MASK 0xFFFF /* EQ4_B3_B - [15:0] */ | ||
| 4320 | #define WM5100_EQ4_B3_B_SHIFT 0 /* EQ4_B3_B - [15:0] */ | ||
| 4321 | #define WM5100_EQ4_B3_B_WIDTH 16 /* EQ4_B3_B - [15:0] */ | ||
| 4322 | |||
| 4323 | /* | ||
| 4324 | * R3677 (0xE5D) - EQ4_12 | ||
| 4325 | */ | ||
| 4326 | #define WM5100_EQ4_B3_C_MASK 0xFFFF /* EQ4_B3_C - [15:0] */ | ||
| 4327 | #define WM5100_EQ4_B3_C_SHIFT 0 /* EQ4_B3_C - [15:0] */ | ||
| 4328 | #define WM5100_EQ4_B3_C_WIDTH 16 /* EQ4_B3_C - [15:0] */ | ||
| 4329 | |||
| 4330 | /* | ||
| 4331 | * R3678 (0xE5E) - EQ4_13 | ||
| 4332 | */ | ||
| 4333 | #define WM5100_EQ4_B3_PG_MASK 0xFFFF /* EQ4_B3_PG - [15:0] */ | ||
| 4334 | #define WM5100_EQ4_B3_PG_SHIFT 0 /* EQ4_B3_PG - [15:0] */ | ||
| 4335 | #define WM5100_EQ4_B3_PG_WIDTH 16 /* EQ4_B3_PG - [15:0] */ | ||
| 4336 | |||
| 4337 | /* | ||
| 4338 | * R3679 (0xE5F) - EQ4_14 | ||
| 4339 | */ | ||
| 4340 | #define WM5100_EQ4_B4_A_MASK 0xFFFF /* EQ4_B4_A - [15:0] */ | ||
| 4341 | #define WM5100_EQ4_B4_A_SHIFT 0 /* EQ4_B4_A - [15:0] */ | ||
| 4342 | #define WM5100_EQ4_B4_A_WIDTH 16 /* EQ4_B4_A - [15:0] */ | ||
| 4343 | |||
| 4344 | /* | ||
| 4345 | * R3680 (0xE60) - EQ4_15 | ||
| 4346 | */ | ||
| 4347 | #define WM5100_EQ4_B4_B_MASK 0xFFFF /* EQ4_B4_B - [15:0] */ | ||
| 4348 | #define WM5100_EQ4_B4_B_SHIFT 0 /* EQ4_B4_B - [15:0] */ | ||
| 4349 | #define WM5100_EQ4_B4_B_WIDTH 16 /* EQ4_B4_B - [15:0] */ | ||
| 4350 | |||
| 4351 | /* | ||
| 4352 | * R3681 (0xE61) - EQ4_16 | ||
| 4353 | */ | ||
| 4354 | #define WM5100_EQ4_B4_C_MASK 0xFFFF /* EQ4_B4_C - [15:0] */ | ||
| 4355 | #define WM5100_EQ4_B4_C_SHIFT 0 /* EQ4_B4_C - [15:0] */ | ||
| 4356 | #define WM5100_EQ4_B4_C_WIDTH 16 /* EQ4_B4_C - [15:0] */ | ||
| 4357 | |||
| 4358 | /* | ||
| 4359 | * R3682 (0xE62) - EQ4_17 | ||
| 4360 | */ | ||
| 4361 | #define WM5100_EQ4_B4_PG_MASK 0xFFFF /* EQ4_B4_PG - [15:0] */ | ||
| 4362 | #define WM5100_EQ4_B4_PG_SHIFT 0 /* EQ4_B4_PG - [15:0] */ | ||
| 4363 | #define WM5100_EQ4_B4_PG_WIDTH 16 /* EQ4_B4_PG - [15:0] */ | ||
| 4364 | |||
| 4365 | /* | ||
| 4366 | * R3683 (0xE63) - EQ4_18 | ||
| 4367 | */ | ||
| 4368 | #define WM5100_EQ4_B5_A_MASK 0xFFFF /* EQ4_B5_A - [15:0] */ | ||
| 4369 | #define WM5100_EQ4_B5_A_SHIFT 0 /* EQ4_B5_A - [15:0] */ | ||
| 4370 | #define WM5100_EQ4_B5_A_WIDTH 16 /* EQ4_B5_A - [15:0] */ | ||
| 4371 | |||
| 4372 | /* | ||
| 4373 | * R3684 (0xE64) - EQ4_19 | ||
| 4374 | */ | ||
| 4375 | #define WM5100_EQ4_B5_B_MASK 0xFFFF /* EQ4_B5_B - [15:0] */ | ||
| 4376 | #define WM5100_EQ4_B5_B_SHIFT 0 /* EQ4_B5_B - [15:0] */ | ||
| 4377 | #define WM5100_EQ4_B5_B_WIDTH 16 /* EQ4_B5_B - [15:0] */ | ||
| 4378 | |||
| 4379 | /* | ||
| 4380 | * R3685 (0xE65) - EQ4_20 | ||
| 4381 | */ | ||
| 4382 | #define WM5100_EQ4_B5_PG_MASK 0xFFFF /* EQ4_B5_PG - [15:0] */ | ||
| 4383 | #define WM5100_EQ4_B5_PG_SHIFT 0 /* EQ4_B5_PG - [15:0] */ | ||
| 4384 | #define WM5100_EQ4_B5_PG_WIDTH 16 /* EQ4_B5_PG - [15:0] */ | ||
| 4385 | |||
| 4386 | /* | ||
| 4387 | * R3712 (0xE80) - DRC1 ctrl1 | ||
| 4388 | */ | ||
| 4389 | #define WM5100_DRC_SIG_DET_RMS_MASK 0xF800 /* DRC_SIG_DET_RMS - [15:11] */ | ||
| 4390 | #define WM5100_DRC_SIG_DET_RMS_SHIFT 11 /* DRC_SIG_DET_RMS - [15:11] */ | ||
| 4391 | #define WM5100_DRC_SIG_DET_RMS_WIDTH 5 /* DRC_SIG_DET_RMS - [15:11] */ | ||
| 4392 | #define WM5100_DRC_SIG_DET_PK_MASK 0x0600 /* DRC_SIG_DET_PK - [10:9] */ | ||
| 4393 | #define WM5100_DRC_SIG_DET_PK_SHIFT 9 /* DRC_SIG_DET_PK - [10:9] */ | ||
| 4394 | #define WM5100_DRC_SIG_DET_PK_WIDTH 2 /* DRC_SIG_DET_PK - [10:9] */ | ||
| 4395 | #define WM5100_DRC_NG_ENA 0x0100 /* DRC_NG_ENA */ | ||
| 4396 | #define WM5100_DRC_NG_ENA_MASK 0x0100 /* DRC_NG_ENA */ | ||
| 4397 | #define WM5100_DRC_NG_ENA_SHIFT 8 /* DRC_NG_ENA */ | ||
| 4398 | #define WM5100_DRC_NG_ENA_WIDTH 1 /* DRC_NG_ENA */ | ||
| 4399 | #define WM5100_DRC_SIG_DET_MODE 0x0080 /* DRC_SIG_DET_MODE */ | ||
| 4400 | #define WM5100_DRC_SIG_DET_MODE_MASK 0x0080 /* DRC_SIG_DET_MODE */ | ||
| 4401 | #define WM5100_DRC_SIG_DET_MODE_SHIFT 7 /* DRC_SIG_DET_MODE */ | ||
| 4402 | #define WM5100_DRC_SIG_DET_MODE_WIDTH 1 /* DRC_SIG_DET_MODE */ | ||
| 4403 | #define WM5100_DRC_SIG_DET 0x0040 /* DRC_SIG_DET */ | ||
| 4404 | #define WM5100_DRC_SIG_DET_MASK 0x0040 /* DRC_SIG_DET */ | ||
| 4405 | #define WM5100_DRC_SIG_DET_SHIFT 6 /* DRC_SIG_DET */ | ||
| 4406 | #define WM5100_DRC_SIG_DET_WIDTH 1 /* DRC_SIG_DET */ | ||
| 4407 | #define WM5100_DRC_KNEE2_OP_ENA 0x0020 /* DRC_KNEE2_OP_ENA */ | ||
| 4408 | #define WM5100_DRC_KNEE2_OP_ENA_MASK 0x0020 /* DRC_KNEE2_OP_ENA */ | ||
| 4409 | #define WM5100_DRC_KNEE2_OP_ENA_SHIFT 5 /* DRC_KNEE2_OP_ENA */ | ||
| 4410 | #define WM5100_DRC_KNEE2_OP_ENA_WIDTH 1 /* DRC_KNEE2_OP_ENA */ | ||
| 4411 | #define WM5100_DRC_QR 0x0010 /* DRC_QR */ | ||
| 4412 | #define WM5100_DRC_QR_MASK 0x0010 /* DRC_QR */ | ||
| 4413 | #define WM5100_DRC_QR_SHIFT 4 /* DRC_QR */ | ||
| 4414 | #define WM5100_DRC_QR_WIDTH 1 /* DRC_QR */ | ||
| 4415 | #define WM5100_DRC_ANTICLIP 0x0008 /* DRC_ANTICLIP */ | ||
| 4416 | #define WM5100_DRC_ANTICLIP_MASK 0x0008 /* DRC_ANTICLIP */ | ||
| 4417 | #define WM5100_DRC_ANTICLIP_SHIFT 3 /* DRC_ANTICLIP */ | ||
| 4418 | #define WM5100_DRC_ANTICLIP_WIDTH 1 /* DRC_ANTICLIP */ | ||
| 4419 | #define WM5100_DRCL_ENA 0x0002 /* DRCL_ENA */ | ||
| 4420 | #define WM5100_DRCL_ENA_MASK 0x0002 /* DRCL_ENA */ | ||
| 4421 | #define WM5100_DRCL_ENA_SHIFT 1 /* DRCL_ENA */ | ||
| 4422 | #define WM5100_DRCL_ENA_WIDTH 1 /* DRCL_ENA */ | ||
| 4423 | #define WM5100_DRCR_ENA 0x0001 /* DRCR_ENA */ | ||
| 4424 | #define WM5100_DRCR_ENA_MASK 0x0001 /* DRCR_ENA */ | ||
| 4425 | #define WM5100_DRCR_ENA_SHIFT 0 /* DRCR_ENA */ | ||
| 4426 | #define WM5100_DRCR_ENA_WIDTH 1 /* DRCR_ENA */ | ||
| 4427 | |||
| 4428 | /* | ||
| 4429 | * R3713 (0xE81) - DRC1 ctrl2 | ||
| 4430 | */ | ||
| 4431 | #define WM5100_DRC_ATK_MASK 0x1E00 /* DRC_ATK - [12:9] */ | ||
| 4432 | #define WM5100_DRC_ATK_SHIFT 9 /* DRC_ATK - [12:9] */ | ||
| 4433 | #define WM5100_DRC_ATK_WIDTH 4 /* DRC_ATK - [12:9] */ | ||
| 4434 | #define WM5100_DRC_DCY_MASK 0x01E0 /* DRC_DCY - [8:5] */ | ||
| 4435 | #define WM5100_DRC_DCY_SHIFT 5 /* DRC_DCY - [8:5] */ | ||
| 4436 | #define WM5100_DRC_DCY_WIDTH 4 /* DRC_DCY - [8:5] */ | ||
| 4437 | #define WM5100_DRC_MINGAIN_MASK 0x001C /* DRC_MINGAIN - [4:2] */ | ||
| 4438 | #define WM5100_DRC_MINGAIN_SHIFT 2 /* DRC_MINGAIN - [4:2] */ | ||
| 4439 | #define WM5100_DRC_MINGAIN_WIDTH 3 /* DRC_MINGAIN - [4:2] */ | ||
| 4440 | #define WM5100_DRC_MAXGAIN_MASK 0x0003 /* DRC_MAXGAIN - [1:0] */ | ||
| 4441 | #define WM5100_DRC_MAXGAIN_SHIFT 0 /* DRC_MAXGAIN - [1:0] */ | ||
| 4442 | #define WM5100_DRC_MAXGAIN_WIDTH 2 /* DRC_MAXGAIN - [1:0] */ | ||
| 4443 | |||
| 4444 | /* | ||
| 4445 | * R3714 (0xE82) - DRC1 ctrl3 | ||
| 4446 | */ | ||
| 4447 | #define WM5100_DRC_NG_MINGAIN_MASK 0xF000 /* DRC_NG_MINGAIN - [15:12] */ | ||
| 4448 | #define WM5100_DRC_NG_MINGAIN_SHIFT 12 /* DRC_NG_MINGAIN - [15:12] */ | ||
| 4449 | #define WM5100_DRC_NG_MINGAIN_WIDTH 4 /* DRC_NG_MINGAIN - [15:12] */ | ||
| 4450 | #define WM5100_DRC_NG_EXP_MASK 0x0C00 /* DRC_NG_EXP - [11:10] */ | ||
| 4451 | #define WM5100_DRC_NG_EXP_SHIFT 10 /* DRC_NG_EXP - [11:10] */ | ||
| 4452 | #define WM5100_DRC_NG_EXP_WIDTH 2 /* DRC_NG_EXP - [11:10] */ | ||
| 4453 | #define WM5100_DRC_QR_THR_MASK 0x0300 /* DRC_QR_THR - [9:8] */ | ||
| 4454 | #define WM5100_DRC_QR_THR_SHIFT 8 /* DRC_QR_THR - [9:8] */ | ||
| 4455 | #define WM5100_DRC_QR_THR_WIDTH 2 /* DRC_QR_THR - [9:8] */ | ||
| 4456 | #define WM5100_DRC_QR_DCY_MASK 0x00C0 /* DRC_QR_DCY - [7:6] */ | ||
| 4457 | #define WM5100_DRC_QR_DCY_SHIFT 6 /* DRC_QR_DCY - [7:6] */ | ||
| 4458 | #define WM5100_DRC_QR_DCY_WIDTH 2 /* DRC_QR_DCY - [7:6] */ | ||
| 4459 | #define WM5100_DRC_HI_COMP_MASK 0x0038 /* DRC_HI_COMP - [5:3] */ | ||
| 4460 | #define WM5100_DRC_HI_COMP_SHIFT 3 /* DRC_HI_COMP - [5:3] */ | ||
| 4461 | #define WM5100_DRC_HI_COMP_WIDTH 3 /* DRC_HI_COMP - [5:3] */ | ||
| 4462 | #define WM5100_DRC_LO_COMP_MASK 0x0007 /* DRC_LO_COMP - [2:0] */ | ||
| 4463 | #define WM5100_DRC_LO_COMP_SHIFT 0 /* DRC_LO_COMP - [2:0] */ | ||
| 4464 | #define WM5100_DRC_LO_COMP_WIDTH 3 /* DRC_LO_COMP - [2:0] */ | ||
| 4465 | |||
| 4466 | /* | ||
| 4467 | * R3715 (0xE83) - DRC1 ctrl4 | ||
| 4468 | */ | ||
| 4469 | #define WM5100_DRC_KNEE_IP_MASK 0x07E0 /* DRC_KNEE_IP - [10:5] */ | ||
| 4470 | #define WM5100_DRC_KNEE_IP_SHIFT 5 /* DRC_KNEE_IP - [10:5] */ | ||
| 4471 | #define WM5100_DRC_KNEE_IP_WIDTH 6 /* DRC_KNEE_IP - [10:5] */ | ||
| 4472 | #define WM5100_DRC_KNEE_OP_MASK 0x001F /* DRC_KNEE_OP - [4:0] */ | ||
| 4473 | #define WM5100_DRC_KNEE_OP_SHIFT 0 /* DRC_KNEE_OP - [4:0] */ | ||
| 4474 | #define WM5100_DRC_KNEE_OP_WIDTH 5 /* DRC_KNEE_OP - [4:0] */ | ||
| 4475 | |||
| 4476 | /* | ||
| 4477 | * R3716 (0xE84) - DRC1 ctrl5 | ||
| 4478 | */ | ||
| 4479 | #define WM5100_DRC_KNEE2_IP_MASK 0x03E0 /* DRC_KNEE2_IP - [9:5] */ | ||
| 4480 | #define WM5100_DRC_KNEE2_IP_SHIFT 5 /* DRC_KNEE2_IP - [9:5] */ | ||
| 4481 | #define WM5100_DRC_KNEE2_IP_WIDTH 5 /* DRC_KNEE2_IP - [9:5] */ | ||
| 4482 | #define WM5100_DRC_KNEE2_OP_MASK 0x001F /* DRC_KNEE2_OP - [4:0] */ | ||
| 4483 | #define WM5100_DRC_KNEE2_OP_SHIFT 0 /* DRC_KNEE2_OP - [4:0] */ | ||
| 4484 | #define WM5100_DRC_KNEE2_OP_WIDTH 5 /* DRC_KNEE2_OP - [4:0] */ | ||
| 4485 | |||
| 4486 | /* | ||
| 4487 | * R3776 (0xEC0) - HPLPF1_1 | ||
| 4488 | */ | ||
| 4489 | #define WM5100_LHPF1_MODE 0x0002 /* LHPF1_MODE */ | ||
| 4490 | #define WM5100_LHPF1_MODE_MASK 0x0002 /* LHPF1_MODE */ | ||
| 4491 | #define WM5100_LHPF1_MODE_SHIFT 1 /* LHPF1_MODE */ | ||
| 4492 | #define WM5100_LHPF1_MODE_WIDTH 1 /* LHPF1_MODE */ | ||
| 4493 | #define WM5100_LHPF1_ENA 0x0001 /* LHPF1_ENA */ | ||
| 4494 | #define WM5100_LHPF1_ENA_MASK 0x0001 /* LHPF1_ENA */ | ||
| 4495 | #define WM5100_LHPF1_ENA_SHIFT 0 /* LHPF1_ENA */ | ||
| 4496 | #define WM5100_LHPF1_ENA_WIDTH 1 /* LHPF1_ENA */ | ||
| 4497 | |||
| 4498 | /* | ||
| 4499 | * R3777 (0xEC1) - HPLPF1_2 | ||
| 4500 | */ | ||
| 4501 | #define WM5100_LHPF1_COEFF_MASK 0xFFFF /* LHPF1_COEFF - [15:0] */ | ||
| 4502 | #define WM5100_LHPF1_COEFF_SHIFT 0 /* LHPF1_COEFF - [15:0] */ | ||
| 4503 | #define WM5100_LHPF1_COEFF_WIDTH 16 /* LHPF1_COEFF - [15:0] */ | ||
| 4504 | |||
| 4505 | /* | ||
| 4506 | * R3780 (0xEC4) - HPLPF2_1 | ||
| 4507 | */ | ||
| 4508 | #define WM5100_LHPF2_MODE 0x0002 /* LHPF2_MODE */ | ||
| 4509 | #define WM5100_LHPF2_MODE_MASK 0x0002 /* LHPF2_MODE */ | ||
| 4510 | #define WM5100_LHPF2_MODE_SHIFT 1 /* LHPF2_MODE */ | ||
| 4511 | #define WM5100_LHPF2_MODE_WIDTH 1 /* LHPF2_MODE */ | ||
| 4512 | #define WM5100_LHPF2_ENA 0x0001 /* LHPF2_ENA */ | ||
| 4513 | #define WM5100_LHPF2_ENA_MASK 0x0001 /* LHPF2_ENA */ | ||
| 4514 | #define WM5100_LHPF2_ENA_SHIFT 0 /* LHPF2_ENA */ | ||
| 4515 | #define WM5100_LHPF2_ENA_WIDTH 1 /* LHPF2_ENA */ | ||
| 4516 | |||
| 4517 | /* | ||
| 4518 | * R3781 (0xEC5) - HPLPF2_2 | ||
| 4519 | */ | ||
| 4520 | #define WM5100_LHPF2_COEFF_MASK 0xFFFF /* LHPF2_COEFF - [15:0] */ | ||
| 4521 | #define WM5100_LHPF2_COEFF_SHIFT 0 /* LHPF2_COEFF - [15:0] */ | ||
| 4522 | #define WM5100_LHPF2_COEFF_WIDTH 16 /* LHPF2_COEFF - [15:0] */ | ||
| 4523 | |||
| 4524 | /* | ||
| 4525 | * R3784 (0xEC8) - HPLPF3_1 | ||
| 4526 | */ | ||
| 4527 | #define WM5100_LHPF3_MODE 0x0002 /* LHPF3_MODE */ | ||
| 4528 | #define WM5100_LHPF3_MODE_MASK 0x0002 /* LHPF3_MODE */ | ||
| 4529 | #define WM5100_LHPF3_MODE_SHIFT 1 /* LHPF3_MODE */ | ||
| 4530 | #define WM5100_LHPF3_MODE_WIDTH 1 /* LHPF3_MODE */ | ||
| 4531 | #define WM5100_LHPF3_ENA 0x0001 /* LHPF3_ENA */ | ||
| 4532 | #define WM5100_LHPF3_ENA_MASK 0x0001 /* LHPF3_ENA */ | ||
| 4533 | #define WM5100_LHPF3_ENA_SHIFT 0 /* LHPF3_ENA */ | ||
| 4534 | #define WM5100_LHPF3_ENA_WIDTH 1 /* LHPF3_ENA */ | ||
| 4535 | |||
| 4536 | /* | ||
| 4537 | * R3785 (0xEC9) - HPLPF3_2 | ||
| 4538 | */ | ||
| 4539 | #define WM5100_LHPF3_COEFF_MASK 0xFFFF /* LHPF3_COEFF - [15:0] */ | ||
| 4540 | #define WM5100_LHPF3_COEFF_SHIFT 0 /* LHPF3_COEFF - [15:0] */ | ||
| 4541 | #define WM5100_LHPF3_COEFF_WIDTH 16 /* LHPF3_COEFF - [15:0] */ | ||
| 4542 | |||
| 4543 | /* | ||
| 4544 | * R3788 (0xECC) - HPLPF4_1 | ||
| 4545 | */ | ||
| 4546 | #define WM5100_LHPF4_MODE 0x0002 /* LHPF4_MODE */ | ||
| 4547 | #define WM5100_LHPF4_MODE_MASK 0x0002 /* LHPF4_MODE */ | ||
| 4548 | #define WM5100_LHPF4_MODE_SHIFT 1 /* LHPF4_MODE */ | ||
| 4549 | #define WM5100_LHPF4_MODE_WIDTH 1 /* LHPF4_MODE */ | ||
| 4550 | #define WM5100_LHPF4_ENA 0x0001 /* LHPF4_ENA */ | ||
| 4551 | #define WM5100_LHPF4_ENA_MASK 0x0001 /* LHPF4_ENA */ | ||
| 4552 | #define WM5100_LHPF4_ENA_SHIFT 0 /* LHPF4_ENA */ | ||
| 4553 | #define WM5100_LHPF4_ENA_WIDTH 1 /* LHPF4_ENA */ | ||
| 4554 | |||
| 4555 | /* | ||
| 4556 | * R3789 (0xECD) - HPLPF4_2 | ||
| 4557 | */ | ||
| 4558 | #define WM5100_LHPF4_COEFF_MASK 0xFFFF /* LHPF4_COEFF - [15:0] */ | ||
| 4559 | #define WM5100_LHPF4_COEFF_SHIFT 0 /* LHPF4_COEFF - [15:0] */ | ||
| 4560 | #define WM5100_LHPF4_COEFF_WIDTH 16 /* LHPF4_COEFF - [15:0] */ | ||
| 4561 | |||
| 4562 | /* | ||
| 4563 | * R16384 (0x4000) - DSP1 DM 0 | ||
| 4564 | */ | ||
| 4565 | #define WM5100_DSP1_DM_START_1_MASK 0x00FF /* DSP1_DM_START - [7:0] */ | ||
| 4566 | #define WM5100_DSP1_DM_START_1_SHIFT 0 /* DSP1_DM_START - [7:0] */ | ||
| 4567 | #define WM5100_DSP1_DM_START_1_WIDTH 8 /* DSP1_DM_START - [7:0] */ | ||
| 4568 | |||
| 4569 | /* | ||
| 4570 | * R16385 (0x4001) - DSP1 DM 1 | ||
| 4571 | */ | ||
| 4572 | #define WM5100_DSP1_DM_START_MASK 0xFFFF /* DSP1_DM_START - [15:0] */ | ||
| 4573 | #define WM5100_DSP1_DM_START_SHIFT 0 /* DSP1_DM_START - [15:0] */ | ||
| 4574 | #define WM5100_DSP1_DM_START_WIDTH 16 /* DSP1_DM_START - [15:0] */ | ||
| 4575 | |||
| 4576 | /* | ||
| 4577 | * R16386 (0x4002) - DSP1 DM 2 | ||
| 4578 | */ | ||
| 4579 | #define WM5100_DSP1_DM_1_1_MASK 0x00FF /* DSP1_DM_1 - [7:0] */ | ||
| 4580 | #define WM5100_DSP1_DM_1_1_SHIFT 0 /* DSP1_DM_1 - [7:0] */ | ||
| 4581 | #define WM5100_DSP1_DM_1_1_WIDTH 8 /* DSP1_DM_1 - [7:0] */ | ||
| 4582 | |||
| 4583 | /* | ||
| 4584 | * R16387 (0x4003) - DSP1 DM 3 | ||
| 4585 | */ | ||
| 4586 | #define WM5100_DSP1_DM_1_MASK 0xFFFF /* DSP1_DM_1 - [15:0] */ | ||
| 4587 | #define WM5100_DSP1_DM_1_SHIFT 0 /* DSP1_DM_1 - [15:0] */ | ||
| 4588 | #define WM5100_DSP1_DM_1_WIDTH 16 /* DSP1_DM_1 - [15:0] */ | ||
| 4589 | |||
| 4590 | /* | ||
| 4591 | * R16892 (0x41FC) - DSP1 DM 508 | ||
| 4592 | */ | ||
| 4593 | #define WM5100_DSP1_DM_254_1_MASK 0x00FF /* DSP1_DM_254 - [7:0] */ | ||
| 4594 | #define WM5100_DSP1_DM_254_1_SHIFT 0 /* DSP1_DM_254 - [7:0] */ | ||
| 4595 | #define WM5100_DSP1_DM_254_1_WIDTH 8 /* DSP1_DM_254 - [7:0] */ | ||
| 4596 | |||
| 4597 | /* | ||
| 4598 | * R16893 (0x41FD) - DSP1 DM 509 | ||
| 4599 | */ | ||
| 4600 | #define WM5100_DSP1_DM_254_MASK 0xFFFF /* DSP1_DM_254 - [15:0] */ | ||
| 4601 | #define WM5100_DSP1_DM_254_SHIFT 0 /* DSP1_DM_254 - [15:0] */ | ||
| 4602 | #define WM5100_DSP1_DM_254_WIDTH 16 /* DSP1_DM_254 - [15:0] */ | ||
| 4603 | |||
| 4604 | /* | ||
| 4605 | * R16894 (0x41FE) - DSP1 DM 510 | ||
| 4606 | */ | ||
| 4607 | #define WM5100_DSP1_DM_END_1_MASK 0x00FF /* DSP1_DM_END - [7:0] */ | ||
| 4608 | #define WM5100_DSP1_DM_END_1_SHIFT 0 /* DSP1_DM_END - [7:0] */ | ||
| 4609 | #define WM5100_DSP1_DM_END_1_WIDTH 8 /* DSP1_DM_END - [7:0] */ | ||
| 4610 | |||
| 4611 | /* | ||
| 4612 | * R16895 (0x41FF) - DSP1 DM 511 | ||
| 4613 | */ | ||
| 4614 | #define WM5100_DSP1_DM_END_MASK 0xFFFF /* DSP1_DM_END - [15:0] */ | ||
| 4615 | #define WM5100_DSP1_DM_END_SHIFT 0 /* DSP1_DM_END - [15:0] */ | ||
| 4616 | #define WM5100_DSP1_DM_END_WIDTH 16 /* DSP1_DM_END - [15:0] */ | ||
| 4617 | |||
| 4618 | /* | ||
| 4619 | * R18432 (0x4800) - DSP1 PM 0 | ||
| 4620 | */ | ||
| 4621 | #define WM5100_DSP1_PM_START_2_MASK 0x00FF /* DSP1_PM_START - [7:0] */ | ||
| 4622 | #define WM5100_DSP1_PM_START_2_SHIFT 0 /* DSP1_PM_START - [7:0] */ | ||
| 4623 | #define WM5100_DSP1_PM_START_2_WIDTH 8 /* DSP1_PM_START - [7:0] */ | ||
| 4624 | |||
| 4625 | /* | ||
| 4626 | * R18433 (0x4801) - DSP1 PM 1 | ||
| 4627 | */ | ||
| 4628 | #define WM5100_DSP1_PM_START_1_MASK 0xFFFF /* DSP1_PM_START - [15:0] */ | ||
| 4629 | #define WM5100_DSP1_PM_START_1_SHIFT 0 /* DSP1_PM_START - [15:0] */ | ||
| 4630 | #define WM5100_DSP1_PM_START_1_WIDTH 16 /* DSP1_PM_START - [15:0] */ | ||
| 4631 | |||
| 4632 | /* | ||
| 4633 | * R18434 (0x4802) - DSP1 PM 2 | ||
| 4634 | */ | ||
| 4635 | #define WM5100_DSP1_PM_START_MASK 0xFFFF /* DSP1_PM_START - [15:0] */ | ||
| 4636 | #define WM5100_DSP1_PM_START_SHIFT 0 /* DSP1_PM_START - [15:0] */ | ||
| 4637 | #define WM5100_DSP1_PM_START_WIDTH 16 /* DSP1_PM_START - [15:0] */ | ||
| 4638 | |||
| 4639 | /* | ||
| 4640 | * R18435 (0x4803) - DSP1 PM 3 | ||
| 4641 | */ | ||
| 4642 | #define WM5100_DSP1_PM_1_2_MASK 0x00FF /* DSP1_PM_1 - [7:0] */ | ||
| 4643 | #define WM5100_DSP1_PM_1_2_SHIFT 0 /* DSP1_PM_1 - [7:0] */ | ||
| 4644 | #define WM5100_DSP1_PM_1_2_WIDTH 8 /* DSP1_PM_1 - [7:0] */ | ||
| 4645 | |||
| 4646 | /* | ||
| 4647 | * R18436 (0x4804) - DSP1 PM 4 | ||
| 4648 | */ | ||
| 4649 | #define WM5100_DSP1_PM_1_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */ | ||
| 4650 | #define WM5100_DSP1_PM_1_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */ | ||
| 4651 | #define WM5100_DSP1_PM_1_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */ | ||
| 4652 | |||
| 4653 | /* | ||
| 4654 | * R18437 (0x4805) - DSP1 PM 5 | ||
| 4655 | */ | ||
| 4656 | #define WM5100_DSP1_PM_1_MASK 0xFFFF /* DSP1_PM_1 - [15:0] */ | ||
| 4657 | #define WM5100_DSP1_PM_1_SHIFT 0 /* DSP1_PM_1 - [15:0] */ | ||
| 4658 | #define WM5100_DSP1_PM_1_WIDTH 16 /* DSP1_PM_1 - [15:0] */ | ||
| 4659 | |||
| 4660 | /* | ||
| 4661 | * R19962 (0x4DFA) - DSP1 PM 1530 | ||
| 4662 | */ | ||
| 4663 | #define WM5100_DSP1_PM_510_2_MASK 0x00FF /* DSP1_PM_510 - [7:0] */ | ||
| 4664 | #define WM5100_DSP1_PM_510_2_SHIFT 0 /* DSP1_PM_510 - [7:0] */ | ||
| 4665 | #define WM5100_DSP1_PM_510_2_WIDTH 8 /* DSP1_PM_510 - [7:0] */ | ||
| 4666 | |||
| 4667 | /* | ||
| 4668 | * R19963 (0x4DFB) - DSP1 PM 1531 | ||
| 4669 | */ | ||
| 4670 | #define WM5100_DSP1_PM_510_1_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */ | ||
| 4671 | #define WM5100_DSP1_PM_510_1_SHIFT 0 /* DSP1_PM_510 - [15:0] */ | ||
| 4672 | #define WM5100_DSP1_PM_510_1_WIDTH 16 /* DSP1_PM_510 - [15:0] */ | ||
| 4673 | |||
| 4674 | /* | ||
| 4675 | * R19964 (0x4DFC) - DSP1 PM 1532 | ||
| 4676 | */ | ||
| 4677 | #define WM5100_DSP1_PM_510_MASK 0xFFFF /* DSP1_PM_510 - [15:0] */ | ||
| 4678 | #define WM5100_DSP1_PM_510_SHIFT 0 /* DSP1_PM_510 - [15:0] */ | ||
| 4679 | #define WM5100_DSP1_PM_510_WIDTH 16 /* DSP1_PM_510 - [15:0] */ | ||
| 4680 | |||
| 4681 | /* | ||
| 4682 | * R19965 (0x4DFD) - DSP1 PM 1533 | ||
| 4683 | */ | ||
| 4684 | #define WM5100_DSP1_PM_END_2_MASK 0x00FF /* DSP1_PM_END - [7:0] */ | ||
| 4685 | #define WM5100_DSP1_PM_END_2_SHIFT 0 /* DSP1_PM_END - [7:0] */ | ||
| 4686 | #define WM5100_DSP1_PM_END_2_WIDTH 8 /* DSP1_PM_END - [7:0] */ | ||
| 4687 | |||
| 4688 | /* | ||
| 4689 | * R19966 (0x4DFE) - DSP1 PM 1534 | ||
| 4690 | */ | ||
| 4691 | #define WM5100_DSP1_PM_END_1_MASK 0xFFFF /* DSP1_PM_END - [15:0] */ | ||
| 4692 | #define WM5100_DSP1_PM_END_1_SHIFT 0 /* DSP1_PM_END - [15:0] */ | ||
| 4693 | #define WM5100_DSP1_PM_END_1_WIDTH 16 /* DSP1_PM_END - [15:0] */ | ||
| 4694 | |||
| 4695 | /* | ||
| 4696 | * R19967 (0x4DFF) - DSP1 PM 1535 | ||
| 4697 | */ | ||
| 4698 | #define WM5100_DSP1_PM_END_MASK 0xFFFF /* DSP1_PM_END - [15:0] */ | ||
| 4699 | #define WM5100_DSP1_PM_END_SHIFT 0 /* DSP1_PM_END - [15:0] */ | ||
| 4700 | #define WM5100_DSP1_PM_END_WIDTH 16 /* DSP1_PM_END - [15:0] */ | ||
| 4701 | |||
| 4702 | /* | ||
| 4703 | * R20480 (0x5000) - DSP1 ZM 0 | ||
| 4704 | */ | ||
| 4705 | #define WM5100_DSP1_ZM_START_1_MASK 0x00FF /* DSP1_ZM_START - [7:0] */ | ||
| 4706 | #define WM5100_DSP1_ZM_START_1_SHIFT 0 /* DSP1_ZM_START - [7:0] */ | ||
| 4707 | #define WM5100_DSP1_ZM_START_1_WIDTH 8 /* DSP1_ZM_START - [7:0] */ | ||
| 4708 | |||
| 4709 | /* | ||
| 4710 | * R20481 (0x5001) - DSP1 ZM 1 | ||
| 4711 | */ | ||
| 4712 | #define WM5100_DSP1_ZM_START_MASK 0xFFFF /* DSP1_ZM_START - [15:0] */ | ||
| 4713 | #define WM5100_DSP1_ZM_START_SHIFT 0 /* DSP1_ZM_START - [15:0] */ | ||
| 4714 | #define WM5100_DSP1_ZM_START_WIDTH 16 /* DSP1_ZM_START - [15:0] */ | ||
| 4715 | |||
| 4716 | /* | ||
| 4717 | * R20482 (0x5002) - DSP1 ZM 2 | ||
| 4718 | */ | ||
| 4719 | #define WM5100_DSP1_ZM_1_1_MASK 0x00FF /* DSP1_ZM_1 - [7:0] */ | ||
| 4720 | #define WM5100_DSP1_ZM_1_1_SHIFT 0 /* DSP1_ZM_1 - [7:0] */ | ||
| 4721 | #define WM5100_DSP1_ZM_1_1_WIDTH 8 /* DSP1_ZM_1 - [7:0] */ | ||
| 4722 | |||
| 4723 | /* | ||
| 4724 | * R20483 (0x5003) - DSP1 ZM 3 | ||
| 4725 | */ | ||
| 4726 | #define WM5100_DSP1_ZM_1_MASK 0xFFFF /* DSP1_ZM_1 - [15:0] */ | ||
| 4727 | #define WM5100_DSP1_ZM_1_SHIFT 0 /* DSP1_ZM_1 - [15:0] */ | ||
| 4728 | #define WM5100_DSP1_ZM_1_WIDTH 16 /* DSP1_ZM_1 - [15:0] */ | ||
| 4729 | |||
| 4730 | /* | ||
| 4731 | * R22524 (0x57FC) - DSP1 ZM 2044 | ||
| 4732 | */ | ||
| 4733 | #define WM5100_DSP1_ZM_1022_1_MASK 0x00FF /* DSP1_ZM_1022 - [7:0] */ | ||
| 4734 | #define WM5100_DSP1_ZM_1022_1_SHIFT 0 /* DSP1_ZM_1022 - [7:0] */ | ||
| 4735 | #define WM5100_DSP1_ZM_1022_1_WIDTH 8 /* DSP1_ZM_1022 - [7:0] */ | ||
| 4736 | |||
| 4737 | /* | ||
| 4738 | * R22525 (0x57FD) - DSP1 ZM 2045 | ||
| 4739 | */ | ||
| 4740 | #define WM5100_DSP1_ZM_1022_MASK 0xFFFF /* DSP1_ZM_1022 - [15:0] */ | ||
| 4741 | #define WM5100_DSP1_ZM_1022_SHIFT 0 /* DSP1_ZM_1022 - [15:0] */ | ||
| 4742 | #define WM5100_DSP1_ZM_1022_WIDTH 16 /* DSP1_ZM_1022 - [15:0] */ | ||
| 4743 | |||
| 4744 | /* | ||
| 4745 | * R22526 (0x57FE) - DSP1 ZM 2046 | ||
| 4746 | */ | ||
| 4747 | #define WM5100_DSP1_ZM_END_1_MASK 0x00FF /* DSP1_ZM_END - [7:0] */ | ||
| 4748 | #define WM5100_DSP1_ZM_END_1_SHIFT 0 /* DSP1_ZM_END - [7:0] */ | ||
| 4749 | #define WM5100_DSP1_ZM_END_1_WIDTH 8 /* DSP1_ZM_END - [7:0] */ | ||
| 4750 | |||
| 4751 | /* | ||
| 4752 | * R22527 (0x57FF) - DSP1 ZM 2047 | ||
| 4753 | */ | ||
| 4754 | #define WM5100_DSP1_ZM_END_MASK 0xFFFF /* DSP1_ZM_END - [15:0] */ | ||
| 4755 | #define WM5100_DSP1_ZM_END_SHIFT 0 /* DSP1_ZM_END - [15:0] */ | ||
| 4756 | #define WM5100_DSP1_ZM_END_WIDTH 16 /* DSP1_ZM_END - [15:0] */ | ||
| 4757 | |||
| 4758 | /* | ||
| 4759 | * R24576 (0x6000) - DSP2 DM 0 | ||
| 4760 | */ | ||
| 4761 | #define WM5100_DSP2_DM_START_1_MASK 0x00FF /* DSP2_DM_START - [7:0] */ | ||
| 4762 | #define WM5100_DSP2_DM_START_1_SHIFT 0 /* DSP2_DM_START - [7:0] */ | ||
| 4763 | #define WM5100_DSP2_DM_START_1_WIDTH 8 /* DSP2_DM_START - [7:0] */ | ||
| 4764 | |||
| 4765 | /* | ||
| 4766 | * R24577 (0x6001) - DSP2 DM 1 | ||
| 4767 | */ | ||
| 4768 | #define WM5100_DSP2_DM_START_MASK 0xFFFF /* DSP2_DM_START - [15:0] */ | ||
| 4769 | #define WM5100_DSP2_DM_START_SHIFT 0 /* DSP2_DM_START - [15:0] */ | ||
| 4770 | #define WM5100_DSP2_DM_START_WIDTH 16 /* DSP2_DM_START - [15:0] */ | ||
| 4771 | |||
| 4772 | /* | ||
| 4773 | * R24578 (0x6002) - DSP2 DM 2 | ||
| 4774 | */ | ||
| 4775 | #define WM5100_DSP2_DM_1_1_MASK 0x00FF /* DSP2_DM_1 - [7:0] */ | ||
| 4776 | #define WM5100_DSP2_DM_1_1_SHIFT 0 /* DSP2_DM_1 - [7:0] */ | ||
| 4777 | #define WM5100_DSP2_DM_1_1_WIDTH 8 /* DSP2_DM_1 - [7:0] */ | ||
| 4778 | |||
| 4779 | /* | ||
| 4780 | * R24579 (0x6003) - DSP2 DM 3 | ||
| 4781 | */ | ||
| 4782 | #define WM5100_DSP2_DM_1_MASK 0xFFFF /* DSP2_DM_1 - [15:0] */ | ||
| 4783 | #define WM5100_DSP2_DM_1_SHIFT 0 /* DSP2_DM_1 - [15:0] */ | ||
| 4784 | #define WM5100_DSP2_DM_1_WIDTH 16 /* DSP2_DM_1 - [15:0] */ | ||
| 4785 | |||
| 4786 | /* | ||
| 4787 | * R25084 (0x61FC) - DSP2 DM 508 | ||
| 4788 | */ | ||
| 4789 | #define WM5100_DSP2_DM_254_1_MASK 0x00FF /* DSP2_DM_254 - [7:0] */ | ||
| 4790 | #define WM5100_DSP2_DM_254_1_SHIFT 0 /* DSP2_DM_254 - [7:0] */ | ||
| 4791 | #define WM5100_DSP2_DM_254_1_WIDTH 8 /* DSP2_DM_254 - [7:0] */ | ||
| 4792 | |||
| 4793 | /* | ||
| 4794 | * R25085 (0x61FD) - DSP2 DM 509 | ||
| 4795 | */ | ||
| 4796 | #define WM5100_DSP2_DM_254_MASK 0xFFFF /* DSP2_DM_254 - [15:0] */ | ||
| 4797 | #define WM5100_DSP2_DM_254_SHIFT 0 /* DSP2_DM_254 - [15:0] */ | ||
| 4798 | #define WM5100_DSP2_DM_254_WIDTH 16 /* DSP2_DM_254 - [15:0] */ | ||
| 4799 | |||
| 4800 | /* | ||
| 4801 | * R25086 (0x61FE) - DSP2 DM 510 | ||
| 4802 | */ | ||
| 4803 | #define WM5100_DSP2_DM_END_1_MASK 0x00FF /* DSP2_DM_END - [7:0] */ | ||
| 4804 | #define WM5100_DSP2_DM_END_1_SHIFT 0 /* DSP2_DM_END - [7:0] */ | ||
| 4805 | #define WM5100_DSP2_DM_END_1_WIDTH 8 /* DSP2_DM_END - [7:0] */ | ||
| 4806 | |||
| 4807 | /* | ||
| 4808 | * R25087 (0x61FF) - DSP2 DM 511 | ||
| 4809 | */ | ||
| 4810 | #define WM5100_DSP2_DM_END_MASK 0xFFFF /* DSP2_DM_END - [15:0] */ | ||
| 4811 | #define WM5100_DSP2_DM_END_SHIFT 0 /* DSP2_DM_END - [15:0] */ | ||
| 4812 | #define WM5100_DSP2_DM_END_WIDTH 16 /* DSP2_DM_END - [15:0] */ | ||
| 4813 | |||
| 4814 | /* | ||
| 4815 | * R26624 (0x6800) - DSP2 PM 0 | ||
| 4816 | */ | ||
| 4817 | #define WM5100_DSP2_PM_START_2_MASK 0x00FF /* DSP2_PM_START - [7:0] */ | ||
| 4818 | #define WM5100_DSP2_PM_START_2_SHIFT 0 /* DSP2_PM_START - [7:0] */ | ||
| 4819 | #define WM5100_DSP2_PM_START_2_WIDTH 8 /* DSP2_PM_START - [7:0] */ | ||
| 4820 | |||
| 4821 | /* | ||
| 4822 | * R26625 (0x6801) - DSP2 PM 1 | ||
| 4823 | */ | ||
| 4824 | #define WM5100_DSP2_PM_START_1_MASK 0xFFFF /* DSP2_PM_START - [15:0] */ | ||
| 4825 | #define WM5100_DSP2_PM_START_1_SHIFT 0 /* DSP2_PM_START - [15:0] */ | ||
| 4826 | #define WM5100_DSP2_PM_START_1_WIDTH 16 /* DSP2_PM_START - [15:0] */ | ||
| 4827 | |||
| 4828 | /* | ||
| 4829 | * R26626 (0x6802) - DSP2 PM 2 | ||
| 4830 | */ | ||
| 4831 | #define WM5100_DSP2_PM_START_MASK 0xFFFF /* DSP2_PM_START - [15:0] */ | ||
| 4832 | #define WM5100_DSP2_PM_START_SHIFT 0 /* DSP2_PM_START - [15:0] */ | ||
| 4833 | #define WM5100_DSP2_PM_START_WIDTH 16 /* DSP2_PM_START - [15:0] */ | ||
| 4834 | |||
| 4835 | /* | ||
| 4836 | * R26627 (0x6803) - DSP2 PM 3 | ||
| 4837 | */ | ||
| 4838 | #define WM5100_DSP2_PM_1_2_MASK 0x00FF /* DSP2_PM_1 - [7:0] */ | ||
| 4839 | #define WM5100_DSP2_PM_1_2_SHIFT 0 /* DSP2_PM_1 - [7:0] */ | ||
| 4840 | #define WM5100_DSP2_PM_1_2_WIDTH 8 /* DSP2_PM_1 - [7:0] */ | ||
| 4841 | |||
| 4842 | /* | ||
| 4843 | * R26628 (0x6804) - DSP2 PM 4 | ||
| 4844 | */ | ||
| 4845 | #define WM5100_DSP2_PM_1_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */ | ||
| 4846 | #define WM5100_DSP2_PM_1_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */ | ||
| 4847 | #define WM5100_DSP2_PM_1_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */ | ||
| 4848 | |||
| 4849 | /* | ||
| 4850 | * R26629 (0x6805) - DSP2 PM 5 | ||
| 4851 | */ | ||
| 4852 | #define WM5100_DSP2_PM_1_MASK 0xFFFF /* DSP2_PM_1 - [15:0] */ | ||
| 4853 | #define WM5100_DSP2_PM_1_SHIFT 0 /* DSP2_PM_1 - [15:0] */ | ||
| 4854 | #define WM5100_DSP2_PM_1_WIDTH 16 /* DSP2_PM_1 - [15:0] */ | ||
| 4855 | |||
| 4856 | /* | ||
| 4857 | * R28154 (0x6DFA) - DSP2 PM 1530 | ||
| 4858 | */ | ||
| 4859 | #define WM5100_DSP2_PM_510_2_MASK 0x00FF /* DSP2_PM_510 - [7:0] */ | ||
| 4860 | #define WM5100_DSP2_PM_510_2_SHIFT 0 /* DSP2_PM_510 - [7:0] */ | ||
| 4861 | #define WM5100_DSP2_PM_510_2_WIDTH 8 /* DSP2_PM_510 - [7:0] */ | ||
| 4862 | |||
| 4863 | /* | ||
| 4864 | * R28155 (0x6DFB) - DSP2 PM 1531 | ||
| 4865 | */ | ||
| 4866 | #define WM5100_DSP2_PM_510_1_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */ | ||
| 4867 | #define WM5100_DSP2_PM_510_1_SHIFT 0 /* DSP2_PM_510 - [15:0] */ | ||
| 4868 | #define WM5100_DSP2_PM_510_1_WIDTH 16 /* DSP2_PM_510 - [15:0] */ | ||
| 4869 | |||
| 4870 | /* | ||
| 4871 | * R28156 (0x6DFC) - DSP2 PM 1532 | ||
| 4872 | */ | ||
| 4873 | #define WM5100_DSP2_PM_510_MASK 0xFFFF /* DSP2_PM_510 - [15:0] */ | ||
| 4874 | #define WM5100_DSP2_PM_510_SHIFT 0 /* DSP2_PM_510 - [15:0] */ | ||
| 4875 | #define WM5100_DSP2_PM_510_WIDTH 16 /* DSP2_PM_510 - [15:0] */ | ||
| 4876 | |||
| 4877 | /* | ||
| 4878 | * R28157 (0x6DFD) - DSP2 PM 1533 | ||
| 4879 | */ | ||
| 4880 | #define WM5100_DSP2_PM_END_2_MASK 0x00FF /* DSP2_PM_END - [7:0] */ | ||
| 4881 | #define WM5100_DSP2_PM_END_2_SHIFT 0 /* DSP2_PM_END - [7:0] */ | ||
| 4882 | #define WM5100_DSP2_PM_END_2_WIDTH 8 /* DSP2_PM_END - [7:0] */ | ||
| 4883 | |||
| 4884 | /* | ||
| 4885 | * R28158 (0x6DFE) - DSP2 PM 1534 | ||
| 4886 | */ | ||
| 4887 | #define WM5100_DSP2_PM_END_1_MASK 0xFFFF /* DSP2_PM_END - [15:0] */ | ||
| 4888 | #define WM5100_DSP2_PM_END_1_SHIFT 0 /* DSP2_PM_END - [15:0] */ | ||
| 4889 | #define WM5100_DSP2_PM_END_1_WIDTH 16 /* DSP2_PM_END - [15:0] */ | ||
| 4890 | |||
| 4891 | /* | ||
| 4892 | * R28159 (0x6DFF) - DSP2 PM 1535 | ||
| 4893 | */ | ||
| 4894 | #define WM5100_DSP2_PM_END_MASK 0xFFFF /* DSP2_PM_END - [15:0] */ | ||
| 4895 | #define WM5100_DSP2_PM_END_SHIFT 0 /* DSP2_PM_END - [15:0] */ | ||
| 4896 | #define WM5100_DSP2_PM_END_WIDTH 16 /* DSP2_PM_END - [15:0] */ | ||
| 4897 | |||
| 4898 | /* | ||
| 4899 | * R28672 (0x7000) - DSP2 ZM 0 | ||
| 4900 | */ | ||
| 4901 | #define WM5100_DSP2_ZM_START_1_MASK 0x00FF /* DSP2_ZM_START - [7:0] */ | ||
| 4902 | #define WM5100_DSP2_ZM_START_1_SHIFT 0 /* DSP2_ZM_START - [7:0] */ | ||
| 4903 | #define WM5100_DSP2_ZM_START_1_WIDTH 8 /* DSP2_ZM_START - [7:0] */ | ||
| 4904 | |||
| 4905 | /* | ||
| 4906 | * R28673 (0x7001) - DSP2 ZM 1 | ||
| 4907 | */ | ||
| 4908 | #define WM5100_DSP2_ZM_START_MASK 0xFFFF /* DSP2_ZM_START - [15:0] */ | ||
| 4909 | #define WM5100_DSP2_ZM_START_SHIFT 0 /* DSP2_ZM_START - [15:0] */ | ||
| 4910 | #define WM5100_DSP2_ZM_START_WIDTH 16 /* DSP2_ZM_START - [15:0] */ | ||
| 4911 | |||
| 4912 | /* | ||
| 4913 | * R28674 (0x7002) - DSP2 ZM 2 | ||
| 4914 | */ | ||
| 4915 | #define WM5100_DSP2_ZM_1_1_MASK 0x00FF /* DSP2_ZM_1 - [7:0] */ | ||
| 4916 | #define WM5100_DSP2_ZM_1_1_SHIFT 0 /* DSP2_ZM_1 - [7:0] */ | ||
| 4917 | #define WM5100_DSP2_ZM_1_1_WIDTH 8 /* DSP2_ZM_1 - [7:0] */ | ||
| 4918 | |||
| 4919 | /* | ||
| 4920 | * R28675 (0x7003) - DSP2 ZM 3 | ||
| 4921 | */ | ||
| 4922 | #define WM5100_DSP2_ZM_1_MASK 0xFFFF /* DSP2_ZM_1 - [15:0] */ | ||
| 4923 | #define WM5100_DSP2_ZM_1_SHIFT 0 /* DSP2_ZM_1 - [15:0] */ | ||
| 4924 | #define WM5100_DSP2_ZM_1_WIDTH 16 /* DSP2_ZM_1 - [15:0] */ | ||
| 4925 | |||
| 4926 | /* | ||
| 4927 | * R30716 (0x77FC) - DSP2 ZM 2044 | ||
| 4928 | */ | ||
| 4929 | #define WM5100_DSP2_ZM_1022_1_MASK 0x00FF /* DSP2_ZM_1022 - [7:0] */ | ||
| 4930 | #define WM5100_DSP2_ZM_1022_1_SHIFT 0 /* DSP2_ZM_1022 - [7:0] */ | ||
| 4931 | #define WM5100_DSP2_ZM_1022_1_WIDTH 8 /* DSP2_ZM_1022 - [7:0] */ | ||
| 4932 | |||
| 4933 | /* | ||
| 4934 | * R30717 (0x77FD) - DSP2 ZM 2045 | ||
| 4935 | */ | ||
| 4936 | #define WM5100_DSP2_ZM_1022_MASK 0xFFFF /* DSP2_ZM_1022 - [15:0] */ | ||
| 4937 | #define WM5100_DSP2_ZM_1022_SHIFT 0 /* DSP2_ZM_1022 - [15:0] */ | ||
| 4938 | #define WM5100_DSP2_ZM_1022_WIDTH 16 /* DSP2_ZM_1022 - [15:0] */ | ||
| 4939 | |||
| 4940 | /* | ||
| 4941 | * R30718 (0x77FE) - DSP2 ZM 2046 | ||
| 4942 | */ | ||
| 4943 | #define WM5100_DSP2_ZM_END_1_MASK 0x00FF /* DSP2_ZM_END - [7:0] */ | ||
| 4944 | #define WM5100_DSP2_ZM_END_1_SHIFT 0 /* DSP2_ZM_END - [7:0] */ | ||
| 4945 | #define WM5100_DSP2_ZM_END_1_WIDTH 8 /* DSP2_ZM_END - [7:0] */ | ||
| 4946 | |||
| 4947 | /* | ||
| 4948 | * R30719 (0x77FF) - DSP2 ZM 2047 | ||
| 4949 | */ | ||
| 4950 | #define WM5100_DSP2_ZM_END_MASK 0xFFFF /* DSP2_ZM_END - [15:0] */ | ||
| 4951 | #define WM5100_DSP2_ZM_END_SHIFT 0 /* DSP2_ZM_END - [15:0] */ | ||
| 4952 | #define WM5100_DSP2_ZM_END_WIDTH 16 /* DSP2_ZM_END - [15:0] */ | ||
| 4953 | |||
| 4954 | /* | ||
| 4955 | * R32768 (0x8000) - DSP3 DM 0 | ||
| 4956 | */ | ||
| 4957 | #define WM5100_DSP3_DM_START_1_MASK 0x00FF /* DSP3_DM_START - [7:0] */ | ||
| 4958 | #define WM5100_DSP3_DM_START_1_SHIFT 0 /* DSP3_DM_START - [7:0] */ | ||
| 4959 | #define WM5100_DSP3_DM_START_1_WIDTH 8 /* DSP3_DM_START - [7:0] */ | ||
| 4960 | |||
| 4961 | /* | ||
| 4962 | * R32769 (0x8001) - DSP3 DM 1 | ||
| 4963 | */ | ||
| 4964 | #define WM5100_DSP3_DM_START_MASK 0xFFFF /* DSP3_DM_START - [15:0] */ | ||
| 4965 | #define WM5100_DSP3_DM_START_SHIFT 0 /* DSP3_DM_START - [15:0] */ | ||
| 4966 | #define WM5100_DSP3_DM_START_WIDTH 16 /* DSP3_DM_START - [15:0] */ | ||
| 4967 | |||
| 4968 | /* | ||
| 4969 | * R32770 (0x8002) - DSP3 DM 2 | ||
| 4970 | */ | ||
| 4971 | #define WM5100_DSP3_DM_1_1_MASK 0x00FF /* DSP3_DM_1 - [7:0] */ | ||
| 4972 | #define WM5100_DSP3_DM_1_1_SHIFT 0 /* DSP3_DM_1 - [7:0] */ | ||
| 4973 | #define WM5100_DSP3_DM_1_1_WIDTH 8 /* DSP3_DM_1 - [7:0] */ | ||
| 4974 | |||
| 4975 | /* | ||
| 4976 | * R32771 (0x8003) - DSP3 DM 3 | ||
| 4977 | */ | ||
| 4978 | #define WM5100_DSP3_DM_1_MASK 0xFFFF /* DSP3_DM_1 - [15:0] */ | ||
| 4979 | #define WM5100_DSP3_DM_1_SHIFT 0 /* DSP3_DM_1 - [15:0] */ | ||
| 4980 | #define WM5100_DSP3_DM_1_WIDTH 16 /* DSP3_DM_1 - [15:0] */ | ||
| 4981 | |||
| 4982 | /* | ||
| 4983 | * R33276 (0x81FC) - DSP3 DM 508 | ||
| 4984 | */ | ||
| 4985 | #define WM5100_DSP3_DM_254_1_MASK 0x00FF /* DSP3_DM_254 - [7:0] */ | ||
| 4986 | #define WM5100_DSP3_DM_254_1_SHIFT 0 /* DSP3_DM_254 - [7:0] */ | ||
| 4987 | #define WM5100_DSP3_DM_254_1_WIDTH 8 /* DSP3_DM_254 - [7:0] */ | ||
| 4988 | |||
| 4989 | /* | ||
| 4990 | * R33277 (0x81FD) - DSP3 DM 509 | ||
| 4991 | */ | ||
| 4992 | #define WM5100_DSP3_DM_254_MASK 0xFFFF /* DSP3_DM_254 - [15:0] */ | ||
| 4993 | #define WM5100_DSP3_DM_254_SHIFT 0 /* DSP3_DM_254 - [15:0] */ | ||
| 4994 | #define WM5100_DSP3_DM_254_WIDTH 16 /* DSP3_DM_254 - [15:0] */ | ||
| 4995 | |||
| 4996 | /* | ||
| 4997 | * R33278 (0x81FE) - DSP3 DM 510 | ||
| 4998 | */ | ||
| 4999 | #define WM5100_DSP3_DM_END_1_MASK 0x00FF /* DSP3_DM_END - [7:0] */ | ||
| 5000 | #define WM5100_DSP3_DM_END_1_SHIFT 0 /* DSP3_DM_END - [7:0] */ | ||
| 5001 | #define WM5100_DSP3_DM_END_1_WIDTH 8 /* DSP3_DM_END - [7:0] */ | ||
| 5002 | |||
| 5003 | /* | ||
| 5004 | * R33279 (0x81FF) - DSP3 DM 511 | ||
| 5005 | */ | ||
| 5006 | #define WM5100_DSP3_DM_END_MASK 0xFFFF /* DSP3_DM_END - [15:0] */ | ||
| 5007 | #define WM5100_DSP3_DM_END_SHIFT 0 /* DSP3_DM_END - [15:0] */ | ||
| 5008 | #define WM5100_DSP3_DM_END_WIDTH 16 /* DSP3_DM_END - [15:0] */ | ||
| 5009 | |||
| 5010 | /* | ||
| 5011 | * R34816 (0x8800) - DSP3 PM 0 | ||
| 5012 | */ | ||
| 5013 | #define WM5100_DSP3_PM_START_2_MASK 0x00FF /* DSP3_PM_START - [7:0] */ | ||
| 5014 | #define WM5100_DSP3_PM_START_2_SHIFT 0 /* DSP3_PM_START - [7:0] */ | ||
| 5015 | #define WM5100_DSP3_PM_START_2_WIDTH 8 /* DSP3_PM_START - [7:0] */ | ||
| 5016 | |||
| 5017 | /* | ||
| 5018 | * R34817 (0x8801) - DSP3 PM 1 | ||
| 5019 | */ | ||
| 5020 | #define WM5100_DSP3_PM_START_1_MASK 0xFFFF /* DSP3_PM_START - [15:0] */ | ||
| 5021 | #define WM5100_DSP3_PM_START_1_SHIFT 0 /* DSP3_PM_START - [15:0] */ | ||
| 5022 | #define WM5100_DSP3_PM_START_1_WIDTH 16 /* DSP3_PM_START - [15:0] */ | ||
| 5023 | |||
| 5024 | /* | ||
| 5025 | * R34818 (0x8802) - DSP3 PM 2 | ||
| 5026 | */ | ||
| 5027 | #define WM5100_DSP3_PM_START_MASK 0xFFFF /* DSP3_PM_START - [15:0] */ | ||
| 5028 | #define WM5100_DSP3_PM_START_SHIFT 0 /* DSP3_PM_START - [15:0] */ | ||
| 5029 | #define WM5100_DSP3_PM_START_WIDTH 16 /* DSP3_PM_START - [15:0] */ | ||
| 5030 | |||
| 5031 | /* | ||
| 5032 | * R34819 (0x8803) - DSP3 PM 3 | ||
| 5033 | */ | ||
| 5034 | #define WM5100_DSP3_PM_1_2_MASK 0x00FF /* DSP3_PM_1 - [7:0] */ | ||
| 5035 | #define WM5100_DSP3_PM_1_2_SHIFT 0 /* DSP3_PM_1 - [7:0] */ | ||
| 5036 | #define WM5100_DSP3_PM_1_2_WIDTH 8 /* DSP3_PM_1 - [7:0] */ | ||
| 5037 | |||
| 5038 | /* | ||
| 5039 | * R34820 (0x8804) - DSP3 PM 4 | ||
| 5040 | */ | ||
| 5041 | #define WM5100_DSP3_PM_1_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */ | ||
| 5042 | #define WM5100_DSP3_PM_1_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */ | ||
| 5043 | #define WM5100_DSP3_PM_1_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */ | ||
| 5044 | |||
| 5045 | /* | ||
| 5046 | * R34821 (0x8805) - DSP3 PM 5 | ||
| 5047 | */ | ||
| 5048 | #define WM5100_DSP3_PM_1_MASK 0xFFFF /* DSP3_PM_1 - [15:0] */ | ||
| 5049 | #define WM5100_DSP3_PM_1_SHIFT 0 /* DSP3_PM_1 - [15:0] */ | ||
| 5050 | #define WM5100_DSP3_PM_1_WIDTH 16 /* DSP3_PM_1 - [15:0] */ | ||
| 5051 | |||
| 5052 | /* | ||
| 5053 | * R36346 (0x8DFA) - DSP3 PM 1530 | ||
| 5054 | */ | ||
| 5055 | #define WM5100_DSP3_PM_510_2_MASK 0x00FF /* DSP3_PM_510 - [7:0] */ | ||
| 5056 | #define WM5100_DSP3_PM_510_2_SHIFT 0 /* DSP3_PM_510 - [7:0] */ | ||
| 5057 | #define WM5100_DSP3_PM_510_2_WIDTH 8 /* DSP3_PM_510 - [7:0] */ | ||
| 5058 | |||
| 5059 | /* | ||
| 5060 | * R36347 (0x8DFB) - DSP3 PM 1531 | ||
| 5061 | */ | ||
| 5062 | #define WM5100_DSP3_PM_510_1_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */ | ||
| 5063 | #define WM5100_DSP3_PM_510_1_SHIFT 0 /* DSP3_PM_510 - [15:0] */ | ||
| 5064 | #define WM5100_DSP3_PM_510_1_WIDTH 16 /* DSP3_PM_510 - [15:0] */ | ||
| 5065 | |||
| 5066 | /* | ||
| 5067 | * R36348 (0x8DFC) - DSP3 PM 1532 | ||
| 5068 | */ | ||
| 5069 | #define WM5100_DSP3_PM_510_MASK 0xFFFF /* DSP3_PM_510 - [15:0] */ | ||
| 5070 | #define WM5100_DSP3_PM_510_SHIFT 0 /* DSP3_PM_510 - [15:0] */ | ||
| 5071 | #define WM5100_DSP3_PM_510_WIDTH 16 /* DSP3_PM_510 - [15:0] */ | ||
| 5072 | |||
| 5073 | /* | ||
| 5074 | * R36349 (0x8DFD) - DSP3 PM 1533 | ||
| 5075 | */ | ||
| 5076 | #define WM5100_DSP3_PM_END_2_MASK 0x00FF /* DSP3_PM_END - [7:0] */ | ||
| 5077 | #define WM5100_DSP3_PM_END_2_SHIFT 0 /* DSP3_PM_END - [7:0] */ | ||
| 5078 | #define WM5100_DSP3_PM_END_2_WIDTH 8 /* DSP3_PM_END - [7:0] */ | ||
| 5079 | |||
| 5080 | /* | ||
| 5081 | * R36350 (0x8DFE) - DSP3 PM 1534 | ||
| 5082 | */ | ||
| 5083 | #define WM5100_DSP3_PM_END_1_MASK 0xFFFF /* DSP3_PM_END - [15:0] */ | ||
| 5084 | #define WM5100_DSP3_PM_END_1_SHIFT 0 /* DSP3_PM_END - [15:0] */ | ||
| 5085 | #define WM5100_DSP3_PM_END_1_WIDTH 16 /* DSP3_PM_END - [15:0] */ | ||
| 5086 | |||
| 5087 | /* | ||
| 5088 | * R36351 (0x8DFF) - DSP3 PM 1535 | ||
| 5089 | */ | ||
| 5090 | #define WM5100_DSP3_PM_END_MASK 0xFFFF /* DSP3_PM_END - [15:0] */ | ||
| 5091 | #define WM5100_DSP3_PM_END_SHIFT 0 /* DSP3_PM_END - [15:0] */ | ||
| 5092 | #define WM5100_DSP3_PM_END_WIDTH 16 /* DSP3_PM_END - [15:0] */ | ||
| 5093 | |||
| 5094 | /* | ||
| 5095 | * R36864 (0x9000) - DSP3 ZM 0 | ||
| 5096 | */ | ||
| 5097 | #define WM5100_DSP3_ZM_START_1_MASK 0x00FF /* DSP3_ZM_START - [7:0] */ | ||
| 5098 | #define WM5100_DSP3_ZM_START_1_SHIFT 0 /* DSP3_ZM_START - [7:0] */ | ||
| 5099 | #define WM5100_DSP3_ZM_START_1_WIDTH 8 /* DSP3_ZM_START - [7:0] */ | ||
| 5100 | |||
| 5101 | /* | ||
| 5102 | * R36865 (0x9001) - DSP3 ZM 1 | ||
| 5103 | */ | ||
| 5104 | #define WM5100_DSP3_ZM_START_MASK 0xFFFF /* DSP3_ZM_START - [15:0] */ | ||
| 5105 | #define WM5100_DSP3_ZM_START_SHIFT 0 /* DSP3_ZM_START - [15:0] */ | ||
| 5106 | #define WM5100_DSP3_ZM_START_WIDTH 16 /* DSP3_ZM_START - [15:0] */ | ||
| 5107 | |||
| 5108 | /* | ||
| 5109 | * R36866 (0x9002) - DSP3 ZM 2 | ||
| 5110 | */ | ||
| 5111 | #define WM5100_DSP3_ZM_1_1_MASK 0x00FF /* DSP3_ZM_1 - [7:0] */ | ||
| 5112 | #define WM5100_DSP3_ZM_1_1_SHIFT 0 /* DSP3_ZM_1 - [7:0] */ | ||
| 5113 | #define WM5100_DSP3_ZM_1_1_WIDTH 8 /* DSP3_ZM_1 - [7:0] */ | ||
| 5114 | |||
| 5115 | /* | ||
| 5116 | * R36867 (0x9003) - DSP3 ZM 3 | ||
| 5117 | */ | ||
| 5118 | #define WM5100_DSP3_ZM_1_MASK 0xFFFF /* DSP3_ZM_1 - [15:0] */ | ||
| 5119 | #define WM5100_DSP3_ZM_1_SHIFT 0 /* DSP3_ZM_1 - [15:0] */ | ||
| 5120 | #define WM5100_DSP3_ZM_1_WIDTH 16 /* DSP3_ZM_1 - [15:0] */ | ||
| 5121 | |||
| 5122 | /* | ||
| 5123 | * R38908 (0x97FC) - DSP3 ZM 2044 | ||
| 5124 | */ | ||
| 5125 | #define WM5100_DSP3_ZM_1022_1_MASK 0x00FF /* DSP3_ZM_1022 - [7:0] */ | ||
| 5126 | #define WM5100_DSP3_ZM_1022_1_SHIFT 0 /* DSP3_ZM_1022 - [7:0] */ | ||
| 5127 | #define WM5100_DSP3_ZM_1022_1_WIDTH 8 /* DSP3_ZM_1022 - [7:0] */ | ||
| 5128 | |||
| 5129 | /* | ||
| 5130 | * R38909 (0x97FD) - DSP3 ZM 2045 | ||
| 5131 | */ | ||
| 5132 | #define WM5100_DSP3_ZM_1022_MASK 0xFFFF /* DSP3_ZM_1022 - [15:0] */ | ||
| 5133 | #define WM5100_DSP3_ZM_1022_SHIFT 0 /* DSP3_ZM_1022 - [15:0] */ | ||
| 5134 | #define WM5100_DSP3_ZM_1022_WIDTH 16 /* DSP3_ZM_1022 - [15:0] */ | ||
| 5135 | |||
| 5136 | /* | ||
| 5137 | * R38910 (0x97FE) - DSP3 ZM 2046 | ||
| 5138 | */ | ||
| 5139 | #define WM5100_DSP3_ZM_END_1_MASK 0x00FF /* DSP3_ZM_END - [7:0] */ | ||
| 5140 | #define WM5100_DSP3_ZM_END_1_SHIFT 0 /* DSP3_ZM_END - [7:0] */ | ||
| 5141 | #define WM5100_DSP3_ZM_END_1_WIDTH 8 /* DSP3_ZM_END - [7:0] */ | ||
| 5142 | |||
| 5143 | /* | ||
| 5144 | * R38911 (0x97FF) - DSP3 ZM 2047 | ||
| 5145 | */ | ||
| 5146 | #define WM5100_DSP3_ZM_END_MASK 0xFFFF /* DSP3_ZM_END - [15:0] */ | ||
| 5147 | #define WM5100_DSP3_ZM_END_SHIFT 0 /* DSP3_ZM_END - [15:0] */ | ||
| 5148 | #define WM5100_DSP3_ZM_END_WIDTH 16 /* DSP3_ZM_END - [15:0] */ | ||
| 5149 | |||
| 5150 | int wm5100_readable_register(struct snd_soc_codec *codec, unsigned int reg); | ||
| 5151 | int wm5100_volatile_register(struct snd_soc_codec *codec, unsigned int reg); | ||
| 5152 | |||
| 5153 | extern u16 wm5100_reg_defaults[WM5100_MAX_REGISTER + 1]; | ||
| 5154 | |||
| 5155 | #endif | ||
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 6d6dc9efe914..35f3ad83dfb6 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
| @@ -355,7 +355,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, | |||
| 355 | return 1; | 355 | return 1; |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); | 358 | ret = snd_soc_put_volsw(kcontrol, ucontrol); |
| 359 | if (ret < 0) | 359 | if (ret < 0) |
| 360 | return ret; | 360 | return ret; |
| 361 | 361 | ||
| @@ -392,23 +392,9 @@ static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol, | |||
| 392 | break; | 392 | break; |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | return snd_soc_get_volsw_2r(kcontrol, ucontrol); | 395 | return snd_soc_get_volsw(kcontrol, ucontrol); |
| 396 | } | 396 | } |
| 397 | 397 | ||
| 398 | /* double control with volume update */ | ||
| 399 | #define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \ | ||
| 400 | xinvert, tlv_array) \ | ||
| 401 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | ||
| 402 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ | ||
| 403 | SNDRV_CTL_ELEM_ACCESS_READWRITE | \ | ||
| 404 | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ | ||
| 405 | .tlv.p = (tlv_array), \ | ||
| 406 | .info = snd_soc_info_volsw_2r, \ | ||
| 407 | .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \ | ||
| 408 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
| 409 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | ||
| 410 | .rshift = xshift, .max = xmax, .invert = xinvert}, } | ||
| 411 | |||
| 412 | static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; | 398 | static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" }; |
| 413 | static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" }; | 399 | static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" }; |
| 414 | static const char *wm8350_dacmutem[] = { "Normal", "Soft" }; | 400 | static const char *wm8350_dacmutem[] = { "Normal", "Soft" }; |
| @@ -443,26 +429,29 @@ static const unsigned int capture_sd_tlv[] = { | |||
| 443 | static const struct snd_kcontrol_new wm8350_snd_controls[] = { | 429 | static const struct snd_kcontrol_new wm8350_snd_controls[] = { |
| 444 | SOC_ENUM("Playback Deemphasis", wm8350_enum[0]), | 430 | SOC_ENUM("Playback Deemphasis", wm8350_enum[0]), |
| 445 | SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]), | 431 | SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]), |
| 446 | SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume", | 432 | SOC_DOUBLE_R_EXT_TLV("Playback PCM Volume", |
| 447 | WM8350_DAC_DIGITAL_VOLUME_L, | 433 | WM8350_DAC_DIGITAL_VOLUME_L, |
| 448 | WM8350_DAC_DIGITAL_VOLUME_R, | 434 | WM8350_DAC_DIGITAL_VOLUME_R, |
| 449 | 0, 255, 0, dac_pcm_tlv), | 435 | 0, 255, 0, wm8350_get_volsw_2r, |
| 436 | wm8350_put_volsw_2r_vu, dac_pcm_tlv), | ||
| 450 | SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]), | 437 | SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]), |
| 451 | SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]), | 438 | SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]), |
| 452 | SOC_ENUM("Capture PCM Filter", wm8350_enum[4]), | 439 | SOC_ENUM("Capture PCM Filter", wm8350_enum[4]), |
| 453 | SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]), | 440 | SOC_ENUM("Capture PCM HP Filter", wm8350_enum[5]), |
| 454 | SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]), | 441 | SOC_ENUM("Capture ADC Inversion", wm8350_enum[6]), |
| 455 | SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume", | 442 | SOC_DOUBLE_R_EXT_TLV("Capture PCM Volume", |
| 456 | WM8350_ADC_DIGITAL_VOLUME_L, | 443 | WM8350_ADC_DIGITAL_VOLUME_L, |
| 457 | WM8350_ADC_DIGITAL_VOLUME_R, | 444 | WM8350_ADC_DIGITAL_VOLUME_R, |
| 458 | 0, 255, 0, adc_pcm_tlv), | 445 | 0, 255, 0, wm8350_get_volsw_2r, |
| 446 | wm8350_put_volsw_2r_vu, adc_pcm_tlv), | ||
| 459 | SOC_DOUBLE_TLV("Capture Sidetone Volume", | 447 | SOC_DOUBLE_TLV("Capture Sidetone Volume", |
| 460 | WM8350_ADC_DIVIDER, | 448 | WM8350_ADC_DIVIDER, |
| 461 | 8, 4, 15, 1, capture_sd_tlv), | 449 | 8, 4, 15, 1, capture_sd_tlv), |
| 462 | SOC_WM8350_DOUBLE_R_TLV("Capture Volume", | 450 | SOC_DOUBLE_R_EXT_TLV("Capture Volume", |
| 463 | WM8350_LEFT_INPUT_VOLUME, | 451 | WM8350_LEFT_INPUT_VOLUME, |
| 464 | WM8350_RIGHT_INPUT_VOLUME, | 452 | WM8350_RIGHT_INPUT_VOLUME, |
| 465 | 2, 63, 0, pre_amp_tlv), | 453 | 2, 63, 0, wm8350_get_volsw_2r, |
| 454 | wm8350_put_volsw_2r_vu, pre_amp_tlv), | ||
| 466 | SOC_DOUBLE_R("Capture ZC Switch", | 455 | SOC_DOUBLE_R("Capture ZC Switch", |
| 467 | WM8350_LEFT_INPUT_VOLUME, | 456 | WM8350_LEFT_INPUT_VOLUME, |
| 468 | WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0), | 457 | WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0), |
| @@ -490,17 +479,19 @@ static const struct snd_kcontrol_new wm8350_snd_controls[] = { | |||
| 490 | SOC_SINGLE_TLV("Out4 Capture Volume", | 479 | SOC_SINGLE_TLV("Out4 Capture Volume", |
| 491 | WM8350_INPUT_MIXER_VOLUME, | 480 | WM8350_INPUT_MIXER_VOLUME, |
| 492 | 1, 7, 0, out_mix_tlv), | 481 | 1, 7, 0, out_mix_tlv), |
| 493 | SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume", | 482 | SOC_DOUBLE_R_EXT_TLV("Out1 Playback Volume", |
| 494 | WM8350_LOUT1_VOLUME, | 483 | WM8350_LOUT1_VOLUME, |
| 495 | WM8350_ROUT1_VOLUME, | 484 | WM8350_ROUT1_VOLUME, |
| 496 | 2, 63, 0, out_pga_tlv), | 485 | 2, 63, 0, wm8350_get_volsw_2r, |
| 486 | wm8350_put_volsw_2r_vu, out_pga_tlv), | ||
| 497 | SOC_DOUBLE_R("Out1 Playback ZC Switch", | 487 | SOC_DOUBLE_R("Out1 Playback ZC Switch", |
| 498 | WM8350_LOUT1_VOLUME, | 488 | WM8350_LOUT1_VOLUME, |
| 499 | WM8350_ROUT1_VOLUME, 13, 1, 0), | 489 | WM8350_ROUT1_VOLUME, 13, 1, 0), |
| 500 | SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume", | 490 | SOC_DOUBLE_R_EXT_TLV("Out2 Playback Volume", |
| 501 | WM8350_LOUT2_VOLUME, | 491 | WM8350_LOUT2_VOLUME, |
| 502 | WM8350_ROUT2_VOLUME, | 492 | WM8350_ROUT2_VOLUME, |
| 503 | 2, 63, 0, out_pga_tlv), | 493 | 2, 63, 0, wm8350_get_volsw_2r, |
| 494 | wm8350_put_volsw_2r_vu, out_pga_tlv), | ||
| 504 | SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME, | 495 | SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME, |
| 505 | WM8350_ROUT2_VOLUME, 13, 1, 0), | 496 | WM8350_ROUT2_VOLUME, 13, 1, 0), |
| 506 | SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0), | 497 | SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0), |
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index fbee556cbf35..dc13be2a09c5 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
| @@ -383,7 +383,7 @@ static int inmixer_event (struct snd_soc_dapm_widget *w, | |||
| 383 | (1 << WM8400_AINRMUX_PWR))) { | 383 | (1 << WM8400_AINRMUX_PWR))) { |
| 384 | reg |= WM8400_AINR_ENA; | 384 | reg |= WM8400_AINR_ENA; |
| 385 | } else { | 385 | } else { |
| 386 | reg &= ~WM8400_AINL_ENA; | 386 | reg &= ~WM8400_AINR_ENA; |
| 387 | } | 387 | } |
| 388 | wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); | 388 | wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg); |
| 389 | 389 | ||
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index db0dced74843..07c9cc759e97 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/of_device.h> | ||
| 23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
| 24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
| 25 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
| @@ -479,6 +480,8 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, | |||
| 479 | power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; | 480 | power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; |
| 480 | 481 | ||
| 481 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 482 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 483 | snd_soc_cache_sync(codec); | ||
| 484 | |||
| 482 | /* Initial cap charge at VMID 5k */ | 485 | /* Initial cap charge at VMID 5k */ |
| 483 | snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); | 486 | snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); |
| 484 | mdelay(100); | 487 | mdelay(100); |
| @@ -540,18 +543,7 @@ static int wm8510_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 540 | 543 | ||
| 541 | static int wm8510_resume(struct snd_soc_codec *codec) | 544 | static int wm8510_resume(struct snd_soc_codec *codec) |
| 542 | { | 545 | { |
| 543 | int i; | ||
| 544 | u8 data[2]; | ||
| 545 | u16 *cache = codec->reg_cache; | ||
| 546 | |||
| 547 | /* Sync reg_cache with the hardware */ | ||
| 548 | for (i = 0; i < ARRAY_SIZE(wm8510_reg); i++) { | ||
| 549 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 550 | data[1] = cache[i] & 0x00ff; | ||
| 551 | codec->hw_write(codec->control_data, data, 2); | ||
| 552 | } | ||
| 553 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 546 | wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 554 | |||
| 555 | return 0; | 547 | return 0; |
| 556 | } | 548 | } |
| 557 | 549 | ||
| @@ -598,6 +590,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8510 = { | |||
| 598 | .reg_cache_default =wm8510_reg, | 590 | .reg_cache_default =wm8510_reg, |
| 599 | }; | 591 | }; |
| 600 | 592 | ||
| 593 | static const struct of_device_id wm8510_of_match[] = { | ||
| 594 | { .compatible = "wlf,wm8510" }, | ||
| 595 | { }, | ||
| 596 | }; | ||
| 597 | |||
| 601 | #if defined(CONFIG_SPI_MASTER) | 598 | #if defined(CONFIG_SPI_MASTER) |
| 602 | static int __devinit wm8510_spi_probe(struct spi_device *spi) | 599 | static int __devinit wm8510_spi_probe(struct spi_device *spi) |
| 603 | { | 600 | { |
| @@ -628,6 +625,7 @@ static struct spi_driver wm8510_spi_driver = { | |||
| 628 | .driver = { | 625 | .driver = { |
| 629 | .name = "wm8510", | 626 | .name = "wm8510", |
| 630 | .owner = THIS_MODULE, | 627 | .owner = THIS_MODULE, |
| 628 | .of_match_table = wm8510_of_match, | ||
| 631 | }, | 629 | }, |
| 632 | .probe = wm8510_spi_probe, | 630 | .probe = wm8510_spi_probe, |
| 633 | .remove = __devexit_p(wm8510_spi_remove), | 631 | .remove = __devexit_p(wm8510_spi_remove), |
| @@ -671,6 +669,7 @@ static struct i2c_driver wm8510_i2c_driver = { | |||
| 671 | .driver = { | 669 | .driver = { |
| 672 | .name = "wm8510-codec", | 670 | .name = "wm8510-codec", |
| 673 | .owner = THIS_MODULE, | 671 | .owner = THIS_MODULE, |
| 672 | .of_match_table = wm8510_of_match, | ||
| 674 | }, | 673 | }, |
| 675 | .probe = wm8510_i2c_probe, | 674 | .probe = wm8510_i2c_probe, |
| 676 | .remove = __devexit_p(wm8510_i2c_remove), | 675 | .remove = __devexit_p(wm8510_i2c_remove), |
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 4fd4d8dca0fc..db7a6819499f 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/of_device.h> | ||
| 23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
| 24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
| 25 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
| @@ -84,7 +85,7 @@ static const char *wm8523_zd_count_text[] = { | |||
| 84 | static const struct soc_enum wm8523_zc_count = | 85 | static const struct soc_enum wm8523_zc_count = |
| 85 | SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text); | 86 | SOC_ENUM_SINGLE(WM8523_ZERO_DETECT, 0, 2, wm8523_zd_count_text); |
| 86 | 87 | ||
| 87 | static const struct snd_kcontrol_new wm8523_snd_controls[] = { | 88 | static const struct snd_kcontrol_new wm8523_controls[] = { |
| 88 | SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, | 89 | SOC_DOUBLE_R_TLV("Playback Volume", WM8523_DAC_GAINL, WM8523_DAC_GAINR, |
| 89 | 0, 448, 0, dac_tlv), | 90 | 0, 448, 0, dac_tlv), |
| 90 | SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), | 91 | SOC_SINGLE("ZC Switch", WM8523_DAC_CTRL3, 4, 1, 0), |
| @@ -101,22 +102,11 @@ SND_SOC_DAPM_OUTPUT("LINEVOUTL"), | |||
| 101 | SND_SOC_DAPM_OUTPUT("LINEVOUTR"), | 102 | SND_SOC_DAPM_OUTPUT("LINEVOUTR"), |
| 102 | }; | 103 | }; |
| 103 | 104 | ||
| 104 | static const struct snd_soc_dapm_route intercon[] = { | 105 | static const struct snd_soc_dapm_route wm8523_dapm_routes[] = { |
| 105 | { "LINEVOUTL", NULL, "DAC" }, | 106 | { "LINEVOUTL", NULL, "DAC" }, |
| 106 | { "LINEVOUTR", NULL, "DAC" }, | 107 | { "LINEVOUTR", NULL, "DAC" }, |
| 107 | }; | 108 | }; |
| 108 | 109 | ||
| 109 | static int wm8523_add_widgets(struct snd_soc_codec *codec) | ||
| 110 | { | ||
| 111 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 112 | |||
| 113 | snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets, | ||
| 114 | ARRAY_SIZE(wm8523_dapm_widgets)); | ||
| 115 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | ||
| 116 | |||
| 117 | return 0; | ||
| 118 | } | ||
| 119 | |||
| 120 | static struct { | 110 | static struct { |
| 121 | int value; | 111 | int value; |
| 122 | int ratio; | 112 | int ratio; |
| @@ -416,7 +406,6 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
| 416 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 406 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
| 417 | int ret, i; | 407 | int ret, i; |
| 418 | 408 | ||
| 419 | codec->hw_write = (hw_write_t)i2c_master_send; | ||
| 420 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; | 409 | wm8523->rate_constraint.list = &wm8523->rate_constraint_list[0]; |
| 421 | wm8523->rate_constraint.count = | 410 | wm8523->rate_constraint.count = |
| 422 | ARRAY_SIZE(wm8523->rate_constraint_list); | 411 | ARRAY_SIZE(wm8523->rate_constraint_list); |
| @@ -479,10 +468,6 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
| 479 | /* Bias level configuration will have done an extra enable */ | 468 | /* Bias level configuration will have done an extra enable */ |
| 480 | regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); | 469 | regulator_bulk_disable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); |
| 481 | 470 | ||
| 482 | snd_soc_add_controls(codec, wm8523_snd_controls, | ||
| 483 | ARRAY_SIZE(wm8523_snd_controls)); | ||
| 484 | wm8523_add_widgets(codec); | ||
| 485 | |||
| 486 | return 0; | 471 | return 0; |
| 487 | 472 | ||
| 488 | err_enable: | 473 | err_enable: |
| @@ -512,6 +497,18 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8523 = { | |||
| 512 | .reg_word_size = sizeof(u16), | 497 | .reg_word_size = sizeof(u16), |
| 513 | .reg_cache_default = wm8523_reg, | 498 | .reg_cache_default = wm8523_reg, |
| 514 | .volatile_register = wm8523_volatile_register, | 499 | .volatile_register = wm8523_volatile_register, |
| 500 | |||
| 501 | .controls = wm8523_controls, | ||
| 502 | .num_controls = ARRAY_SIZE(wm8523_controls), | ||
| 503 | .dapm_widgets = wm8523_dapm_widgets, | ||
| 504 | .num_dapm_widgets = ARRAY_SIZE(wm8523_dapm_widgets), | ||
| 505 | .dapm_routes = wm8523_dapm_routes, | ||
| 506 | .num_dapm_routes = ARRAY_SIZE(wm8523_dapm_routes), | ||
| 507 | }; | ||
| 508 | |||
| 509 | static const struct of_device_id wm8523_of_match[] = { | ||
| 510 | { .compatible = "wlf,wm8523" }, | ||
| 511 | { }, | ||
| 515 | }; | 512 | }; |
| 516 | 513 | ||
| 517 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 514 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| @@ -551,8 +548,9 @@ MODULE_DEVICE_TABLE(i2c, wm8523_i2c_id); | |||
| 551 | 548 | ||
| 552 | static struct i2c_driver wm8523_i2c_driver = { | 549 | static struct i2c_driver wm8523_i2c_driver = { |
| 553 | .driver = { | 550 | .driver = { |
| 554 | .name = "wm8523-codec", | 551 | .name = "wm8523", |
| 555 | .owner = THIS_MODULE, | 552 | .owner = THIS_MODULE, |
| 553 | .of_match_table = wm8523_of_match, | ||
| 556 | }, | 554 | }, |
| 557 | .probe = wm8523_i2c_probe, | 555 | .probe = wm8523_i2c_probe, |
| 558 | .remove = __devexit_p(wm8523_i2c_remove), | 556 | .remove = __devexit_p(wm8523_i2c_remove), |
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 4bbc0a79f01e..8212b3c8bfdd 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
| 27 | #include <linux/regulator/consumer.h> | 27 | #include <linux/regulator/consumer.h> |
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/of_device.h> | ||
| 29 | 30 | ||
| 30 | #include <sound/core.h> | 31 | #include <sound/core.h> |
| 31 | #include <sound/pcm.h> | 32 | #include <sound/pcm.h> |
| @@ -212,7 +213,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, | |||
| 212 | reg_cache[reg] = 0; | 213 | reg_cache[reg] = 0; |
| 213 | reg_cache[reg2] = 0; | 214 | reg_cache[reg2] = 0; |
| 214 | 215 | ||
| 215 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); | 216 | ret = snd_soc_put_volsw(kcontrol, ucontrol); |
| 216 | if (ret < 0) | 217 | if (ret < 0) |
| 217 | return ret; | 218 | return ret; |
| 218 | 219 | ||
| @@ -223,31 +224,19 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol, | |||
| 223 | return 0; | 224 | return 0; |
| 224 | } | 225 | } |
| 225 | 226 | ||
| 226 | #define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \ | ||
| 227 | xinvert, tlv_array) \ | ||
| 228 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ | ||
| 229 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
| 230 | SNDRV_CTL_ELEM_ACCESS_READWRITE, \ | ||
| 231 | .tlv.p = (tlv_array), \ | ||
| 232 | .info = snd_soc_info_volsw_2r, \ | ||
| 233 | .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \ | ||
| 234 | .private_value = (unsigned long)&(struct soc_mixer_control) \ | ||
| 235 | {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ | ||
| 236 | .max = xmax, .invert = xinvert} } | ||
| 237 | |||
| 238 | static const struct snd_kcontrol_new wm8580_snd_controls[] = { | 227 | static const struct snd_kcontrol_new wm8580_snd_controls[] = { |
| 239 | SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume", | 228 | SOC_DOUBLE_R_EXT_TLV("DAC1 Playback Volume", |
| 240 | WM8580_DIGITAL_ATTENUATION_DACL1, | 229 | WM8580_DIGITAL_ATTENUATION_DACL1, |
| 241 | WM8580_DIGITAL_ATTENUATION_DACR1, | 230 | WM8580_DIGITAL_ATTENUATION_DACR1, |
| 242 | 0, 0xff, 0, dac_tlv), | 231 | 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv), |
| 243 | SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume", | 232 | SOC_DOUBLE_R_EXT_TLV("DAC2 Playback Volume", |
| 244 | WM8580_DIGITAL_ATTENUATION_DACL2, | 233 | WM8580_DIGITAL_ATTENUATION_DACL2, |
| 245 | WM8580_DIGITAL_ATTENUATION_DACR2, | 234 | WM8580_DIGITAL_ATTENUATION_DACR2, |
| 246 | 0, 0xff, 0, dac_tlv), | 235 | 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv), |
| 247 | SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume", | 236 | SOC_DOUBLE_R_EXT_TLV("DAC3 Playback Volume", |
| 248 | WM8580_DIGITAL_ATTENUATION_DACL3, | 237 | WM8580_DIGITAL_ATTENUATION_DACL3, |
| 249 | WM8580_DIGITAL_ATTENUATION_DACR3, | 238 | WM8580_DIGITAL_ATTENUATION_DACR3, |
| 250 | 0, 0xff, 0, dac_tlv), | 239 | 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv), |
| 251 | 240 | ||
| 252 | SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0), | 241 | SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0), |
| 253 | SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0), | 242 | SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0), |
| @@ -441,8 +430,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
| 441 | /* Always disable the PLL - it is not safe to leave it running | 430 | /* Always disable the PLL - it is not safe to leave it running |
| 442 | * while reprogramming it. | 431 | * while reprogramming it. |
| 443 | */ | 432 | */ |
| 444 | reg = snd_soc_read(codec, WM8580_PWRDN2); | 433 | snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask); |
| 445 | snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask); | ||
| 446 | 434 | ||
| 447 | if (!freq_in || !freq_out) | 435 | if (!freq_in || !freq_out) |
| 448 | return 0; | 436 | return 0; |
| @@ -460,8 +448,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
| 460 | snd_soc_write(codec, WM8580_PLLA4 + offset, reg); | 448 | snd_soc_write(codec, WM8580_PLLA4 + offset, reg); |
| 461 | 449 | ||
| 462 | /* All done, turn it on */ | 450 | /* All done, turn it on */ |
| 463 | reg = snd_soc_read(codec, WM8580_PWRDN2); | 451 | snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0); |
| 464 | snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask); | ||
| 465 | 452 | ||
| 466 | return 0; | 453 | return 0; |
| 467 | } | 454 | } |
| @@ -759,7 +746,6 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
| 759 | static int wm8580_set_bias_level(struct snd_soc_codec *codec, | 746 | static int wm8580_set_bias_level(struct snd_soc_codec *codec, |
| 760 | enum snd_soc_bias_level level) | 747 | enum snd_soc_bias_level level) |
| 761 | { | 748 | { |
| 762 | u16 reg; | ||
| 763 | switch (level) { | 749 | switch (level) { |
| 764 | case SND_SOC_BIAS_ON: | 750 | case SND_SOC_BIAS_ON: |
| 765 | case SND_SOC_BIAS_PREPARE: | 751 | case SND_SOC_BIAS_PREPARE: |
| @@ -768,20 +754,19 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, | |||
| 768 | case SND_SOC_BIAS_STANDBY: | 754 | case SND_SOC_BIAS_STANDBY: |
| 769 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 755 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 770 | /* Power up and get individual control of the DACs */ | 756 | /* Power up and get individual control of the DACs */ |
| 771 | reg = snd_soc_read(codec, WM8580_PWRDN1); | 757 | snd_soc_update_bits(codec, WM8580_PWRDN1, |
| 772 | reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); | 758 | WM8580_PWRDN1_PWDN | |
| 773 | snd_soc_write(codec, WM8580_PWRDN1, reg); | 759 | WM8580_PWRDN1_ALLDACPD, 0); |
| 774 | 760 | ||
| 775 | /* Make VMID high impedance */ | 761 | /* Make VMID high impedance */ |
| 776 | reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); | 762 | snd_soc_update_bits(codec, WM8580_ADC_CONTROL1, |
| 777 | reg &= ~0x100; | 763 | 0x100, 0); |
| 778 | snd_soc_write(codec, WM8580_ADC_CONTROL1, reg); | ||
| 779 | } | 764 | } |
| 780 | break; | 765 | break; |
| 781 | 766 | ||
| 782 | case SND_SOC_BIAS_OFF: | 767 | case SND_SOC_BIAS_OFF: |
| 783 | reg = snd_soc_read(codec, WM8580_PWRDN1); | 768 | snd_soc_update_bits(codec, WM8580_PWRDN1, |
| 784 | snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); | 769 | WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN); |
| 785 | break; | 770 | break; |
| 786 | } | 771 | } |
| 787 | codec->dapm.bias_level = level; | 772 | codec->dapm.bias_level = level; |
| @@ -907,6 +892,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { | |||
| 907 | .reg_cache_default = wm8580_reg, | 892 | .reg_cache_default = wm8580_reg, |
| 908 | }; | 893 | }; |
| 909 | 894 | ||
| 895 | static const struct of_device_id wm8580_of_match[] = { | ||
| 896 | { .compatible = "wlf,wm8580" }, | ||
| 897 | { }, | ||
| 898 | }; | ||
| 899 | |||
| 910 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 900 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 911 | static int wm8580_i2c_probe(struct i2c_client *i2c, | 901 | static int wm8580_i2c_probe(struct i2c_client *i2c, |
| 912 | const struct i2c_device_id *id) | 902 | const struct i2c_device_id *id) |
| @@ -943,8 +933,9 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id); | |||
| 943 | 933 | ||
| 944 | static struct i2c_driver wm8580_i2c_driver = { | 934 | static struct i2c_driver wm8580_i2c_driver = { |
| 945 | .driver = { | 935 | .driver = { |
| 946 | .name = "wm8580-codec", | 936 | .name = "wm8580", |
| 947 | .owner = THIS_MODULE, | 937 | .owner = THIS_MODULE, |
| 938 | .of_match_table = wm8580_of_match, | ||
| 948 | }, | 939 | }, |
| 949 | .probe = wm8580_i2c_probe, | 940 | .probe = wm8580_i2c_probe, |
| 950 | .remove = wm8580_i2c_remove, | 941 | .remove = wm8580_i2c_remove, |
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index a537e4af6ae7..8d0347cf0e9a 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright 2006 Wolfson Microelectronics | 4 | * Copyright 2006 Wolfson Microelectronics |
| 5 | * | 5 | * |
| 6 | * Author: Mike Arthur <linux@wolfsonmicro.com> | 6 | * Author: Mike Arthur <Mike.Arthur@wolfsonmicro.com> |
| 7 | * | 7 | * |
| 8 | * Based on wm8731.c by Richard Purdie | 8 | * Based on wm8731.c by Richard Purdie |
| 9 | * | 9 | * |
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/of_device.h> | ||
| 24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
| 25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
| 26 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
| @@ -286,7 +287,6 @@ static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 286 | return 0; | 287 | return 0; |
| 287 | } | 288 | } |
| 288 | 289 | ||
| 289 | |||
| 290 | static int wm8711_set_bias_level(struct snd_soc_codec *codec, | 290 | static int wm8711_set_bias_level(struct snd_soc_codec *codec, |
| 291 | enum snd_soc_bias_level level) | 291 | enum snd_soc_bias_level level) |
| 292 | { | 292 | { |
| @@ -299,6 +299,9 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec, | |||
| 299 | case SND_SOC_BIAS_PREPARE: | 299 | case SND_SOC_BIAS_PREPARE: |
| 300 | break; | 300 | break; |
| 301 | case SND_SOC_BIAS_STANDBY: | 301 | case SND_SOC_BIAS_STANDBY: |
| 302 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
| 303 | snd_soc_cache_sync(codec); | ||
| 304 | |||
| 302 | snd_soc_write(codec, WM8711_PWR, reg | 0x0040); | 305 | snd_soc_write(codec, WM8711_PWR, reg | 0x0040); |
| 303 | break; | 306 | break; |
| 304 | case SND_SOC_BIAS_OFF: | 307 | case SND_SOC_BIAS_OFF: |
| @@ -345,25 +348,14 @@ static int wm8711_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 345 | 348 | ||
| 346 | static int wm8711_resume(struct snd_soc_codec *codec) | 349 | static int wm8711_resume(struct snd_soc_codec *codec) |
| 347 | { | 350 | { |
| 348 | int i; | ||
| 349 | u8 data[2]; | ||
| 350 | u16 *cache = codec->reg_cache; | ||
| 351 | |||
| 352 | /* Sync reg_cache with the hardware */ | ||
| 353 | for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) { | ||
| 354 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 355 | data[1] = cache[i] & 0x00ff; | ||
| 356 | codec->hw_write(codec->control_data, data, 2); | ||
| 357 | } | ||
| 358 | wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 351 | wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 359 | |||
| 360 | return 0; | 352 | return 0; |
| 361 | } | 353 | } |
| 362 | 354 | ||
| 363 | static int wm8711_probe(struct snd_soc_codec *codec) | 355 | static int wm8711_probe(struct snd_soc_codec *codec) |
| 364 | { | 356 | { |
| 365 | struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); | 357 | struct wm8711_priv *wm8711 = snd_soc_codec_get_drvdata(codec); |
| 366 | int ret, reg; | 358 | int ret; |
| 367 | 359 | ||
| 368 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type); | 360 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8711->bus_type); |
| 369 | if (ret < 0) { | 361 | if (ret < 0) { |
| @@ -380,10 +372,8 @@ static int wm8711_probe(struct snd_soc_codec *codec) | |||
| 380 | wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 372 | wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 381 | 373 | ||
| 382 | /* Latch the update bits */ | 374 | /* Latch the update bits */ |
| 383 | reg = snd_soc_read(codec, WM8711_LOUT1V); | 375 | snd_soc_update_bits(codec, WM8711_LOUT1V, 0x0100, 0x0100); |
| 384 | snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100); | 376 | snd_soc_update_bits(codec, WM8711_ROUT1V, 0x0100, 0x0100); |
| 385 | reg = snd_soc_read(codec, WM8711_ROUT1V); | ||
| 386 | snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100); | ||
| 387 | 377 | ||
| 388 | snd_soc_add_controls(codec, wm8711_snd_controls, | 378 | snd_soc_add_controls(codec, wm8711_snd_controls, |
| 389 | ARRAY_SIZE(wm8711_snd_controls)); | 379 | ARRAY_SIZE(wm8711_snd_controls)); |
| @@ -414,6 +404,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8711 = { | |||
| 414 | .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), | 404 | .num_dapm_routes = ARRAY_SIZE(wm8711_intercon), |
| 415 | }; | 405 | }; |
| 416 | 406 | ||
| 407 | static const struct of_device_id wm8711_of_match[] = { | ||
| 408 | { .compatible = "wlf,wm8711", }, | ||
| 409 | { } | ||
| 410 | }; | ||
| 411 | MODULE_DEVICE_TABLE(of, wm8711_of_match); | ||
| 412 | |||
| 417 | #if defined(CONFIG_SPI_MASTER) | 413 | #if defined(CONFIG_SPI_MASTER) |
| 418 | static int __devinit wm8711_spi_probe(struct spi_device *spi) | 414 | static int __devinit wm8711_spi_probe(struct spi_device *spi) |
| 419 | { | 415 | { |
| @@ -443,8 +439,9 @@ static int __devexit wm8711_spi_remove(struct spi_device *spi) | |||
| 443 | 439 | ||
| 444 | static struct spi_driver wm8711_spi_driver = { | 440 | static struct spi_driver wm8711_spi_driver = { |
| 445 | .driver = { | 441 | .driver = { |
| 446 | .name = "wm8711-codec", | 442 | .name = "wm8711", |
| 447 | .owner = THIS_MODULE, | 443 | .owner = THIS_MODULE, |
| 444 | .of_match_table = wm8711_of_match, | ||
| 448 | }, | 445 | }, |
| 449 | .probe = wm8711_spi_probe, | 446 | .probe = wm8711_spi_probe, |
| 450 | .remove = __devexit_p(wm8711_spi_remove), | 447 | .remove = __devexit_p(wm8711_spi_remove), |
| @@ -487,8 +484,9 @@ MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id); | |||
| 487 | 484 | ||
| 488 | static struct i2c_driver wm8711_i2c_driver = { | 485 | static struct i2c_driver wm8711_i2c_driver = { |
| 489 | .driver = { | 486 | .driver = { |
| 490 | .name = "wm8711-codec", | 487 | .name = "wm8711", |
| 491 | .owner = THIS_MODULE, | 488 | .owner = THIS_MODULE, |
| 489 | .of_match_table = wm8711_of_match, | ||
| 492 | }, | 490 | }, |
| 493 | .probe = wm8711_i2c_probe, | 491 | .probe = wm8711_i2c_probe, |
| 494 | .remove = __devexit_p(wm8711_i2c_remove), | 492 | .remove = __devexit_p(wm8711_i2c_remove), |
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 86d4718d3a76..04b027efd5c0 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 20 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/of_device.h> | ||
| 22 | #include <sound/core.h> | 23 | #include <sound/core.h> |
| 23 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
| 24 | #include <sound/pcm_params.h> | 25 | #include <sound/pcm_params.h> |
| @@ -269,6 +270,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8728 = { | |||
| 269 | .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), | 270 | .num_dapm_routes = ARRAY_SIZE(wm8728_intercon), |
| 270 | }; | 271 | }; |
| 271 | 272 | ||
| 273 | static const struct of_device_id wm8728_of_match[] = { | ||
| 274 | { .compatible = "wlf,wm8728", }, | ||
| 275 | { } | ||
| 276 | }; | ||
| 277 | MODULE_DEVICE_TABLE(of, wm8728_of_match); | ||
| 278 | |||
| 272 | #if defined(CONFIG_SPI_MASTER) | 279 | #if defined(CONFIG_SPI_MASTER) |
| 273 | static int __devinit wm8728_spi_probe(struct spi_device *spi) | 280 | static int __devinit wm8728_spi_probe(struct spi_device *spi) |
| 274 | { | 281 | { |
| @@ -298,8 +305,9 @@ static int __devexit wm8728_spi_remove(struct spi_device *spi) | |||
| 298 | 305 | ||
| 299 | static struct spi_driver wm8728_spi_driver = { | 306 | static struct spi_driver wm8728_spi_driver = { |
| 300 | .driver = { | 307 | .driver = { |
| 301 | .name = "wm8728-codec", | 308 | .name = "wm8728", |
| 302 | .owner = THIS_MODULE, | 309 | .owner = THIS_MODULE, |
| 310 | .of_match_table = wm8728_of_match, | ||
| 303 | }, | 311 | }, |
| 304 | .probe = wm8728_spi_probe, | 312 | .probe = wm8728_spi_probe, |
| 305 | .remove = __devexit_p(wm8728_spi_remove), | 313 | .remove = __devexit_p(wm8728_spi_remove), |
| @@ -342,8 +350,9 @@ MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id); | |||
| 342 | 350 | ||
| 343 | static struct i2c_driver wm8728_i2c_driver = { | 351 | static struct i2c_driver wm8728_i2c_driver = { |
| 344 | .driver = { | 352 | .driver = { |
| 345 | .name = "wm8728-codec", | 353 | .name = "wm8728", |
| 346 | .owner = THIS_MODULE, | 354 | .owner = THIS_MODULE, |
| 355 | .of_match_table = wm8728_of_match, | ||
| 347 | }, | 356 | }, |
| 348 | .probe = wm8728_i2c_probe, | 357 | .probe = wm8728_i2c_probe, |
| 349 | .remove = __devexit_p(wm8728_i2c_remove), | 358 | .remove = __devexit_p(wm8728_i2c_remove), |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 76b4361e9b80..7e5ec03f6f8d 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
| 24 | #include <linux/spi/spi.h> | 24 | #include <linux/spi/spi.h> |
| 25 | #include <linux/of_device.h> | ||
| 25 | #include <sound/core.h> | 26 | #include <sound/core.h> |
| 26 | #include <sound/pcm.h> | 27 | #include <sound/pcm.h> |
| 27 | #include <sound/pcm_params.h> | 28 | #include <sound/pcm_params.h> |
| @@ -426,9 +427,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
| 426 | enum snd_soc_bias_level level) | 427 | enum snd_soc_bias_level level) |
| 427 | { | 428 | { |
| 428 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 429 | struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 429 | int i, ret; | 430 | int ret; |
| 430 | u8 data[2]; | ||
| 431 | u16 *cache = codec->reg_cache; | ||
| 432 | u16 reg; | 431 | u16 reg; |
| 433 | 432 | ||
| 434 | switch (level) { | 433 | switch (level) { |
| @@ -443,16 +442,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
| 443 | if (ret != 0) | 442 | if (ret != 0) |
| 444 | return ret; | 443 | return ret; |
| 445 | 444 | ||
| 446 | /* Sync reg_cache with the hardware */ | 445 | snd_soc_cache_sync(codec); |
| 447 | for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { | ||
| 448 | if (cache[i] == wm8731_reg[i]) | ||
| 449 | continue; | ||
| 450 | |||
| 451 | data[0] = (i << 1) | ((cache[i] >> 8) | ||
| 452 | & 0x0001); | ||
| 453 | data[1] = cache[i] & 0x00ff; | ||
| 454 | codec->hw_write(codec->control_data, data, 2); | ||
| 455 | } | ||
| 456 | } | 446 | } |
| 457 | 447 | ||
| 458 | /* Clear PWROFF, gate CLKOUT, everything else as-is */ | 448 | /* Clear PWROFF, gate CLKOUT, everything else as-is */ |
| @@ -607,6 +597,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8731 = { | |||
| 607 | .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), | 597 | .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), |
| 608 | }; | 598 | }; |
| 609 | 599 | ||
| 600 | static const struct of_device_id wm8731_of_match[] = { | ||
| 601 | { .compatible = "wlf,wm8731", }, | ||
| 602 | { } | ||
| 603 | }; | ||
| 604 | |||
| 605 | MODULE_DEVICE_TABLE(of, wm8731_of_match); | ||
| 606 | |||
| 610 | #if defined(CONFIG_SPI_MASTER) | 607 | #if defined(CONFIG_SPI_MASTER) |
| 611 | static int __devinit wm8731_spi_probe(struct spi_device *spi) | 608 | static int __devinit wm8731_spi_probe(struct spi_device *spi) |
| 612 | { | 609 | { |
| @@ -638,6 +635,7 @@ static struct spi_driver wm8731_spi_driver = { | |||
| 638 | .driver = { | 635 | .driver = { |
| 639 | .name = "wm8731", | 636 | .name = "wm8731", |
| 640 | .owner = THIS_MODULE, | 637 | .owner = THIS_MODULE, |
| 638 | .of_match_table = wm8731_of_match, | ||
| 641 | }, | 639 | }, |
| 642 | .probe = wm8731_spi_probe, | 640 | .probe = wm8731_spi_probe, |
| 643 | .remove = __devexit_p(wm8731_spi_remove), | 641 | .remove = __devexit_p(wm8731_spi_remove), |
| @@ -682,6 +680,7 @@ static struct i2c_driver wm8731_i2c_driver = { | |||
| 682 | .driver = { | 680 | .driver = { |
| 683 | .name = "wm8731", | 681 | .name = "wm8731", |
| 684 | .owner = THIS_MODULE, | 682 | .owner = THIS_MODULE, |
| 683 | .of_match_table = wm8731_of_match, | ||
| 685 | }, | 684 | }, |
| 686 | .probe = wm8731_i2c_probe, | 685 | .probe = wm8731_i2c_probe, |
| 687 | .remove = __devexit_p(wm8731_i2c_remove), | 686 | .remove = __devexit_p(wm8731_i2c_remove), |
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 30c67d06a904..f6aef58845c2 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/regulator/consumer.h> | 20 | #include <linux/regulator/consumer.h> |
| 21 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 23 | #include <linux/of_device.h> | ||
| 23 | #include <sound/core.h> | 24 | #include <sound/core.h> |
| 24 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
| 25 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
| @@ -634,6 +635,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { | |||
| 634 | .reg_cache_default = wm8737_reg, | 635 | .reg_cache_default = wm8737_reg, |
| 635 | }; | 636 | }; |
| 636 | 637 | ||
| 638 | static const struct of_device_id wm8737_of_match[] = { | ||
| 639 | { .compatible = "wlf,wm8737", }, | ||
| 640 | { } | ||
| 641 | }; | ||
| 642 | |||
| 643 | MODULE_DEVICE_TABLE(of, wm8737_of_match); | ||
| 644 | |||
| 637 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 645 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 638 | static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, | 646 | static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, |
| 639 | const struct i2c_device_id *id) | 647 | const struct i2c_device_id *id) |
| @@ -673,6 +681,7 @@ static struct i2c_driver wm8737_i2c_driver = { | |||
| 673 | .driver = { | 681 | .driver = { |
| 674 | .name = "wm8737", | 682 | .name = "wm8737", |
| 675 | .owner = THIS_MODULE, | 683 | .owner = THIS_MODULE, |
| 684 | .of_match_table = wm8737_of_match, | ||
| 676 | }, | 685 | }, |
| 677 | .probe = wm8737_i2c_probe, | 686 | .probe = wm8737_i2c_probe, |
| 678 | .remove = __devexit_p(wm8737_i2c_remove), | 687 | .remove = __devexit_p(wm8737_i2c_remove), |
| @@ -711,6 +720,7 @@ static struct spi_driver wm8737_spi_driver = { | |||
| 711 | .driver = { | 720 | .driver = { |
| 712 | .name = "wm8737", | 721 | .name = "wm8737", |
| 713 | .owner = THIS_MODULE, | 722 | .owner = THIS_MODULE, |
| 723 | .of_match_table = wm8737_of_match, | ||
| 714 | }, | 724 | }, |
| 715 | .probe = wm8737_spi_probe, | 725 | .probe = wm8737_spi_probe, |
| 716 | .remove = __devexit_p(wm8737_spi_remove), | 726 | .remove = __devexit_p(wm8737_spi_remove), |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 25af901fe813..57ad22aacc51 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
| @@ -17,9 +17,11 @@ | |||
| 17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
| 18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
| 19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
| 20 | #include <linux/spi/spi.h> | ||
| 20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 21 | #include <linux/regulator/consumer.h> | 22 | #include <linux/regulator/consumer.h> |
| 22 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/of_device.h> | ||
| 23 | #include <sound/core.h> | 25 | #include <sound/core.h> |
| 24 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
| 25 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
| @@ -337,10 +339,10 @@ static int wm8741_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
| 337 | iface |= 0x0004; | 339 | iface |= 0x0004; |
| 338 | break; | 340 | break; |
| 339 | case SND_SOC_DAIFMT_DSP_A: | 341 | case SND_SOC_DAIFMT_DSP_A: |
| 340 | iface |= 0x0003; | 342 | iface |= 0x000C; |
| 341 | break; | 343 | break; |
| 342 | case SND_SOC_DAIFMT_DSP_B: | 344 | case SND_SOC_DAIFMT_DSP_B: |
| 343 | iface |= 0x0013; | 345 | iface |= 0x001C; |
| 344 | break; | 346 | break; |
| 345 | default: | 347 | default: |
| 346 | return -EINVAL; | 348 | return -EINVAL; |
| @@ -402,15 +404,7 @@ static struct snd_soc_dai_driver wm8741_dai = { | |||
| 402 | #ifdef CONFIG_PM | 404 | #ifdef CONFIG_PM |
| 403 | static int wm8741_resume(struct snd_soc_codec *codec) | 405 | static int wm8741_resume(struct snd_soc_codec *codec) |
| 404 | { | 406 | { |
| 405 | u16 *cache = codec->reg_cache; | 407 | snd_soc_cache_sync(codec); |
| 406 | int i; | ||
| 407 | |||
| 408 | /* RESTORE REG Cache */ | ||
| 409 | for (i = 0; i < WM8741_REGISTER_COUNT; i++) { | ||
| 410 | if (cache[i] == wm8741_reg_defaults[i] || WM8741_RESET == i) | ||
| 411 | continue; | ||
| 412 | snd_soc_write(codec, i, cache[i]); | ||
| 413 | } | ||
| 414 | return 0; | 408 | return 0; |
| 415 | } | 409 | } |
| 416 | #else | 410 | #else |
| @@ -422,17 +416,35 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
| 422 | { | 416 | { |
| 423 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | 417 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); |
| 424 | int ret = 0; | 418 | int ret = 0; |
| 419 | int i; | ||
| 420 | |||
| 421 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) | ||
| 422 | wm8741->supplies[i].supply = wm8741_supply_names[i]; | ||
| 423 | |||
| 424 | ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8741->supplies), | ||
| 425 | wm8741->supplies); | ||
| 426 | if (ret != 0) { | ||
| 427 | dev_err(codec->dev, "Failed to request supplies: %d\n", ret); | ||
| 428 | goto err; | ||
| 429 | } | ||
| 430 | |||
| 431 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), | ||
| 432 | wm8741->supplies); | ||
| 433 | if (ret != 0) { | ||
| 434 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | ||
| 435 | goto err_get; | ||
| 436 | } | ||
| 425 | 437 | ||
| 426 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); | 438 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); |
| 427 | if (ret != 0) { | 439 | if (ret != 0) { |
| 428 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 440 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| 429 | return ret; | 441 | goto err_enable; |
| 430 | } | 442 | } |
| 431 | 443 | ||
| 432 | ret = wm8741_reset(codec); | 444 | ret = wm8741_reset(codec); |
| 433 | if (ret < 0) { | 445 | if (ret < 0) { |
| 434 | dev_err(codec->dev, "Failed to issue reset\n"); | 446 | dev_err(codec->dev, "Failed to issue reset\n"); |
| 435 | return ret; | 447 | goto err_enable; |
| 436 | } | 448 | } |
| 437 | 449 | ||
| 438 | /* Change some default settings - latch VU */ | 450 | /* Change some default settings - latch VU */ |
| @@ -442,7 +454,7 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
| 442 | WM8741_UPDATELM, WM8741_UPDATELM); | 454 | WM8741_UPDATELM, WM8741_UPDATELM); |
| 443 | snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, | 455 | snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, |
| 444 | WM8741_UPDATERL, WM8741_UPDATERL); | 456 | WM8741_UPDATERL, WM8741_UPDATERL); |
| 445 | snd_soc_update_bits(codec, WM8741_DACRLSB_ATTENUATION, | 457 | snd_soc_update_bits(codec, WM8741_DACRMSB_ATTENUATION, |
| 446 | WM8741_UPDATERM, WM8741_UPDATERM); | 458 | WM8741_UPDATERM, WM8741_UPDATERM); |
| 447 | 459 | ||
| 448 | snd_soc_add_controls(codec, wm8741_snd_controls, | 460 | snd_soc_add_controls(codec, wm8741_snd_controls, |
| @@ -451,58 +463,61 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
| 451 | 463 | ||
| 452 | dev_dbg(codec->dev, "Successful registration\n"); | 464 | dev_dbg(codec->dev, "Successful registration\n"); |
| 453 | return ret; | 465 | return ret; |
| 466 | |||
| 467 | err_enable: | ||
| 468 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 469 | err_get: | ||
| 470 | regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 471 | err: | ||
| 472 | return ret; | ||
| 473 | } | ||
| 474 | |||
| 475 | static int wm8741_remove(struct snd_soc_codec *codec) | ||
| 476 | { | ||
| 477 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | ||
| 478 | |||
| 479 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 480 | regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 481 | |||
| 482 | return 0; | ||
| 454 | } | 483 | } |
| 455 | 484 | ||
| 456 | static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { | 485 | static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { |
| 457 | .probe = wm8741_probe, | 486 | .probe = wm8741_probe, |
| 487 | .remove = wm8741_remove, | ||
| 458 | .resume = wm8741_resume, | 488 | .resume = wm8741_resume, |
| 459 | .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), | 489 | .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), |
| 460 | .reg_word_size = sizeof(u16), | 490 | .reg_word_size = sizeof(u16), |
| 461 | .reg_cache_default = wm8741_reg_defaults, | 491 | .reg_cache_default = wm8741_reg_defaults, |
| 462 | }; | 492 | }; |
| 463 | 493 | ||
| 494 | static const struct of_device_id wm8741_of_match[] = { | ||
| 495 | { .compatible = "wlf,wm8741", }, | ||
| 496 | { } | ||
| 497 | }; | ||
| 498 | MODULE_DEVICE_TABLE(of, wm8741_of_match); | ||
| 499 | |||
| 464 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 500 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 465 | static int wm8741_i2c_probe(struct i2c_client *i2c, | 501 | static int wm8741_i2c_probe(struct i2c_client *i2c, |
| 466 | const struct i2c_device_id *id) | 502 | const struct i2c_device_id *id) |
| 467 | { | 503 | { |
| 468 | struct wm8741_priv *wm8741; | 504 | struct wm8741_priv *wm8741; |
| 469 | int ret, i; | 505 | int ret; |
| 470 | 506 | ||
| 471 | wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); | 507 | wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); |
| 472 | if (wm8741 == NULL) | 508 | if (wm8741 == NULL) |
| 473 | return -ENOMEM; | 509 | return -ENOMEM; |
| 474 | 510 | ||
| 475 | for (i = 0; i < ARRAY_SIZE(wm8741->supplies); i++) | ||
| 476 | wm8741->supplies[i].supply = wm8741_supply_names[i]; | ||
| 477 | |||
| 478 | ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8741->supplies), | ||
| 479 | wm8741->supplies); | ||
| 480 | if (ret != 0) { | ||
| 481 | dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret); | ||
| 482 | goto err; | ||
| 483 | } | ||
| 484 | |||
| 485 | ret = regulator_bulk_enable(ARRAY_SIZE(wm8741->supplies), | ||
| 486 | wm8741->supplies); | ||
| 487 | if (ret != 0) { | ||
| 488 | dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret); | ||
| 489 | goto err_get; | ||
| 490 | } | ||
| 491 | |||
| 492 | i2c_set_clientdata(i2c, wm8741); | 511 | i2c_set_clientdata(i2c, wm8741); |
| 493 | wm8741->control_type = SND_SOC_I2C; | 512 | wm8741->control_type = SND_SOC_I2C; |
| 494 | 513 | ||
| 495 | ret = snd_soc_register_codec(&i2c->dev, | 514 | ret = snd_soc_register_codec(&i2c->dev, |
| 496 | &soc_codec_dev_wm8741, &wm8741_dai, 1); | 515 | &soc_codec_dev_wm8741, &wm8741_dai, 1); |
| 497 | if (ret < 0) | 516 | if (ret != 0) |
| 498 | goto err_enable; | 517 | goto err; |
| 499 | return ret; | ||
| 500 | 518 | ||
| 501 | err_enable: | 519 | return ret; |
| 502 | regulator_bulk_disable(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 503 | 520 | ||
| 504 | err_get: | ||
| 505 | regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 506 | err: | 521 | err: |
| 507 | kfree(wm8741); | 522 | kfree(wm8741); |
| 508 | return ret; | 523 | return ret; |
| @@ -510,10 +525,7 @@ err: | |||
| 510 | 525 | ||
| 511 | static int wm8741_i2c_remove(struct i2c_client *client) | 526 | static int wm8741_i2c_remove(struct i2c_client *client) |
| 512 | { | 527 | { |
| 513 | struct wm8741_priv *wm8741 = i2c_get_clientdata(client); | ||
| 514 | |||
| 515 | snd_soc_unregister_codec(&client->dev); | 528 | snd_soc_unregister_codec(&client->dev); |
| 516 | regulator_bulk_free(ARRAY_SIZE(wm8741->supplies), wm8741->supplies); | ||
| 517 | kfree(i2c_get_clientdata(client)); | 529 | kfree(i2c_get_clientdata(client)); |
| 518 | return 0; | 530 | return 0; |
| 519 | } | 531 | } |
| @@ -526,8 +538,9 @@ MODULE_DEVICE_TABLE(i2c, wm8741_i2c_id); | |||
| 526 | 538 | ||
| 527 | static struct i2c_driver wm8741_i2c_driver = { | 539 | static struct i2c_driver wm8741_i2c_driver = { |
| 528 | .driver = { | 540 | .driver = { |
| 529 | .name = "wm8741-codec", | 541 | .name = "wm8741", |
| 530 | .owner = THIS_MODULE, | 542 | .owner = THIS_MODULE, |
| 543 | .of_match_table = wm8741_of_match, | ||
| 531 | }, | 544 | }, |
| 532 | .probe = wm8741_i2c_probe, | 545 | .probe = wm8741_i2c_probe, |
| 533 | .remove = wm8741_i2c_remove, | 546 | .remove = wm8741_i2c_remove, |
| @@ -535,6 +548,44 @@ static struct i2c_driver wm8741_i2c_driver = { | |||
| 535 | }; | 548 | }; |
| 536 | #endif | 549 | #endif |
| 537 | 550 | ||
| 551 | #if defined(CONFIG_SPI_MASTER) | ||
| 552 | static int __devinit wm8741_spi_probe(struct spi_device *spi) | ||
| 553 | { | ||
| 554 | struct wm8741_priv *wm8741; | ||
| 555 | int ret; | ||
| 556 | |||
| 557 | wm8741 = kzalloc(sizeof(struct wm8741_priv), GFP_KERNEL); | ||
| 558 | if (wm8741 == NULL) | ||
| 559 | return -ENOMEM; | ||
| 560 | |||
| 561 | wm8741->control_type = SND_SOC_SPI; | ||
| 562 | spi_set_drvdata(spi, wm8741); | ||
| 563 | |||
| 564 | ret = snd_soc_register_codec(&spi->dev, | ||
| 565 | &soc_codec_dev_wm8741, &wm8741_dai, 1); | ||
| 566 | if (ret < 0) | ||
| 567 | kfree(wm8741); | ||
| 568 | return ret; | ||
| 569 | } | ||
| 570 | |||
| 571 | static int __devexit wm8741_spi_remove(struct spi_device *spi) | ||
| 572 | { | ||
| 573 | snd_soc_unregister_codec(&spi->dev); | ||
| 574 | kfree(spi_get_drvdata(spi)); | ||
| 575 | return 0; | ||
| 576 | } | ||
| 577 | |||
| 578 | static struct spi_driver wm8741_spi_driver = { | ||
| 579 | .driver = { | ||
| 580 | .name = "wm8741", | ||
| 581 | .owner = THIS_MODULE, | ||
| 582 | .of_match_table = wm8741_of_match, | ||
| 583 | }, | ||
| 584 | .probe = wm8741_spi_probe, | ||
| 585 | .remove = __devexit_p(wm8741_spi_remove), | ||
| 586 | }; | ||
| 587 | #endif /* CONFIG_SPI_MASTER */ | ||
| 588 | |||
| 538 | static int __init wm8741_modinit(void) | 589 | static int __init wm8741_modinit(void) |
| 539 | { | 590 | { |
| 540 | int ret = 0; | 591 | int ret = 0; |
| @@ -544,6 +595,13 @@ static int __init wm8741_modinit(void) | |||
| 544 | if (ret != 0) | 595 | if (ret != 0) |
| 545 | pr_err("Failed to register WM8741 I2C driver: %d\n", ret); | 596 | pr_err("Failed to register WM8741 I2C driver: %d\n", ret); |
| 546 | #endif | 597 | #endif |
| 598 | #if defined(CONFIG_SPI_MASTER) | ||
| 599 | ret = spi_register_driver(&wm8741_spi_driver); | ||
| 600 | if (ret != 0) { | ||
| 601 | printk(KERN_ERR "Failed to register wm8741 SPI driver: %d\n", | ||
| 602 | ret); | ||
| 603 | } | ||
| 604 | #endif | ||
| 547 | 605 | ||
| 548 | return ret; | 606 | return ret; |
| 549 | } | 607 | } |
| @@ -551,6 +609,9 @@ module_init(wm8741_modinit); | |||
| 551 | 609 | ||
| 552 | static void __exit wm8741_exit(void) | 610 | static void __exit wm8741_exit(void) |
| 553 | { | 611 | { |
| 612 | #if defined(CONFIG_SPI_MASTER) | ||
| 613 | spi_unregister_driver(&wm8741_spi_driver); | ||
| 614 | #endif | ||
| 554 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 615 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 555 | i2c_del_driver(&wm8741_i2c_driver); | 616 | i2c_del_driver(&wm8741_i2c_driver); |
| 556 | #endif | 617 | #endif |
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index d0003cc3bcd6..ca75a8180708 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
| 22 | #include <linux/spi/spi.h> | 22 | #include <linux/spi/spi.h> |
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/of_device.h> | ||
| 24 | #include <sound/core.h> | 25 | #include <sound/core.h> |
| 25 | #include <sound/pcm.h> | 26 | #include <sound/pcm.h> |
| 26 | #include <sound/pcm_params.h> | 27 | #include <sound/pcm_params.h> |
| @@ -615,6 +616,8 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, | |||
| 615 | break; | 616 | break; |
| 616 | case SND_SOC_BIAS_STANDBY: | 617 | case SND_SOC_BIAS_STANDBY: |
| 617 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 618 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 619 | snd_soc_cache_sync(codec); | ||
| 620 | |||
| 618 | /* Set VMID to 5k */ | 621 | /* Set VMID to 5k */ |
| 619 | snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); | 622 | snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); |
| 620 | 623 | ||
| @@ -672,28 +675,14 @@ static int wm8750_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 672 | 675 | ||
| 673 | static int wm8750_resume(struct snd_soc_codec *codec) | 676 | static int wm8750_resume(struct snd_soc_codec *codec) |
| 674 | { | 677 | { |
| 675 | int i; | ||
| 676 | u8 data[2]; | ||
| 677 | u16 *cache = codec->reg_cache; | ||
| 678 | |||
| 679 | /* Sync reg_cache with the hardware */ | ||
| 680 | for (i = 0; i < ARRAY_SIZE(wm8750_reg); i++) { | ||
| 681 | if (i == WM8750_RESET) | ||
| 682 | continue; | ||
| 683 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 684 | data[1] = cache[i] & 0x00ff; | ||
| 685 | codec->hw_write(codec->control_data, data, 2); | ||
| 686 | } | ||
| 687 | |||
| 688 | wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 678 | wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 689 | |||
| 690 | return 0; | 679 | return 0; |
| 691 | } | 680 | } |
| 692 | 681 | ||
| 693 | static int wm8750_probe(struct snd_soc_codec *codec) | 682 | static int wm8750_probe(struct snd_soc_codec *codec) |
| 694 | { | 683 | { |
| 695 | struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); | 684 | struct wm8750_priv *wm8750 = snd_soc_codec_get_drvdata(codec); |
| 696 | int reg, ret; | 685 | int ret; |
| 697 | 686 | ||
| 698 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); | 687 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8750->control_type); |
| 699 | if (ret < 0) { | 688 | if (ret < 0) { |
| @@ -711,22 +700,14 @@ static int wm8750_probe(struct snd_soc_codec *codec) | |||
| 711 | wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 700 | wm8750_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 712 | 701 | ||
| 713 | /* set the update bits */ | 702 | /* set the update bits */ |
| 714 | reg = snd_soc_read(codec, WM8750_LDAC); | 703 | snd_soc_update_bits(codec, WM8750_LDAC, 0x0100, 0x0100); |
| 715 | snd_soc_write(codec, WM8750_LDAC, reg | 0x0100); | 704 | snd_soc_update_bits(codec, WM8750_RDAC, 0x0100, 0x0100); |
| 716 | reg = snd_soc_read(codec, WM8750_RDAC); | 705 | snd_soc_update_bits(codec, WM8750_LOUT1V, 0x0100, 0x0100); |
| 717 | snd_soc_write(codec, WM8750_RDAC, reg | 0x0100); | 706 | snd_soc_update_bits(codec, WM8750_ROUT1V, 0x0100, 0x0100); |
| 718 | reg = snd_soc_read(codec, WM8750_LOUT1V); | 707 | snd_soc_update_bits(codec, WM8750_LOUT2V, 0x0100, 0x0100); |
| 719 | snd_soc_write(codec, WM8750_LOUT1V, reg | 0x0100); | 708 | snd_soc_update_bits(codec, WM8750_ROUT2V, 0x0100, 0x0100); |
| 720 | reg = snd_soc_read(codec, WM8750_ROUT1V); | 709 | snd_soc_update_bits(codec, WM8750_LINVOL, 0x0100, 0x0100); |
| 721 | snd_soc_write(codec, WM8750_ROUT1V, reg | 0x0100); | 710 | snd_soc_update_bits(codec, WM8750_RINVOL, 0x0100, 0x0100); |
| 722 | reg = snd_soc_read(codec, WM8750_LOUT2V); | ||
| 723 | snd_soc_write(codec, WM8750_LOUT2V, reg | 0x0100); | ||
| 724 | reg = snd_soc_read(codec, WM8750_ROUT2V); | ||
| 725 | snd_soc_write(codec, WM8750_ROUT2V, reg | 0x0100); | ||
| 726 | reg = snd_soc_read(codec, WM8750_LINVOL); | ||
| 727 | snd_soc_write(codec, WM8750_LINVOL, reg | 0x0100); | ||
| 728 | reg = snd_soc_read(codec, WM8750_RINVOL); | ||
| 729 | snd_soc_write(codec, WM8750_RINVOL, reg | 0x0100); | ||
| 730 | 711 | ||
| 731 | snd_soc_add_controls(codec, wm8750_snd_controls, | 712 | snd_soc_add_controls(codec, wm8750_snd_controls, |
| 732 | ARRAY_SIZE(wm8750_snd_controls)); | 713 | ARRAY_SIZE(wm8750_snd_controls)); |
| @@ -751,6 +732,13 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8750 = { | |||
| 751 | .reg_cache_default = wm8750_reg, | 732 | .reg_cache_default = wm8750_reg, |
| 752 | }; | 733 | }; |
| 753 | 734 | ||
| 735 | static const struct of_device_id wm8750_of_match[] = { | ||
| 736 | { .compatible = "wlf,wm8750", }, | ||
| 737 | { .compatible = "wlf,wm8987", }, | ||
| 738 | { } | ||
| 739 | }; | ||
| 740 | MODULE_DEVICE_TABLE(of, wm8750_of_match); | ||
| 741 | |||
| 754 | #if defined(CONFIG_SPI_MASTER) | 742 | #if defined(CONFIG_SPI_MASTER) |
| 755 | static int __devinit wm8750_spi_probe(struct spi_device *spi) | 743 | static int __devinit wm8750_spi_probe(struct spi_device *spi) |
| 756 | { | 744 | { |
| @@ -787,8 +775,9 @@ MODULE_DEVICE_TABLE(spi, wm8750_spi_ids); | |||
| 787 | 775 | ||
| 788 | static struct spi_driver wm8750_spi_driver = { | 776 | static struct spi_driver wm8750_spi_driver = { |
| 789 | .driver = { | 777 | .driver = { |
| 790 | .name = "wm8750-codec", | 778 | .name = "wm8750", |
| 791 | .owner = THIS_MODULE, | 779 | .owner = THIS_MODULE, |
| 780 | .of_match_table = wm8750_of_match, | ||
| 792 | }, | 781 | }, |
| 793 | .id_table = wm8750_spi_ids, | 782 | .id_table = wm8750_spi_ids, |
| 794 | .probe = wm8750_spi_probe, | 783 | .probe = wm8750_spi_probe, |
| @@ -833,8 +822,9 @@ MODULE_DEVICE_TABLE(i2c, wm8750_i2c_id); | |||
| 833 | 822 | ||
| 834 | static struct i2c_driver wm8750_i2c_driver = { | 823 | static struct i2c_driver wm8750_i2c_driver = { |
| 835 | .driver = { | 824 | .driver = { |
| 836 | .name = "wm8750-codec", | 825 | .name = "wm8750", |
| 837 | .owner = THIS_MODULE, | 826 | .owner = THIS_MODULE, |
| 827 | .of_match_table = wm8750_of_match, | ||
| 838 | }, | 828 | }, |
| 839 | .probe = wm8750_i2c_probe, | 829 | .probe = wm8750_i2c_probe, |
| 840 | .remove = __devexit_p(wm8750_i2c_remove), | 830 | .remove = __devexit_p(wm8750_i2c_remove), |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index aa091a0d8187..a9504710bb69 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/delay.h> | 38 | #include <linux/delay.h> |
| 39 | #include <linux/pm.h> | 39 | #include <linux/pm.h> |
| 40 | #include <linux/i2c.h> | 40 | #include <linux/i2c.h> |
| 41 | #include <linux/of_device.h> | ||
| 41 | #include <linux/platform_device.h> | 42 | #include <linux/platform_device.h> |
| 42 | #include <linux/spi/spi.h> | 43 | #include <linux/spi/spi.h> |
| 43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
| @@ -1490,6 +1491,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8753 = { | |||
| 1490 | .reg_cache_default = wm8753_reg, | 1491 | .reg_cache_default = wm8753_reg, |
| 1491 | }; | 1492 | }; |
| 1492 | 1493 | ||
| 1494 | static const struct of_device_id wm8753_of_match[] = { | ||
| 1495 | { .compatible = "wlf,wm8753", }, | ||
| 1496 | { } | ||
| 1497 | }; | ||
| 1498 | MODULE_DEVICE_TABLE(of, wm8753_of_match); | ||
| 1499 | |||
| 1493 | #if defined(CONFIG_SPI_MASTER) | 1500 | #if defined(CONFIG_SPI_MASTER) |
| 1494 | static int __devinit wm8753_spi_probe(struct spi_device *spi) | 1501 | static int __devinit wm8753_spi_probe(struct spi_device *spi) |
| 1495 | { | 1502 | { |
| @@ -1519,8 +1526,9 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi) | |||
| 1519 | 1526 | ||
| 1520 | static struct spi_driver wm8753_spi_driver = { | 1527 | static struct spi_driver wm8753_spi_driver = { |
| 1521 | .driver = { | 1528 | .driver = { |
| 1522 | .name = "wm8753-codec", | 1529 | .name = "wm8753", |
| 1523 | .owner = THIS_MODULE, | 1530 | .owner = THIS_MODULE, |
| 1531 | .of_match_table = wm8753_of_match, | ||
| 1524 | }, | 1532 | }, |
| 1525 | .probe = wm8753_spi_probe, | 1533 | .probe = wm8753_spi_probe, |
| 1526 | .remove = __devexit_p(wm8753_spi_remove), | 1534 | .remove = __devexit_p(wm8753_spi_remove), |
| @@ -1563,8 +1571,9 @@ MODULE_DEVICE_TABLE(i2c, wm8753_i2c_id); | |||
| 1563 | 1571 | ||
| 1564 | static struct i2c_driver wm8753_i2c_driver = { | 1572 | static struct i2c_driver wm8753_i2c_driver = { |
| 1565 | .driver = { | 1573 | .driver = { |
| 1566 | .name = "wm8753-codec", | 1574 | .name = "wm8753", |
| 1567 | .owner = THIS_MODULE, | 1575 | .owner = THIS_MODULE, |
| 1576 | .of_match_table = wm8753_of_match, | ||
| 1568 | }, | 1577 | }, |
| 1569 | .probe = wm8753_i2c_probe, | 1578 | .probe = wm8753_i2c_probe, |
| 1570 | .remove = __devexit_p(wm8753_i2c_remove), | 1579 | .remove = __devexit_p(wm8753_i2c_remove), |
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 19b92baa9e8c..aa05e6507f84 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/moduleparam.h> | 14 | #include <linux/moduleparam.h> |
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
| 17 | #include <linux/of_device.h> | ||
| 17 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
| 18 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
| @@ -684,6 +685,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { | |||
| 684 | .reg_cache_default = wm8770_reg_defs | 685 | .reg_cache_default = wm8770_reg_defs |
| 685 | }; | 686 | }; |
| 686 | 687 | ||
| 688 | static const struct of_device_id wm8770_of_match[] = { | ||
| 689 | { .compatible = "wlf,wm8770", }, | ||
| 690 | { } | ||
| 691 | }; | ||
| 692 | MODULE_DEVICE_TABLE(of, wm8770_of_match); | ||
| 693 | |||
| 687 | #if defined(CONFIG_SPI_MASTER) | 694 | #if defined(CONFIG_SPI_MASTER) |
| 688 | static int __devinit wm8770_spi_probe(struct spi_device *spi) | 695 | static int __devinit wm8770_spi_probe(struct spi_device *spi) |
| 689 | { | 696 | { |
| @@ -715,6 +722,7 @@ static struct spi_driver wm8770_spi_driver = { | |||
| 715 | .driver = { | 722 | .driver = { |
| 716 | .name = "wm8770", | 723 | .name = "wm8770", |
| 717 | .owner = THIS_MODULE, | 724 | .owner = THIS_MODULE, |
| 725 | .of_match_table = wm8770_of_match, | ||
| 718 | }, | 726 | }, |
| 719 | .probe = wm8770_spi_probe, | 727 | .probe = wm8770_spi_probe, |
| 720 | .remove = __devexit_p(wm8770_spi_remove) | 728 | .remove = __devexit_p(wm8770_spi_remove) |
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 8e7953b1b790..bfdc52370ad0 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
| 19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
| 20 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
| 21 | #include <linux/of_device.h> | ||
| 21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 22 | #include <linux/spi/spi.h> | 23 | #include <linux/spi/spi.h> |
| 23 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| @@ -215,8 +216,6 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream, | |||
| 215 | int ratio_shift, master; | 216 | int ratio_shift, master; |
| 216 | int i; | 217 | int i; |
| 217 | 218 | ||
| 218 | iface = 0; | ||
| 219 | |||
| 220 | switch (dai->driver->id) { | 219 | switch (dai->driver->id) { |
| 221 | case WM8776_DAI_DAC: | 220 | case WM8776_DAI_DAC: |
| 222 | iface_reg = WM8776_DACIFCTRL; | 221 | iface_reg = WM8776_DACIFCTRL; |
| @@ -232,20 +231,23 @@ static int wm8776_hw_params(struct snd_pcm_substream *substream, | |||
| 232 | return -EINVAL; | 231 | return -EINVAL; |
| 233 | } | 232 | } |
| 234 | 233 | ||
| 235 | |||
| 236 | /* Set word length */ | 234 | /* Set word length */ |
| 237 | switch (params_format(params)) { | 235 | switch (snd_pcm_format_width(params_format(params))) { |
| 238 | case SNDRV_PCM_FORMAT_S16_LE: | 236 | case 16: |
| 239 | break; | 237 | iface = 0; |
| 240 | case SNDRV_PCM_FORMAT_S20_3LE: | 238 | case 20: |
| 241 | iface |= 0x10; | 239 | iface = 0x10; |
| 242 | break; | 240 | break; |
| 243 | case SNDRV_PCM_FORMAT_S24_LE: | 241 | case 24: |
| 244 | iface |= 0x20; | 242 | iface = 0x20; |
| 245 | break; | 243 | break; |
| 246 | case SNDRV_PCM_FORMAT_S32_LE: | 244 | case 32: |
| 247 | iface |= 0x30; | 245 | iface = 0x30; |
| 248 | break; | 246 | break; |
| 247 | default: | ||
| 248 | dev_err(codec->dev, "Unsupported sample size: %i\n", | ||
| 249 | snd_pcm_format_width(params_format(params))); | ||
| 250 | return -EINVAL; | ||
| 249 | } | 251 | } |
| 250 | 252 | ||
| 251 | /* Only need to set MCLK/LRCLK ratio if we're master */ | 253 | /* Only need to set MCLK/LRCLK ratio if we're master */ |
| @@ -306,6 +308,8 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, | |||
| 306 | break; | 308 | break; |
| 307 | case SND_SOC_BIAS_STANDBY: | 309 | case SND_SOC_BIAS_STANDBY: |
| 308 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 310 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 311 | snd_soc_cache_sync(codec); | ||
| 312 | |||
| 309 | /* Disable the global powerdown; DAPM does the rest */ | 313 | /* Disable the global powerdown; DAPM does the rest */ |
| 310 | snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); | 314 | snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); |
| 311 | } | 315 | } |
| @@ -320,11 +324,6 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, | |||
| 320 | return 0; | 324 | return 0; |
| 321 | } | 325 | } |
| 322 | 326 | ||
| 323 | #define WM8776_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\ | ||
| 324 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ | ||
| 325 | SNDRV_PCM_RATE_96000) | ||
| 326 | |||
| 327 | |||
| 328 | #define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 327 | #define WM8776_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 329 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | 328 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
| 330 | 329 | ||
| @@ -349,7 +348,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = { | |||
| 349 | .stream_name = "Playback", | 348 | .stream_name = "Playback", |
| 350 | .channels_min = 2, | 349 | .channels_min = 2, |
| 351 | .channels_max = 2, | 350 | .channels_max = 2, |
| 352 | .rates = WM8776_RATES, | 351 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
| 352 | .rate_min = 32000, | ||
| 353 | .rate_max = 192000, | ||
| 353 | .formats = WM8776_FORMATS, | 354 | .formats = WM8776_FORMATS, |
| 354 | }, | 355 | }, |
| 355 | .ops = &wm8776_dac_ops, | 356 | .ops = &wm8776_dac_ops, |
| @@ -361,7 +362,9 @@ static struct snd_soc_dai_driver wm8776_dai[] = { | |||
| 361 | .stream_name = "Capture", | 362 | .stream_name = "Capture", |
| 362 | .channels_min = 2, | 363 | .channels_min = 2, |
| 363 | .channels_max = 2, | 364 | .channels_max = 2, |
| 364 | .rates = WM8776_RATES, | 365 | .rates = SNDRV_PCM_RATE_CONTINUOUS, |
| 366 | .rate_min = 32000, | ||
| 367 | .rate_max = 96000, | ||
| 365 | .formats = WM8776_FORMATS, | 368 | .formats = WM8776_FORMATS, |
| 366 | }, | 369 | }, |
| 367 | .ops = &wm8776_adc_ops, | 370 | .ops = &wm8776_adc_ops, |
| @@ -378,21 +381,7 @@ static int wm8776_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 378 | 381 | ||
| 379 | static int wm8776_resume(struct snd_soc_codec *codec) | 382 | static int wm8776_resume(struct snd_soc_codec *codec) |
| 380 | { | 383 | { |
| 381 | int i; | ||
| 382 | u8 data[2]; | ||
| 383 | u16 *cache = codec->reg_cache; | ||
| 384 | |||
| 385 | /* Sync reg_cache with the hardware */ | ||
| 386 | for (i = 0; i < ARRAY_SIZE(wm8776_reg); i++) { | ||
| 387 | if (cache[i] == wm8776_reg[i]) | ||
| 388 | continue; | ||
| 389 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 390 | data[1] = cache[i] & 0x00ff; | ||
| 391 | codec->hw_write(codec->control_data, data, 2); | ||
| 392 | } | ||
| 393 | |||
| 394 | wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 384 | wm8776_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 395 | |||
| 396 | return 0; | 385 | return 0; |
| 397 | } | 386 | } |
| 398 | #else | 387 | #else |
| @@ -452,6 +441,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8776 = { | |||
| 452 | .reg_cache_default = wm8776_reg, | 441 | .reg_cache_default = wm8776_reg, |
| 453 | }; | 442 | }; |
| 454 | 443 | ||
| 444 | static const struct of_device_id wm8776_of_match[] = { | ||
| 445 | { .compatible = "wlf,wm8776", }, | ||
| 446 | { } | ||
| 447 | }; | ||
| 448 | MODULE_DEVICE_TABLE(of, wm8776_of_match); | ||
| 449 | |||
| 455 | #if defined(CONFIG_SPI_MASTER) | 450 | #if defined(CONFIG_SPI_MASTER) |
| 456 | static int __devinit wm8776_spi_probe(struct spi_device *spi) | 451 | static int __devinit wm8776_spi_probe(struct spi_device *spi) |
| 457 | { | 452 | { |
| @@ -481,8 +476,9 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi) | |||
| 481 | 476 | ||
| 482 | static struct spi_driver wm8776_spi_driver = { | 477 | static struct spi_driver wm8776_spi_driver = { |
| 483 | .driver = { | 478 | .driver = { |
| 484 | .name = "wm8776-codec", | 479 | .name = "wm8776", |
| 485 | .owner = THIS_MODULE, | 480 | .owner = THIS_MODULE, |
| 481 | .of_match_table = wm8776_of_match, | ||
| 486 | }, | 482 | }, |
| 487 | .probe = wm8776_spi_probe, | 483 | .probe = wm8776_spi_probe, |
| 488 | .remove = __devexit_p(wm8776_spi_remove), | 484 | .remove = __devexit_p(wm8776_spi_remove), |
| @@ -525,8 +521,9 @@ MODULE_DEVICE_TABLE(i2c, wm8776_i2c_id); | |||
| 525 | 521 | ||
| 526 | static struct i2c_driver wm8776_i2c_driver = { | 522 | static struct i2c_driver wm8776_i2c_driver = { |
| 527 | .driver = { | 523 | .driver = { |
| 528 | .name = "wm8776-codec", | 524 | .name = "wm8776", |
| 529 | .owner = THIS_MODULE, | 525 | .owner = THIS_MODULE, |
| 526 | .of_match_table = wm8776_of_match, | ||
| 530 | }, | 527 | }, |
| 531 | .probe = wm8776_i2c_probe, | 528 | .probe = wm8776_i2c_probe, |
| 532 | .remove = __devexit_p(wm8776_i2c_remove), | 529 | .remove = __devexit_p(wm8776_i2c_remove), |
diff --git a/sound/soc/codecs/wm8782.c b/sound/soc/codecs/wm8782.c index a2a09f85ea99..f2ced71328b0 100644 --- a/sound/soc/codecs/wm8782.c +++ b/sound/soc/codecs/wm8782.c | |||
| @@ -60,7 +60,7 @@ static struct platform_driver wm8782_codec_driver = { | |||
| 60 | .owner = THIS_MODULE, | 60 | .owner = THIS_MODULE, |
| 61 | }, | 61 | }, |
| 62 | .probe = wm8782_probe, | 62 | .probe = wm8782_probe, |
| 63 | .remove = wm8782_remove, | 63 | .remove = __devexit_p(wm8782_remove), |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | static int __init wm8782_init(void) | 66 | static int __init wm8782_init(void) |
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 9a5e67c5a6bd..9ee072b85975 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
| 17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
| 18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
| 19 | #include <linux/of_device.h> | ||
| 19 | #include <linux/spi/spi.h> | 20 | #include <linux/spi/spi.h> |
| 20 | #include <linux/regulator/consumer.h> | 21 | #include <linux/regulator/consumer.h> |
| 21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| @@ -717,6 +718,12 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8804 = { | |||
| 717 | .volatile_register = wm8804_volatile | 718 | .volatile_register = wm8804_volatile |
| 718 | }; | 719 | }; |
| 719 | 720 | ||
| 721 | static const struct of_device_id wm8804_of_match[] = { | ||
| 722 | { .compatible = "wlf,wm8804", }, | ||
| 723 | { } | ||
| 724 | }; | ||
| 725 | MODULE_DEVICE_TABLE(of, wm8804_of_match); | ||
| 726 | |||
| 720 | #if defined(CONFIG_SPI_MASTER) | 727 | #if defined(CONFIG_SPI_MASTER) |
| 721 | static int __devinit wm8804_spi_probe(struct spi_device *spi) | 728 | static int __devinit wm8804_spi_probe(struct spi_device *spi) |
| 722 | { | 729 | { |
| @@ -748,6 +755,7 @@ static struct spi_driver wm8804_spi_driver = { | |||
| 748 | .driver = { | 755 | .driver = { |
| 749 | .name = "wm8804", | 756 | .name = "wm8804", |
| 750 | .owner = THIS_MODULE, | 757 | .owner = THIS_MODULE, |
| 758 | .of_match_table = wm8804_of_match, | ||
| 751 | }, | 759 | }, |
| 752 | .probe = wm8804_spi_probe, | 760 | .probe = wm8804_spi_probe, |
| 753 | .remove = __devexit_p(wm8804_spi_remove) | 761 | .remove = __devexit_p(wm8804_spi_remove) |
| @@ -792,6 +800,7 @@ static struct i2c_driver wm8804_i2c_driver = { | |||
| 792 | .driver = { | 800 | .driver = { |
| 793 | .name = "wm8804", | 801 | .name = "wm8804", |
| 794 | .owner = THIS_MODULE, | 802 | .owner = THIS_MODULE, |
| 803 | .of_match_table = wm8804_of_match, | ||
| 795 | }, | 804 | }, |
| 796 | .probe = wm8804_i2c_probe, | 805 | .probe = wm8804_i2c_probe, |
| 797 | .remove = __devexit_p(wm8804_i2c_remove), | 806 | .remove = __devexit_p(wm8804_i2c_remove), |
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 082040eda8a2..3d0dc1591ecc 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c | |||
| @@ -110,8 +110,8 @@ | |||
| 110 | 110 | ||
| 111 | #define WM8900_REG_CLOCKING1_BCLK_DIR 0x1 | 111 | #define WM8900_REG_CLOCKING1_BCLK_DIR 0x1 |
| 112 | #define WM8900_REG_CLOCKING1_MCLK_SRC 0x100 | 112 | #define WM8900_REG_CLOCKING1_MCLK_SRC 0x100 |
| 113 | #define WM8900_REG_CLOCKING1_BCLK_MASK (~0x01e) | 113 | #define WM8900_REG_CLOCKING1_BCLK_MASK 0x01e |
| 114 | #define WM8900_REG_CLOCKING1_OPCLK_MASK (~0x7000) | 114 | #define WM8900_REG_CLOCKING1_OPCLK_MASK 0x7000 |
| 115 | 115 | ||
| 116 | #define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 | 116 | #define WM8900_REG_CLOCKING2_ADC_CLKDIV 0xe0 |
| 117 | #define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c | 117 | #define WM8900_REG_CLOCKING2_DAC_CLKDIV 0x1c |
| @@ -135,7 +135,7 @@ | |||
| 135 | #define WM8900_REG_HPCTL1_HP_SHORT 0x08 | 135 | #define WM8900_REG_HPCTL1_HP_SHORT 0x08 |
| 136 | #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 | 136 | #define WM8900_REG_HPCTL1_HP_SHORT2 0x04 |
| 137 | 137 | ||
| 138 | #define WM8900_LRC_MASK 0xfc00 | 138 | #define WM8900_LRC_MASK 0x03ff |
| 139 | 139 | ||
| 140 | struct wm8900_priv { | 140 | struct wm8900_priv { |
| 141 | enum snd_soc_control_type control_type; | 141 | enum snd_soc_control_type control_type; |
| @@ -742,26 +742,20 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, | |||
| 742 | { | 742 | { |
| 743 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); | 743 | struct wm8900_priv *wm8900 = snd_soc_codec_get_drvdata(codec); |
| 744 | struct _fll_div fll_div; | 744 | struct _fll_div fll_div; |
| 745 | unsigned int reg; | ||
| 746 | 745 | ||
| 747 | if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) | 746 | if (wm8900->fll_in == freq_in && wm8900->fll_out == freq_out) |
| 748 | return 0; | 747 | return 0; |
| 749 | 748 | ||
| 750 | /* The digital side should be disabled during any change. */ | 749 | /* The digital side should be disabled during any change. */ |
| 751 | reg = snd_soc_read(codec, WM8900_REG_POWER1); | 750 | snd_soc_update_bits(codec, WM8900_REG_POWER1, |
| 752 | snd_soc_write(codec, WM8900_REG_POWER1, | 751 | WM8900_REG_POWER1_FLL_ENA, 0); |
| 753 | reg & (~WM8900_REG_POWER1_FLL_ENA)); | ||
| 754 | 752 | ||
| 755 | /* Disable the FLL? */ | 753 | /* Disable the FLL? */ |
| 756 | if (!freq_in || !freq_out) { | 754 | if (!freq_in || !freq_out) { |
| 757 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 755 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
| 758 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 756 | WM8900_REG_CLOCKING1_MCLK_SRC, 0); |
| 759 | reg & (~WM8900_REG_CLOCKING1_MCLK_SRC)); | 757 | snd_soc_update_bits(codec, WM8900_REG_FLLCTL1, |
| 760 | 758 | WM8900_REG_FLLCTL1_OSC_ENA, 0); | |
| 761 | reg = snd_soc_read(codec, WM8900_REG_FLLCTL1); | ||
| 762 | snd_soc_write(codec, WM8900_REG_FLLCTL1, | ||
| 763 | reg & (~WM8900_REG_FLLCTL1_OSC_ENA)); | ||
| 764 | |||
| 765 | wm8900->fll_in = freq_in; | 759 | wm8900->fll_in = freq_in; |
| 766 | wm8900->fll_out = freq_out; | 760 | wm8900->fll_out = freq_out; |
| 767 | 761 | ||
| @@ -796,15 +790,14 @@ static int wm8900_set_fll(struct snd_soc_codec *codec, | |||
| 796 | else | 790 | else |
| 797 | snd_soc_write(codec, WM8900_REG_FLLCTL6, 0); | 791 | snd_soc_write(codec, WM8900_REG_FLLCTL6, 0); |
| 798 | 792 | ||
| 799 | reg = snd_soc_read(codec, WM8900_REG_POWER1); | 793 | snd_soc_update_bits(codec, WM8900_REG_POWER1, |
| 800 | snd_soc_write(codec, WM8900_REG_POWER1, | 794 | WM8900_REG_POWER1_FLL_ENA, |
| 801 | reg | WM8900_REG_POWER1_FLL_ENA); | 795 | WM8900_REG_POWER1_FLL_ENA); |
| 802 | 796 | ||
| 803 | reenable: | 797 | reenable: |
| 804 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 798 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
| 805 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 799 | WM8900_REG_CLOCKING1_MCLK_SRC, |
| 806 | reg | WM8900_REG_CLOCKING1_MCLK_SRC); | 800 | WM8900_REG_CLOCKING1_MCLK_SRC); |
| 807 | |||
| 808 | return 0; | 801 | return 0; |
| 809 | } | 802 | } |
| 810 | 803 | ||
| @@ -818,43 +811,35 @@ static int wm8900_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
| 818 | int div_id, int div) | 811 | int div_id, int div) |
| 819 | { | 812 | { |
| 820 | struct snd_soc_codec *codec = codec_dai->codec; | 813 | struct snd_soc_codec *codec = codec_dai->codec; |
| 821 | unsigned int reg; | ||
| 822 | 814 | ||
| 823 | switch (div_id) { | 815 | switch (div_id) { |
| 824 | case WM8900_BCLK_DIV: | 816 | case WM8900_BCLK_DIV: |
| 825 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 817 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
| 826 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 818 | WM8900_REG_CLOCKING1_BCLK_MASK, div); |
| 827 | div | (reg & WM8900_REG_CLOCKING1_BCLK_MASK)); | ||
| 828 | break; | 819 | break; |
| 829 | case WM8900_OPCLK_DIV: | 820 | case WM8900_OPCLK_DIV: |
| 830 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING1); | 821 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING1, |
| 831 | snd_soc_write(codec, WM8900_REG_CLOCKING1, | 822 | WM8900_REG_CLOCKING1_OPCLK_MASK, div); |
| 832 | div | (reg & WM8900_REG_CLOCKING1_OPCLK_MASK)); | ||
| 833 | break; | 823 | break; |
| 834 | case WM8900_DAC_LRCLK: | 824 | case WM8900_DAC_LRCLK: |
| 835 | reg = snd_soc_read(codec, WM8900_REG_AUDIO4); | 825 | snd_soc_update_bits(codec, WM8900_REG_AUDIO4, |
| 836 | snd_soc_write(codec, WM8900_REG_AUDIO4, | 826 | WM8900_LRC_MASK, div); |
| 837 | div | (reg & WM8900_LRC_MASK)); | ||
| 838 | break; | 827 | break; |
| 839 | case WM8900_ADC_LRCLK: | 828 | case WM8900_ADC_LRCLK: |
| 840 | reg = snd_soc_read(codec, WM8900_REG_AUDIO3); | 829 | snd_soc_update_bits(codec, WM8900_REG_AUDIO3, |
| 841 | snd_soc_write(codec, WM8900_REG_AUDIO3, | 830 | WM8900_LRC_MASK, div); |
| 842 | div | (reg & WM8900_LRC_MASK)); | ||
| 843 | break; | 831 | break; |
| 844 | case WM8900_DAC_CLKDIV: | 832 | case WM8900_DAC_CLKDIV: |
| 845 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); | 833 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING2, |
| 846 | snd_soc_write(codec, WM8900_REG_CLOCKING2, | 834 | WM8900_REG_CLOCKING2_DAC_CLKDIV, div); |
| 847 | div | (reg & WM8900_REG_CLOCKING2_DAC_CLKDIV)); | ||
| 848 | break; | 835 | break; |
| 849 | case WM8900_ADC_CLKDIV: | 836 | case WM8900_ADC_CLKDIV: |
| 850 | reg = snd_soc_read(codec, WM8900_REG_CLOCKING2); | 837 | snd_soc_update_bits(codec, WM8900_REG_CLOCKING2, |
| 851 | snd_soc_write(codec, WM8900_REG_CLOCKING2, | 838 | WM8900_REG_CLOCKING2_ADC_CLKDIV, div); |
| 852 | div | (reg & WM8900_REG_CLOCKING2_ADC_CLKDIV)); | ||
| 853 | break; | 839 | break; |
| 854 | case WM8900_LRCLK_MODE: | 840 | case WM8900_LRCLK_MODE: |
| 855 | reg = snd_soc_read(codec, WM8900_REG_DACCTRL); | 841 | snd_soc_update_bits(codec, WM8900_REG_DACCTRL, |
| 856 | snd_soc_write(codec, WM8900_REG_DACCTRL, | 842 | WM8900_REG_DACCTRL_AIF_LRCLKRATE, div); |
| 857 | div | (reg & WM8900_REG_DACCTRL_AIF_LRCLKRATE)); | ||
| 858 | break; | 843 | break; |
| 859 | default: | 844 | default: |
| 860 | return -EINVAL; | 845 | return -EINVAL; |
| @@ -1037,12 +1022,12 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, | |||
| 1037 | switch (level) { | 1022 | switch (level) { |
| 1038 | case SND_SOC_BIAS_ON: | 1023 | case SND_SOC_BIAS_ON: |
| 1039 | /* Enable thermal shutdown */ | 1024 | /* Enable thermal shutdown */ |
| 1040 | reg = snd_soc_read(codec, WM8900_REG_GPIO); | 1025 | snd_soc_update_bits(codec, WM8900_REG_GPIO, |
| 1041 | snd_soc_write(codec, WM8900_REG_GPIO, | 1026 | WM8900_REG_GPIO_TEMP_ENA, |
| 1042 | reg | WM8900_REG_GPIO_TEMP_ENA); | 1027 | WM8900_REG_GPIO_TEMP_ENA); |
| 1043 | reg = snd_soc_read(codec, WM8900_REG_ADDCTL); | 1028 | snd_soc_update_bits(codec, WM8900_REG_ADDCTL, |
| 1044 | snd_soc_write(codec, WM8900_REG_ADDCTL, | 1029 | WM8900_REG_ADDCTL_TEMP_SD, |
| 1045 | reg | WM8900_REG_ADDCTL_TEMP_SD); | 1030 | WM8900_REG_ADDCTL_TEMP_SD); |
| 1046 | break; | 1031 | break; |
| 1047 | 1032 | ||
| 1048 | case SND_SOC_BIAS_PREPARE: | 1033 | case SND_SOC_BIAS_PREPARE: |
| @@ -1205,26 +1190,16 @@ static int wm8900_probe(struct snd_soc_codec *codec) | |||
| 1205 | wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1190 | wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 1206 | 1191 | ||
| 1207 | /* Latch the volume update bits */ | 1192 | /* Latch the volume update bits */ |
| 1208 | snd_soc_write(codec, WM8900_REG_LINVOL, | 1193 | snd_soc_update_bits(codec, WM8900_REG_LINVOL, 0x100, 0x100); |
| 1209 | snd_soc_read(codec, WM8900_REG_LINVOL) | 0x100); | 1194 | snd_soc_update_bits(codec, WM8900_REG_RINVOL, 0x100, 0x100); |
| 1210 | snd_soc_write(codec, WM8900_REG_RINVOL, | 1195 | snd_soc_update_bits(codec, WM8900_REG_LOUT1CTL, 0x100, 0x100); |
| 1211 | snd_soc_read(codec, WM8900_REG_RINVOL) | 0x100); | 1196 | snd_soc_update_bits(codec, WM8900_REG_ROUT1CTL, 0x100, 0x100); |
| 1212 | snd_soc_write(codec, WM8900_REG_LOUT1CTL, | 1197 | snd_soc_update_bits(codec, WM8900_REG_LOUT2CTL, 0x100, 0x100); |
| 1213 | snd_soc_read(codec, WM8900_REG_LOUT1CTL) | 0x100); | 1198 | snd_soc_update_bits(codec, WM8900_REG_ROUT2CTL, 0x100, 0x100); |
| 1214 | snd_soc_write(codec, WM8900_REG_ROUT1CTL, | 1199 | snd_soc_update_bits(codec, WM8900_REG_LDAC_DV, 0x100, 0x100); |
| 1215 | snd_soc_read(codec, WM8900_REG_ROUT1CTL) | 0x100); | 1200 | snd_soc_update_bits(codec, WM8900_REG_RDAC_DV, 0x100, 0x100); |
| 1216 | snd_soc_write(codec, WM8900_REG_LOUT2CTL, | 1201 | snd_soc_update_bits(codec, WM8900_REG_LADC_DV, 0x100, 0x100); |
| 1217 | snd_soc_read(codec, WM8900_REG_LOUT2CTL) | 0x100); | 1202 | snd_soc_update_bits(codec, WM8900_REG_RADC_DV, 0x100, 0x100); |
| 1218 | snd_soc_write(codec, WM8900_REG_ROUT2CTL, | ||
| 1219 | snd_soc_read(codec, WM8900_REG_ROUT2CTL) | 0x100); | ||
| 1220 | snd_soc_write(codec, WM8900_REG_LDAC_DV, | ||
| 1221 | snd_soc_read(codec, WM8900_REG_LDAC_DV) | 0x100); | ||
| 1222 | snd_soc_write(codec, WM8900_REG_RDAC_DV, | ||
| 1223 | snd_soc_read(codec, WM8900_REG_RDAC_DV) | 0x100); | ||
| 1224 | snd_soc_write(codec, WM8900_REG_LADC_DV, | ||
| 1225 | snd_soc_read(codec, WM8900_REG_LADC_DV) | 0x100); | ||
| 1226 | snd_soc_write(codec, WM8900_REG_RADC_DV, | ||
| 1227 | snd_soc_read(codec, WM8900_REG_RADC_DV) | 0x100); | ||
| 1228 | 1203 | ||
| 1229 | /* Set the DAC and mixer output bias */ | 1204 | /* Set the DAC and mixer output bias */ |
| 1230 | snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); | 1205 | snd_soc_write(codec, WM8900_REG_OUTBIASCTL, 0x81); |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index b085575d4aa5..9fc8f4c0a9a9 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
| @@ -50,7 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { | |||
| 50 | struct wm8904_priv { | 50 | struct wm8904_priv { |
| 51 | 51 | ||
| 52 | enum wm8904_type devtype; | 52 | enum wm8904_type devtype; |
| 53 | void *control_data; | ||
| 54 | 53 | ||
| 55 | struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; | 54 | struct regulator_bulk_data supplies[WM8904_NUM_SUPPLIES]; |
| 56 | 55 | ||
| @@ -2540,7 +2539,6 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c, | |||
| 2540 | 2539 | ||
| 2541 | wm8904->devtype = id->driver_data; | 2540 | wm8904->devtype = id->driver_data; |
| 2542 | i2c_set_clientdata(i2c, wm8904); | 2541 | i2c_set_clientdata(i2c, wm8904); |
| 2543 | wm8904->control_data = i2c; | ||
| 2544 | wm8904->pdata = i2c->dev.platform_data; | 2542 | wm8904->pdata = i2c->dev.platform_data; |
| 2545 | 2543 | ||
| 2546 | ret = snd_soc_register_codec(&i2c->dev, | 2544 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 056daa0010f9..dc5cb3150857 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
| @@ -43,9 +43,19 @@ | |||
| 43 | struct wm8940_priv { | 43 | struct wm8940_priv { |
| 44 | unsigned int sysclk; | 44 | unsigned int sysclk; |
| 45 | enum snd_soc_control_type control_type; | 45 | enum snd_soc_control_type control_type; |
| 46 | void *control_data; | ||
| 47 | }; | 46 | }; |
| 48 | 47 | ||
| 48 | static int wm8940_volatile_register(struct snd_soc_codec *codec, | ||
| 49 | unsigned int reg) | ||
| 50 | { | ||
| 51 | switch (reg) { | ||
| 52 | case WM8940_SOFTRESET: | ||
| 53 | return 1; | ||
| 54 | default: | ||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 49 | static u16 wm8940_reg_defaults[] = { | 59 | static u16 wm8940_reg_defaults[] = { |
| 50 | 0x8940, /* Soft Reset */ | 60 | 0x8940, /* Soft Reset */ |
| 51 | 0x0000, /* Power 1 */ | 61 | 0x0000, /* Power 1 */ |
| @@ -460,6 +470,14 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec, | |||
| 460 | ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1); | 470 | ret = snd_soc_write(codec, WM8940_POWER1, pwr_reg | 0x1); |
| 461 | break; | 471 | break; |
| 462 | case SND_SOC_BIAS_STANDBY: | 472 | case SND_SOC_BIAS_STANDBY: |
| 473 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | ||
| 474 | ret = snd_soc_cache_sync(codec); | ||
| 475 | if (ret < 0) { | ||
| 476 | dev_err(codec->dev, "Failed to sync cache: %d\n", ret); | ||
| 477 | return ret; | ||
| 478 | } | ||
| 479 | } | ||
| 480 | |||
| 463 | /* ensure bufioen and biasen */ | 481 | /* ensure bufioen and biasen */ |
| 464 | pwr_reg |= (1 << 2) | (1 << 3); | 482 | pwr_reg |= (1 << 2) | (1 << 3); |
| 465 | /* set vmid to 300k for standby */ | 483 | /* set vmid to 300k for standby */ |
| @@ -470,6 +488,8 @@ static int wm8940_set_bias_level(struct snd_soc_codec *codec, | |||
| 470 | break; | 488 | break; |
| 471 | } | 489 | } |
| 472 | 490 | ||
| 491 | codec->dapm.bias_level = level; | ||
| 492 | |||
| 473 | return ret; | 493 | return ret; |
| 474 | } | 494 | } |
| 475 | 495 | ||
| @@ -660,30 +680,8 @@ static int wm8940_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 660 | 680 | ||
| 661 | static int wm8940_resume(struct snd_soc_codec *codec) | 681 | static int wm8940_resume(struct snd_soc_codec *codec) |
| 662 | { | 682 | { |
| 663 | int i; | 683 | wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 664 | int ret; | 684 | return 0; |
| 665 | u8 data[3]; | ||
| 666 | u16 *cache = codec->reg_cache; | ||
| 667 | |||
| 668 | /* Sync reg_cache with the hardware | ||
| 669 | * Could use auto incremented writes to speed this up | ||
| 670 | */ | ||
| 671 | for (i = 0; i < ARRAY_SIZE(wm8940_reg_defaults); i++) { | ||
| 672 | data[0] = i; | ||
| 673 | data[1] = (cache[i] & 0xFF00) >> 8; | ||
| 674 | data[2] = cache[i] & 0x00FF; | ||
| 675 | ret = codec->hw_write(codec->control_data, data, 3); | ||
| 676 | if (ret < 0) | ||
| 677 | goto error_ret; | ||
| 678 | else if (ret != 3) { | ||
| 679 | ret = -EIO; | ||
| 680 | goto error_ret; | ||
| 681 | } | ||
| 682 | } | ||
| 683 | ret = wm8940_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
| 684 | |||
| 685 | error_ret: | ||
| 686 | return ret; | ||
| 687 | } | 685 | } |
| 688 | 686 | ||
| 689 | static int wm8940_probe(struct snd_soc_codec *codec) | 687 | static int wm8940_probe(struct snd_soc_codec *codec) |
| @@ -693,7 +691,6 @@ static int wm8940_probe(struct snd_soc_codec *codec) | |||
| 693 | int ret; | 691 | int ret; |
| 694 | u16 reg; | 692 | u16 reg; |
| 695 | 693 | ||
| 696 | codec->control_data = wm8940->control_data; | ||
| 697 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type); | 694 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm8940->control_type); |
| 698 | if (ret < 0) { | 695 | if (ret < 0) { |
| 699 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 696 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| @@ -744,6 +741,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8940 = { | |||
| 744 | .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults), | 741 | .reg_cache_size = ARRAY_SIZE(wm8940_reg_defaults), |
| 745 | .reg_word_size = sizeof(u16), | 742 | .reg_word_size = sizeof(u16), |
| 746 | .reg_cache_default = wm8940_reg_defaults, | 743 | .reg_cache_default = wm8940_reg_defaults, |
| 744 | .volatile_register = wm8940_volatile_register, | ||
| 747 | }; | 745 | }; |
| 748 | 746 | ||
| 749 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 747 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| @@ -758,7 +756,6 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, | |||
| 758 | return -ENOMEM; | 756 | return -ENOMEM; |
| 759 | 757 | ||
| 760 | i2c_set_clientdata(i2c, wm8940); | 758 | i2c_set_clientdata(i2c, wm8940); |
| 761 | wm8940->control_data = i2c; | ||
| 762 | wm8940->control_type = SND_SOC_I2C; | 759 | wm8940->control_type = SND_SOC_I2C; |
| 763 | 760 | ||
| 764 | ret = snd_soc_register_codec(&i2c->dev, | 761 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 4393394b7bc1..2df253c18568 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
| @@ -72,7 +72,6 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = { | |||
| 72 | 72 | ||
| 73 | struct wm8960_priv { | 73 | struct wm8960_priv { |
| 74 | enum snd_soc_control_type control_type; | 74 | enum snd_soc_control_type control_type; |
| 75 | void *control_data; | ||
| 76 | int (*set_bias_level)(struct snd_soc_codec *, | 75 | int (*set_bias_level)(struct snd_soc_codec *, |
| 77 | enum snd_soc_bias_level level); | 76 | enum snd_soc_bias_level level); |
| 78 | struct snd_soc_dapm_widget *lout1; | 77 | struct snd_soc_dapm_widget *lout1; |
| @@ -575,6 +574,8 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, | |||
| 575 | 574 | ||
| 576 | case SND_SOC_BIAS_STANDBY: | 575 | case SND_SOC_BIAS_STANDBY: |
| 577 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 576 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 577 | snd_soc_cache_sync(codec); | ||
| 578 | |||
| 578 | /* Enable anti-pop features */ | 579 | /* Enable anti-pop features */ |
| 579 | snd_soc_write(codec, WM8960_APOP1, | 580 | snd_soc_write(codec, WM8960_APOP1, |
| 580 | WM8960_POBCTRL | WM8960_SOFT_ST | | 581 | WM8960_POBCTRL | WM8960_SOFT_ST | |
| @@ -677,6 +678,9 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, | |||
| 677 | WM8960_VREF | WM8960_VMID_MASK, 0); | 678 | WM8960_VREF | WM8960_VMID_MASK, 0); |
| 678 | break; | 679 | break; |
| 679 | 680 | ||
| 681 | case SND_SOC_BIAS_OFF: | ||
| 682 | snd_soc_cache_sync(codec); | ||
| 683 | break; | ||
| 680 | default: | 684 | default: |
| 681 | break; | 685 | break; |
| 682 | } | 686 | } |
| @@ -902,16 +906,6 @@ static int wm8960_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 902 | static int wm8960_resume(struct snd_soc_codec *codec) | 906 | static int wm8960_resume(struct snd_soc_codec *codec) |
| 903 | { | 907 | { |
| 904 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 908 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
| 905 | int i; | ||
| 906 | u8 data[2]; | ||
| 907 | u16 *cache = codec->reg_cache; | ||
| 908 | |||
| 909 | /* Sync reg_cache with the hardware */ | ||
| 910 | for (i = 0; i < ARRAY_SIZE(wm8960_reg); i++) { | ||
| 911 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 912 | data[1] = cache[i] & 0x00ff; | ||
| 913 | codec->hw_write(codec->control_data, data, 2); | ||
| 914 | } | ||
| 915 | 909 | ||
| 916 | wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 910 | wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 917 | return 0; | 911 | return 0; |
| @@ -925,7 +919,6 @@ static int wm8960_probe(struct snd_soc_codec *codec) | |||
| 925 | u16 reg; | 919 | u16 reg; |
| 926 | 920 | ||
| 927 | wm8960->set_bias_level = wm8960_set_bias_level_out3; | 921 | wm8960->set_bias_level = wm8960_set_bias_level_out3; |
| 928 | codec->control_data = wm8960->control_data; | ||
| 929 | 922 | ||
| 930 | if (!pdata) { | 923 | if (!pdata) { |
| 931 | dev_warn(codec->dev, "No platform data supplied\n"); | 924 | dev_warn(codec->dev, "No platform data supplied\n"); |
| @@ -1015,7 +1008,6 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, | |||
| 1015 | 1008 | ||
| 1016 | i2c_set_clientdata(i2c, wm8960); | 1009 | i2c_set_clientdata(i2c, wm8960); |
| 1017 | wm8960->control_type = SND_SOC_I2C; | 1010 | wm8960->control_type = SND_SOC_I2C; |
| 1018 | wm8960->control_data = i2c; | ||
| 1019 | 1011 | ||
| 1020 | ret = snd_soc_register_codec(&i2c->dev, | 1012 | ret = snd_soc_register_codec(&i2c->dev, |
| 1021 | &soc_codec_dev_wm8960, &wm8960_dai, 1); | 1013 | &soc_codec_dev_wm8960, &wm8960_dai, 1); |
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index cdee8103d09b..9568c8a49f96 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c | |||
| @@ -974,7 +974,9 @@ static int wm8961_probe(struct snd_soc_codec *codec) | |||
| 974 | } | 974 | } |
| 975 | 975 | ||
| 976 | /* This isn't volatile - readback doesn't correspond to write */ | 976 | /* This isn't volatile - readback doesn't correspond to write */ |
| 977 | reg = codec->hw_read(codec, WM8961_RIGHT_INPUT_VOLUME); | 977 | codec->cache_bypass = 1; |
| 978 | reg = snd_soc_read(codec, WM8961_RIGHT_INPUT_VOLUME); | ||
| 979 | codec->cache_bypass = 0; | ||
| 978 | dev_info(codec->dev, "WM8961 family %d revision %c\n", | 980 | dev_info(codec->dev, "WM8961 family %d revision %c\n", |
| 979 | (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, | 981 | (reg & WM8961_DEVICE_ID_MASK) >> WM8961_DEVICE_ID_SHIFT, |
| 980 | ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) | 982 | ((reg & WM8961_CHIP_REV_MASK) >> WM8961_CHIP_REV_SHIFT) |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index d2c315fa1b9b..f60dfa16545e 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
| @@ -63,6 +63,8 @@ struct wm8962_priv { | |||
| 63 | int fll_fref; | 63 | int fll_fref; |
| 64 | int fll_fout; | 64 | int fll_fout; |
| 65 | 65 | ||
| 66 | u16 dsp2_ena; | ||
| 67 | |||
| 66 | struct delayed_work mic_work; | 68 | struct delayed_work mic_work; |
| 67 | struct snd_soc_jack *jack; | 69 | struct snd_soc_jack *jack; |
| 68 | 70 | ||
| @@ -837,7 +839,7 @@ static const struct wm8962_reg_access { | |||
| 837 | [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ | 839 | [40] = { 0x00FF, 0x01FF, 0x0000 }, /* R40 - SPKOUTL volume */ |
| 838 | [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ | 840 | [41] = { 0x00FF, 0x01FF, 0x0000 }, /* R41 - SPKOUTR volume */ |
| 839 | 841 | ||
| 840 | [47] = { 0x000F, 0x0000, 0x0000 }, /* R47 - Thermal Shutdown Status */ | 842 | [47] = { 0x000F, 0x0000, 0xFFFF }, /* R47 - Thermal Shutdown Status */ |
| 841 | [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ | 843 | [48] = { 0x7EC7, 0x7E07, 0xFFFF }, /* R48 - Additional Control (4) */ |
| 842 | [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ | 844 | [49] = { 0x00D3, 0x00D7, 0xFFFF }, /* R49 - Class D Control 1 */ |
| 843 | [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ | 845 | [51] = { 0x0047, 0x0047, 0x0000 }, /* R51 - Class D Control 2 */ |
| @@ -965,7 +967,7 @@ static const struct wm8962_reg_access { | |||
| 965 | [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ | 967 | [584] = { 0x002D, 0x002D, 0x0000 }, /* R584 - IRQ Debounce */ |
| 966 | [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ | 968 | [586] = { 0xC000, 0xC000, 0x0000 }, /* R586 - MICINT Source Pol */ |
| 967 | [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ | 969 | [768] = { 0x0001, 0x0001, 0x0000 }, /* R768 - DSP2 Power Management */ |
| 968 | [1037] = { 0x0000, 0x003F, 0x0000 }, /* R1037 - DSP2_ExecControl */ | 970 | [1037] = { 0x0000, 0x003F, 0xFFFF }, /* R1037 - DSP2_ExecControl */ |
| 969 | [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ | 971 | [4096] = { 0x3FFF, 0x3FFF, 0x0000 }, /* R4096 - Write Sequencer 0 */ |
| 970 | [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ | 972 | [4097] = { 0x00FF, 0x00FF, 0x0000 }, /* R4097 - Write Sequencer 1 */ |
| 971 | [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ | 973 | [4098] = { 0x070F, 0x070F, 0x0000 }, /* R4098 - Write Sequencer 2 */ |
| @@ -1986,6 +1988,122 @@ static const unsigned int classd_tlv[] = { | |||
| 1986 | }; | 1988 | }; |
| 1987 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | 1989 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
| 1988 | 1990 | ||
| 1991 | static int wm8962_dsp2_write_config(struct snd_soc_codec *codec) | ||
| 1992 | { | ||
| 1993 | return 0; | ||
| 1994 | } | ||
| 1995 | |||
| 1996 | static int wm8962_dsp2_set_enable(struct snd_soc_codec *codec, u16 val) | ||
| 1997 | { | ||
| 1998 | u16 adcl = snd_soc_read(codec, WM8962_LEFT_ADC_VOLUME); | ||
| 1999 | u16 adcr = snd_soc_read(codec, WM8962_RIGHT_ADC_VOLUME); | ||
| 2000 | u16 dac = snd_soc_read(codec, WM8962_ADC_DAC_CONTROL_1); | ||
| 2001 | |||
| 2002 | /* Mute the ADCs and DACs */ | ||
| 2003 | snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, 0); | ||
| 2004 | snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, WM8962_ADC_VU); | ||
| 2005 | snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1, | ||
| 2006 | WM8962_DAC_MUTE, WM8962_DAC_MUTE); | ||
| 2007 | |||
| 2008 | snd_soc_write(codec, WM8962_SOUNDSTAGE_ENABLES_0, val); | ||
| 2009 | |||
| 2010 | /* Restore the ADCs and DACs */ | ||
| 2011 | snd_soc_write(codec, WM8962_LEFT_ADC_VOLUME, adcl); | ||
| 2012 | snd_soc_write(codec, WM8962_RIGHT_ADC_VOLUME, adcr); | ||
| 2013 | snd_soc_update_bits(codec, WM8962_ADC_DAC_CONTROL_1, | ||
| 2014 | WM8962_DAC_MUTE, dac); | ||
| 2015 | |||
| 2016 | return 0; | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | static int wm8962_dsp2_start(struct snd_soc_codec *codec) | ||
| 2020 | { | ||
| 2021 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
| 2022 | |||
| 2023 | wm8962_dsp2_write_config(codec); | ||
| 2024 | |||
| 2025 | snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_RUNR); | ||
| 2026 | |||
| 2027 | wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena); | ||
| 2028 | |||
| 2029 | return 0; | ||
| 2030 | } | ||
| 2031 | |||
| 2032 | static int wm8962_dsp2_stop(struct snd_soc_codec *codec) | ||
| 2033 | { | ||
| 2034 | wm8962_dsp2_set_enable(codec, 0); | ||
| 2035 | |||
| 2036 | snd_soc_write(codec, WM8962_DSP2_EXECCONTROL, WM8962_DSP2_STOP); | ||
| 2037 | |||
| 2038 | return 0; | ||
| 2039 | } | ||
| 2040 | |||
| 2041 | #define WM8962_DSP2_ENABLE(xname, xshift) \ | ||
| 2042 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | ||
| 2043 | .info = wm8962_dsp2_ena_info, \ | ||
| 2044 | .get = wm8962_dsp2_ena_get, .put = wm8962_dsp2_ena_put, \ | ||
| 2045 | .private_value = xshift } | ||
| 2046 | |||
| 2047 | static int wm8962_dsp2_ena_info(struct snd_kcontrol *kcontrol, | ||
| 2048 | struct snd_ctl_elem_info *uinfo) | ||
| 2049 | { | ||
| 2050 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
| 2051 | |||
| 2052 | uinfo->count = 1; | ||
| 2053 | uinfo->value.integer.min = 0; | ||
| 2054 | uinfo->value.integer.max = 1; | ||
| 2055 | |||
| 2056 | return 0; | ||
| 2057 | } | ||
| 2058 | |||
| 2059 | static int wm8962_dsp2_ena_get(struct snd_kcontrol *kcontrol, | ||
| 2060 | struct snd_ctl_elem_value *ucontrol) | ||
| 2061 | { | ||
| 2062 | int shift = kcontrol->private_value; | ||
| 2063 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 2064 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
| 2065 | |||
| 2066 | ucontrol->value.integer.value[0] = !!(wm8962->dsp2_ena & 1 << shift); | ||
| 2067 | |||
| 2068 | return 0; | ||
| 2069 | } | ||
| 2070 | |||
| 2071 | static int wm8962_dsp2_ena_put(struct snd_kcontrol *kcontrol, | ||
| 2072 | struct snd_ctl_elem_value *ucontrol) | ||
| 2073 | { | ||
| 2074 | int shift = kcontrol->private_value; | ||
| 2075 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 2076 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
| 2077 | int old = wm8962->dsp2_ena; | ||
| 2078 | int ret = 0; | ||
| 2079 | int dsp2_running = snd_soc_read(codec, WM8962_DSP2_POWER_MANAGEMENT) & | ||
| 2080 | WM8962_DSP2_ENA; | ||
| 2081 | |||
| 2082 | mutex_lock(&codec->mutex); | ||
| 2083 | |||
| 2084 | if (ucontrol->value.integer.value[0]) | ||
| 2085 | wm8962->dsp2_ena |= 1 << shift; | ||
| 2086 | else | ||
| 2087 | wm8962->dsp2_ena &= ~(1 << shift); | ||
| 2088 | |||
| 2089 | if (wm8962->dsp2_ena == old) | ||
| 2090 | goto out; | ||
| 2091 | |||
| 2092 | ret = 1; | ||
| 2093 | |||
| 2094 | if (dsp2_running) { | ||
| 2095 | if (wm8962->dsp2_ena) | ||
| 2096 | wm8962_dsp2_set_enable(codec, wm8962->dsp2_ena); | ||
| 2097 | else | ||
| 2098 | wm8962_dsp2_stop(codec); | ||
| 2099 | } | ||
| 2100 | |||
| 2101 | out: | ||
| 2102 | mutex_unlock(&codec->mutex); | ||
| 2103 | |||
| 2104 | return ret; | ||
| 2105 | } | ||
| 2106 | |||
| 1989 | /* The VU bits for the headphones are in a different register to the mute | 2107 | /* The VU bits for the headphones are in a different register to the mute |
| 1990 | * bits and only take effect on the PGA if it is actually powered. | 2108 | * bits and only take effect on the PGA if it is actually powered. |
| 1991 | */ | 2109 | */ |
| @@ -2021,7 +2139,6 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, | |||
| 2021 | struct snd_ctl_elem_value *ucontrol) | 2139 | struct snd_ctl_elem_value *ucontrol) |
| 2022 | { | 2140 | { |
| 2023 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2141 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 2024 | u16 *reg_cache = codec->reg_cache; | ||
| 2025 | int ret; | 2142 | int ret; |
| 2026 | 2143 | ||
| 2027 | /* Apply the update (if any) */ | 2144 | /* Apply the update (if any) */ |
| @@ -2030,16 +2147,19 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, | |||
| 2030 | return 0; | 2147 | return 0; |
| 2031 | 2148 | ||
| 2032 | /* If the left PGA is enabled hit that VU bit... */ | 2149 | /* If the left PGA is enabled hit that VU bit... */ |
| 2033 | if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTL_PGA_ENA) | 2150 | ret = snd_soc_read(codec, WM8962_PWR_MGMT_2); |
| 2034 | return snd_soc_write(codec, WM8962_SPKOUTL_VOLUME, | 2151 | if (ret & WM8962_SPKOUTL_PGA_ENA) { |
| 2035 | reg_cache[WM8962_SPKOUTL_VOLUME]); | 2152 | snd_soc_write(codec, WM8962_SPKOUTL_VOLUME, |
| 2153 | snd_soc_read(codec, WM8962_SPKOUTL_VOLUME)); | ||
| 2154 | return 1; | ||
| 2155 | } | ||
| 2036 | 2156 | ||
| 2037 | /* ...otherwise the right. The VU is stereo. */ | 2157 | /* ...otherwise the right. The VU is stereo. */ |
| 2038 | if (reg_cache[WM8962_PWR_MGMT_2] & WM8962_SPKOUTR_PGA_ENA) | 2158 | if (ret & WM8962_SPKOUTR_PGA_ENA) |
| 2039 | return snd_soc_write(codec, WM8962_SPKOUTR_VOLUME, | 2159 | snd_soc_write(codec, WM8962_SPKOUTR_VOLUME, |
| 2040 | reg_cache[WM8962_SPKOUTR_VOLUME]); | 2160 | snd_soc_read(codec, WM8962_SPKOUTR_VOLUME)); |
| 2041 | 2161 | ||
| 2042 | return 0; | 2162 | return 1; |
| 2043 | } | 2163 | } |
| 2044 | 2164 | ||
| 2045 | static const char *cap_hpf_mode_text[] = { | 2165 | static const char *cap_hpf_mode_text[] = { |
| @@ -2049,6 +2169,14 @@ static const char *cap_hpf_mode_text[] = { | |||
| 2049 | static const struct soc_enum cap_hpf_mode = | 2169 | static const struct soc_enum cap_hpf_mode = |
| 2050 | SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); | 2170 | SOC_ENUM_SINGLE(WM8962_ADC_DAC_CONTROL_2, 10, 2, cap_hpf_mode_text); |
| 2051 | 2171 | ||
| 2172 | |||
| 2173 | static const char *cap_lhpf_mode_text[] = { | ||
| 2174 | "LPF", "HPF" | ||
| 2175 | }; | ||
| 2176 | |||
| 2177 | static const struct soc_enum cap_lhpf_mode = | ||
| 2178 | SOC_ENUM_SINGLE(WM8962_LHPF1, 1, 2, cap_lhpf_mode_text); | ||
| 2179 | |||
| 2052 | static const struct snd_kcontrol_new wm8962_snd_controls[] = { | 2180 | static const struct snd_kcontrol_new wm8962_snd_controls[] = { |
| 2053 | SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), | 2181 | SOC_DOUBLE("Input Mixer Switch", WM8962_INPUT_MIXER_CONTROL_1, 3, 2, 1, 1), |
| 2054 | 2182 | ||
| @@ -2077,6 +2205,8 @@ SOC_DOUBLE_R("Capture ZC Switch", WM8962_LEFT_INPUT_VOLUME, | |||
| 2077 | SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1), | 2205 | SOC_SINGLE("Capture HPF Switch", WM8962_ADC_DAC_CONTROL_1, 0, 1, 1), |
| 2078 | SOC_ENUM("Capture HPF Mode", cap_hpf_mode), | 2206 | SOC_ENUM("Capture HPF Mode", cap_hpf_mode), |
| 2079 | SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0), | 2207 | SOC_SINGLE("Capture HPF Cutoff", WM8962_ADC_DAC_CONTROL_2, 7, 7, 0), |
| 2208 | SOC_SINGLE("Capture LHPF Switch", WM8962_LHPF1, 0, 1, 0), | ||
| 2209 | SOC_ENUM("Capture LHPF Mode", cap_lhpf_mode), | ||
| 2080 | 2210 | ||
| 2081 | SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, | 2211 | SOC_DOUBLE_R_TLV("Sidetone Volume", WM8962_DAC_DSP_MIXING_1, |
| 2082 | WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), | 2212 | WM8962_DAC_DSP_MIXING_2, 4, 12, 0, st_tlv), |
| @@ -2134,6 +2264,11 @@ SOC_DOUBLE_R_TLV("EQ4 Volume", WM8962_EQ3, WM8962_EQ23, | |||
| 2134 | WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv), | 2264 | WM8962_EQL_B4_GAIN_SHIFT, 31, 0, eq_tlv), |
| 2135 | SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, | 2265 | SOC_DOUBLE_R_TLV("EQ5 Volume", WM8962_EQ3, WM8962_EQ23, |
| 2136 | WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), | 2266 | WM8962_EQL_B5_GAIN_SHIFT, 31, 0, eq_tlv), |
| 2267 | |||
| 2268 | WM8962_DSP2_ENABLE("VSS Switch", WM8962_VSS_ENA_SHIFT), | ||
| 2269 | WM8962_DSP2_ENABLE("HPF1 Switch", WM8962_HPF1_ENA_SHIFT), | ||
| 2270 | WM8962_DSP2_ENABLE("HPF2 Switch", WM8962_HPF2_ENA_SHIFT), | ||
| 2271 | WM8962_DSP2_ENABLE("HD Bass Switch", WM8962_HDBASS_ENA_SHIFT), | ||
| 2137 | }; | 2272 | }; |
| 2138 | 2273 | ||
| 2139 | static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { | 2274 | static const struct snd_kcontrol_new wm8962_spk_mono_controls[] = { |
| @@ -2365,7 +2500,6 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, | |||
| 2365 | struct snd_kcontrol *kcontrol, int event) | 2500 | struct snd_kcontrol *kcontrol, int event) |
| 2366 | { | 2501 | { |
| 2367 | struct snd_soc_codec *codec = w->codec; | 2502 | struct snd_soc_codec *codec = w->codec; |
| 2368 | u16 *reg_cache = codec->reg_cache; | ||
| 2369 | int reg; | 2503 | int reg; |
| 2370 | 2504 | ||
| 2371 | switch (w->shift) { | 2505 | switch (w->shift) { |
| @@ -2388,11 +2522,36 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, | |||
| 2388 | 2522 | ||
| 2389 | switch (event) { | 2523 | switch (event) { |
| 2390 | case SND_SOC_DAPM_POST_PMU: | 2524 | case SND_SOC_DAPM_POST_PMU: |
| 2391 | return snd_soc_write(codec, reg, reg_cache[reg]); | 2525 | return snd_soc_write(codec, reg, snd_soc_read(codec, reg)); |
| 2526 | default: | ||
| 2527 | BUG(); | ||
| 2528 | return -EINVAL; | ||
| 2529 | } | ||
| 2530 | } | ||
| 2531 | |||
| 2532 | static int dsp2_event(struct snd_soc_dapm_widget *w, | ||
| 2533 | struct snd_kcontrol *kcontrol, int event) | ||
| 2534 | { | ||
| 2535 | struct snd_soc_codec *codec = w->codec; | ||
| 2536 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
| 2537 | |||
| 2538 | switch (event) { | ||
| 2539 | case SND_SOC_DAPM_POST_PMU: | ||
| 2540 | if (wm8962->dsp2_ena) | ||
| 2541 | wm8962_dsp2_start(codec); | ||
| 2542 | break; | ||
| 2543 | |||
| 2544 | case SND_SOC_DAPM_PRE_PMD: | ||
| 2545 | if (wm8962->dsp2_ena) | ||
| 2546 | wm8962_dsp2_stop(codec); | ||
| 2547 | break; | ||
| 2548 | |||
| 2392 | default: | 2549 | default: |
| 2393 | BUG(); | 2550 | BUG(); |
| 2394 | return -EINVAL; | 2551 | return -EINVAL; |
| 2395 | } | 2552 | } |
| 2553 | |||
| 2554 | return 0; | ||
| 2396 | } | 2555 | } |
| 2397 | 2556 | ||
| 2398 | static const char *st_text[] = { "None", "Right", "Left" }; | 2557 | static const char *st_text[] = { "None", "Right", "Left" }; |
| @@ -2509,7 +2668,7 @@ SND_SOC_DAPM_INPUT("IN4R"), | |||
| 2509 | SND_SOC_DAPM_INPUT("Beep"), | 2668 | SND_SOC_DAPM_INPUT("Beep"), |
| 2510 | SND_SOC_DAPM_INPUT("DMICDAT"), | 2669 | SND_SOC_DAPM_INPUT("DMICDAT"), |
| 2511 | 2670 | ||
| 2512 | SND_SOC_DAPM_MICBIAS("MICBIAS", WM8962_PWR_MGMT_1, 1, 0), | 2671 | SND_SOC_DAPM_SUPPLY("MICBIAS", WM8962_PWR_MGMT_1, 1, 0, NULL, 0), |
| 2513 | 2672 | ||
| 2514 | SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), | 2673 | SND_SOC_DAPM_SUPPLY("Class G", WM8962_CHARGE_PUMP_B, 0, 1, NULL, 0), |
| 2515 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, | 2674 | SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, |
| @@ -2517,6 +2676,9 @@ SND_SOC_DAPM_SUPPLY("SYSCLK", WM8962_CLOCKING2, 5, 0, sysclk_event, | |||
| 2517 | SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, | 2676 | SND_SOC_DAPM_SUPPLY("Charge Pump", WM8962_CHARGE_PUMP_1, 0, 0, cp_event, |
| 2518 | SND_SOC_DAPM_POST_PMU), | 2677 | SND_SOC_DAPM_POST_PMU), |
| 2519 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), | 2678 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8962_ADDITIONAL_CONTROL_1, 0, 0, NULL, 0), |
| 2679 | SND_SOC_DAPM_SUPPLY_S("DSP2", 1, WM8962_DSP2_POWER_MANAGEMENT, | ||
| 2680 | WM8962_DSP2_ENA_SHIFT, 0, dsp2_event, | ||
| 2681 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
| 2520 | 2682 | ||
| 2521 | SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, | 2683 | SND_SOC_DAPM_MIXER("INPGAL", WM8962_LEFT_INPUT_PGA_CONTROL, 4, 0, |
| 2522 | inpgal, ARRAY_SIZE(inpgal)), | 2684 | inpgal, ARRAY_SIZE(inpgal)), |
| @@ -2527,7 +2689,7 @@ SND_SOC_DAPM_MIXER("MIXINL", WM8962_PWR_MGMT_1, 5, 0, | |||
| 2527 | SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, | 2689 | SND_SOC_DAPM_MIXER("MIXINR", WM8962_PWR_MGMT_1, 4, 0, |
| 2528 | mixinr, ARRAY_SIZE(mixinr)), | 2690 | mixinr, ARRAY_SIZE(mixinr)), |
| 2529 | 2691 | ||
| 2530 | SND_SOC_DAPM_AIF_IN("DMIC", NULL, 0, WM8962_PWR_MGMT_1, 10, 0), | 2692 | SND_SOC_DAPM_AIF_IN("DMIC_ENA", NULL, 0, WM8962_PWR_MGMT_1, 10, 0), |
| 2531 | 2693 | ||
| 2532 | SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), | 2694 | SND_SOC_DAPM_ADC("ADCL", "Capture", WM8962_PWR_MGMT_1, 3, 0), |
| 2533 | SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), | 2695 | SND_SOC_DAPM_ADC("ADCR", "Capture", WM8962_PWR_MGMT_1, 2, 0), |
| @@ -2606,17 +2768,19 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = { | |||
| 2606 | 2768 | ||
| 2607 | { "MICBIAS", NULL, "SYSCLK" }, | 2769 | { "MICBIAS", NULL, "SYSCLK" }, |
| 2608 | 2770 | ||
| 2609 | { "DMIC", NULL, "DMICDAT" }, | 2771 | { "DMIC_ENA", NULL, "DMICDAT" }, |
| 2610 | 2772 | ||
| 2611 | { "ADCL", NULL, "SYSCLK" }, | 2773 | { "ADCL", NULL, "SYSCLK" }, |
| 2612 | { "ADCL", NULL, "TOCLK" }, | 2774 | { "ADCL", NULL, "TOCLK" }, |
| 2613 | { "ADCL", NULL, "MIXINL" }, | 2775 | { "ADCL", NULL, "MIXINL" }, |
| 2614 | { "ADCL", NULL, "DMIC" }, | 2776 | { "ADCL", NULL, "DMIC_ENA" }, |
| 2777 | { "ADCL", NULL, "DSP2" }, | ||
| 2615 | 2778 | ||
| 2616 | { "ADCR", NULL, "SYSCLK" }, | 2779 | { "ADCR", NULL, "SYSCLK" }, |
| 2617 | { "ADCR", NULL, "TOCLK" }, | 2780 | { "ADCR", NULL, "TOCLK" }, |
| 2618 | { "ADCR", NULL, "MIXINR" }, | 2781 | { "ADCR", NULL, "MIXINR" }, |
| 2619 | { "ADCR", NULL, "DMIC" }, | 2782 | { "ADCR", NULL, "DMIC_ENA" }, |
| 2783 | { "ADCR", NULL, "DSP2" }, | ||
| 2620 | 2784 | ||
| 2621 | { "STL", "Left", "ADCL" }, | 2785 | { "STL", "Left", "ADCL" }, |
| 2622 | { "STL", "Right", "ADCR" }, | 2786 | { "STL", "Right", "ADCR" }, |
| @@ -2628,11 +2792,13 @@ static const struct snd_soc_dapm_route wm8962_intercon[] = { | |||
| 2628 | { "DACL", NULL, "TOCLK" }, | 2792 | { "DACL", NULL, "TOCLK" }, |
| 2629 | { "DACL", NULL, "Beep" }, | 2793 | { "DACL", NULL, "Beep" }, |
| 2630 | { "DACL", NULL, "STL" }, | 2794 | { "DACL", NULL, "STL" }, |
| 2795 | { "DACL", NULL, "DSP2" }, | ||
| 2631 | 2796 | ||
| 2632 | { "DACR", NULL, "SYSCLK" }, | 2797 | { "DACR", NULL, "SYSCLK" }, |
| 2633 | { "DACR", NULL, "TOCLK" }, | 2798 | { "DACR", NULL, "TOCLK" }, |
| 2634 | { "DACR", NULL, "Beep" }, | 2799 | { "DACR", NULL, "Beep" }, |
| 2635 | { "DACR", NULL, "STR" }, | 2800 | { "DACR", NULL, "STR" }, |
| 2801 | { "DACR", NULL, "DSP2" }, | ||
| 2636 | 2802 | ||
| 2637 | { "HPMIXL", "IN4L Switch", "IN4L" }, | 2803 | { "HPMIXL", "IN4L Switch", "IN4L" }, |
| 2638 | { "HPMIXL", "IN4R Switch", "IN4R" }, | 2804 | { "HPMIXL", "IN4R Switch", "IN4R" }, |
| @@ -3058,9 +3224,9 @@ static int wm8962_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
| 3058 | int aif0 = 0; | 3224 | int aif0 = 0; |
| 3059 | 3225 | ||
| 3060 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 3226 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
| 3061 | case SND_SOC_DAIFMT_DSP_A: | ||
| 3062 | aif0 |= WM8962_LRCLK_INV; | ||
| 3063 | case SND_SOC_DAIFMT_DSP_B: | 3227 | case SND_SOC_DAIFMT_DSP_B: |
| 3228 | aif0 |= WM8962_LRCLK_INV | 3; | ||
| 3229 | case SND_SOC_DAIFMT_DSP_A: | ||
| 3064 | aif0 |= 3; | 3230 | aif0 |= 3; |
| 3065 | 3231 | ||
| 3066 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | 3232 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
| @@ -3403,12 +3569,16 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
| 3403 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3569 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
| 3404 | int mask; | 3570 | int mask; |
| 3405 | int active; | 3571 | int active; |
| 3572 | int reg; | ||
| 3406 | 3573 | ||
| 3407 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); | 3574 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); |
| 3408 | 3575 | ||
| 3409 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); | 3576 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); |
| 3410 | active &= ~mask; | 3577 | active &= ~mask; |
| 3411 | 3578 | ||
| 3579 | if (!active) | ||
| 3580 | return IRQ_NONE; | ||
| 3581 | |||
| 3412 | /* Acknowledge the interrupts */ | 3582 | /* Acknowledge the interrupts */ |
| 3413 | snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); | 3583 | snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); |
| 3414 | 3584 | ||
| @@ -3420,9 +3590,21 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
| 3420 | if (active & WM8962_FIFOS_ERR_EINT) | 3590 | if (active & WM8962_FIFOS_ERR_EINT) |
| 3421 | dev_err(codec->dev, "FIFO error\n"); | 3591 | dev_err(codec->dev, "FIFO error\n"); |
| 3422 | 3592 | ||
| 3423 | if (active & WM8962_TEMP_SHUT_EINT) | 3593 | if (active & WM8962_TEMP_SHUT_EINT) { |
| 3424 | dev_crit(codec->dev, "Thermal shutdown\n"); | 3594 | dev_crit(codec->dev, "Thermal shutdown\n"); |
| 3425 | 3595 | ||
| 3596 | reg = snd_soc_read(codec, WM8962_THERMAL_SHUTDOWN_STATUS); | ||
| 3597 | |||
| 3598 | if (reg & WM8962_TEMP_ERR_HP) | ||
| 3599 | dev_crit(codec->dev, "Headphone thermal error\n"); | ||
| 3600 | if (reg & WM8962_TEMP_WARN_HP) | ||
| 3601 | dev_crit(codec->dev, "Headphone thermal warning\n"); | ||
| 3602 | if (reg & WM8962_TEMP_ERR_SPK) | ||
| 3603 | dev_crit(codec->dev, "Speaker thermal error\n"); | ||
| 3604 | if (reg & WM8962_TEMP_WARN_SPK) | ||
| 3605 | dev_crit(codec->dev, "Speaker thermal warning\n"); | ||
| 3606 | } | ||
| 3607 | |||
| 3426 | if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { | 3608 | if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { |
| 3427 | dev_dbg(codec->dev, "Microphone event detected\n"); | 3609 | dev_dbg(codec->dev, "Microphone event detected\n"); |
| 3428 | 3610 | ||
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 572bb80627a4..b444b297d0b2 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
| @@ -546,6 +546,9 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec, | |||
| 546 | case SND_SOC_BIAS_PREPARE: | 546 | case SND_SOC_BIAS_PREPARE: |
| 547 | break; | 547 | break; |
| 548 | case SND_SOC_BIAS_STANDBY: | 548 | case SND_SOC_BIAS_STANDBY: |
| 549 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
| 550 | snd_soc_cache_sync(codec); | ||
| 551 | |||
| 549 | /* mute dac and set vmid to 500k, enable VREF */ | 552 | /* mute dac and set vmid to 500k, enable VREF */ |
| 550 | snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140); | 553 | snd_soc_write(codec, WM8971_PWR1, pwr_reg | 0x0140); |
| 551 | break; | 554 | break; |
| @@ -605,20 +608,8 @@ static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 605 | 608 | ||
| 606 | static int wm8971_resume(struct snd_soc_codec *codec) | 609 | static int wm8971_resume(struct snd_soc_codec *codec) |
| 607 | { | 610 | { |
| 608 | int i; | ||
| 609 | u8 data[2]; | ||
| 610 | u16 *cache = codec->reg_cache; | ||
| 611 | u16 reg; | 611 | u16 reg; |
| 612 | 612 | ||
| 613 | /* Sync reg_cache with the hardware */ | ||
| 614 | for (i = 0; i < ARRAY_SIZE(wm8971_reg); i++) { | ||
| 615 | if (i + 1 == WM8971_RESET) | ||
| 616 | continue; | ||
| 617 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 618 | data[1] = cache[i] & 0x00ff; | ||
| 619 | codec->hw_write(codec->control_data, data, 2); | ||
| 620 | } | ||
| 621 | |||
| 622 | wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 613 | wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 623 | 614 | ||
| 624 | /* charge wm8971 caps */ | 615 | /* charge wm8971 caps */ |
| @@ -660,25 +651,14 @@ static int wm8971_probe(struct snd_soc_codec *codec) | |||
| 660 | msecs_to_jiffies(1000)); | 651 | msecs_to_jiffies(1000)); |
| 661 | 652 | ||
| 662 | /* set the update bits */ | 653 | /* set the update bits */ |
| 663 | reg = snd_soc_read(codec, WM8971_LDAC); | 654 | snd_soc_update_bits(codec, WM8971_LDAC, 0x0100, 0x0100); |
| 664 | snd_soc_write(codec, WM8971_LDAC, reg | 0x0100); | 655 | snd_soc_update_bits(codec, WM8971_RDAC, 0x0100, 0x0100); |
| 665 | reg = snd_soc_read(codec, WM8971_RDAC); | 656 | snd_soc_update_bits(codec, WM8971_LOUT1V, 0x0100, 0x0100); |
| 666 | snd_soc_write(codec, WM8971_RDAC, reg | 0x0100); | 657 | snd_soc_update_bits(codec, WM8971_ROUT1V, 0x0100, 0x0100); |
| 667 | 658 | snd_soc_update_bits(codec, WM8971_LOUT2V, 0x0100, 0x0100); | |
| 668 | reg = snd_soc_read(codec, WM8971_LOUT1V); | 659 | snd_soc_update_bits(codec, WM8971_ROUT2V, 0x0100, 0x0100); |
| 669 | snd_soc_write(codec, WM8971_LOUT1V, reg | 0x0100); | 660 | snd_soc_update_bits(codec, WM8971_LINVOL, 0x0100, 0x0100); |
| 670 | reg = snd_soc_read(codec, WM8971_ROUT1V); | 661 | snd_soc_update_bits(codec, WM8971_RINVOL, 0x0100, 0x0100); |
| 671 | snd_soc_write(codec, WM8971_ROUT1V, reg | 0x0100); | ||
| 672 | |||
| 673 | reg = snd_soc_read(codec, WM8971_LOUT2V); | ||
| 674 | snd_soc_write(codec, WM8971_LOUT2V, reg | 0x0100); | ||
| 675 | reg = snd_soc_read(codec, WM8971_ROUT2V); | ||
| 676 | snd_soc_write(codec, WM8971_ROUT2V, reg | 0x0100); | ||
| 677 | |||
| 678 | reg = snd_soc_read(codec, WM8971_LINVOL); | ||
| 679 | snd_soc_write(codec, WM8971_LINVOL, reg | 0x0100); | ||
| 680 | reg = snd_soc_read(codec, WM8971_RINVOL); | ||
| 681 | snd_soc_write(codec, WM8971_RINVOL, reg | 0x0100); | ||
| 682 | 662 | ||
| 683 | snd_soc_add_controls(codec, wm8971_snd_controls, | 663 | snd_soc_add_controls(codec, wm8971_snd_controls, |
| 684 | ARRAY_SIZE(wm8971_snd_controls)); | 664 | ARRAY_SIZE(wm8971_snd_controls)); |
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index ca646a822444..9352f1e088d2 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright 2006-2009 Wolfson Microelectronics PLC. | 4 | * Copyright 2006-2009 Wolfson Microelectronics PLC. |
| 5 | * | 5 | * |
| 6 | * Author: Liam Girdwood <linux@wolfsonmicro.com> | 6 | * Author: Liam Girdwood <Liam.Girdwood@wolfsonmicro.com> |
| 7 | * | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify | 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 | 9 | * it under the terms of the GNU General Public License version 2 as |
| @@ -530,6 +530,8 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, | |||
| 530 | power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; | 530 | power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; |
| 531 | 531 | ||
| 532 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 532 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 533 | snd_soc_cache_sync(codec); | ||
| 534 | |||
| 533 | /* Initial cap charge at VMID 5k */ | 535 | /* Initial cap charge at VMID 5k */ |
| 534 | snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); | 536 | snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); |
| 535 | mdelay(100); | 537 | mdelay(100); |
| @@ -589,18 +591,7 @@ static int wm8974_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 589 | 591 | ||
| 590 | static int wm8974_resume(struct snd_soc_codec *codec) | 592 | static int wm8974_resume(struct snd_soc_codec *codec) |
| 591 | { | 593 | { |
| 592 | int i; | ||
| 593 | u8 data[2]; | ||
| 594 | u16 *cache = codec->reg_cache; | ||
| 595 | |||
| 596 | /* Sync reg_cache with the hardware */ | ||
| 597 | for (i = 0; i < ARRAY_SIZE(wm8974_reg); i++) { | ||
| 598 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 599 | data[1] = cache[i] & 0x00ff; | ||
| 600 | codec->hw_write(codec->control_data, data, 2); | ||
| 601 | } | ||
| 602 | wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 594 | wm8974_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 603 | |||
| 604 | return 0; | 595 | return 0; |
| 605 | } | 596 | } |
| 606 | 597 | ||
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 85e3e630e763..41ca4d9ac20c 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c | |||
| @@ -52,7 +52,6 @@ static const u16 wm8978_reg[WM8978_CACHEREGNUM] = { | |||
| 52 | /* codec private data */ | 52 | /* codec private data */ |
| 53 | struct wm8978_priv { | 53 | struct wm8978_priv { |
| 54 | enum snd_soc_control_type control_type; | 54 | enum snd_soc_control_type control_type; |
| 55 | void *control_data; | ||
| 56 | unsigned int f_pllout; | 55 | unsigned int f_pllout; |
| 57 | unsigned int f_mclk; | 56 | unsigned int f_mclk; |
| 58 | unsigned int f_256fs; | 57 | unsigned int f_256fs; |
| @@ -955,7 +954,6 @@ static int wm8978_probe(struct snd_soc_codec *codec) | |||
| 955 | * default hardware setting | 954 | * default hardware setting |
| 956 | */ | 955 | */ |
| 957 | wm8978->sysclk = WM8978_PLL; | 956 | wm8978->sysclk = WM8978_PLL; |
| 958 | codec->control_data = wm8978->control_data; | ||
| 959 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); | 957 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, SND_SOC_I2C); |
| 960 | if (ret < 0) { | 958 | if (ret < 0) { |
| 961 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 959 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| @@ -1016,7 +1014,6 @@ static __devinit int wm8978_i2c_probe(struct i2c_client *i2c, | |||
| 1016 | return -ENOMEM; | 1014 | return -ENOMEM; |
| 1017 | 1015 | ||
| 1018 | i2c_set_clientdata(i2c, wm8978); | 1016 | i2c_set_clientdata(i2c, wm8978); |
| 1019 | wm8978->control_data = i2c; | ||
| 1020 | 1017 | ||
| 1021 | ret = snd_soc_register_codec(&i2c->dev, | 1018 | ret = snd_soc_register_codec(&i2c->dev, |
| 1022 | &soc_codec_dev_wm8978, &wm8978_dai, 1); | 1019 | &soc_codec_dev_wm8978, &wm8978_dai, 1); |
diff --git a/sound/soc/codecs/wm8983.c b/sound/soc/codecs/wm8983.c index 17f04ec2b940..93ee28439be5 100644 --- a/sound/soc/codecs/wm8983.c +++ b/sound/soc/codecs/wm8983.c | |||
| @@ -1007,7 +1007,7 @@ static int wm8983_probe(struct snd_soc_codec *codec) | |||
| 1007 | return ret; | 1007 | return ret; |
| 1008 | } | 1008 | } |
| 1009 | 1009 | ||
| 1010 | ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0x8983); | 1010 | ret = snd_soc_write(codec, WM8983_SOFTWARE_RESET, 0); |
| 1011 | if (ret < 0) { | 1011 | if (ret < 0) { |
| 1012 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); | 1012 | dev_err(codec->dev, "Failed to issue reset: %d\n", ret); |
| 1013 | return ret; | 1013 | return ret; |
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index d7170f1381aa..2e9eba717d1a 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c | |||
| @@ -55,7 +55,6 @@ struct wm8988_priv { | |||
| 55 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 55 | struct snd_pcm_hw_constraint_list *sysclk_constraints; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | |||
| 59 | #define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) | 58 | #define wm8988_reset(c) snd_soc_write(c, WM8988_RESET, 0) |
| 60 | 59 | ||
| 61 | /* | 60 | /* |
| @@ -676,6 +675,8 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, | |||
| 676 | 675 | ||
| 677 | case SND_SOC_BIAS_STANDBY: | 676 | case SND_SOC_BIAS_STANDBY: |
| 678 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 677 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 678 | snd_soc_cache_sync(codec); | ||
| 679 | |||
| 679 | /* VREF, VMID=2x5k */ | 680 | /* VREF, VMID=2x5k */ |
| 680 | snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); | 681 | snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); |
| 681 | 682 | ||
| @@ -736,21 +737,7 @@ static int wm8988_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 736 | 737 | ||
| 737 | static int wm8988_resume(struct snd_soc_codec *codec) | 738 | static int wm8988_resume(struct snd_soc_codec *codec) |
| 738 | { | 739 | { |
| 739 | int i; | ||
| 740 | u8 data[2]; | ||
| 741 | u16 *cache = codec->reg_cache; | ||
| 742 | |||
| 743 | /* Sync reg_cache with the hardware */ | ||
| 744 | for (i = 0; i < WM8988_NUM_REG; i++) { | ||
| 745 | if (i == WM8988_RESET) | ||
| 746 | continue; | ||
| 747 | data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 748 | data[1] = cache[i] & 0x00ff; | ||
| 749 | codec->hw_write(codec->control_data, data, 2); | ||
| 750 | } | ||
| 751 | |||
| 752 | wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 740 | wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 753 | |||
| 754 | return 0; | 741 | return 0; |
| 755 | } | 742 | } |
| 756 | 743 | ||
| @@ -759,7 +746,6 @@ static int wm8988_probe(struct snd_soc_codec *codec) | |||
| 759 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); | 746 | struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); |
| 760 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 747 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 761 | int ret = 0; | 748 | int ret = 0; |
| 762 | u16 reg; | ||
| 763 | 749 | ||
| 764 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); | 750 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8988->control_type); |
| 765 | if (ret < 0) { | 751 | if (ret < 0) { |
| @@ -774,16 +760,11 @@ static int wm8988_probe(struct snd_soc_codec *codec) | |||
| 774 | } | 760 | } |
| 775 | 761 | ||
| 776 | /* set the update bits (we always update left then right) */ | 762 | /* set the update bits (we always update left then right) */ |
| 777 | reg = snd_soc_read(codec, WM8988_RADC); | 763 | snd_soc_update_bits(codec, WM8988_RADC, 0x0100, 0x0100); |
| 778 | snd_soc_write(codec, WM8988_RADC, reg | 0x100); | 764 | snd_soc_update_bits(codec, WM8988_RDAC, 0x0100, 0x0100); |
| 779 | reg = snd_soc_read(codec, WM8988_RDAC); | 765 | snd_soc_update_bits(codec, WM8988_ROUT1V, 0x0100, 0x0100); |
| 780 | snd_soc_write(codec, WM8988_RDAC, reg | 0x0100); | 766 | snd_soc_update_bits(codec, WM8988_ROUT2V, 0x0100, 0x0100); |
| 781 | reg = snd_soc_read(codec, WM8988_ROUT1V); | 767 | snd_soc_update_bits(codec, WM8988_RINVOL, 0x0100, 0x0100); |
| 782 | snd_soc_write(codec, WM8988_ROUT1V, reg | 0x0100); | ||
| 783 | reg = snd_soc_read(codec, WM8988_ROUT2V); | ||
| 784 | snd_soc_write(codec, WM8988_ROUT2V, reg | 0x0100); | ||
| 785 | reg = snd_soc_read(codec, WM8988_RINVOL); | ||
| 786 | snd_soc_write(codec, WM8988_RINVOL, reg | 0x0100); | ||
| 787 | 768 | ||
| 788 | wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 769 | wm8988_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 789 | 770 | ||
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 100aeee5ba96..d29a9622964c 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c | |||
| @@ -36,10 +36,17 @@ struct wm8990_priv { | |||
| 36 | unsigned int pcmclk; | 36 | unsigned int pcmclk; |
| 37 | }; | 37 | }; |
| 38 | 38 | ||
| 39 | /* | 39 | static int wm8990_volatile_register(struct snd_soc_codec *codec, |
| 40 | * wm8990 register cache. Note that register 0 is not included in the | 40 | unsigned int reg) |
| 41 | * cache. | 41 | { |
| 42 | */ | 42 | switch (reg) { |
| 43 | case WM8990_RESET: | ||
| 44 | return 1; | ||
| 45 | default: | ||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 43 | static const u16 wm8990_reg[] = { | 50 | static const u16 wm8990_reg[] = { |
| 44 | 0x8990, /* R0 - Reset */ | 51 | 0x8990, /* R0 - Reset */ |
| 45 | 0x0000, /* R1 - Power Management (1) */ | 52 | 0x0000, /* R1 - Power Management (1) */ |
| @@ -394,7 +401,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w, | |||
| 394 | (1 << WM8990_AINRMUX_PWR_BIT))) { | 401 | (1 << WM8990_AINRMUX_PWR_BIT))) { |
| 395 | reg |= WM8990_AINR_ENA; | 402 | reg |= WM8990_AINR_ENA; |
| 396 | } else { | 403 | } else { |
| 397 | reg &= ~WM8990_AINL_ENA; | 404 | reg &= ~WM8990_AINR_ENA; |
| 398 | } | 405 | } |
| 399 | snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); | 406 | snd_soc_write(w->codec, WM8990_POWER_MANAGEMENT_2, reg); |
| 400 | 407 | ||
| @@ -974,7 +981,6 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target, | |||
| 974 | static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | 981 | static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, |
| 975 | int source, unsigned int freq_in, unsigned int freq_out) | 982 | int source, unsigned int freq_in, unsigned int freq_out) |
| 976 | { | 983 | { |
| 977 | u16 reg; | ||
| 978 | struct snd_soc_codec *codec = codec_dai->codec; | 984 | struct snd_soc_codec *codec = codec_dai->codec; |
| 979 | struct _pll_div pll_div; | 985 | struct _pll_div pll_div; |
| 980 | 986 | ||
| @@ -982,13 +988,12 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
| 982 | pll_factors(&pll_div, freq_out * 4, freq_in); | 988 | pll_factors(&pll_div, freq_out * 4, freq_in); |
| 983 | 989 | ||
| 984 | /* Turn on PLL */ | 990 | /* Turn on PLL */ |
| 985 | reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); | 991 | snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2, |
| 986 | reg |= WM8990_PLL_ENA; | 992 | WM8990_PLL_ENA, WM8990_PLL_ENA); |
| 987 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg); | ||
| 988 | 993 | ||
| 989 | /* sysclk comes from PLL */ | 994 | /* sysclk comes from PLL */ |
| 990 | reg = snd_soc_read(codec, WM8990_CLOCKING_2); | 995 | snd_soc_update_bits(codec, WM8990_CLOCKING_2, |
| 991 | snd_soc_write(codec, WM8990_CLOCKING_2, reg | WM8990_SYSCLK_SRC); | 996 | WM8990_SYSCLK_SRC, WM8990_SYSCLK_SRC); |
| 992 | 997 | ||
| 993 | /* set up N , fractional mode and pre-divisor if necessary */ | 998 | /* set up N , fractional mode and pre-divisor if necessary */ |
| 994 | snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | | 999 | snd_soc_write(codec, WM8990_PLL1, pll_div.n | WM8990_SDM | |
| @@ -996,10 +1001,9 @@ static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
| 996 | snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); | 1001 | snd_soc_write(codec, WM8990_PLL2, (u8)(pll_div.k>>8)); |
| 997 | snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF)); | 1002 | snd_soc_write(codec, WM8990_PLL3, (u8)(pll_div.k & 0xFF)); |
| 998 | } else { | 1003 | } else { |
| 999 | /* Turn on PLL */ | 1004 | /* Turn off PLL */ |
| 1000 | reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); | 1005 | snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2, |
| 1001 | reg &= ~WM8990_PLL_ENA; | 1006 | WM8990_PLL_ENA, 0); |
| 1002 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg); | ||
| 1003 | } | 1007 | } |
| 1004 | return 0; | 1008 | return 0; |
| 1005 | } | 1009 | } |
| @@ -1077,28 +1081,23 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
| 1077 | int div_id, int div) | 1081 | int div_id, int div) |
| 1078 | { | 1082 | { |
| 1079 | struct snd_soc_codec *codec = codec_dai->codec; | 1083 | struct snd_soc_codec *codec = codec_dai->codec; |
| 1080 | u16 reg; | ||
| 1081 | 1084 | ||
| 1082 | switch (div_id) { | 1085 | switch (div_id) { |
| 1083 | case WM8990_MCLK_DIV: | 1086 | case WM8990_MCLK_DIV: |
| 1084 | reg = snd_soc_read(codec, WM8990_CLOCKING_2) & | 1087 | snd_soc_update_bits(codec, WM8990_CLOCKING_2, |
| 1085 | ~WM8990_MCLK_DIV_MASK; | 1088 | WM8990_MCLK_DIV_MASK, div); |
| 1086 | snd_soc_write(codec, WM8990_CLOCKING_2, reg | div); | ||
| 1087 | break; | 1089 | break; |
| 1088 | case WM8990_DACCLK_DIV: | 1090 | case WM8990_DACCLK_DIV: |
| 1089 | reg = snd_soc_read(codec, WM8990_CLOCKING_2) & | 1091 | snd_soc_update_bits(codec, WM8990_CLOCKING_2, |
| 1090 | ~WM8990_DAC_CLKDIV_MASK; | 1092 | WM8990_DAC_CLKDIV_MASK, div); |
| 1091 | snd_soc_write(codec, WM8990_CLOCKING_2, reg | div); | ||
| 1092 | break; | 1093 | break; |
| 1093 | case WM8990_ADCCLK_DIV: | 1094 | case WM8990_ADCCLK_DIV: |
| 1094 | reg = snd_soc_read(codec, WM8990_CLOCKING_2) & | 1095 | snd_soc_update_bits(codec, WM8990_CLOCKING_2, |
| 1095 | ~WM8990_ADC_CLKDIV_MASK; | 1096 | WM8990_ADC_CLKDIV_MASK, div); |
| 1096 | snd_soc_write(codec, WM8990_CLOCKING_2, reg | div); | ||
| 1097 | break; | 1097 | break; |
| 1098 | case WM8990_BCLK_DIV: | 1098 | case WM8990_BCLK_DIV: |
| 1099 | reg = snd_soc_read(codec, WM8990_CLOCKING_1) & | 1099 | snd_soc_update_bits(codec, WM8990_CLOCKING_1, |
| 1100 | ~WM8990_BCLK_DIV_MASK; | 1100 | WM8990_BCLK_DIV_MASK, div); |
| 1101 | snd_soc_write(codec, WM8990_CLOCKING_1, reg | div); | ||
| 1102 | break; | 1101 | break; |
| 1103 | default: | 1102 | default: |
| 1104 | return -EINVAL; | 1103 | return -EINVAL; |
| @@ -1156,7 +1155,7 @@ static int wm8990_mute(struct snd_soc_dai *dai, int mute) | |||
| 1156 | static int wm8990_set_bias_level(struct snd_soc_codec *codec, | 1155 | static int wm8990_set_bias_level(struct snd_soc_codec *codec, |
| 1157 | enum snd_soc_bias_level level) | 1156 | enum snd_soc_bias_level level) |
| 1158 | { | 1157 | { |
| 1159 | u16 val; | 1158 | int ret; |
| 1160 | 1159 | ||
| 1161 | switch (level) { | 1160 | switch (level) { |
| 1162 | case SND_SOC_BIAS_ON: | 1161 | case SND_SOC_BIAS_ON: |
| @@ -1164,13 +1163,18 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, | |||
| 1164 | 1163 | ||
| 1165 | case SND_SOC_BIAS_PREPARE: | 1164 | case SND_SOC_BIAS_PREPARE: |
| 1166 | /* VMID=2*50k */ | 1165 | /* VMID=2*50k */ |
| 1167 | val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & | 1166 | snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1, |
| 1168 | ~WM8990_VMID_MODE_MASK; | 1167 | WM8990_VMID_MODE_MASK, 0x2); |
| 1169 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2); | ||
| 1170 | break; | 1168 | break; |
| 1171 | 1169 | ||
| 1172 | case SND_SOC_BIAS_STANDBY: | 1170 | case SND_SOC_BIAS_STANDBY: |
| 1173 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { | 1171 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 1172 | ret = snd_soc_cache_sync(codec); | ||
| 1173 | if (ret < 0) { | ||
| 1174 | dev_err(codec->dev, "Failed to sync cache: %d\n", ret); | ||
| 1175 | return ret; | ||
| 1176 | } | ||
| 1177 | |||
| 1174 | /* Enable all output discharge bits */ | 1178 | /* Enable all output discharge bits */ |
| 1175 | snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | | 1179 | snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | |
| 1176 | WM8990_DIS_RLINE | WM8990_DIS_OUT3 | | 1180 | WM8990_DIS_RLINE | WM8990_DIS_OUT3 | |
| @@ -1225,9 +1229,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, | |||
| 1225 | } | 1229 | } |
| 1226 | 1230 | ||
| 1227 | /* VMID=2*250k */ | 1231 | /* VMID=2*250k */ |
| 1228 | val = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_1) & | 1232 | snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_1, |
| 1229 | ~WM8990_VMID_MODE_MASK; | 1233 | WM8990_VMID_MODE_MASK, 0x4); |
| 1230 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4); | ||
| 1231 | break; | 1234 | break; |
| 1232 | 1235 | ||
| 1233 | case SND_SOC_BIAS_OFF: | 1236 | case SND_SOC_BIAS_OFF: |
| @@ -1241,8 +1244,8 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, | |||
| 1241 | WM8990_BUFIOEN); | 1244 | WM8990_BUFIOEN); |
| 1242 | 1245 | ||
| 1243 | /* mute DAC */ | 1246 | /* mute DAC */ |
| 1244 | val = snd_soc_read(codec, WM8990_DAC_CTRL); | 1247 | snd_soc_update_bits(codec, WM8990_DAC_CTRL, |
| 1245 | snd_soc_write(codec, WM8990_DAC_CTRL, val | WM8990_DAC_MUTE); | 1248 | WM8990_DAC_MUTE, WM8990_DAC_MUTE); |
| 1246 | 1249 | ||
| 1247 | /* Enable any disabled outputs */ | 1250 | /* Enable any disabled outputs */ |
| 1248 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); | 1251 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_1, 0x1f03); |
| @@ -1319,19 +1322,6 @@ static int wm8990_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 1319 | 1322 | ||
| 1320 | static int wm8990_resume(struct snd_soc_codec *codec) | 1323 | static int wm8990_resume(struct snd_soc_codec *codec) |
| 1321 | { | 1324 | { |
| 1322 | int i; | ||
| 1323 | u8 data[2]; | ||
| 1324 | u16 *cache = codec->reg_cache; | ||
| 1325 | |||
| 1326 | /* Sync reg_cache with the hardware */ | ||
| 1327 | for (i = 0; i < ARRAY_SIZE(wm8990_reg); i++) { | ||
| 1328 | if (i + 1 == WM8990_RESET) | ||
| 1329 | continue; | ||
| 1330 | data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); | ||
| 1331 | data[1] = cache[i] & 0x00ff; | ||
| 1332 | codec->hw_write(codec->control_data, data, 2); | ||
| 1333 | } | ||
| 1334 | |||
| 1335 | wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1325 | wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 1336 | return 0; | 1326 | return 0; |
| 1337 | } | 1327 | } |
| @@ -1343,7 +1333,6 @@ static int wm8990_resume(struct snd_soc_codec *codec) | |||
| 1343 | static int wm8990_probe(struct snd_soc_codec *codec) | 1333 | static int wm8990_probe(struct snd_soc_codec *codec) |
| 1344 | { | 1334 | { |
| 1345 | int ret; | 1335 | int ret; |
| 1346 | u16 reg; | ||
| 1347 | 1336 | ||
| 1348 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 1337 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
| 1349 | if (ret < 0) { | 1338 | if (ret < 0) { |
| @@ -1356,15 +1345,14 @@ static int wm8990_probe(struct snd_soc_codec *codec) | |||
| 1356 | /* charge output caps */ | 1345 | /* charge output caps */ |
| 1357 | wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1346 | wm8990_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 1358 | 1347 | ||
| 1359 | reg = snd_soc_read(codec, WM8990_AUDIO_INTERFACE_4); | 1348 | snd_soc_update_bits(codec, WM8990_AUDIO_INTERFACE_4, |
| 1360 | snd_soc_write(codec, WM8990_AUDIO_INTERFACE_4, reg | WM8990_ALRCGPIO1); | 1349 | WM8990_ALRCGPIO1, WM8990_ALRCGPIO1); |
| 1361 | 1350 | ||
| 1362 | reg = snd_soc_read(codec, WM8990_GPIO1_GPIO2) & | 1351 | snd_soc_update_bits(codec, WM8990_GPIO1_GPIO2, |
| 1363 | ~WM8990_GPIO1_SEL_MASK; | 1352 | WM8990_GPIO1_SEL_MASK, 1); |
| 1364 | snd_soc_write(codec, WM8990_GPIO1_GPIO2, reg | 1); | ||
| 1365 | 1353 | ||
| 1366 | reg = snd_soc_read(codec, WM8990_POWER_MANAGEMENT_2); | 1354 | snd_soc_update_bits(codec, WM8990_POWER_MANAGEMENT_2, |
| 1367 | snd_soc_write(codec, WM8990_POWER_MANAGEMENT_2, reg | WM8990_OPCLK_ENA); | 1355 | WM8990_OPCLK_ENA, WM8990_OPCLK_ENA); |
| 1368 | 1356 | ||
| 1369 | snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1357 | snd_soc_write(codec, WM8990_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
| 1370 | snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1358 | snd_soc_write(codec, WM8990_RIGHT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
| @@ -1392,6 +1380,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8990 = { | |||
| 1392 | .reg_cache_size = ARRAY_SIZE(wm8990_reg), | 1380 | .reg_cache_size = ARRAY_SIZE(wm8990_reg), |
| 1393 | .reg_word_size = sizeof(u16), | 1381 | .reg_word_size = sizeof(u16), |
| 1394 | .reg_cache_default = wm8990_reg, | 1382 | .reg_cache_default = wm8990_reg, |
| 1383 | .volatile_register = wm8990_volatile_register, | ||
| 1395 | }; | 1384 | }; |
| 1396 | 1385 | ||
| 1397 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 1386 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
diff --git a/sound/soc/codecs/wm8991.c b/sound/soc/codecs/wm8991.c index 6af23d06870f..c9ab3ba9bced 100644 --- a/sound/soc/codecs/wm8991.c +++ b/sound/soc/codecs/wm8991.c | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * | 3 | * |
| 4 | * Copyright 2007-2010 Wolfson Microelectronics PLC. | 4 | * Copyright 2007-2010 Wolfson Microelectronics PLC. |
| 5 | * Author: Graeme Gregory | 5 | * Author: Graeme Gregory |
| 6 | * linux@wolfsonmicro.com | 6 | * Graeme.Gregory@wolfsonmicro.com |
| 7 | * | 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
| 9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
| @@ -393,7 +393,7 @@ static int inmixer_event(struct snd_soc_dapm_widget *w, | |||
| 393 | (1 << WM8991_AINRMUX_PWR_BIT))) | 393 | (1 << WM8991_AINRMUX_PWR_BIT))) |
| 394 | reg |= WM8991_AINR_ENA; | 394 | reg |= WM8991_AINR_ENA; |
| 395 | else | 395 | else |
| 396 | reg &= ~WM8991_AINL_ENA; | 396 | reg &= ~WM8991_AINR_ENA; |
| 397 | 397 | ||
| 398 | snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg); | 398 | snd_soc_write(w->codec, WM8991_POWER_MANAGEMENT_2, reg); |
| 399 | return 0; | 399 | return 0; |
| @@ -1264,7 +1264,6 @@ static int wm8991_probe(struct snd_soc_codec *codec) | |||
| 1264 | { | 1264 | { |
| 1265 | struct wm8991_priv *wm8991; | 1265 | struct wm8991_priv *wm8991; |
| 1266 | int ret; | 1266 | int ret; |
| 1267 | unsigned int reg; | ||
| 1268 | 1267 | ||
| 1269 | wm8991 = snd_soc_codec_get_drvdata(codec); | 1268 | wm8991 = snd_soc_codec_get_drvdata(codec); |
| 1270 | 1269 | ||
| @@ -1282,19 +1281,18 @@ static int wm8991_probe(struct snd_soc_codec *codec) | |||
| 1282 | 1281 | ||
| 1283 | wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1282 | wm8991_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 1284 | 1283 | ||
| 1285 | reg = snd_soc_read(codec, WM8991_AUDIO_INTERFACE_4); | 1284 | snd_soc_update_bits(codec, WM8991_AUDIO_INTERFACE_4, |
| 1286 | snd_soc_write(codec, WM8991_AUDIO_INTERFACE_4, reg | WM8991_ALRCGPIO1); | 1285 | WM8991_ALRCGPIO1, WM8991_ALRCGPIO1); |
| 1287 | 1286 | ||
| 1288 | reg = snd_soc_read(codec, WM8991_GPIO1_GPIO2) & | 1287 | snd_soc_update_bits(codec, WM8991_GPIO1_GPIO2, |
| 1289 | ~WM8991_GPIO1_SEL_MASK; | 1288 | WM8991_GPIO1_SEL_MASK, 1); |
| 1290 | snd_soc_write(codec, WM8991_GPIO1_GPIO2, reg | 1); | ||
| 1291 | 1289 | ||
| 1292 | reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_1); | 1290 | snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_1, |
| 1293 | snd_soc_write(codec, WM8991_POWER_MANAGEMENT_1, reg | WM8991_VREF_ENA| | 1291 | WM8991_VREF_ENA | WM8991_VMID_MODE_MASK, |
| 1294 | WM8991_VMID_MODE_MASK); | 1292 | WM8991_VREF_ENA | WM8991_VMID_MODE_MASK); |
| 1295 | 1293 | ||
| 1296 | reg = snd_soc_read(codec, WM8991_POWER_MANAGEMENT_2); | 1294 | snd_soc_update_bits(codec, WM8991_POWER_MANAGEMENT_2, |
| 1297 | snd_soc_write(codec, WM8991_POWER_MANAGEMENT_2, reg | WM8991_OPCLK_ENA); | 1295 | WM8991_OPCLK_ENA, WM8991_OPCLK_ENA); |
| 1298 | 1296 | ||
| 1299 | snd_soc_write(codec, WM8991_DAC_CTRL, 0); | 1297 | snd_soc_write(codec, WM8991_DAC_CTRL, 0); |
| 1300 | snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); | 1298 | snd_soc_write(codec, WM8991_LEFT_OUTPUT_VOLUME, 0x50 | (1<<8)); |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 6e85b8869af7..eec8e1435116 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
| @@ -847,6 +847,7 @@ SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8993_BUS_CONTROL_1, 1, 0, clk_sys_event, | |||
| 847 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | 847 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
| 848 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0), | 848 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8993_CLOCKING_1, 14, 0, NULL, 0), |
| 849 | SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0), | 849 | SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8993_CLOCKING_3, 0, 0, NULL, 0), |
| 850 | SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
| 850 | 851 | ||
| 851 | SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0), | 852 | SND_SOC_DAPM_ADC("ADCL", NULL, WM8993_POWER_MANAGEMENT_2, 1, 0), |
| 852 | SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0), | 853 | SND_SOC_DAPM_ADC("ADCR", NULL, WM8993_POWER_MANAGEMENT_2, 0, 0), |
| @@ -880,6 +881,9 @@ SND_SOC_DAPM_PGA("Direct Voice", SND_SOC_NOPM, 0, 0, NULL, 0), | |||
| 880 | }; | 881 | }; |
| 881 | 882 | ||
| 882 | static const struct snd_soc_dapm_route routes[] = { | 883 | static const struct snd_soc_dapm_route routes[] = { |
| 884 | { "MICBIAS1", NULL, "VMID" }, | ||
| 885 | { "MICBIAS2", NULL, "VMID" }, | ||
| 886 | |||
| 883 | { "ADCL", NULL, "CLK_SYS" }, | 887 | { "ADCL", NULL, "CLK_SYS" }, |
| 884 | { "ADCL", NULL, "CLK_DSP" }, | 888 | { "ADCL", NULL, "CLK_DSP" }, |
| 885 | { "ADCR", NULL, "CLK_SYS" }, | 889 | { "ADCR", NULL, "CLK_SYS" }, |
| @@ -1433,7 +1437,8 @@ static int wm8993_probe(struct snd_soc_codec *codec) | |||
| 1433 | int ret, i, val; | 1437 | int ret, i, val; |
| 1434 | 1438 | ||
| 1435 | wm8993->hubs_data.hp_startup_mode = 1; | 1439 | wm8993->hubs_data.hp_startup_mode = 1; |
| 1436 | wm8993->hubs_data.dcs_codes = -2; | 1440 | wm8993->hubs_data.dcs_codes_l = -2; |
| 1441 | wm8993->hubs_data.dcs_codes_r = -2; | ||
| 1437 | wm8993->hubs_data.series_startup = 1; | 1442 | wm8993->hubs_data.series_startup = 1; |
| 1438 | 1443 | ||
| 1439 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 1444 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c index a87adbd05ee1..df5a8b9a250f 100644 --- a/sound/soc/codecs/wm8994-tables.c +++ b/sound/soc/codecs/wm8994-tables.c | |||
| @@ -1073,8 +1073,8 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { | |||
| 1073 | { 0x0000, 0x0000 }, /* R1069 */ | 1073 | { 0x0000, 0x0000 }, /* R1069 */ |
| 1074 | { 0x0000, 0x0000 }, /* R1070 */ | 1074 | { 0x0000, 0x0000 }, /* R1070 */ |
| 1075 | { 0x0000, 0x0000 }, /* R1071 */ | 1075 | { 0x0000, 0x0000 }, /* R1071 */ |
| 1076 | { 0x0000, 0x0000 }, /* R1072 */ | 1076 | { 0x006F, 0x006F }, /* R1072 - AIF1 DAC1 Noise Gate */ |
| 1077 | { 0x0000, 0x0000 }, /* R1073 */ | 1077 | { 0x006F, 0x006F }, /* R1073 - AIF1 DAC2 Noise Gate */ |
| 1078 | { 0x0000, 0x0000 }, /* R1074 */ | 1078 | { 0x0000, 0x0000 }, /* R1074 */ |
| 1079 | { 0x0000, 0x0000 }, /* R1075 */ | 1079 | { 0x0000, 0x0000 }, /* R1075 */ |
| 1080 | { 0x0000, 0x0000 }, /* R1076 */ | 1080 | { 0x0000, 0x0000 }, /* R1076 */ |
| @@ -1329,7 +1329,7 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { | |||
| 1329 | { 0x0000, 0x0000 }, /* R1325 */ | 1329 | { 0x0000, 0x0000 }, /* R1325 */ |
| 1330 | { 0x0000, 0x0000 }, /* R1326 */ | 1330 | { 0x0000, 0x0000 }, /* R1326 */ |
| 1331 | { 0x0000, 0x0000 }, /* R1327 */ | 1331 | { 0x0000, 0x0000 }, /* R1327 */ |
| 1332 | { 0x0000, 0x0000 }, /* R1328 */ | 1332 | { 0x006F, 0x006F }, /* R1328 - AIF2 DAC Noise Gate */ |
| 1333 | { 0x0000, 0x0000 }, /* R1329 */ | 1333 | { 0x0000, 0x0000 }, /* R1329 */ |
| 1334 | { 0x0000, 0x0000 }, /* R1330 */ | 1334 | { 0x0000, 0x0000 }, /* R1330 */ |
| 1335 | { 0x0000, 0x0000 }, /* R1331 */ | 1335 | { 0x0000, 0x0000 }, /* R1331 */ |
| @@ -1635,8 +1635,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { | |||
| 1635 | 0x0000, /* R58 - MICBIAS */ | 1635 | 0x0000, /* R58 - MICBIAS */ |
| 1636 | 0x000D, /* R59 - LDO 1 */ | 1636 | 0x000D, /* R59 - LDO 1 */ |
| 1637 | 0x0003, /* R60 - LDO 2 */ | 1637 | 0x0003, /* R60 - LDO 2 */ |
| 1638 | 0x0000, /* R61 */ | 1638 | 0x0039, /* R61 - MICBIAS1 */ |
| 1639 | 0x0000, /* R62 */ | 1639 | 0x0039, /* R62 - MICBIAS2 */ |
| 1640 | 0x0000, /* R63 */ | 1640 | 0x0000, /* R63 */ |
| 1641 | 0x0000, /* R64 */ | 1641 | 0x0000, /* R64 */ |
| 1642 | 0x0000, /* R65 */ | 1642 | 0x0000, /* R65 */ |
| @@ -2646,8 +2646,8 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { | |||
| 2646 | 0x0000, /* R1069 */ | 2646 | 0x0000, /* R1069 */ |
| 2647 | 0x0000, /* R1070 */ | 2647 | 0x0000, /* R1070 */ |
| 2648 | 0x0000, /* R1071 */ | 2648 | 0x0000, /* R1071 */ |
| 2649 | 0x0000, /* R1072 */ | 2649 | 0x0068, /* R1072 - AIF1 DAC1 Noise Gate */ |
| 2650 | 0x0000, /* R1073 */ | 2650 | 0x0068, /* R1073 - AIF1 DAC2 Noise Gate */ |
| 2651 | 0x0000, /* R1074 */ | 2651 | 0x0000, /* R1074 */ |
| 2652 | 0x0000, /* R1075 */ | 2652 | 0x0000, /* R1075 */ |
| 2653 | 0x0000, /* R1076 */ | 2653 | 0x0000, /* R1076 */ |
| @@ -2902,7 +2902,7 @@ const u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { | |||
| 2902 | 0x0000, /* R1325 */ | 2902 | 0x0000, /* R1325 */ |
| 2903 | 0x0000, /* R1326 */ | 2903 | 0x0000, /* R1326 */ |
| 2904 | 0x0000, /* R1327 */ | 2904 | 0x0000, /* R1327 */ |
| 2905 | 0x0000, /* R1328 */ | 2905 | 0x0068, /* R1328 - AIF2 DAC Noise Gate */ |
| 2906 | 0x0000, /* R1329 */ | 2906 | 0x0000, /* R1329 */ |
| 2907 | 0x0000, /* R1330 */ | 2907 | 0x0000, /* R1330 */ |
| 2908 | 0x0000, /* R1331 */ | 2908 | 0x0000, /* R1331 */ |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b393f9fac97a..6b73efd26991 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
| @@ -107,6 +107,7 @@ static int wm8994_volatile(struct snd_soc_codec *codec, unsigned int reg) | |||
| 107 | case WM8994_LDO_2: | 107 | case WM8994_LDO_2: |
| 108 | case WM8958_DSP2_EXECCONTROL: | 108 | case WM8958_DSP2_EXECCONTROL: |
| 109 | case WM8958_MIC_DETECT_3: | 109 | case WM8958_MIC_DETECT_3: |
| 110 | case WM8994_DC_SERVO_4E: | ||
| 110 | return 1; | 111 | return 1; |
| 111 | default: | 112 | default: |
| 112 | return 0; | 113 | return 0; |
| @@ -207,7 +208,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif) | |||
| 207 | static int configure_clock(struct snd_soc_codec *codec) | 208 | static int configure_clock(struct snd_soc_codec *codec) |
| 208 | { | 209 | { |
| 209 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 210 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
| 210 | int old, new; | 211 | int change, new; |
| 211 | 212 | ||
| 212 | /* Bring up the AIF clocks first */ | 213 | /* Bring up the AIF clocks first */ |
| 213 | configure_aif_clock(codec, 0); | 214 | configure_aif_clock(codec, 0); |
| @@ -228,14 +229,11 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
| 228 | else | 229 | else |
| 229 | new = 0; | 230 | new = 0; |
| 230 | 231 | ||
| 231 | old = snd_soc_read(codec, WM8994_CLOCKING_1) & WM8994_SYSCLK_SRC; | 232 | change = snd_soc_update_bits(codec, WM8994_CLOCKING_1, |
| 232 | 233 | WM8994_SYSCLK_SRC, new); | |
| 233 | /* If there's no change then we're done. */ | 234 | if (!change) |
| 234 | if (old == new) | ||
| 235 | return 0; | 235 | return 0; |
| 236 | 236 | ||
| 237 | snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); | ||
| 238 | |||
| 239 | snd_soc_dapm_sync(&codec->dapm); | 237 | snd_soc_dapm_sync(&codec->dapm); |
| 240 | 238 | ||
| 241 | return 0; | 239 | return 0; |
| @@ -281,6 +279,8 @@ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | |||
| 281 | static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); | 279 | static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); |
| 282 | static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); | 280 | static const DECLARE_TLV_DB_SCALE(wm8994_3d_tlv, -1600, 183, 0); |
| 283 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | 281 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
| 282 | static const DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0); | ||
| 283 | static const DECLARE_TLV_DB_SCALE(mixin_boost_tlv, 0, 900, 0); | ||
| 284 | 284 | ||
| 285 | #define WM8994_DRC_SWITCH(xname, reg, shift) \ | 285 | #define WM8994_DRC_SWITCH(xname, reg, shift) \ |
| 286 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 286 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
| @@ -660,8 +660,52 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, | |||
| 660 | eq_tlv), | 660 | eq_tlv), |
| 661 | }; | 661 | }; |
| 662 | 662 | ||
| 663 | static const char *wm8958_ng_text[] = { | ||
| 664 | "30ms", "125ms", "250ms", "500ms", | ||
| 665 | }; | ||
| 666 | |||
| 667 | static const struct soc_enum wm8958_aif1dac1_ng_hold = | ||
| 668 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC1_NOISE_GATE, | ||
| 669 | WM8958_AIF1DAC1_NG_THR_SHIFT, 4, wm8958_ng_text); | ||
| 670 | |||
| 671 | static const struct soc_enum wm8958_aif1dac2_ng_hold = | ||
| 672 | SOC_ENUM_SINGLE(WM8958_AIF1_DAC2_NOISE_GATE, | ||
| 673 | WM8958_AIF1DAC2_NG_THR_SHIFT, 4, wm8958_ng_text); | ||
| 674 | |||
| 675 | static const struct soc_enum wm8958_aif2dac_ng_hold = | ||
| 676 | SOC_ENUM_SINGLE(WM8958_AIF2_DAC_NOISE_GATE, | ||
| 677 | WM8958_AIF2DAC_NG_THR_SHIFT, 4, wm8958_ng_text); | ||
| 678 | |||
| 663 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { | 679 | static const struct snd_kcontrol_new wm8958_snd_controls[] = { |
| 664 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), | 680 | SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), |
| 681 | |||
| 682 | SOC_SINGLE("AIF1DAC1 Noise Gate Switch", WM8958_AIF1_DAC1_NOISE_GATE, | ||
| 683 | WM8958_AIF1DAC1_NG_ENA_SHIFT, 1, 0), | ||
| 684 | SOC_ENUM("AIF1DAC1 Noise Gate Hold Time", wm8958_aif1dac1_ng_hold), | ||
| 685 | SOC_SINGLE_TLV("AIF1DAC1 Noise Gate Threshold Volume", | ||
| 686 | WM8958_AIF1_DAC1_NOISE_GATE, WM8958_AIF1DAC1_NG_THR_SHIFT, | ||
| 687 | 7, 1, ng_tlv), | ||
| 688 | |||
| 689 | SOC_SINGLE("AIF1DAC2 Noise Gate Switch", WM8958_AIF1_DAC2_NOISE_GATE, | ||
| 690 | WM8958_AIF1DAC2_NG_ENA_SHIFT, 1, 0), | ||
| 691 | SOC_ENUM("AIF1DAC2 Noise Gate Hold Time", wm8958_aif1dac2_ng_hold), | ||
| 692 | SOC_SINGLE_TLV("AIF1DAC2 Noise Gate Threshold Volume", | ||
| 693 | WM8958_AIF1_DAC2_NOISE_GATE, WM8958_AIF1DAC2_NG_THR_SHIFT, | ||
| 694 | 7, 1, ng_tlv), | ||
| 695 | |||
| 696 | SOC_SINGLE("AIF2DAC Noise Gate Switch", WM8958_AIF2_DAC_NOISE_GATE, | ||
| 697 | WM8958_AIF2DAC_NG_ENA_SHIFT, 1, 0), | ||
| 698 | SOC_ENUM("AIF2DAC Noise Gate Hold Time", wm8958_aif2dac_ng_hold), | ||
| 699 | SOC_SINGLE_TLV("AIF2DAC Noise Gate Threshold Volume", | ||
| 700 | WM8958_AIF2_DAC_NOISE_GATE, WM8958_AIF2DAC_NG_THR_SHIFT, | ||
| 701 | 7, 1, ng_tlv), | ||
| 702 | }; | ||
| 703 | |||
| 704 | static const struct snd_kcontrol_new wm1811_snd_controls[] = { | ||
| 705 | SOC_SINGLE_TLV("MIXINL IN1LP Boost Volume", WM8994_INPUT_MIXER_1, 7, 1, 0, | ||
| 706 | mixin_boost_tlv), | ||
| 707 | SOC_SINGLE_TLV("MIXINL IN1RP Boost Volume", WM8994_INPUT_MIXER_1, 8, 1, 0, | ||
| 708 | mixin_boost_tlv), | ||
| 665 | }; | 709 | }; |
| 666 | 710 | ||
| 667 | static int clk_sys_event(struct snd_soc_dapm_widget *w, | 711 | static int clk_sys_event(struct snd_soc_dapm_widget *w, |
| @@ -681,6 +725,97 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w, | |||
| 681 | return 0; | 725 | return 0; |
| 682 | } | 726 | } |
| 683 | 727 | ||
| 728 | static void vmid_reference(struct snd_soc_codec *codec) | ||
| 729 | { | ||
| 730 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
| 731 | |||
| 732 | wm8994->vmid_refcount++; | ||
| 733 | |||
| 734 | dev_dbg(codec->dev, "Referencing VMID, refcount is now %d\n", | ||
| 735 | wm8994->vmid_refcount); | ||
| 736 | |||
| 737 | if (wm8994->vmid_refcount == 1) { | ||
| 738 | /* Startup bias, VMID ramp & buffer */ | ||
| 739 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
| 740 | WM8994_STARTUP_BIAS_ENA | | ||
| 741 | WM8994_VMID_BUF_ENA | | ||
| 742 | WM8994_VMID_RAMP_MASK, | ||
| 743 | WM8994_STARTUP_BIAS_ENA | | ||
| 744 | WM8994_VMID_BUF_ENA | | ||
| 745 | (0x11 << WM8994_VMID_RAMP_SHIFT)); | ||
| 746 | |||
| 747 | /* Main bias enable, VMID=2x40k */ | ||
| 748 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
| 749 | WM8994_BIAS_ENA | | ||
| 750 | WM8994_VMID_SEL_MASK, | ||
| 751 | WM8994_BIAS_ENA | 0x2); | ||
| 752 | |||
| 753 | msleep(20); | ||
| 754 | } | ||
| 755 | } | ||
| 756 | |||
| 757 | static void vmid_dereference(struct snd_soc_codec *codec) | ||
| 758 | { | ||
| 759 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | ||
| 760 | |||
| 761 | wm8994->vmid_refcount--; | ||
| 762 | |||
| 763 | dev_dbg(codec->dev, "Dereferencing VMID, refcount is now %d\n", | ||
| 764 | wm8994->vmid_refcount); | ||
| 765 | |||
| 766 | if (wm8994->vmid_refcount == 0) { | ||
| 767 | /* Switch over to startup biases */ | ||
| 768 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
| 769 | WM8994_BIAS_SRC | | ||
| 770 | WM8994_STARTUP_BIAS_ENA | | ||
| 771 | WM8994_VMID_BUF_ENA | | ||
| 772 | WM8994_VMID_RAMP_MASK, | ||
| 773 | WM8994_BIAS_SRC | | ||
| 774 | WM8994_STARTUP_BIAS_ENA | | ||
| 775 | WM8994_VMID_BUF_ENA | | ||
| 776 | (1 << WM8994_VMID_RAMP_SHIFT)); | ||
| 777 | |||
| 778 | /* Disable main biases */ | ||
| 779 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
| 780 | WM8994_BIAS_ENA | | ||
| 781 | WM8994_VMID_SEL_MASK, 0); | ||
| 782 | |||
| 783 | /* Discharge line */ | ||
| 784 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | ||
| 785 | WM8994_LINEOUT1_DISCH | | ||
| 786 | WM8994_LINEOUT2_DISCH, | ||
| 787 | WM8994_LINEOUT1_DISCH | | ||
| 788 | WM8994_LINEOUT2_DISCH); | ||
| 789 | |||
| 790 | msleep(5); | ||
| 791 | |||
| 792 | /* Switch off startup biases */ | ||
| 793 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
| 794 | WM8994_BIAS_SRC | | ||
| 795 | WM8994_STARTUP_BIAS_ENA | | ||
| 796 | WM8994_VMID_BUF_ENA | | ||
| 797 | WM8994_VMID_RAMP_MASK, 0); | ||
| 798 | } | ||
| 799 | } | ||
| 800 | |||
| 801 | static int vmid_event(struct snd_soc_dapm_widget *w, | ||
| 802 | struct snd_kcontrol *kcontrol, int event) | ||
| 803 | { | ||
| 804 | struct snd_soc_codec *codec = w->codec; | ||
| 805 | |||
| 806 | switch (event) { | ||
| 807 | case SND_SOC_DAPM_PRE_PMU: | ||
| 808 | vmid_reference(codec); | ||
| 809 | break; | ||
| 810 | |||
| 811 | case SND_SOC_DAPM_POST_PMD: | ||
| 812 | vmid_dereference(codec); | ||
| 813 | break; | ||
| 814 | } | ||
| 815 | |||
| 816 | return 0; | ||
| 817 | } | ||
| 818 | |||
| 684 | static void wm8994_update_class_w(struct snd_soc_codec *codec) | 819 | static void wm8994_update_class_w(struct snd_soc_codec *codec) |
| 685 | { | 820 | { |
| 686 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 821 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
| @@ -1208,6 +1343,8 @@ SND_SOC_DAPM_INPUT("Clock"), | |||
| 1208 | 1343 | ||
| 1209 | SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, | 1344 | SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, |
| 1210 | SND_SOC_DAPM_PRE_PMU), | 1345 | SND_SOC_DAPM_PRE_PMU), |
| 1346 | SND_SOC_DAPM_SUPPLY("VMID", SND_SOC_NOPM, 0, 0, vmid_event, | ||
| 1347 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 1211 | 1348 | ||
| 1212 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, | 1349 | SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, |
| 1213 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | 1350 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), |
| @@ -1282,7 +1419,7 @@ SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), | |||
| 1282 | SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), | 1419 | SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), |
| 1283 | 1420 | ||
| 1284 | SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), | 1421 | SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), |
| 1285 | SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), | 1422 | SND_SOC_DAPM_AIF_OUT("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), |
| 1286 | 1423 | ||
| 1287 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), | 1424 | SND_SOC_DAPM_SUPPLY("TOCLK", WM8994_CLOCKING_1, 4, 0, NULL, 0), |
| 1288 | 1425 | ||
| @@ -1525,6 +1662,8 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { | |||
| 1525 | static const struct snd_soc_dapm_route wm8994_intercon[] = { | 1662 | static const struct snd_soc_dapm_route wm8994_intercon[] = { |
| 1526 | { "AIF2DACL", NULL, "AIF2DAC Mux" }, | 1663 | { "AIF2DACL", NULL, "AIF2DAC Mux" }, |
| 1527 | { "AIF2DACR", NULL, "AIF2DAC Mux" }, | 1664 | { "AIF2DACR", NULL, "AIF2DAC Mux" }, |
| 1665 | { "MICBIAS1", NULL, "VMID" }, | ||
| 1666 | { "MICBIAS2", NULL, "VMID" }, | ||
| 1528 | }; | 1667 | }; |
| 1529 | 1668 | ||
| 1530 | static const struct snd_soc_dapm_route wm8958_intercon[] = { | 1669 | static const struct snd_soc_dapm_route wm8958_intercon[] = { |
| @@ -1629,10 +1768,12 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
| 1629 | unsigned int freq_in, unsigned int freq_out) | 1768 | unsigned int freq_in, unsigned int freq_out) |
| 1630 | { | 1769 | { |
| 1631 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 1770 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
| 1771 | struct wm8994 *control = codec->control_data; | ||
| 1632 | int reg_offset, ret; | 1772 | int reg_offset, ret; |
| 1633 | struct fll_div fll; | 1773 | struct fll_div fll; |
| 1634 | u16 reg, aif1, aif2; | 1774 | u16 reg, aif1, aif2; |
| 1635 | unsigned long timeout; | 1775 | unsigned long timeout; |
| 1776 | bool was_enabled; | ||
| 1636 | 1777 | ||
| 1637 | aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) | 1778 | aif1 = snd_soc_read(codec, WM8994_AIF1_CLOCKING_1) |
| 1638 | & WM8994_AIF1CLK_ENA; | 1779 | & WM8994_AIF1CLK_ENA; |
| @@ -1653,6 +1794,9 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
| 1653 | return -EINVAL; | 1794 | return -EINVAL; |
| 1654 | } | 1795 | } |
| 1655 | 1796 | ||
| 1797 | reg = snd_soc_read(codec, WM8994_FLL1_CONTROL_1 + reg_offset); | ||
| 1798 | was_enabled = reg & WM8994_FLL1_ENA; | ||
| 1799 | |||
| 1656 | switch (src) { | 1800 | switch (src) { |
| 1657 | case 0: | 1801 | case 0: |
| 1658 | /* Allow no source specification when stopping */ | 1802 | /* Allow no source specification when stopping */ |
| @@ -1719,6 +1863,21 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
| 1719 | 1863 | ||
| 1720 | /* Enable (with fractional mode if required) */ | 1864 | /* Enable (with fractional mode if required) */ |
| 1721 | if (freq_out) { | 1865 | if (freq_out) { |
| 1866 | /* Enable VMID if we need it */ | ||
| 1867 | if (!was_enabled) { | ||
| 1868 | switch (control->type) { | ||
| 1869 | case WM8994: | ||
| 1870 | vmid_reference(codec); | ||
| 1871 | break; | ||
| 1872 | case WM8958: | ||
| 1873 | if (wm8994->revision < 1) | ||
| 1874 | vmid_reference(codec); | ||
| 1875 | break; | ||
| 1876 | default: | ||
| 1877 | break; | ||
| 1878 | } | ||
| 1879 | } | ||
| 1880 | |||
| 1722 | if (fll.k) | 1881 | if (fll.k) |
| 1723 | reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; | 1882 | reg = WM8994_FLL1_ENA | WM8994_FLL1_FRAC; |
| 1724 | else | 1883 | else |
| @@ -1736,6 +1895,20 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
| 1736 | } else { | 1895 | } else { |
| 1737 | msleep(5); | 1896 | msleep(5); |
| 1738 | } | 1897 | } |
| 1898 | } else { | ||
| 1899 | if (was_enabled) { | ||
| 1900 | switch (control->type) { | ||
| 1901 | case WM8994: | ||
| 1902 | vmid_dereference(codec); | ||
| 1903 | break; | ||
| 1904 | case WM8958: | ||
| 1905 | if (wm8994->revision < 1) | ||
| 1906 | vmid_dereference(codec); | ||
| 1907 | break; | ||
| 1908 | default: | ||
| 1909 | break; | ||
| 1910 | } | ||
| 1911 | } | ||
| 1739 | } | 1912 | } |
| 1740 | 1913 | ||
| 1741 | wm8994->fll[id].in = freq_in; | 1914 | wm8994->fll[id].in = freq_in; |
| @@ -1852,9 +2025,6 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
| 1852 | break; | 2025 | break; |
| 1853 | 2026 | ||
| 1854 | case SND_SOC_BIAS_PREPARE: | 2027 | case SND_SOC_BIAS_PREPARE: |
| 1855 | /* VMID=2x40k */ | ||
| 1856 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
| 1857 | WM8994_VMID_SEL_MASK, 0x2); | ||
| 1858 | break; | 2028 | break; |
| 1859 | 2029 | ||
| 1860 | case SND_SOC_BIAS_STANDBY: | 2030 | case SND_SOC_BIAS_STANDBY: |
| @@ -1888,6 +2058,15 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
| 1888 | WM8958_CP_DISCH); | 2058 | WM8958_CP_DISCH); |
| 1889 | } | 2059 | } |
| 1890 | break; | 2060 | break; |
| 2061 | |||
| 2062 | case WM1811: | ||
| 2063 | if (wm8994->revision < 2) { | ||
| 2064 | snd_soc_write(codec, 0x102, 0x3); | ||
| 2065 | snd_soc_write(codec, 0x5d, 0x7e); | ||
| 2066 | snd_soc_write(codec, 0x5e, 0x0); | ||
| 2067 | snd_soc_write(codec, 0x102, 0x0); | ||
| 2068 | } | ||
| 2069 | break; | ||
| 1891 | } | 2070 | } |
| 1892 | 2071 | ||
| 1893 | /* Discharge LINEOUT1 & 2 */ | 2072 | /* Discharge LINEOUT1 & 2 */ |
| @@ -1896,65 +2075,13 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
| 1896 | WM8994_LINEOUT2_DISCH, | 2075 | WM8994_LINEOUT2_DISCH, |
| 1897 | WM8994_LINEOUT1_DISCH | | 2076 | WM8994_LINEOUT1_DISCH | |
| 1898 | WM8994_LINEOUT2_DISCH); | 2077 | WM8994_LINEOUT2_DISCH); |
| 1899 | |||
| 1900 | /* Startup bias, VMID ramp & buffer */ | ||
| 1901 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
| 1902 | WM8994_STARTUP_BIAS_ENA | | ||
| 1903 | WM8994_VMID_BUF_ENA | | ||
| 1904 | WM8994_VMID_RAMP_MASK, | ||
| 1905 | WM8994_STARTUP_BIAS_ENA | | ||
| 1906 | WM8994_VMID_BUF_ENA | | ||
| 1907 | (0x11 << WM8994_VMID_RAMP_SHIFT)); | ||
| 1908 | |||
| 1909 | /* Main bias enable, VMID=2x40k */ | ||
| 1910 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
| 1911 | WM8994_BIAS_ENA | | ||
| 1912 | WM8994_VMID_SEL_MASK, | ||
| 1913 | WM8994_BIAS_ENA | 0x2); | ||
| 1914 | |||
| 1915 | msleep(20); | ||
| 1916 | } | 2078 | } |
| 1917 | 2079 | ||
| 1918 | /* VMID=2x500k */ | ||
| 1919 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
| 1920 | WM8994_VMID_SEL_MASK, 0x4); | ||
| 1921 | 2080 | ||
| 1922 | break; | 2081 | break; |
| 1923 | 2082 | ||
| 1924 | case SND_SOC_BIAS_OFF: | 2083 | case SND_SOC_BIAS_OFF: |
| 1925 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { | 2084 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { |
| 1926 | /* Switch over to startup biases */ | ||
| 1927 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
| 1928 | WM8994_BIAS_SRC | | ||
| 1929 | WM8994_STARTUP_BIAS_ENA | | ||
| 1930 | WM8994_VMID_BUF_ENA | | ||
| 1931 | WM8994_VMID_RAMP_MASK, | ||
| 1932 | WM8994_BIAS_SRC | | ||
| 1933 | WM8994_STARTUP_BIAS_ENA | | ||
| 1934 | WM8994_VMID_BUF_ENA | | ||
| 1935 | (1 << WM8994_VMID_RAMP_SHIFT)); | ||
| 1936 | |||
| 1937 | /* Disable main biases */ | ||
| 1938 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | ||
| 1939 | WM8994_BIAS_ENA | | ||
| 1940 | WM8994_VMID_SEL_MASK, 0); | ||
| 1941 | |||
| 1942 | /* Discharge line */ | ||
| 1943 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | ||
| 1944 | WM8994_LINEOUT1_DISCH | | ||
| 1945 | WM8994_LINEOUT2_DISCH, | ||
| 1946 | WM8994_LINEOUT1_DISCH | | ||
| 1947 | WM8994_LINEOUT2_DISCH); | ||
| 1948 | |||
| 1949 | msleep(5); | ||
| 1950 | |||
| 1951 | /* Switch off startup biases */ | ||
| 1952 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
| 1953 | WM8994_BIAS_SRC | | ||
| 1954 | WM8994_STARTUP_BIAS_ENA | | ||
| 1955 | WM8994_VMID_BUF_ENA | | ||
| 1956 | WM8994_VMID_RAMP_MASK, 0); | ||
| 1957 | |||
| 1958 | wm8994->cur_fw = NULL; | 2085 | wm8994->cur_fw = NULL; |
| 1959 | 2086 | ||
| 1960 | pm_runtime_put(codec->dev); | 2087 | pm_runtime_put(codec->dev); |
| @@ -2055,10 +2182,18 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
| 2055 | 2182 | ||
| 2056 | /* The AIF2 format configuration needs to be mirrored to AIF3 | 2183 | /* The AIF2 format configuration needs to be mirrored to AIF3 |
| 2057 | * on WM8958 if it's in use so just do it all the time. */ | 2184 | * on WM8958 if it's in use so just do it all the time. */ |
| 2058 | if (control->type == WM8958 && dai->id == 2) | 2185 | switch (control->type) { |
| 2059 | snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1, | 2186 | case WM1811: |
| 2060 | WM8994_AIF1_LRCLK_INV | | 2187 | case WM8958: |
| 2061 | WM8958_AIF3_FMT_MASK, aif1); | 2188 | if (dai->id == 2) |
| 2189 | snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1, | ||
| 2190 | WM8994_AIF1_LRCLK_INV | | ||
| 2191 | WM8958_AIF3_FMT_MASK, aif1); | ||
| 2192 | break; | ||
| 2193 | |||
| 2194 | default: | ||
| 2195 | break; | ||
| 2196 | } | ||
| 2062 | 2197 | ||
| 2063 | snd_soc_update_bits(codec, aif1_reg, | 2198 | snd_soc_update_bits(codec, aif1_reg, |
| 2064 | WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | | 2199 | WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | |
| @@ -2100,7 +2235,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
| 2100 | struct snd_soc_dai *dai) | 2235 | struct snd_soc_dai *dai) |
| 2101 | { | 2236 | { |
| 2102 | struct snd_soc_codec *codec = dai->codec; | 2237 | struct snd_soc_codec *codec = dai->codec; |
| 2103 | struct wm8994 *control = codec->control_data; | ||
| 2104 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2238 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
| 2105 | int aif1_reg; | 2239 | int aif1_reg; |
| 2106 | int aif2_reg; | 2240 | int aif2_reg; |
| @@ -2143,14 +2277,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
| 2143 | dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); | 2277 | dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); |
| 2144 | } | 2278 | } |
| 2145 | break; | 2279 | break; |
| 2146 | case 3: | ||
| 2147 | switch (control->type) { | ||
| 2148 | case WM8958: | ||
| 2149 | aif1_reg = WM8958_AIF3_CONTROL_1; | ||
| 2150 | break; | ||
| 2151 | default: | ||
| 2152 | return 0; | ||
| 2153 | } | ||
| 2154 | default: | 2280 | default: |
| 2155 | return -EINVAL; | 2281 | return -EINVAL; |
| 2156 | } | 2282 | } |
| @@ -2271,6 +2397,7 @@ static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream, | |||
| 2271 | switch (dai->id) { | 2397 | switch (dai->id) { |
| 2272 | case 3: | 2398 | case 3: |
| 2273 | switch (control->type) { | 2399 | switch (control->type) { |
| 2400 | case WM1811: | ||
| 2274 | case WM8958: | 2401 | case WM8958: |
| 2275 | aif1_reg = WM8958_AIF3_CONTROL_1; | 2402 | aif1_reg = WM8958_AIF3_CONTROL_1; |
| 2276 | break; | 2403 | break; |
| @@ -2311,7 +2438,7 @@ static void wm8994_aif_shutdown(struct snd_pcm_substream *substream, | |||
| 2311 | rate_reg = WM8994_AIF1_RATE; | 2438 | rate_reg = WM8994_AIF1_RATE; |
| 2312 | break; | 2439 | break; |
| 2313 | case 2: | 2440 | case 2: |
| 2314 | rate_reg = WM8994_AIF1_RATE; | 2441 | rate_reg = WM8994_AIF2_RATE; |
| 2315 | break; | 2442 | break; |
| 2316 | default: | 2443 | default: |
| 2317 | break; | 2444 | break; |
| @@ -2384,6 +2511,21 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate) | |||
| 2384 | return snd_soc_update_bits(codec, reg, mask, val); | 2511 | return snd_soc_update_bits(codec, reg, mask, val); |
| 2385 | } | 2512 | } |
| 2386 | 2513 | ||
| 2514 | static int wm8994_aif2_probe(struct snd_soc_dai *dai) | ||
| 2515 | { | ||
| 2516 | struct snd_soc_codec *codec = dai->codec; | ||
| 2517 | |||
| 2518 | /* Disable the pulls on the AIF if we're using it to save power. */ | ||
| 2519 | snd_soc_update_bits(codec, WM8994_GPIO_3, | ||
| 2520 | WM8994_GPN_PU | WM8994_GPN_PD, 0); | ||
| 2521 | snd_soc_update_bits(codec, WM8994_GPIO_4, | ||
| 2522 | WM8994_GPN_PU | WM8994_GPN_PD, 0); | ||
| 2523 | snd_soc_update_bits(codec, WM8994_GPIO_5, | ||
| 2524 | WM8994_GPN_PU | WM8994_GPN_PD, 0); | ||
| 2525 | |||
| 2526 | return 0; | ||
| 2527 | } | ||
| 2528 | |||
| 2387 | #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 | 2529 | #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 |
| 2388 | 2530 | ||
| 2389 | #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 2531 | #define WM8994_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| @@ -2451,6 +2593,7 @@ static struct snd_soc_dai_driver wm8994_dai[] = { | |||
| 2451 | .rates = WM8994_RATES, | 2593 | .rates = WM8994_RATES, |
| 2452 | .formats = WM8994_FORMATS, | 2594 | .formats = WM8994_FORMATS, |
| 2453 | }, | 2595 | }, |
| 2596 | .probe = wm8994_aif2_probe, | ||
| 2454 | .ops = &wm8994_aif2_dai_ops, | 2597 | .ops = &wm8994_aif2_dai_ops, |
| 2455 | }, | 2598 | }, |
| 2456 | { | 2599 | { |
| @@ -2485,6 +2628,7 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
| 2485 | case WM8994: | 2628 | case WM8994: |
| 2486 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); | 2629 | snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0); |
| 2487 | break; | 2630 | break; |
| 2631 | case WM1811: | ||
| 2488 | case WM8958: | 2632 | case WM8958: |
| 2489 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 2633 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
| 2490 | WM8958_MICD_ENA, 0); | 2634 | WM8958_MICD_ENA, 0); |
| @@ -2553,6 +2697,7 @@ static int wm8994_resume(struct snd_soc_codec *codec) | |||
| 2553 | snd_soc_update_bits(codec, WM8994_MICBIAS, | 2697 | snd_soc_update_bits(codec, WM8994_MICBIAS, |
| 2554 | WM8994_MICD_ENA, WM8994_MICD_ENA); | 2698 | WM8994_MICD_ENA, WM8994_MICD_ENA); |
| 2555 | break; | 2699 | break; |
| 2700 | case WM1811: | ||
| 2556 | case WM8958: | 2701 | case WM8958: |
| 2557 | if (wm8994->jack_cb) | 2702 | if (wm8994->jack_cb) |
| 2558 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, | 2703 | snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, |
| @@ -2851,8 +2996,13 @@ int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
| 2851 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); | 2996 | struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); |
| 2852 | struct wm8994 *control = codec->control_data; | 2997 | struct wm8994 *control = codec->control_data; |
| 2853 | 2998 | ||
| 2854 | if (control->type != WM8958) | 2999 | switch (control->type) { |
| 3000 | case WM1811: | ||
| 3001 | case WM8958: | ||
| 3002 | break; | ||
| 3003 | default: | ||
| 2855 | return -EINVAL; | 3004 | return -EINVAL; |
| 3005 | } | ||
| 2856 | 3006 | ||
| 2857 | if (jack) { | 3007 | if (jack) { |
| 2858 | if (!cb) { | 3008 | if (!cb) { |
| @@ -2916,6 +3066,24 @@ static irqreturn_t wm8994_fifo_error(int irq, void *data) | |||
| 2916 | return IRQ_HANDLED; | 3066 | return IRQ_HANDLED; |
| 2917 | } | 3067 | } |
| 2918 | 3068 | ||
| 3069 | static irqreturn_t wm8994_temp_warn(int irq, void *data) | ||
| 3070 | { | ||
| 3071 | struct snd_soc_codec *codec = data; | ||
| 3072 | |||
| 3073 | dev_err(codec->dev, "Thermal warning\n"); | ||
| 3074 | |||
| 3075 | return IRQ_HANDLED; | ||
| 3076 | } | ||
| 3077 | |||
| 3078 | static irqreturn_t wm8994_temp_shut(int irq, void *data) | ||
| 3079 | { | ||
| 3080 | struct snd_soc_codec *codec = data; | ||
| 3081 | |||
| 3082 | dev_crit(codec->dev, "Thermal shutdown\n"); | ||
| 3083 | |||
| 3084 | return IRQ_HANDLED; | ||
| 3085 | } | ||
| 3086 | |||
| 2919 | static int wm8994_codec_probe(struct snd_soc_codec *codec) | 3087 | static int wm8994_codec_probe(struct snd_soc_codec *codec) |
| 2920 | { | 3088 | { |
| 2921 | struct wm8994 *control; | 3089 | struct wm8994 *control; |
| @@ -2972,13 +3140,14 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 2972 | switch (wm8994->revision) { | 3140 | switch (wm8994->revision) { |
| 2973 | case 2: | 3141 | case 2: |
| 2974 | case 3: | 3142 | case 3: |
| 2975 | wm8994->hubs.dcs_codes = -5; | 3143 | wm8994->hubs.dcs_codes_l = -5; |
| 3144 | wm8994->hubs.dcs_codes_r = -5; | ||
| 2976 | wm8994->hubs.hp_startup_mode = 1; | 3145 | wm8994->hubs.hp_startup_mode = 1; |
| 2977 | wm8994->hubs.dcs_readback_mode = 1; | 3146 | wm8994->hubs.dcs_readback_mode = 1; |
| 2978 | wm8994->hubs.series_startup = 1; | 3147 | wm8994->hubs.series_startup = 1; |
| 2979 | break; | 3148 | break; |
| 2980 | default: | 3149 | default: |
| 2981 | wm8994->hubs.dcs_readback_mode = 1; | 3150 | wm8994->hubs.dcs_readback_mode = 2; |
| 2982 | break; | 3151 | break; |
| 2983 | } | 3152 | } |
| 2984 | break; | 3153 | break; |
| @@ -2987,12 +3156,34 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 2987 | wm8994->hubs.dcs_readback_mode = 1; | 3156 | wm8994->hubs.dcs_readback_mode = 1; |
| 2988 | break; | 3157 | break; |
| 2989 | 3158 | ||
| 3159 | case WM1811: | ||
| 3160 | wm8994->hubs.dcs_readback_mode = 2; | ||
| 3161 | wm8994->hubs.no_series_update = 1; | ||
| 3162 | |||
| 3163 | switch (wm8994->revision) { | ||
| 3164 | case 0: | ||
| 3165 | case 1: | ||
| 3166 | wm8994->hubs.dcs_codes_l = -9; | ||
| 3167 | wm8994->hubs.dcs_codes_r = -5; | ||
| 3168 | break; | ||
| 3169 | default: | ||
| 3170 | break; | ||
| 3171 | } | ||
| 3172 | |||
| 3173 | snd_soc_update_bits(codec, WM8994_ANALOGUE_HP_1, | ||
| 3174 | WM1811_HPOUT1_ATTN, WM1811_HPOUT1_ATTN); | ||
| 3175 | break; | ||
| 3176 | |||
| 2990 | default: | 3177 | default: |
| 2991 | break; | 3178 | break; |
| 2992 | } | 3179 | } |
| 2993 | 3180 | ||
| 2994 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, | 3181 | wm8994_request_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, |
| 2995 | wm8994_fifo_error, "FIFO error", codec); | 3182 | wm8994_fifo_error, "FIFO error", codec); |
| 3183 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_WARN, | ||
| 3184 | wm8994_temp_warn, "Thermal warning", codec); | ||
| 3185 | wm8994_request_irq(wm8994->control_data, WM8994_IRQ_TEMP_SHUT, | ||
| 3186 | wm8994_temp_shut, "Thermal shutdown", codec); | ||
| 2996 | 3187 | ||
| 2997 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3188 | ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
| 2998 | wm_hubs_dcs_done, "DC servo done", | 3189 | wm_hubs_dcs_done, "DC servo done", |
| @@ -3043,6 +3234,7 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 3043 | break; | 3234 | break; |
| 3044 | 3235 | ||
| 3045 | case WM8958: | 3236 | case WM8958: |
| 3237 | case WM1811: | ||
| 3046 | if (wm8994->micdet_irq) { | 3238 | if (wm8994->micdet_irq) { |
| 3047 | ret = request_threaded_irq(wm8994->micdet_irq, NULL, | 3239 | ret = request_threaded_irq(wm8994->micdet_irq, NULL, |
| 3048 | wm8958_mic_irq, | 3240 | wm8958_mic_irq, |
| @@ -3205,6 +3397,19 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 3205 | ARRAY_SIZE(wm8994_dac_widgets)); | 3397 | ARRAY_SIZE(wm8994_dac_widgets)); |
| 3206 | } | 3398 | } |
| 3207 | break; | 3399 | break; |
| 3400 | |||
| 3401 | case WM1811: | ||
| 3402 | snd_soc_add_controls(codec, wm8958_snd_controls, | ||
| 3403 | ARRAY_SIZE(wm8958_snd_controls)); | ||
| 3404 | snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, | ||
| 3405 | ARRAY_SIZE(wm8958_dapm_widgets)); | ||
| 3406 | snd_soc_dapm_new_controls(dapm, wm8994_lateclk_widgets, | ||
| 3407 | ARRAY_SIZE(wm8994_lateclk_widgets)); | ||
| 3408 | snd_soc_dapm_new_controls(dapm, wm8994_adc_widgets, | ||
| 3409 | ARRAY_SIZE(wm8994_adc_widgets)); | ||
| 3410 | snd_soc_dapm_new_controls(dapm, wm8994_dac_widgets, | ||
| 3411 | ARRAY_SIZE(wm8994_dac_widgets)); | ||
| 3412 | break; | ||
| 3208 | } | 3413 | } |
| 3209 | 3414 | ||
| 3210 | 3415 | ||
| @@ -3241,6 +3446,12 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 3241 | 3446 | ||
| 3242 | wm8958_dsp2_init(codec); | 3447 | wm8958_dsp2_init(codec); |
| 3243 | break; | 3448 | break; |
| 3449 | case WM1811: | ||
| 3450 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_intercon, | ||
| 3451 | ARRAY_SIZE(wm8994_lateclk_intercon)); | ||
| 3452 | snd_soc_dapm_add_routes(dapm, wm8958_intercon, | ||
| 3453 | ARRAY_SIZE(wm8958_intercon)); | ||
| 3454 | break; | ||
| 3244 | } | 3455 | } |
| 3245 | 3456 | ||
| 3246 | return 0; | 3457 | return 0; |
| @@ -3257,6 +3468,8 @@ err_irq: | |||
| 3257 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3468 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
| 3258 | &wm8994->hubs); | 3469 | &wm8994->hubs); |
| 3259 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); | 3470 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); |
| 3471 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec); | ||
| 3472 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec); | ||
| 3260 | err: | 3473 | err: |
| 3261 | kfree(wm8994); | 3474 | kfree(wm8994); |
| 3262 | return ret; | 3475 | return ret; |
| @@ -3279,6 +3492,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
| 3279 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, | 3492 | wm8994_free_irq(codec->control_data, WM8994_IRQ_DCS_DONE, |
| 3280 | &wm8994->hubs); | 3493 | &wm8994->hubs); |
| 3281 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); | 3494 | wm8994_free_irq(codec->control_data, WM8994_IRQ_FIFOS_ERR, codec); |
| 3495 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_SHUT, codec); | ||
| 3496 | wm8994_free_irq(codec->control_data, WM8994_IRQ_TEMP_WARN, codec); | ||
| 3282 | 3497 | ||
| 3283 | switch (control->type) { | 3498 | switch (control->type) { |
| 3284 | case WM8994: | 3499 | case WM8994: |
| @@ -3292,6 +3507,7 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) | |||
| 3292 | wm8994); | 3507 | wm8994); |
| 3293 | break; | 3508 | break; |
| 3294 | 3509 | ||
| 3510 | case WM1811: | ||
| 3295 | case WM8958: | 3511 | case WM8958: |
| 3296 | if (wm8994->micdet_irq) | 3512 | if (wm8994->micdet_irq) |
| 3297 | free_irq(wm8994->micdet_irq, wm8994); | 3513 | free_irq(wm8994->micdet_irq, wm8994); |
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 1ab2266039f7..f4f1355efc82 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h | |||
| @@ -83,6 +83,8 @@ struct wm8994_priv { | |||
| 83 | struct completion fll_locked[2]; | 83 | struct completion fll_locked[2]; |
| 84 | bool fll_locked_irq; | 84 | bool fll_locked_irq; |
| 85 | 85 | ||
| 86 | int vmid_refcount; | ||
| 87 | |||
| 86 | int dac_rates[2]; | 88 | int dac_rates[2]; |
| 87 | int lrclk_shared[2]; | 89 | int lrclk_shared[2]; |
| 88 | 90 | ||
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 5ad873fda814..78eeb21e6696 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c | |||
| @@ -485,7 +485,7 @@ static int configure_aif_clock(struct snd_soc_codec *codec, int aif) | |||
| 485 | static int configure_clock(struct snd_soc_codec *codec) | 485 | static int configure_clock(struct snd_soc_codec *codec) |
| 486 | { | 486 | { |
| 487 | struct wm8995_priv *wm8995; | 487 | struct wm8995_priv *wm8995; |
| 488 | int old, new; | 488 | int change, new; |
| 489 | 489 | ||
| 490 | wm8995 = snd_soc_codec_get_drvdata(codec); | 490 | wm8995 = snd_soc_codec_get_drvdata(codec); |
| 491 | 491 | ||
| @@ -509,15 +509,11 @@ static int configure_clock(struct snd_soc_codec *codec) | |||
| 509 | else | 509 | else |
| 510 | new = 0; | 510 | new = 0; |
| 511 | 511 | ||
| 512 | old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC; | 512 | change = snd_soc_update_bits(codec, WM8995_CLOCKING_1, |
| 513 | 513 | WM8995_SYSCLK_SRC_MASK, new); | |
| 514 | /* If there's no change then we're done. */ | 514 | if (!change) |
| 515 | if (old == new) | ||
| 516 | return 0; | 515 | return 0; |
| 517 | 516 | ||
| 518 | snd_soc_update_bits(codec, WM8995_CLOCKING_1, | ||
| 519 | WM8995_SYSCLK_SRC_MASK, new); | ||
| 520 | |||
| 521 | snd_soc_dapm_sync(&codec->dapm); | 517 | snd_soc_dapm_sync(&codec->dapm); |
| 522 | 518 | ||
| 523 | return 0; | 519 | return 0; |
| @@ -1573,11 +1569,16 @@ static int wm8995_resume(struct snd_soc_codec *codec) | |||
| 1573 | static int wm8995_remove(struct snd_soc_codec *codec) | 1569 | static int wm8995_remove(struct snd_soc_codec *codec) |
| 1574 | { | 1570 | { |
| 1575 | struct wm8995_priv *wm8995; | 1571 | struct wm8995_priv *wm8995; |
| 1576 | struct i2c_client *i2c; | 1572 | int i; |
| 1577 | 1573 | ||
| 1578 | i2c = container_of(codec->dev, struct i2c_client, dev); | ||
| 1579 | wm8995 = snd_soc_codec_get_drvdata(codec); | 1574 | wm8995 = snd_soc_codec_get_drvdata(codec); |
| 1580 | wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1575 | wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); |
| 1576 | |||
| 1577 | for (i = 0; i < ARRAY_SIZE(wm8995->supplies); ++i) | ||
| 1578 | regulator_unregister_notifier(wm8995->supplies[i].consumer, | ||
| 1579 | &wm8995->disable_nb[i]); | ||
| 1580 | |||
| 1581 | regulator_bulk_free(ARRAY_SIZE(wm8995->supplies), wm8995->supplies); | ||
| 1581 | return 0; | 1582 | return 0; |
| 1582 | } | 1583 | } |
| 1583 | 1584 | ||
| @@ -1642,6 +1643,7 @@ static int wm8995_probe(struct snd_soc_codec *codec) | |||
| 1642 | 1643 | ||
| 1643 | if (ret != 0x8995) { | 1644 | if (ret != 0x8995) { |
| 1644 | dev_err(codec->dev, "Invalid device ID: %#x\n", ret); | 1645 | dev_err(codec->dev, "Invalid device ID: %#x\n", ret); |
| 1646 | ret = -EINVAL; | ||
| 1645 | goto err_reg_enable; | 1647 | goto err_reg_enable; |
| 1646 | } | 1648 | } |
| 1647 | 1649 | ||
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c index 0cdb9d105671..645c980d6b80 100644 --- a/sound/soc/codecs/wm8996.c +++ b/sound/soc/codecs/wm8996.c | |||
| @@ -41,12 +41,11 @@ | |||
| 41 | #define HPOUT2L 4 | 41 | #define HPOUT2L 4 |
| 42 | #define HPOUT2R 8 | 42 | #define HPOUT2R 8 |
| 43 | 43 | ||
| 44 | #define WM8996_NUM_SUPPLIES 4 | 44 | #define WM8996_NUM_SUPPLIES 3 |
| 45 | static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { | 45 | static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = { |
| 46 | "DBVDD", | 46 | "DBVDD", |
| 47 | "AVDD1", | 47 | "AVDD1", |
| 48 | "AVDD2", | 48 | "AVDD2", |
| 49 | "CPVDD", | ||
| 50 | }; | 49 | }; |
| 51 | 50 | ||
| 52 | struct wm8996_priv { | 51 | struct wm8996_priv { |
| @@ -71,6 +70,8 @@ struct wm8996_priv { | |||
| 71 | 70 | ||
| 72 | struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; | 71 | struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES]; |
| 73 | struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; | 72 | struct notifier_block disable_nb[WM8996_NUM_SUPPLIES]; |
| 73 | struct regulator *cpvdd; | ||
| 74 | int bg_ena; | ||
| 74 | 75 | ||
| 75 | struct wm8996_pdata pdata; | 76 | struct wm8996_pdata pdata; |
| 76 | 77 | ||
| @@ -112,7 +113,6 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \ | |||
| 112 | WM8996_REGULATOR_EVENT(0) | 113 | WM8996_REGULATOR_EVENT(0) |
| 113 | WM8996_REGULATOR_EVENT(1) | 114 | WM8996_REGULATOR_EVENT(1) |
| 114 | WM8996_REGULATOR_EVENT(2) | 115 | WM8996_REGULATOR_EVENT(2) |
| 115 | WM8996_REGULATOR_EVENT(3) | ||
| 116 | 116 | ||
| 117 | static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { | 117 | static const u16 wm8996_reg[WM8996_MAX_REGISTER] = { |
| 118 | [WM8996_SOFTWARE_RESET] = 0x8996, | 118 | [WM8996_SOFTWARE_RESET] = 0x8996, |
| @@ -414,6 +414,7 @@ static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0); | |||
| 414 | static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); | 414 | static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0); |
| 415 | static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); | 415 | static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0); |
| 416 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); | 416 | static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0); |
| 417 | static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1); | ||
| 417 | 418 | ||
| 418 | static const char *sidetone_hpf_text[] = { | 419 | static const char *sidetone_hpf_text[] = { |
| 419 | "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" | 420 | "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz" |
| @@ -608,6 +609,14 @@ SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0), | |||
| 608 | SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), | 609 | SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0), |
| 609 | SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), | 610 | SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0), |
| 610 | 611 | ||
| 612 | SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0), | ||
| 613 | SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0), | ||
| 614 | |||
| 615 | SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15, | ||
| 616 | 0, threedstereo_tlv), | ||
| 617 | SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15, | ||
| 618 | 0, threedstereo_tlv), | ||
| 619 | |||
| 611 | SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, | 620 | SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4, |
| 612 | 8, 0, out_digital_tlv), | 621 | 8, 0, out_digital_tlv), |
| 613 | SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, | 622 | SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4, |
| @@ -632,6 +641,14 @@ SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER, | |||
| 632 | 641 | ||
| 633 | SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0), | 642 | SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0), |
| 634 | SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), | 643 | SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0), |
| 644 | |||
| 645 | SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0), | ||
| 646 | SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0), | ||
| 647 | SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0), | ||
| 648 | |||
| 649 | SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0), | ||
| 650 | SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0), | ||
| 651 | SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0), | ||
| 635 | }; | 652 | }; |
| 636 | 653 | ||
| 637 | static const struct snd_kcontrol_new wm8996_eq_controls[] = { | 654 | static const struct snd_kcontrol_new wm8996_eq_controls[] = { |
| @@ -658,19 +675,75 @@ SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0, | |||
| 658 | eq_tlv), | 675 | eq_tlv), |
| 659 | }; | 676 | }; |
| 660 | 677 | ||
| 678 | static void wm8996_bg_enable(struct snd_soc_codec *codec) | ||
| 679 | { | ||
| 680 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
| 681 | |||
| 682 | wm8996->bg_ena++; | ||
| 683 | if (wm8996->bg_ena == 1) { | ||
| 684 | snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1, | ||
| 685 | WM8996_BG_ENA, WM8996_BG_ENA); | ||
| 686 | msleep(2); | ||
| 687 | } | ||
| 688 | } | ||
| 689 | |||
| 690 | static void wm8996_bg_disable(struct snd_soc_codec *codec) | ||
| 691 | { | ||
| 692 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
| 693 | |||
| 694 | wm8996->bg_ena--; | ||
| 695 | if (!wm8996->bg_ena) | ||
| 696 | snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1, | ||
| 697 | WM8996_BG_ENA, 0); | ||
| 698 | } | ||
| 699 | |||
| 700 | static int bg_event(struct snd_soc_dapm_widget *w, | ||
| 701 | struct snd_kcontrol *kcontrol, int event) | ||
| 702 | { | ||
| 703 | struct snd_soc_codec *codec = w->codec; | ||
| 704 | int ret = 0; | ||
| 705 | |||
| 706 | switch (event) { | ||
| 707 | case SND_SOC_DAPM_PRE_PMU: | ||
| 708 | wm8996_bg_enable(codec); | ||
| 709 | break; | ||
| 710 | case SND_SOC_DAPM_POST_PMD: | ||
| 711 | wm8996_bg_disable(codec); | ||
| 712 | break; | ||
| 713 | default: | ||
| 714 | BUG(); | ||
| 715 | ret = -EINVAL; | ||
| 716 | } | ||
| 717 | |||
| 718 | return ret; | ||
| 719 | } | ||
| 720 | |||
| 661 | static int cp_event(struct snd_soc_dapm_widget *w, | 721 | static int cp_event(struct snd_soc_dapm_widget *w, |
| 662 | struct snd_kcontrol *kcontrol, int event) | 722 | struct snd_kcontrol *kcontrol, int event) |
| 663 | { | 723 | { |
| 724 | struct snd_soc_codec *codec = w->codec; | ||
| 725 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
| 726 | int ret = 0; | ||
| 727 | |||
| 664 | switch (event) { | 728 | switch (event) { |
| 729 | case SND_SOC_DAPM_PRE_PMU: | ||
| 730 | ret = regulator_enable(wm8996->cpvdd); | ||
| 731 | if (ret != 0) | ||
| 732 | dev_err(codec->dev, "Failed to enable CPVDD: %d\n", | ||
| 733 | ret); | ||
| 734 | break; | ||
| 665 | case SND_SOC_DAPM_POST_PMU: | 735 | case SND_SOC_DAPM_POST_PMU: |
| 666 | msleep(5); | 736 | msleep(5); |
| 667 | break; | 737 | break; |
| 738 | case SND_SOC_DAPM_POST_PMD: | ||
| 739 | regulator_disable_deferred(wm8996->cpvdd, 20); | ||
| 740 | break; | ||
| 668 | default: | 741 | default: |
| 669 | BUG(); | 742 | BUG(); |
| 670 | return -EINVAL; | 743 | ret = -EINVAL; |
| 671 | } | 744 | } |
| 672 | 745 | ||
| 673 | return 0; | 746 | return ret; |
| 674 | } | 747 | } |
| 675 | 748 | ||
| 676 | static int rmv_short_event(struct snd_soc_dapm_widget *w, | 749 | static int rmv_short_event(struct snd_soc_dapm_widget *w, |
| @@ -698,7 +771,7 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask) | |||
| 698 | { | 771 | { |
| 699 | struct i2c_client *i2c = to_i2c_client(codec->dev); | 772 | struct i2c_client *i2c = to_i2c_client(codec->dev); |
| 700 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 773 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
| 701 | int i, ret; | 774 | int ret; |
| 702 | unsigned long timeout = 200; | 775 | unsigned long timeout = 200; |
| 703 | 776 | ||
| 704 | snd_soc_write(codec, WM8996_DC_SERVO_2, mask); | 777 | snd_soc_write(codec, WM8996_DC_SERVO_2, mask); |
| @@ -713,15 +786,12 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec, u16 mask) | |||
| 713 | 786 | ||
| 714 | } else { | 787 | } else { |
| 715 | msleep(1); | 788 | msleep(1); |
| 716 | if (--i) { | 789 | timeout--; |
| 717 | timeout = 0; | ||
| 718 | break; | ||
| 719 | } | ||
| 720 | } | 790 | } |
| 721 | 791 | ||
| 722 | ret = snd_soc_read(codec, WM8996_DC_SERVO_2); | 792 | ret = snd_soc_read(codec, WM8996_DC_SERVO_2); |
| 723 | dev_dbg(codec->dev, "DC servo state: %x\n", ret); | 793 | dev_dbg(codec->dev, "DC servo state: %x\n", ret); |
| 724 | } while (ret & mask); | 794 | } while (timeout && ret & mask); |
| 725 | 795 | ||
| 726 | if (timeout == 0) | 796 | if (timeout == 0) |
| 727 | dev_err(codec->dev, "DC servo timed out for %x\n", mask); | 797 | dev_err(codec->dev, "DC servo timed out for %x\n", mask); |
| @@ -979,9 +1049,12 @@ SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0), | |||
| 979 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), | 1049 | SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0), |
| 980 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), | 1050 | SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0), |
| 981 | SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, | 1051 | SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event, |
| 982 | SND_SOC_DAPM_POST_PMU), | 1052 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), |
| 983 | 1053 | SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event, | |
| 1054 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), | ||
| 984 | SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), | 1055 | SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0), |
| 1056 | SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0), | ||
| 1057 | SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0), | ||
| 985 | SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), | 1058 | SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0), |
| 986 | SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), | 1059 | SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0), |
| 987 | 1060 | ||
| @@ -1035,14 +1108,14 @@ SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0), | |||
| 1035 | SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), | 1108 | SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0), |
| 1036 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), | 1109 | SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0), |
| 1037 | 1110 | ||
| 1038 | SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 1, | 1111 | SND_SOC_DAPM_AIF_IN("AIF2RX1", "AIF2 Playback", 0, |
| 1039 | WM8996_POWER_MANAGEMENT_4, 9, 0), | 1112 | WM8996_POWER_MANAGEMENT_4, 9, 0), |
| 1040 | SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 2, | 1113 | SND_SOC_DAPM_AIF_IN("AIF2RX0", "AIF2 Playback", 1, |
| 1041 | WM8996_POWER_MANAGEMENT_4, 8, 0), | 1114 | WM8996_POWER_MANAGEMENT_4, 8, 0), |
| 1042 | 1115 | ||
| 1043 | SND_SOC_DAPM_AIF_IN("AIF2TX1", "AIF2 Capture", 1, | 1116 | SND_SOC_DAPM_AIF_OUT("AIF2TX1", "AIF2 Capture", 0, |
| 1044 | WM8996_POWER_MANAGEMENT_6, 9, 0), | 1117 | WM8996_POWER_MANAGEMENT_6, 9, 0), |
| 1045 | SND_SOC_DAPM_AIF_IN("AIF2TX0", "AIF2 Capture", 2, | 1118 | SND_SOC_DAPM_AIF_OUT("AIF2TX0", "AIF2 Capture", 1, |
| 1046 | WM8996_POWER_MANAGEMENT_6, 8, 0), | 1119 | WM8996_POWER_MANAGEMENT_6, 8, 0), |
| 1047 | 1120 | ||
| 1048 | SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, | 1121 | SND_SOC_DAPM_AIF_IN("AIF1RX5", "AIF1 Playback", 5, |
| @@ -1137,17 +1210,23 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
| 1137 | { "Charge Pump", NULL, "SYSCLK" }, | 1210 | { "Charge Pump", NULL, "SYSCLK" }, |
| 1138 | 1211 | ||
| 1139 | { "MICB1", NULL, "LDO2" }, | 1212 | { "MICB1", NULL, "LDO2" }, |
| 1213 | { "MICB1", NULL, "MICB1 Audio" }, | ||
| 1214 | { "MICB1", NULL, "Bandgap" }, | ||
| 1140 | { "MICB2", NULL, "LDO2" }, | 1215 | { "MICB2", NULL, "LDO2" }, |
| 1216 | { "MICB2", NULL, "MICB2 Audio" }, | ||
| 1217 | { "MICB2", NULL, "Bandgap" }, | ||
| 1141 | 1218 | ||
| 1142 | { "IN1L PGA", NULL, "IN2LN" }, | 1219 | { "IN1L PGA", NULL, "IN2LN" }, |
| 1143 | { "IN1L PGA", NULL, "IN2LP" }, | 1220 | { "IN1L PGA", NULL, "IN2LP" }, |
| 1144 | { "IN1L PGA", NULL, "IN1LN" }, | 1221 | { "IN1L PGA", NULL, "IN1LN" }, |
| 1145 | { "IN1L PGA", NULL, "IN1LP" }, | 1222 | { "IN1L PGA", NULL, "IN1LP" }, |
| 1223 | { "IN1L PGA", NULL, "Bandgap" }, | ||
| 1146 | 1224 | ||
| 1147 | { "IN1R PGA", NULL, "IN2RN" }, | 1225 | { "IN1R PGA", NULL, "IN2RN" }, |
| 1148 | { "IN1R PGA", NULL, "IN2RP" }, | 1226 | { "IN1R PGA", NULL, "IN2RP" }, |
| 1149 | { "IN1R PGA", NULL, "IN1RN" }, | 1227 | { "IN1R PGA", NULL, "IN1RN" }, |
| 1150 | { "IN1R PGA", NULL, "IN1RP" }, | 1228 | { "IN1R PGA", NULL, "IN1RP" }, |
| 1229 | { "IN1R PGA", NULL, "Bandgap" }, | ||
| 1151 | 1230 | ||
| 1152 | { "ADCL", NULL, "IN1L PGA" }, | 1231 | { "ADCL", NULL, "IN1L PGA" }, |
| 1153 | 1232 | ||
| @@ -1281,6 +1360,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
| 1281 | { "DAC2R", NULL, "DAC2R Mixer" }, | 1360 | { "DAC2R", NULL, "DAC2R Mixer" }, |
| 1282 | 1361 | ||
| 1283 | { "HPOUT2L PGA", NULL, "Charge Pump" }, | 1362 | { "HPOUT2L PGA", NULL, "Charge Pump" }, |
| 1363 | { "HPOUT2L PGA", NULL, "Bandgap" }, | ||
| 1284 | { "HPOUT2L PGA", NULL, "DAC2L" }, | 1364 | { "HPOUT2L PGA", NULL, "DAC2L" }, |
| 1285 | { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, | 1365 | { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" }, |
| 1286 | { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, | 1366 | { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" }, |
| @@ -1288,6 +1368,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
| 1288 | { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, | 1368 | { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_OUTP" }, |
| 1289 | 1369 | ||
| 1290 | { "HPOUT2R PGA", NULL, "Charge Pump" }, | 1370 | { "HPOUT2R PGA", NULL, "Charge Pump" }, |
| 1371 | { "HPOUT2R PGA", NULL, "Bandgap" }, | ||
| 1291 | { "HPOUT2R PGA", NULL, "DAC2R" }, | 1372 | { "HPOUT2R PGA", NULL, "DAC2R" }, |
| 1292 | { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, | 1373 | { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" }, |
| 1293 | { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, | 1374 | { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" }, |
| @@ -1295,6 +1376,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
| 1295 | { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, | 1376 | { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_OUTP" }, |
| 1296 | 1377 | ||
| 1297 | { "HPOUT1L PGA", NULL, "Charge Pump" }, | 1378 | { "HPOUT1L PGA", NULL, "Charge Pump" }, |
| 1379 | { "HPOUT1L PGA", NULL, "Bandgap" }, | ||
| 1298 | { "HPOUT1L PGA", NULL, "DAC1L" }, | 1380 | { "HPOUT1L PGA", NULL, "DAC1L" }, |
| 1299 | { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, | 1381 | { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" }, |
| 1300 | { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, | 1382 | { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" }, |
| @@ -1302,6 +1384,7 @@ static const struct snd_soc_dapm_route wm8996_dapm_routes[] = { | |||
| 1302 | { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, | 1384 | { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_OUTP" }, |
| 1303 | 1385 | ||
| 1304 | { "HPOUT1R PGA", NULL, "Charge Pump" }, | 1386 | { "HPOUT1R PGA", NULL, "Charge Pump" }, |
| 1387 | { "HPOUT1R PGA", NULL, "Bandgap" }, | ||
| 1305 | { "HPOUT1R PGA", NULL, "DAC1R" }, | 1388 | { "HPOUT1R PGA", NULL, "DAC1R" }, |
| 1306 | { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, | 1389 | { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" }, |
| 1307 | { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, | 1390 | { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" }, |
| @@ -1620,14 +1703,7 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, | |||
| 1620 | 1703 | ||
| 1621 | switch (level) { | 1704 | switch (level) { |
| 1622 | case SND_SOC_BIAS_ON: | 1705 | case SND_SOC_BIAS_ON: |
| 1623 | break; | ||
| 1624 | |||
| 1625 | case SND_SOC_BIAS_PREPARE: | 1706 | case SND_SOC_BIAS_PREPARE: |
| 1626 | if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { | ||
| 1627 | snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1, | ||
| 1628 | WM8996_BG_ENA, WM8996_BG_ENA); | ||
| 1629 | msleep(2); | ||
| 1630 | } | ||
| 1631 | break; | 1707 | break; |
| 1632 | 1708 | ||
| 1633 | case SND_SOC_BIAS_STANDBY: | 1709 | case SND_SOC_BIAS_STANDBY: |
| @@ -1650,9 +1726,6 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec, | |||
| 1650 | codec->cache_only = false; | 1726 | codec->cache_only = false; |
| 1651 | snd_soc_cache_sync(codec); | 1727 | snd_soc_cache_sync(codec); |
| 1652 | } | 1728 | } |
| 1653 | |||
| 1654 | snd_soc_update_bits(codec, WM8996_POWER_MANAGEMENT_1, | ||
| 1655 | WM8996_BG_ENA, 0); | ||
| 1656 | break; | 1729 | break; |
| 1657 | 1730 | ||
| 1658 | case SND_SOC_BIAS_OFF: | 1731 | case SND_SOC_BIAS_OFF: |
| @@ -1847,7 +1920,7 @@ static int wm8996_hw_params(struct snd_pcm_substream *substream, | |||
| 1847 | snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK, | 1920 | snd_soc_update_bits(codec, lrclk_reg, WM8996_AIF1RX_RATE_MASK, |
| 1848 | lrclk); | 1921 | lrclk); |
| 1849 | snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2, | 1922 | snd_soc_update_bits(codec, WM8996_AIF_CLOCKING_2, |
| 1850 | WM8996_DSP1_DIV_SHIFT << dsp_shift, dsp); | 1923 | WM8996_DSP1_DIV_MASK << dsp_shift, dsp); |
| 1851 | 1924 | ||
| 1852 | return 0; | 1925 | return 0; |
| 1853 | } | 1926 | } |
| @@ -2041,7 +2114,7 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
| 2041 | struct i2c_client *i2c = to_i2c_client(codec->dev); | 2114 | struct i2c_client *i2c = to_i2c_client(codec->dev); |
| 2042 | struct _fll_div fll_div; | 2115 | struct _fll_div fll_div; |
| 2043 | unsigned long timeout; | 2116 | unsigned long timeout; |
| 2044 | int ret, reg; | 2117 | int ret, reg, retry; |
| 2045 | 2118 | ||
| 2046 | /* Any change? */ | 2119 | /* Any change? */ |
| 2047 | if (source == wm8996->fll_src && Fref == wm8996->fll_fref && | 2120 | if (source == wm8996->fll_src && Fref == wm8996->fll_fref && |
| @@ -2057,6 +2130,8 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
| 2057 | snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, | 2130 | snd_soc_update_bits(codec, WM8996_FLL_CONTROL_1, |
| 2058 | WM8996_FLL_ENA, 0); | 2131 | WM8996_FLL_ENA, 0); |
| 2059 | 2132 | ||
| 2133 | wm8996_bg_disable(codec); | ||
| 2134 | |||
| 2060 | return 0; | 2135 | return 0; |
| 2061 | } | 2136 | } |
| 2062 | 2137 | ||
| @@ -2111,6 +2186,11 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
| 2111 | 2186 | ||
| 2112 | snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); | 2187 | snd_soc_write(codec, WM8996_FLL_EFS_1, fll_div.lambda); |
| 2113 | 2188 | ||
| 2189 | /* Enable the bandgap if it's not already enabled */ | ||
| 2190 | ret = snd_soc_read(codec, WM8996_FLL_CONTROL_1); | ||
| 2191 | if (!(ret & WM8996_FLL_ENA)) | ||
| 2192 | wm8996_bg_enable(codec); | ||
| 2193 | |||
| 2114 | /* Clear any pending completions (eg, from failed startups) */ | 2194 | /* Clear any pending completions (eg, from failed startups) */ |
| 2115 | try_wait_for_completion(&wm8996->fll_lock); | 2195 | try_wait_for_completion(&wm8996->fll_lock); |
| 2116 | 2196 | ||
| @@ -2128,17 +2208,29 @@ static int wm8996_set_fll(struct snd_soc_codec *codec, int fll_id, int source, | |||
| 2128 | else | 2208 | else |
| 2129 | timeout = msecs_to_jiffies(2); | 2209 | timeout = msecs_to_jiffies(2); |
| 2130 | 2210 | ||
| 2131 | /* Allow substantially longer if we've actually got the IRQ */ | 2211 | /* Allow substantially longer if we've actually got the IRQ, poll |
| 2212 | * at a slightly higher rate if we don't. | ||
| 2213 | */ | ||
| 2132 | if (i2c->irq) | 2214 | if (i2c->irq) |
| 2133 | timeout *= 1000; | 2215 | timeout *= 10; |
| 2216 | else | ||
| 2217 | timeout /= 2; | ||
| 2134 | 2218 | ||
| 2135 | ret = wait_for_completion_timeout(&wm8996->fll_lock, timeout); | 2219 | for (retry = 0; retry < 10; retry++) { |
| 2220 | ret = wait_for_completion_timeout(&wm8996->fll_lock, | ||
| 2221 | timeout); | ||
| 2222 | if (ret != 0) { | ||
| 2223 | WARN_ON(!i2c->irq); | ||
| 2224 | break; | ||
| 2225 | } | ||
| 2136 | 2226 | ||
| 2137 | if (ret == 0 && i2c->irq) { | 2227 | ret = snd_soc_read(codec, WM8996_INTERRUPT_RAW_STATUS_2); |
| 2228 | if (ret & WM8996_FLL_LOCK_STS) | ||
| 2229 | break; | ||
| 2230 | } | ||
| 2231 | if (retry == 10) { | ||
| 2138 | dev_err(codec->dev, "Timed out waiting for FLL\n"); | 2232 | dev_err(codec->dev, "Timed out waiting for FLL\n"); |
| 2139 | ret = -ETIMEDOUT; | 2233 | ret = -ETIMEDOUT; |
| 2140 | } else { | ||
| 2141 | ret = 0; | ||
| 2142 | } | 2234 | } |
| 2143 | 2235 | ||
| 2144 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); | 2236 | dev_dbg(codec->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout); |
| @@ -2297,12 +2389,94 @@ int wm8996_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
| 2297 | 2389 | ||
| 2298 | /* Enable interrupts and we're off */ | 2390 | /* Enable interrupts and we're off */ |
| 2299 | snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, | 2391 | snd_soc_update_bits(codec, WM8996_INTERRUPT_STATUS_2_MASK, |
| 2300 | WM8996_IM_MICD_EINT, 0); | 2392 | WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0); |
| 2301 | 2393 | ||
| 2302 | return 0; | 2394 | return 0; |
| 2303 | } | 2395 | } |
| 2304 | EXPORT_SYMBOL_GPL(wm8996_detect); | 2396 | EXPORT_SYMBOL_GPL(wm8996_detect); |
| 2305 | 2397 | ||
| 2398 | static void wm8996_hpdet_irq(struct snd_soc_codec *codec) | ||
| 2399 | { | ||
| 2400 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | ||
| 2401 | int val, reg, report; | ||
| 2402 | |||
| 2403 | /* Assume headphone in error conditions; we need to report | ||
| 2404 | * something or we stall our state machine. | ||
| 2405 | */ | ||
| 2406 | report = SND_JACK_HEADPHONE; | ||
| 2407 | |||
| 2408 | reg = snd_soc_read(codec, WM8996_HEADPHONE_DETECT_2); | ||
| 2409 | if (reg < 0) { | ||
| 2410 | dev_err(codec->dev, "Failed to read HPDET status\n"); | ||
| 2411 | goto out; | ||
| 2412 | } | ||
| 2413 | |||
| 2414 | if (!(reg & WM8996_HP_DONE)) { | ||
| 2415 | dev_err(codec->dev, "Got HPDET IRQ but HPDET is busy\n"); | ||
| 2416 | goto out; | ||
| 2417 | } | ||
| 2418 | |||
| 2419 | val = reg & WM8996_HP_LVL_MASK; | ||
| 2420 | |||
| 2421 | dev_dbg(codec->dev, "HPDET measured %d ohms\n", val); | ||
| 2422 | |||
| 2423 | /* If we've got high enough impedence then report as line, | ||
| 2424 | * otherwise assume headphone. | ||
| 2425 | */ | ||
| 2426 | if (val >= 126) | ||
| 2427 | report = SND_JACK_LINEOUT; | ||
| 2428 | else | ||
| 2429 | report = SND_JACK_HEADPHONE; | ||
| 2430 | |||
| 2431 | out: | ||
| 2432 | if (wm8996->jack_mic) | ||
| 2433 | report |= SND_JACK_MICROPHONE; | ||
| 2434 | |||
| 2435 | snd_soc_jack_report(wm8996->jack, report, | ||
| 2436 | SND_JACK_LINEOUT | SND_JACK_HEADSET); | ||
| 2437 | |||
| 2438 | wm8996->detecting = false; | ||
| 2439 | |||
| 2440 | /* If the output isn't running re-clamp it */ | ||
| 2441 | if (!(snd_soc_read(codec, WM8996_POWER_MANAGEMENT_1) & | ||
| 2442 | (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT))) | ||
| 2443 | snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1, | ||
| 2444 | WM8996_HPOUT1L_RMV_SHORT | | ||
| 2445 | WM8996_HPOUT1R_RMV_SHORT, 0); | ||
| 2446 | |||
| 2447 | /* Go back to looking at the microphone */ | ||
| 2448 | snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1, | ||
| 2449 | WM8996_JD_MODE_MASK, 0); | ||
| 2450 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, | ||
| 2451 | WM8996_MICD_ENA); | ||
| 2452 | |||
| 2453 | snd_soc_dapm_disable_pin(&codec->dapm, "Bandgap"); | ||
| 2454 | snd_soc_dapm_sync(&codec->dapm); | ||
| 2455 | } | ||
| 2456 | |||
| 2457 | static void wm8996_hpdet_start(struct snd_soc_codec *codec) | ||
| 2458 | { | ||
| 2459 | /* Unclamp the output, we can't measure while we're shorting it */ | ||
| 2460 | snd_soc_update_bits(codec, WM8996_ANALOGUE_HP_1, | ||
| 2461 | WM8996_HPOUT1L_RMV_SHORT | | ||
| 2462 | WM8996_HPOUT1R_RMV_SHORT, | ||
| 2463 | WM8996_HPOUT1L_RMV_SHORT | | ||
| 2464 | WM8996_HPOUT1R_RMV_SHORT); | ||
| 2465 | |||
| 2466 | /* We need bandgap for HPDET */ | ||
| 2467 | snd_soc_dapm_force_enable_pin(&codec->dapm, "Bandgap"); | ||
| 2468 | snd_soc_dapm_sync(&codec->dapm); | ||
| 2469 | |||
| 2470 | /* Go into headphone detect left mode */ | ||
| 2471 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0); | ||
| 2472 | snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_1, | ||
| 2473 | WM8996_JD_MODE_MASK, 1); | ||
| 2474 | |||
| 2475 | /* Trigger a measurement */ | ||
| 2476 | snd_soc_update_bits(codec, WM8996_HEADPHONE_DETECT_1, | ||
| 2477 | WM8996_HP_POLL, WM8996_HP_POLL); | ||
| 2478 | } | ||
| 2479 | |||
| 2306 | static void wm8996_micd(struct snd_soc_codec *codec) | 2480 | static void wm8996_micd(struct snd_soc_codec *codec) |
| 2307 | { | 2481 | { |
| 2308 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); | 2482 | struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); |
| @@ -2323,28 +2497,36 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
| 2323 | wm8996->jack_mic = false; | 2497 | wm8996->jack_mic = false; |
| 2324 | wm8996->detecting = true; | 2498 | wm8996->detecting = true; |
| 2325 | snd_soc_jack_report(wm8996->jack, 0, | 2499 | snd_soc_jack_report(wm8996->jack, 0, |
| 2326 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 2500 | SND_JACK_LINEOUT | SND_JACK_HEADSET | |
| 2501 | SND_JACK_BTN_0); | ||
| 2502 | |||
| 2327 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | 2503 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, |
| 2328 | WM8996_MICD_RATE_MASK, | 2504 | WM8996_MICD_RATE_MASK, |
| 2329 | WM8996_MICD_RATE_MASK); | 2505 | WM8996_MICD_RATE_MASK); |
| 2330 | return; | 2506 | return; |
| 2331 | } | 2507 | } |
| 2332 | 2508 | ||
| 2333 | /* If the measurement is very high we've got a microphone but | 2509 | /* If the measurement is very high we've got a microphone, |
| 2334 | * do a little debounce to account for mechanical issues. | 2510 | * either we just detected one or if we already reported then |
| 2511 | * we've got a button release event. | ||
| 2335 | */ | 2512 | */ |
| 2336 | if (val & 0x400) { | 2513 | if (val & 0x400) { |
| 2337 | dev_dbg(codec->dev, "Microphone detected\n"); | 2514 | if (wm8996->detecting) { |
| 2338 | snd_soc_jack_report(wm8996->jack, SND_JACK_HEADSET, | 2515 | dev_dbg(codec->dev, "Microphone detected\n"); |
| 2339 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 2516 | wm8996->jack_mic = true; |
| 2340 | wm8996->jack_mic = true; | 2517 | wm8996_hpdet_start(codec); |
| 2341 | wm8996->detecting = false; | 2518 | |
| 2342 | 2519 | /* Increase poll rate to give better responsiveness | |
| 2343 | /* Increase poll rate to give better responsiveness | 2520 | * for buttons */ |
| 2344 | * for buttons */ | 2521 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, |
| 2345 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | 2522 | WM8996_MICD_RATE_MASK, |
| 2346 | WM8996_MICD_RATE_MASK, | 2523 | 5 << WM8996_MICD_RATE_SHIFT); |
| 2347 | 5 << WM8996_MICD_RATE_SHIFT); | 2524 | } else { |
| 2525 | dev_dbg(codec->dev, "Mic button up\n"); | ||
| 2526 | snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0); | ||
| 2527 | } | ||
| 2528 | |||
| 2529 | return; | ||
| 2348 | } | 2530 | } |
| 2349 | 2531 | ||
| 2350 | /* If we detected a lower impedence during initial startup | 2532 | /* If we detected a lower impedence during initial startup |
| @@ -2376,15 +2558,11 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
| 2376 | if (val & 0x3fc) { | 2558 | if (val & 0x3fc) { |
| 2377 | if (wm8996->jack_mic) { | 2559 | if (wm8996->jack_mic) { |
| 2378 | dev_dbg(codec->dev, "Mic button detected\n"); | 2560 | dev_dbg(codec->dev, "Mic button detected\n"); |
| 2379 | snd_soc_jack_report(wm8996->jack, | 2561 | snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0, |
| 2380 | SND_JACK_HEADSET | SND_JACK_BTN_0, | ||
| 2381 | SND_JACK_HEADSET | SND_JACK_BTN_0); | ||
| 2382 | } else { | ||
| 2383 | dev_dbg(codec->dev, "Headphone detected\n"); | ||
| 2384 | snd_soc_jack_report(wm8996->jack, | ||
| 2385 | SND_JACK_HEADPHONE, | ||
| 2386 | SND_JACK_HEADSET | | ||
| 2387 | SND_JACK_BTN_0); | 2562 | SND_JACK_BTN_0); |
| 2563 | } else if (wm8996->detecting) { | ||
| 2564 | dev_dbg(codec->dev, "Headphone detected\n"); | ||
| 2565 | wm8996_hpdet_start(codec); | ||
| 2388 | 2566 | ||
| 2389 | /* Increase the detection rate a bit for | 2567 | /* Increase the detection rate a bit for |
| 2390 | * responsiveness. | 2568 | * responsiveness. |
| @@ -2392,8 +2570,6 @@ static void wm8996_micd(struct snd_soc_codec *codec) | |||
| 2392 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, | 2570 | snd_soc_update_bits(codec, WM8996_MIC_DETECT_1, |
| 2393 | WM8996_MICD_RATE_MASK, | 2571 | WM8996_MICD_RATE_MASK, |
| 2394 | 7 << WM8996_MICD_RATE_SHIFT); | 2572 | 7 << WM8996_MICD_RATE_SHIFT); |
| 2395 | |||
| 2396 | wm8996->detecting = false; | ||
| 2397 | } | 2573 | } |
| 2398 | } | 2574 | } |
| 2399 | } | 2575 | } |
| @@ -2412,6 +2588,9 @@ static irqreturn_t wm8996_irq(int irq, void *data) | |||
| 2412 | } | 2588 | } |
| 2413 | irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); | 2589 | irq_val &= ~snd_soc_read(codec, WM8996_INTERRUPT_STATUS_2_MASK); |
| 2414 | 2590 | ||
| 2591 | if (!irq_val) | ||
| 2592 | return IRQ_NONE; | ||
| 2593 | |||
| 2415 | snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); | 2594 | snd_soc_write(codec, WM8996_INTERRUPT_STATUS_2, irq_val); |
| 2416 | 2595 | ||
| 2417 | if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { | 2596 | if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) { |
| @@ -2430,10 +2609,10 @@ static irqreturn_t wm8996_irq(int irq, void *data) | |||
| 2430 | if (irq_val & WM8996_MICD_EINT) | 2609 | if (irq_val & WM8996_MICD_EINT) |
| 2431 | wm8996_micd(codec); | 2610 | wm8996_micd(codec); |
| 2432 | 2611 | ||
| 2433 | if (irq_val) | 2612 | if (irq_val & WM8996_HP_DONE_EINT) |
| 2434 | return IRQ_HANDLED; | 2613 | wm8996_hpdet_irq(codec); |
| 2435 | else | 2614 | |
| 2436 | return IRQ_NONE; | 2615 | return IRQ_HANDLED; |
| 2437 | } | 2616 | } |
| 2438 | 2617 | ||
| 2439 | static irqreturn_t wm8996_edge_irq(int irq, void *data) | 2618 | static irqreturn_t wm8996_edge_irq(int irq, void *data) |
| @@ -2527,7 +2706,6 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
| 2527 | init_completion(&wm8996->fll_lock); | 2706 | init_completion(&wm8996->fll_lock); |
| 2528 | 2707 | ||
| 2529 | dapm->idle_bias_off = true; | 2708 | dapm->idle_bias_off = true; |
| 2530 | dapm->bias_level = SND_SOC_BIAS_OFF; | ||
| 2531 | 2709 | ||
| 2532 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); | 2710 | ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); |
| 2533 | if (ret != 0) { | 2711 | if (ret != 0) { |
| @@ -2548,7 +2726,13 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
| 2548 | wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; | 2726 | wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0; |
| 2549 | wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; | 2727 | wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1; |
| 2550 | wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; | 2728 | wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2; |
| 2551 | wm8996->disable_nb[3].notifier_call = wm8996_regulator_event_3; | 2729 | |
| 2730 | wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD"); | ||
| 2731 | if (IS_ERR(wm8996->cpvdd)) { | ||
| 2732 | ret = PTR_ERR(wm8996->cpvdd); | ||
| 2733 | dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret); | ||
| 2734 | goto err_get; | ||
| 2735 | } | ||
| 2552 | 2736 | ||
| 2553 | /* This should really be moved into the regulator core */ | 2737 | /* This should really be moved into the regulator core */ |
| 2554 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { | 2738 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) { |
| @@ -2565,7 +2749,7 @@ static int wm8996_probe(struct snd_soc_codec *codec) | |||
| 2565 | wm8996->supplies); | 2749 | wm8996->supplies); |
| 2566 | if (ret != 0) { | 2750 | if (ret != 0) { |
| 2567 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); | 2751 | dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); |
| 2568 | goto err_get; | 2752 | goto err_cpvdd; |
| 2569 | } | 2753 | } |
| 2570 | 2754 | ||
| 2571 | if (wm8996->pdata.ldo_ena >= 0) { | 2755 | if (wm8996->pdata.ldo_ena >= 0) { |
| @@ -2808,6 +2992,8 @@ err_enable: | |||
| 2808 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); | 2992 | gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); |
| 2809 | 2993 | ||
| 2810 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | 2994 | regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); |
| 2995 | err_cpvdd: | ||
| 2996 | regulator_put(wm8996->cpvdd); | ||
| 2811 | err_get: | 2997 | err_get: |
| 2812 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | 2998 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); |
| 2813 | err: | 2999 | err: |
| @@ -2831,6 +3017,7 @@ static int wm8996_remove(struct snd_soc_codec *codec) | |||
| 2831 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) | 3017 | for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) |
| 2832 | regulator_unregister_notifier(wm8996->supplies[i].consumer, | 3018 | regulator_unregister_notifier(wm8996->supplies[i].consumer, |
| 2833 | &wm8996->disable_nb[i]); | 3019 | &wm8996->disable_nb[i]); |
| 3020 | regulator_put(wm8996->cpvdd); | ||
| 2834 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); | 3021 | regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); |
| 2835 | 3022 | ||
| 2836 | return 0; | 3023 | return 0; |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index a4691321f9b3..3cd35a02c28c 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
| @@ -157,7 +157,6 @@ static struct { | |||
| 157 | 157 | ||
| 158 | struct wm9081_priv { | 158 | struct wm9081_priv { |
| 159 | enum snd_soc_control_type control_type; | 159 | enum snd_soc_control_type control_type; |
| 160 | void *control_data; | ||
| 161 | int sysclk_source; | 160 | int sysclk_source; |
| 162 | int mclk_rate; | 161 | int mclk_rate; |
| 163 | int sysclk_rate; | 162 | int sysclk_rate; |
| @@ -174,6 +173,7 @@ static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int re | |||
| 174 | { | 173 | { |
| 175 | switch (reg) { | 174 | switch (reg) { |
| 176 | case WM9081_SOFTWARE_RESET: | 175 | case WM9081_SOFTWARE_RESET: |
| 176 | case WM9081_INTERRUPT_STATUS: | ||
| 177 | return 1; | 177 | return 1; |
| 178 | default: | 178 | default: |
| 179 | return 0; | 179 | return 0; |
| @@ -820,7 +820,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
| 820 | /* VMID 2*240k */ | 820 | /* VMID 2*240k */ |
| 821 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 821 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); |
| 822 | reg &= ~WM9081_VMID_SEL_MASK; | 822 | reg &= ~WM9081_VMID_SEL_MASK; |
| 823 | reg |= 0x40; | 823 | reg |= 0x04; |
| 824 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | 824 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); |
| 825 | 825 | ||
| 826 | /* Standby bias current on */ | 826 | /* Standby bias current on */ |
| @@ -1120,8 +1120,8 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
| 1120 | return 0; | 1120 | return 0; |
| 1121 | } | 1121 | } |
| 1122 | 1122 | ||
| 1123 | static int wm9081_set_sysclk(struct snd_soc_codec *codec, | 1123 | static int wm9081_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
| 1124 | int clk_id, unsigned int freq, int dir) | 1124 | int source, unsigned int freq, int dir) |
| 1125 | { | 1125 | { |
| 1126 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); | 1126 | struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); |
| 1127 | 1127 | ||
| @@ -1213,7 +1213,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
| 1213 | int ret; | 1213 | int ret; |
| 1214 | u16 reg; | 1214 | u16 reg; |
| 1215 | 1215 | ||
| 1216 | codec->control_data = wm9081->control_data; | ||
| 1217 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); | 1216 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, wm9081->control_type); |
| 1218 | if (ret != 0) { | 1217 | if (ret != 0) { |
| 1219 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 1218 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| @@ -1250,8 +1249,6 @@ static int wm9081_probe(struct snd_soc_codec *codec) | |||
| 1250 | snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, | 1249 | snd_soc_write(codec, WM9081_ANALOGUE_SPEAKER_PGA, |
| 1251 | reg | WM9081_SPKPGAZC); | 1250 | reg | WM9081_SPKPGAZC); |
| 1252 | 1251 | ||
| 1253 | snd_soc_add_controls(codec, wm9081_snd_controls, | ||
| 1254 | ARRAY_SIZE(wm9081_snd_controls)); | ||
| 1255 | if (!wm9081->pdata.num_retune_configs) { | 1252 | if (!wm9081->pdata.num_retune_configs) { |
| 1256 | dev_dbg(codec->dev, | 1253 | dev_dbg(codec->dev, |
| 1257 | "No ReTune Mobile data, using normal EQ\n"); | 1254 | "No ReTune Mobile data, using normal EQ\n"); |
| @@ -1311,6 +1308,8 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = { | |||
| 1311 | .reg_cache_default = wm9081_reg_defaults, | 1308 | .reg_cache_default = wm9081_reg_defaults, |
| 1312 | .volatile_register = wm9081_volatile_register, | 1309 | .volatile_register = wm9081_volatile_register, |
| 1313 | 1310 | ||
| 1311 | .controls = wm9081_snd_controls, | ||
| 1312 | .num_controls = ARRAY_SIZE(wm9081_snd_controls), | ||
| 1314 | .dapm_widgets = wm9081_dapm_widgets, | 1313 | .dapm_widgets = wm9081_dapm_widgets, |
| 1315 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), | 1314 | .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets), |
| 1316 | .dapm_routes = wm9081_audio_paths, | 1315 | .dapm_routes = wm9081_audio_paths, |
| @@ -1330,7 +1329,6 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
| 1330 | 1329 | ||
| 1331 | i2c_set_clientdata(i2c, wm9081); | 1330 | i2c_set_clientdata(i2c, wm9081); |
| 1332 | wm9081->control_type = SND_SOC_I2C; | 1331 | wm9081->control_type = SND_SOC_I2C; |
| 1333 | wm9081->control_data = i2c; | ||
| 1334 | 1332 | ||
| 1335 | if (dev_get_platdata(&i2c->dev)) | 1333 | if (dev_get_platdata(&i2c->dev)) |
| 1336 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), | 1334 | memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev), |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 4de12203e611..2b5252c9e377 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
| @@ -139,9 +139,7 @@ static const u16 wm9090_reg_defaults[] = { | |||
| 139 | 139 | ||
| 140 | /* This struct is used to save the context */ | 140 | /* This struct is used to save the context */ |
| 141 | struct wm9090_priv { | 141 | struct wm9090_priv { |
| 142 | struct mutex mutex; | ||
| 143 | struct wm9090_platform_data pdata; | 142 | struct wm9090_platform_data pdata; |
| 144 | void *control_data; | ||
| 145 | }; | 143 | }; |
| 146 | 144 | ||
| 147 | static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) | 145 | static int wm9090_volatile(struct snd_soc_codec *codec, unsigned int reg) |
| @@ -550,10 +548,8 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, | |||
| 550 | 548 | ||
| 551 | static int wm9090_probe(struct snd_soc_codec *codec) | 549 | static int wm9090_probe(struct snd_soc_codec *codec) |
| 552 | { | 550 | { |
| 553 | struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); | ||
| 554 | int ret; | 551 | int ret; |
| 555 | 552 | ||
| 556 | codec->control_data = wm9090->control_data; | ||
| 557 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 553 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
| 558 | if (ret != 0) { | 554 | if (ret != 0) { |
| 559 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 555 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| @@ -662,8 +658,6 @@ static int wm9090_i2c_probe(struct i2c_client *i2c, | |||
| 662 | sizeof(wm9090->pdata)); | 658 | sizeof(wm9090->pdata)); |
| 663 | 659 | ||
| 664 | i2c_set_clientdata(i2c, wm9090); | 660 | i2c_set_clientdata(i2c, wm9090); |
| 665 | wm9090->control_data = i2c; | ||
| 666 | mutex_init(&wm9090->mutex); | ||
| 667 | 661 | ||
| 668 | ret = snd_soc_register_codec(&i2c->dev, | 662 | ret = snd_soc_register_codec(&i2c->dev, |
| 669 | &soc_codec_dev_wm9090, NULL, 0); | 663 | &soc_codec_dev_wm9090, NULL, 0); |
| @@ -684,6 +678,7 @@ static int __devexit wm9090_i2c_remove(struct i2c_client *i2c) | |||
| 684 | 678 | ||
| 685 | static const struct i2c_device_id wm9090_id[] = { | 679 | static const struct i2c_device_id wm9090_id[] = { |
| 686 | { "wm9090", 0 }, | 680 | { "wm9090", 0 }, |
| 681 | { "wm9093", 0 }, | ||
| 687 | { } | 682 | { } |
| 688 | }; | 683 | }; |
| 689 | MODULE_DEVICE_TABLE(i2c, wm9090_id); | 684 | MODULE_DEVICE_TABLE(i2c, wm9090_id); |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index e763c54c55dc..84f33d4ea2cd 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
| 19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
| 20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 21 | #include <linux/mfd/wm8994/registers.h> | ||
| 21 | #include <sound/core.h> | 22 | #include <sound/core.h> |
| 22 | #include <sound/pcm.h> | 23 | #include <sound/pcm.h> |
| 23 | #include <sound/pcm_params.h> | 24 | #include <sound/pcm_params.h> |
| @@ -116,14 +117,23 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
| 116 | { | 117 | { |
| 117 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 118 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
| 118 | s8 offset; | 119 | s8 offset; |
| 119 | u16 reg, reg_l, reg_r, dcs_cfg; | 120 | u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg; |
| 121 | |||
| 122 | switch (hubs->dcs_readback_mode) { | ||
| 123 | case 2: | ||
| 124 | dcs_reg = WM8994_DC_SERVO_4E; | ||
| 125 | break; | ||
| 126 | default: | ||
| 127 | dcs_reg = WM8993_DC_SERVO_3; | ||
| 128 | break; | ||
| 129 | } | ||
| 120 | 130 | ||
| 121 | /* If we're using a digital only path and have a previously | 131 | /* If we're using a digital only path and have a previously |
| 122 | * callibrated DC servo offset stored then use that. */ | 132 | * callibrated DC servo offset stored then use that. */ |
| 123 | if (hubs->class_w && hubs->class_w_dcs) { | 133 | if (hubs->class_w && hubs->class_w_dcs) { |
| 124 | dev_dbg(codec->dev, "Using cached DC servo offset %x\n", | 134 | dev_dbg(codec->dev, "Using cached DC servo offset %x\n", |
| 125 | hubs->class_w_dcs); | 135 | hubs->class_w_dcs); |
| 126 | snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs); | 136 | snd_soc_write(codec, dcs_reg, hubs->class_w_dcs); |
| 127 | wait_for_dc_servo(codec, | 137 | wait_for_dc_servo(codec, |
| 128 | WM8993_DCS_TRIG_DAC_WR_0 | | 138 | WM8993_DCS_TRIG_DAC_WR_0 | |
| 129 | WM8993_DCS_TRIG_DAC_WR_1); | 139 | WM8993_DCS_TRIG_DAC_WR_1); |
| @@ -154,8 +164,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
| 154 | reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) | 164 | reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) |
| 155 | & WM8993_DCS_INTEG_CHAN_1_MASK; | 165 | & WM8993_DCS_INTEG_CHAN_1_MASK; |
| 156 | break; | 166 | break; |
| 167 | case 2: | ||
| 157 | case 1: | 168 | case 1: |
| 158 | reg = snd_soc_read(codec, WM8993_DC_SERVO_3); | 169 | reg = snd_soc_read(codec, dcs_reg); |
| 159 | reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) | 170 | reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) |
| 160 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; | 171 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; |
| 161 | reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | 172 | reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; |
| @@ -168,24 +179,25 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) | |||
| 168 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); | 179 | dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); |
| 169 | 180 | ||
| 170 | /* Apply correction to DC servo result */ | 181 | /* Apply correction to DC servo result */ |
| 171 | if (hubs->dcs_codes) { | 182 | if (hubs->dcs_codes_l || hubs->dcs_codes_r) { |
| 172 | dev_dbg(codec->dev, "Applying %d code DC servo correction\n", | 183 | dev_dbg(codec->dev, |
| 173 | hubs->dcs_codes); | 184 | "Applying %d/%d code DC servo correction\n", |
| 185 | hubs->dcs_codes_l, hubs->dcs_codes_r); | ||
| 174 | 186 | ||
| 175 | /* HPOUT1R */ | 187 | /* HPOUT1R */ |
| 176 | offset = reg_r; | 188 | offset = reg_r; |
| 177 | offset += hubs->dcs_codes; | 189 | offset += hubs->dcs_codes_r; |
| 178 | dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; | 190 | dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT; |
| 179 | 191 | ||
| 180 | /* HPOUT1L */ | 192 | /* HPOUT1L */ |
| 181 | offset = reg_l; | 193 | offset = reg_l; |
| 182 | offset += hubs->dcs_codes; | 194 | offset += hubs->dcs_codes_l; |
| 183 | dcs_cfg |= (u8)offset; | 195 | dcs_cfg |= (u8)offset; |
| 184 | 196 | ||
| 185 | dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); | 197 | dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg); |
| 186 | 198 | ||
| 187 | /* Do it */ | 199 | /* Do it */ |
| 188 | snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); | 200 | snd_soc_write(codec, dcs_reg, dcs_cfg); |
| 189 | wait_for_dc_servo(codec, | 201 | wait_for_dc_servo(codec, |
| 190 | WM8993_DCS_TRIG_DAC_WR_0 | | 202 | WM8993_DCS_TRIG_DAC_WR_0 | |
| 191 | WM8993_DCS_TRIG_DAC_WR_1); | 203 | WM8993_DCS_TRIG_DAC_WR_1); |
| @@ -210,14 +222,14 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, | |||
| 210 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); | 222 | struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); |
| 211 | int ret; | 223 | int ret; |
| 212 | 224 | ||
| 213 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); | 225 | ret = snd_soc_put_volsw(kcontrol, ucontrol); |
| 214 | 226 | ||
| 215 | /* Updating the analogue gains invalidates the DC servo cache */ | 227 | /* Updating the analogue gains invalidates the DC servo cache */ |
| 216 | hubs->class_w_dcs = 0; | 228 | hubs->class_w_dcs = 0; |
| 217 | 229 | ||
| 218 | /* If we're applying an offset correction then updating the | 230 | /* If we're applying an offset correction then updating the |
| 219 | * callibration would be likely to introduce further offsets. */ | 231 | * callibration would be likely to introduce further offsets. */ |
| 220 | if (hubs->dcs_codes || hubs->no_series_update) | 232 | if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update) |
| 221 | return ret; | 233 | return ret; |
| 222 | 234 | ||
| 223 | /* Only need to do this if the outputs are active */ | 235 | /* Only need to do this if the outputs are active */ |
| @@ -350,19 +362,11 @@ SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0, | |||
| 350 | SOC_ENUM("Speaker Reference", speaker_ref), | 362 | SOC_ENUM("Speaker Reference", speaker_ref), |
| 351 | SOC_ENUM("Speaker Mode", speaker_mode), | 363 | SOC_ENUM("Speaker Mode", speaker_mode), |
| 352 | 364 | ||
| 353 | { | 365 | SOC_DOUBLE_R_EXT_TLV("Headphone Volume", |
| 354 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Headphone Volume", | 366 | WM8993_LEFT_OUTPUT_VOLUME, WM8993_RIGHT_OUTPUT_VOLUME, |
| 355 | .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | | 367 | 0, 63, 0, snd_soc_get_volsw, wm8993_put_dc_servo, |
| 356 | SNDRV_CTL_ELEM_ACCESS_READWRITE, | 368 | outpga_tlv), |
| 357 | .tlv.p = outpga_tlv, | 369 | |
| 358 | .info = snd_soc_info_volsw_2r, | ||
| 359 | .get = snd_soc_get_volsw_2r, .put = wm8993_put_dc_servo, | ||
| 360 | .private_value = (unsigned long)&(struct soc_mixer_control) { | ||
| 361 | .reg = WM8993_LEFT_OUTPUT_VOLUME, | ||
| 362 | .rreg = WM8993_RIGHT_OUTPUT_VOLUME, | ||
| 363 | .shift = 0, .max = 63 | ||
| 364 | }, | ||
| 365 | }, | ||
| 366 | SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME, | 370 | SOC_DOUBLE_R("Headphone Switch", WM8993_LEFT_OUTPUT_VOLUME, |
| 367 | WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0), | 371 | WM8993_RIGHT_OUTPUT_VOLUME, 6, 1, 0), |
| 368 | SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME, | 372 | SOC_DOUBLE_R("Headphone ZC Switch", WM8993_LEFT_OUTPUT_VOLUME, |
| @@ -699,6 +703,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = { | |||
| 699 | { "IN1L PGA", "IN1LP Switch", "IN1LP" }, | 703 | { "IN1L PGA", "IN1LP Switch", "IN1LP" }, |
| 700 | { "IN1L PGA", "IN1LN Switch", "IN1LN" }, | 704 | { "IN1L PGA", "IN1LN Switch", "IN1LN" }, |
| 701 | 705 | ||
| 706 | { "IN1L PGA", NULL, "VMID" }, | ||
| 707 | { "IN1R PGA", NULL, "VMID" }, | ||
| 708 | { "IN2L PGA", NULL, "VMID" }, | ||
| 709 | { "IN2R PGA", NULL, "VMID" }, | ||
| 710 | |||
| 702 | { "IN1R PGA", "IN1RP Switch", "IN1RP" }, | 711 | { "IN1R PGA", "IN1RP Switch", "IN1RP" }, |
| 703 | { "IN1R PGA", "IN1RN Switch", "IN1RN" }, | 712 | { "IN1R PGA", "IN1RN Switch", "IN1RN" }, |
| 704 | 713 | ||
| @@ -716,12 +725,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = { | |||
| 716 | { "MIXINL", NULL, "Direct Voice" }, | 725 | { "MIXINL", NULL, "Direct Voice" }, |
| 717 | { "MIXINL", NULL, "IN1LP" }, | 726 | { "MIXINL", NULL, "IN1LP" }, |
| 718 | { "MIXINL", NULL, "Left Output Mixer" }, | 727 | { "MIXINL", NULL, "Left Output Mixer" }, |
| 728 | { "MIXINL", NULL, "VMID" }, | ||
| 719 | 729 | ||
| 720 | { "MIXINR", "IN1R Switch", "IN1R PGA" }, | 730 | { "MIXINR", "IN1R Switch", "IN1R PGA" }, |
| 721 | { "MIXINR", "IN2R Switch", "IN2R PGA" }, | 731 | { "MIXINR", "IN2R Switch", "IN2R PGA" }, |
| 722 | { "MIXINR", NULL, "Direct Voice" }, | 732 | { "MIXINR", NULL, "Direct Voice" }, |
| 723 | { "MIXINR", NULL, "IN1RP" }, | 733 | { "MIXINR", NULL, "IN1RP" }, |
| 724 | { "MIXINR", NULL, "Right Output Mixer" }, | 734 | { "MIXINR", NULL, "Right Output Mixer" }, |
| 735 | { "MIXINR", NULL, "VMID" }, | ||
| 725 | 736 | ||
| 726 | { "ADCL", NULL, "MIXINL" }, | 737 | { "ADCL", NULL, "MIXINL" }, |
| 727 | { "ADCR", NULL, "MIXINR" }, | 738 | { "ADCR", NULL, "MIXINR" }, |
| @@ -752,6 +763,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = { | |||
| 752 | { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" }, | 763 | { "Earpiece Mixer", "Left Output Switch", "Left Output PGA" }, |
| 753 | { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" }, | 764 | { "Earpiece Mixer", "Right Output Switch", "Right Output PGA" }, |
| 754 | 765 | ||
| 766 | { "Earpiece Driver", NULL, "VMID" }, | ||
| 755 | { "Earpiece Driver", NULL, "Earpiece Mixer" }, | 767 | { "Earpiece Driver", NULL, "Earpiece Mixer" }, |
| 756 | { "HPOUT2N", NULL, "Earpiece Driver" }, | 768 | { "HPOUT2N", NULL, "Earpiece Driver" }, |
| 757 | { "HPOUT2P", NULL, "Earpiece Driver" }, | 769 | { "HPOUT2P", NULL, "Earpiece Driver" }, |
| @@ -774,9 +786,11 @@ static const struct snd_soc_dapm_route analogue_routes[] = { | |||
| 774 | { "SPKR Boost", "SPKR Switch", "SPKR" }, | 786 | { "SPKR Boost", "SPKR Switch", "SPKR" }, |
| 775 | { "SPKR Boost", "SPKL Switch", "SPKL" }, | 787 | { "SPKR Boost", "SPKL Switch", "SPKL" }, |
| 776 | 788 | ||
| 789 | { "SPKL Driver", NULL, "VMID" }, | ||
| 777 | { "SPKL Driver", NULL, "SPKL Boost" }, | 790 | { "SPKL Driver", NULL, "SPKL Boost" }, |
| 778 | { "SPKL Driver", NULL, "CLK_SYS" }, | 791 | { "SPKL Driver", NULL, "CLK_SYS" }, |
| 779 | 792 | ||
| 793 | { "SPKR Driver", NULL, "VMID" }, | ||
| 780 | { "SPKR Driver", NULL, "SPKR Boost" }, | 794 | { "SPKR Driver", NULL, "SPKR Boost" }, |
| 781 | { "SPKR Driver", NULL, "CLK_SYS" }, | 795 | { "SPKR Driver", NULL, "CLK_SYS" }, |
| 782 | 796 | ||
| @@ -790,12 +804,18 @@ static const struct snd_soc_dapm_route analogue_routes[] = { | |||
| 790 | 804 | ||
| 791 | { "Headphone PGA", NULL, "Left Headphone Mux" }, | 805 | { "Headphone PGA", NULL, "Left Headphone Mux" }, |
| 792 | { "Headphone PGA", NULL, "Right Headphone Mux" }, | 806 | { "Headphone PGA", NULL, "Right Headphone Mux" }, |
| 807 | { "Headphone PGA", NULL, "VMID" }, | ||
| 793 | { "Headphone PGA", NULL, "CLK_SYS" }, | 808 | { "Headphone PGA", NULL, "CLK_SYS" }, |
| 794 | { "Headphone PGA", NULL, "Headphone Supply" }, | 809 | { "Headphone PGA", NULL, "Headphone Supply" }, |
| 795 | 810 | ||
| 796 | { "HPOUT1L", NULL, "Headphone PGA" }, | 811 | { "HPOUT1L", NULL, "Headphone PGA" }, |
| 797 | { "HPOUT1R", NULL, "Headphone PGA" }, | 812 | { "HPOUT1R", NULL, "Headphone PGA" }, |
| 798 | 813 | ||
| 814 | { "LINEOUT1N Driver", NULL, "VMID" }, | ||
| 815 | { "LINEOUT1P Driver", NULL, "VMID" }, | ||
| 816 | { "LINEOUT2N Driver", NULL, "VMID" }, | ||
| 817 | { "LINEOUT2P Driver", NULL, "VMID" }, | ||
| 818 | |||
| 799 | { "LINEOUT1N", NULL, "LINEOUT1N Driver" }, | 819 | { "LINEOUT1N", NULL, "LINEOUT1N Driver" }, |
| 800 | { "LINEOUT1P", NULL, "LINEOUT1P Driver" }, | 820 | { "LINEOUT1P", NULL, "LINEOUT1P Driver" }, |
| 801 | { "LINEOUT2N", NULL, "LINEOUT2N Driver" }, | 821 | { "LINEOUT2N", NULL, "LINEOUT2N Driver" }, |
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index 676b1252ab91..c674c7a502a6 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h | |||
| @@ -23,7 +23,8 @@ extern const unsigned int wm_hubs_spkmix_tlv[]; | |||
| 23 | 23 | ||
| 24 | /* This *must* be the first element of the codec->private_data struct */ | 24 | /* This *must* be the first element of the codec->private_data struct */ |
| 25 | struct wm_hubs_data { | 25 | struct wm_hubs_data { |
| 26 | int dcs_codes; | 26 | int dcs_codes_l; |
| 27 | int dcs_codes_r; | ||
| 27 | int dcs_readback_mode; | 28 | int dcs_readback_mode; |
| 28 | int hp_startup_mode; | 29 | int hp_startup_mode; |
| 29 | int series_startup; | 30 | int series_startup; |
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index fe7984221eb9..f78c3f0f280c 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c | |||
| @@ -150,8 +150,6 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) | |||
| 150 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 150 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 151 | snd_soc_dapm_enable_pin(dapm, "Line In"); | 151 | snd_soc_dapm_enable_pin(dapm, "Line In"); |
| 152 | 152 | ||
| 153 | snd_soc_dapm_sync(dapm); | ||
| 154 | |||
| 155 | return 0; | 153 | return 0; |
| 156 | } | 154 | } |
| 157 | 155 | ||
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index d0d60b8a54d4..300e12118c00 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
| @@ -265,6 +265,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 265 | struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); | 265 | struct davinci_mcbsp_dev *dev = snd_soc_dai_get_drvdata(cpu_dai); |
| 266 | unsigned int pcr; | 266 | unsigned int pcr; |
| 267 | unsigned int srgr; | 267 | unsigned int srgr; |
| 268 | bool inv_fs = false; | ||
| 268 | /* Attention srgr is updated by hw_params! */ | 269 | /* Attention srgr is updated by hw_params! */ |
| 269 | srgr = DAVINCI_MCBSP_SRGR_FSGM | | 270 | srgr = DAVINCI_MCBSP_SRGR_FSGM | |
| 270 | DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | | 271 | DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) | |
| @@ -330,7 +331,7 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 330 | * more empty bit clock slots between channels as the sample | 331 | * more empty bit clock slots between channels as the sample |
| 331 | * rate is lowered. | 332 | * rate is lowered. |
| 332 | */ | 333 | */ |
| 333 | fmt ^= SND_SOC_DAIFMT_NB_IF; | 334 | inv_fs = true; |
| 334 | case SND_SOC_DAIFMT_DSP_A: | 335 | case SND_SOC_DAIFMT_DSP_A: |
| 335 | dev->mode = MOD_DSP_A; | 336 | dev->mode = MOD_DSP_A; |
| 336 | break; | 337 | break; |
| @@ -394,6 +395,8 @@ static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 394 | default: | 395 | default: |
| 395 | return -EINVAL; | 396 | return -EINVAL; |
| 396 | } | 397 | } |
| 398 | if (inv_fs == true) | ||
| 399 | pcr ^= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP); | ||
| 397 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); | 400 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr); |
| 398 | dev->pcr = pcr; | 401 | dev->pcr = pcr; |
| 399 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); | 402 | davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr); |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 8566238db2a5..7173df254a91 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
| @@ -732,16 +732,19 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream, | |||
| 732 | davinci_hw_param(dev, substream->stream); | 732 | davinci_hw_param(dev, substream->stream); |
| 733 | 733 | ||
| 734 | switch (params_format(params)) { | 734 | switch (params_format(params)) { |
| 735 | case SNDRV_PCM_FORMAT_U8: | ||
| 735 | case SNDRV_PCM_FORMAT_S8: | 736 | case SNDRV_PCM_FORMAT_S8: |
| 736 | dma_params->data_type = 1; | 737 | dma_params->data_type = 1; |
| 737 | word_length = DAVINCI_AUDIO_WORD_8; | 738 | word_length = DAVINCI_AUDIO_WORD_8; |
| 738 | break; | 739 | break; |
| 739 | 740 | ||
| 741 | case SNDRV_PCM_FORMAT_U16_LE: | ||
| 740 | case SNDRV_PCM_FORMAT_S16_LE: | 742 | case SNDRV_PCM_FORMAT_S16_LE: |
| 741 | dma_params->data_type = 2; | 743 | dma_params->data_type = 2; |
| 742 | word_length = DAVINCI_AUDIO_WORD_16; | 744 | word_length = DAVINCI_AUDIO_WORD_16; |
| 743 | break; | 745 | break; |
| 744 | 746 | ||
| 747 | case SNDRV_PCM_FORMAT_U32_LE: | ||
| 745 | case SNDRV_PCM_FORMAT_S32_LE: | 748 | case SNDRV_PCM_FORMAT_S32_LE: |
| 746 | dma_params->data_type = 4; | 749 | dma_params->data_type = 4; |
| 747 | word_length = DAVINCI_AUDIO_WORD_32; | 750 | word_length = DAVINCI_AUDIO_WORD_32; |
| @@ -818,6 +821,13 @@ static struct snd_soc_dai_ops davinci_mcasp_dai_ops = { | |||
| 818 | 821 | ||
| 819 | }; | 822 | }; |
| 820 | 823 | ||
| 824 | #define DAVINCI_MCASP_PCM_FMTS (SNDRV_PCM_FMTBIT_S8 | \ | ||
| 825 | SNDRV_PCM_FMTBIT_U8 | \ | ||
| 826 | SNDRV_PCM_FMTBIT_S16_LE | \ | ||
| 827 | SNDRV_PCM_FMTBIT_U16_LE | \ | ||
| 828 | SNDRV_PCM_FMTBIT_S32_LE | \ | ||
| 829 | SNDRV_PCM_FMTBIT_U32_LE) | ||
| 830 | |||
| 821 | static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | 831 | static struct snd_soc_dai_driver davinci_mcasp_dai[] = { |
| 822 | { | 832 | { |
| 823 | .name = "davinci-mcasp.0", | 833 | .name = "davinci-mcasp.0", |
| @@ -825,17 +835,13 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
| 825 | .channels_min = 2, | 835 | .channels_min = 2, |
| 826 | .channels_max = 2, | 836 | .channels_max = 2, |
| 827 | .rates = DAVINCI_MCASP_RATES, | 837 | .rates = DAVINCI_MCASP_RATES, |
| 828 | .formats = SNDRV_PCM_FMTBIT_S8 | | 838 | .formats = DAVINCI_MCASP_PCM_FMTS, |
| 829 | SNDRV_PCM_FMTBIT_S16_LE | | ||
| 830 | SNDRV_PCM_FMTBIT_S32_LE, | ||
| 831 | }, | 839 | }, |
| 832 | .capture = { | 840 | .capture = { |
| 833 | .channels_min = 2, | 841 | .channels_min = 2, |
| 834 | .channels_max = 2, | 842 | .channels_max = 2, |
| 835 | .rates = DAVINCI_MCASP_RATES, | 843 | .rates = DAVINCI_MCASP_RATES, |
| 836 | .formats = SNDRV_PCM_FMTBIT_S8 | | 844 | .formats = DAVINCI_MCASP_PCM_FMTS, |
| 837 | SNDRV_PCM_FMTBIT_S16_LE | | ||
| 838 | SNDRV_PCM_FMTBIT_S32_LE, | ||
| 839 | }, | 845 | }, |
| 840 | .ops = &davinci_mcasp_dai_ops, | 846 | .ops = &davinci_mcasp_dai_ops, |
| 841 | 847 | ||
| @@ -846,7 +852,7 @@ static struct snd_soc_dai_driver davinci_mcasp_dai[] = { | |||
| 846 | .channels_min = 1, | 852 | .channels_min = 1, |
| 847 | .channels_max = 384, | 853 | .channels_max = 384, |
| 848 | .rates = DAVINCI_MCASP_RATES, | 854 | .rates = DAVINCI_MCASP_RATES, |
| 849 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 855 | .formats = DAVINCI_MCASP_PCM_FMTS, |
| 850 | }, | 856 | }, |
| 851 | .ops = &davinci_mcasp_dai_ops, | 857 | .ops = &davinci_mcasp_dai_ops, |
| 852 | }, | 858 | }, |
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index a49e667373bc..d5fe08cc5db7 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
| @@ -180,7 +180,6 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
| 180 | { | 180 | { |
| 181 | struct davinci_runtime_data *prtd = substream->runtime->private_data; | 181 | struct davinci_runtime_data *prtd = substream->runtime->private_data; |
| 182 | struct snd_pcm_runtime *runtime = substream->runtime; | 182 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 183 | int link = prtd->asp_link[0]; | ||
| 184 | unsigned int period_size; | 183 | unsigned int period_size; |
| 185 | unsigned int dma_offset; | 184 | unsigned int dma_offset; |
| 186 | dma_addr_t dma_pos; | 185 | dma_addr_t dma_pos; |
| @@ -198,7 +197,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
| 198 | fifo_level = prtd->params->fifo_level; | 197 | fifo_level = prtd->params->fifo_level; |
| 199 | 198 | ||
| 200 | pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " | 199 | pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " |
| 201 | "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size); | 200 | "dma_ptr = %x period_size=%x\n", prtd->asp_link[0], dma_pos, |
| 201 | period_size); | ||
| 202 | 202 | ||
| 203 | data_type = prtd->params->data_type; | 203 | data_type = prtd->params->data_type; |
| 204 | count = period_size / data_type; | 204 | count = period_size / data_type; |
| @@ -222,17 +222,19 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | acnt = prtd->params->acnt; | 224 | acnt = prtd->params->acnt; |
| 225 | edma_set_src(link, src, INCR, W8BIT); | 225 | edma_set_src(prtd->asp_link[0], src, INCR, W8BIT); |
| 226 | edma_set_dest(link, dst, INCR, W8BIT); | 226 | edma_set_dest(prtd->asp_link[0], dst, INCR, W8BIT); |
| 227 | 227 | ||
| 228 | edma_set_src_index(link, src_bidx, src_cidx); | 228 | edma_set_src_index(prtd->asp_link[0], src_bidx, src_cidx); |
| 229 | edma_set_dest_index(link, dst_bidx, dst_cidx); | 229 | edma_set_dest_index(prtd->asp_link[0], dst_bidx, dst_cidx); |
| 230 | 230 | ||
| 231 | if (!fifo_level) | 231 | if (!fifo_level) |
| 232 | edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC); | 232 | edma_set_transfer_params(prtd->asp_link[0], acnt, count, 1, 0, |
| 233 | ASYNC); | ||
| 233 | else | 234 | else |
| 234 | edma_set_transfer_params(link, acnt, fifo_level, count, | 235 | edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level, |
| 235 | fifo_level, ABSYNC); | 236 | count, fifo_level, |
| 237 | ABSYNC); | ||
| 236 | } | 238 | } |
| 237 | 239 | ||
| 238 | static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) | 240 | static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data) |
| @@ -305,7 +307,6 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) | |||
| 305 | unsigned int acnt = params->acnt; | 307 | unsigned int acnt = params->acnt; |
| 306 | /* divide by 2 for ping/pong */ | 308 | /* divide by 2 for ping/pong */ |
| 307 | unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; | 309 | unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1; |
| 308 | int link = prtd->asp_link[1]; | ||
| 309 | unsigned int fifo_level = prtd->params->fifo_level; | 310 | unsigned int fifo_level = prtd->params->fifo_level; |
| 310 | unsigned int count; | 311 | unsigned int count; |
| 311 | if ((data_type == 0) || (data_type > 4)) { | 312 | if ((data_type == 0) || (data_type > 4)) { |
| @@ -316,28 +317,26 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) | |||
| 316 | dma_addr_t asp_src_pong = iram_dma->addr + ping_size; | 317 | dma_addr_t asp_src_pong = iram_dma->addr + ping_size; |
| 317 | ram_src_cidx = ping_size; | 318 | ram_src_cidx = ping_size; |
| 318 | ram_dst_cidx = -ping_size; | 319 | ram_dst_cidx = -ping_size; |
| 319 | edma_set_src(link, asp_src_pong, INCR, W8BIT); | 320 | edma_set_src(prtd->asp_link[1], asp_src_pong, INCR, W8BIT); |
| 320 | 321 | ||
| 321 | link = prtd->asp_link[0]; | 322 | edma_set_src_index(prtd->asp_link[0], data_type, |
| 322 | edma_set_src_index(link, data_type, data_type * fifo_level); | 323 | data_type * fifo_level); |
| 323 | link = prtd->asp_link[1]; | 324 | edma_set_src_index(prtd->asp_link[1], data_type, |
| 324 | edma_set_src_index(link, data_type, data_type * fifo_level); | 325 | data_type * fifo_level); |
| 325 | 326 | ||
| 326 | link = prtd->ram_link; | 327 | edma_set_src(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); |
| 327 | edma_set_src(link, runtime->dma_addr, INCR, W32BIT); | ||
| 328 | } else { | 328 | } else { |
| 329 | dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; | 329 | dma_addr_t asp_dst_pong = iram_dma->addr + ping_size; |
| 330 | ram_src_cidx = -ping_size; | 330 | ram_src_cidx = -ping_size; |
| 331 | ram_dst_cidx = ping_size; | 331 | ram_dst_cidx = ping_size; |
| 332 | edma_set_dest(link, asp_dst_pong, INCR, W8BIT); | 332 | edma_set_dest(prtd->asp_link[1], asp_dst_pong, INCR, W8BIT); |
| 333 | 333 | ||
| 334 | link = prtd->asp_link[0]; | 334 | edma_set_dest_index(prtd->asp_link[0], data_type, |
| 335 | edma_set_dest_index(link, data_type, data_type * fifo_level); | 335 | data_type * fifo_level); |
| 336 | link = prtd->asp_link[1]; | 336 | edma_set_dest_index(prtd->asp_link[1], data_type, |
| 337 | edma_set_dest_index(link, data_type, data_type * fifo_level); | 337 | data_type * fifo_level); |
| 338 | 338 | ||
| 339 | link = prtd->ram_link; | 339 | edma_set_dest(prtd->ram_link, runtime->dma_addr, INCR, W32BIT); |
| 340 | edma_set_dest(link, runtime->dma_addr, INCR, W32BIT); | ||
| 341 | } | 340 | } |
| 342 | 341 | ||
| 343 | if (!fifo_level) { | 342 | if (!fifo_level) { |
| @@ -354,10 +353,9 @@ static int ping_pong_dma_setup(struct snd_pcm_substream *substream) | |||
| 354 | count, fifo_level, ABSYNC); | 353 | count, fifo_level, ABSYNC); |
| 355 | } | 354 | } |
| 356 | 355 | ||
| 357 | link = prtd->ram_link; | 356 | edma_set_src_index(prtd->ram_link, ping_size, ram_src_cidx); |
| 358 | edma_set_src_index(link, ping_size, ram_src_cidx); | 357 | edma_set_dest_index(prtd->ram_link, ping_size, ram_dst_cidx); |
| 359 | edma_set_dest_index(link, ping_size, ram_dst_cidx); | 358 | edma_set_transfer_params(prtd->ram_link, ping_size, 2, |
| 360 | edma_set_transfer_params(link, ping_size, 2, | ||
| 361 | runtime->periods, 2, ASYNC); | 359 | runtime->periods, 2, ASYNC); |
| 362 | 360 | ||
| 363 | /* init master params */ | 361 | /* init master params */ |
| @@ -406,32 +404,32 @@ static int request_ping_pong(struct snd_pcm_substream *substream, | |||
| 406 | { | 404 | { |
| 407 | dma_addr_t asp_src_ping; | 405 | dma_addr_t asp_src_ping; |
| 408 | dma_addr_t asp_dst_ping; | 406 | dma_addr_t asp_dst_ping; |
| 409 | int link; | 407 | int ret; |
| 410 | struct davinci_pcm_dma_params *params = prtd->params; | 408 | struct davinci_pcm_dma_params *params = prtd->params; |
| 411 | 409 | ||
| 412 | /* Request ram master channel */ | 410 | /* Request ram master channel */ |
| 413 | link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, | 411 | ret = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY, |
| 414 | davinci_pcm_dma_irq, substream, | 412 | davinci_pcm_dma_irq, substream, |
| 415 | prtd->params->ram_chan_q); | 413 | prtd->params->ram_chan_q); |
| 416 | if (link < 0) | 414 | if (ret < 0) |
| 417 | goto exit1; | 415 | goto exit1; |
| 418 | 416 | ||
| 419 | /* Request ram link channel */ | 417 | /* Request ram link channel */ |
| 420 | link = prtd->ram_link = edma_alloc_slot( | 418 | ret = prtd->ram_link = edma_alloc_slot( |
| 421 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); | 419 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); |
| 422 | if (link < 0) | 420 | if (ret < 0) |
| 423 | goto exit2; | 421 | goto exit2; |
| 424 | 422 | ||
| 425 | link = prtd->asp_link[1] = edma_alloc_slot( | 423 | ret = prtd->asp_link[1] = edma_alloc_slot( |
| 426 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); | 424 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); |
| 427 | if (link < 0) | 425 | if (ret < 0) |
| 428 | goto exit3; | 426 | goto exit3; |
| 429 | 427 | ||
| 430 | prtd->ram_link2 = -1; | 428 | prtd->ram_link2 = -1; |
| 431 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 429 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 432 | link = prtd->ram_link2 = edma_alloc_slot( | 430 | ret = prtd->ram_link2 = edma_alloc_slot( |
| 433 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); | 431 | EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY); |
| 434 | if (link < 0) | 432 | if (ret < 0) |
| 435 | goto exit4; | 433 | goto exit4; |
| 436 | } | 434 | } |
| 437 | /* circle ping-pong buffers */ | 435 | /* circle ping-pong buffers */ |
| @@ -448,36 +446,33 @@ static int request_ping_pong(struct snd_pcm_substream *substream, | |||
| 448 | asp_dst_ping = iram_dma->addr; | 446 | asp_dst_ping = iram_dma->addr; |
| 449 | } | 447 | } |
| 450 | /* ping */ | 448 | /* ping */ |
| 451 | link = prtd->asp_link[0]; | 449 | edma_set_src(prtd->asp_link[0], asp_src_ping, INCR, W16BIT); |
| 452 | edma_set_src(link, asp_src_ping, INCR, W16BIT); | 450 | edma_set_dest(prtd->asp_link[0], asp_dst_ping, INCR, W16BIT); |
| 453 | edma_set_dest(link, asp_dst_ping, INCR, W16BIT); | 451 | edma_set_src_index(prtd->asp_link[0], 0, 0); |
| 454 | edma_set_src_index(link, 0, 0); | 452 | edma_set_dest_index(prtd->asp_link[0], 0, 0); |
| 455 | edma_set_dest_index(link, 0, 0); | ||
| 456 | 453 | ||
| 457 | edma_read_slot(link, &prtd->asp_params); | 454 | edma_read_slot(prtd->asp_link[0], &prtd->asp_params); |
| 458 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); | 455 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN); |
| 459 | prtd->asp_params.opt |= TCCHEN | | 456 | prtd->asp_params.opt |= TCCHEN | |
| 460 | EDMA_TCC(prtd->ram_channel & 0x3f); | 457 | EDMA_TCC(prtd->ram_channel & 0x3f); |
| 461 | edma_write_slot(link, &prtd->asp_params); | 458 | edma_write_slot(prtd->asp_link[0], &prtd->asp_params); |
| 462 | 459 | ||
| 463 | /* pong */ | 460 | /* pong */ |
| 464 | link = prtd->asp_link[1]; | 461 | edma_set_src(prtd->asp_link[1], asp_src_ping, INCR, W16BIT); |
| 465 | edma_set_src(link, asp_src_ping, INCR, W16BIT); | 462 | edma_set_dest(prtd->asp_link[1], asp_dst_ping, INCR, W16BIT); |
| 466 | edma_set_dest(link, asp_dst_ping, INCR, W16BIT); | 463 | edma_set_src_index(prtd->asp_link[1], 0, 0); |
| 467 | edma_set_src_index(link, 0, 0); | 464 | edma_set_dest_index(prtd->asp_link[1], 0, 0); |
| 468 | edma_set_dest_index(link, 0, 0); | ||
| 469 | 465 | ||
| 470 | edma_read_slot(link, &prtd->asp_params); | 466 | edma_read_slot(prtd->asp_link[1], &prtd->asp_params); |
| 471 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); | 467 | prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f)); |
| 472 | /* interrupt after every pong completion */ | 468 | /* interrupt after every pong completion */ |
| 473 | prtd->asp_params.opt |= TCINTEN | TCCHEN | | 469 | prtd->asp_params.opt |= TCINTEN | TCCHEN | |
| 474 | EDMA_TCC(prtd->ram_channel & 0x3f); | 470 | EDMA_TCC(prtd->ram_channel & 0x3f); |
| 475 | edma_write_slot(link, &prtd->asp_params); | 471 | edma_write_slot(prtd->asp_link[1], &prtd->asp_params); |
| 476 | 472 | ||
| 477 | /* ram */ | 473 | /* ram */ |
| 478 | link = prtd->ram_link; | 474 | edma_set_src(prtd->ram_link, iram_dma->addr, INCR, W32BIT); |
| 479 | edma_set_src(link, iram_dma->addr, INCR, W32BIT); | 475 | edma_set_dest(prtd->ram_link, iram_dma->addr, INCR, W32BIT); |
| 480 | edma_set_dest(link, iram_dma->addr, INCR, W32BIT); | ||
| 481 | pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," | 476 | pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u," |
| 482 | "for asp:%u %u %u\n", __func__, | 477 | "for asp:%u %u %u\n", __func__, |
| 483 | prtd->ram_channel, prtd->ram_link, prtd->ram_link2, | 478 | prtd->ram_channel, prtd->ram_link, prtd->ram_link2, |
| @@ -494,7 +489,7 @@ exit2: | |||
| 494 | edma_free_channel(prtd->ram_channel); | 489 | edma_free_channel(prtd->ram_channel); |
| 495 | prtd->ram_channel = -1; | 490 | prtd->ram_channel = -1; |
| 496 | exit1: | 491 | exit1: |
| 497 | return link; | 492 | return ret; |
| 498 | } | 493 | } |
| 499 | 494 | ||
| 500 | static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) | 495 | static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) |
| @@ -502,22 +497,22 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) | |||
| 502 | struct snd_dma_buffer *iram_dma; | 497 | struct snd_dma_buffer *iram_dma; |
| 503 | struct davinci_runtime_data *prtd = substream->runtime->private_data; | 498 | struct davinci_runtime_data *prtd = substream->runtime->private_data; |
| 504 | struct davinci_pcm_dma_params *params = prtd->params; | 499 | struct davinci_pcm_dma_params *params = prtd->params; |
| 505 | int link; | 500 | int ret; |
| 506 | 501 | ||
| 507 | if (!params) | 502 | if (!params) |
| 508 | return -ENODEV; | 503 | return -ENODEV; |
| 509 | 504 | ||
| 510 | /* Request asp master DMA channel */ | 505 | /* Request asp master DMA channel */ |
| 511 | link = prtd->asp_channel = edma_alloc_channel(params->channel, | 506 | ret = prtd->asp_channel = edma_alloc_channel(params->channel, |
| 512 | davinci_pcm_dma_irq, substream, | 507 | davinci_pcm_dma_irq, substream, |
| 513 | prtd->params->asp_chan_q); | 508 | prtd->params->asp_chan_q); |
| 514 | if (link < 0) | 509 | if (ret < 0) |
| 515 | goto exit1; | 510 | goto exit1; |
| 516 | 511 | ||
| 517 | /* Request asp link channels */ | 512 | /* Request asp link channels */ |
| 518 | link = prtd->asp_link[0] = edma_alloc_slot( | 513 | ret = prtd->asp_link[0] = edma_alloc_slot( |
| 519 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); | 514 | EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY); |
| 520 | if (link < 0) | 515 | if (ret < 0) |
| 521 | goto exit2; | 516 | goto exit2; |
| 522 | 517 | ||
| 523 | iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; | 518 | iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data; |
| @@ -537,17 +532,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) | |||
| 537 | * the buffer and its length (ccnt) ... use it as a template | 532 | * the buffer and its length (ccnt) ... use it as a template |
| 538 | * so davinci_pcm_enqueue_dma() takes less time in IRQ. | 533 | * so davinci_pcm_enqueue_dma() takes less time in IRQ. |
| 539 | */ | 534 | */ |
| 540 | edma_read_slot(link, &prtd->asp_params); | 535 | edma_read_slot(prtd->asp_link[0], &prtd->asp_params); |
| 541 | prtd->asp_params.opt |= TCINTEN | | 536 | prtd->asp_params.opt |= TCINTEN | |
| 542 | EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); | 537 | EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel)); |
| 543 | prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5; | 538 | prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(prtd->asp_link[0]) << 5; |
| 544 | edma_write_slot(link, &prtd->asp_params); | 539 | edma_write_slot(prtd->asp_link[0], &prtd->asp_params); |
| 545 | return 0; | 540 | return 0; |
| 546 | exit2: | 541 | exit2: |
| 547 | edma_free_channel(prtd->asp_channel); | 542 | edma_free_channel(prtd->asp_channel); |
| 548 | prtd->asp_channel = -1; | 543 | prtd->asp_channel = -1; |
| 549 | exit1: | 544 | exit1: |
| 550 | return link; | 545 | return ret; |
| 551 | } | 546 | } |
| 552 | 547 | ||
| 553 | static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 548 | static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
diff --git a/sound/soc/ep93xx/edb93xx.c b/sound/soc/ep93xx/edb93xx.c index d3aa15119d26..0134d4e9131c 100644 --- a/sound/soc/ep93xx/edb93xx.c +++ b/sound/soc/ep93xx/edb93xx.c | |||
| @@ -28,12 +28,6 @@ | |||
| 28 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
| 29 | #include "ep93xx-pcm.h" | 29 | #include "ep93xx-pcm.h" |
| 30 | 30 | ||
| 31 | #define edb93xx_has_audio() (machine_is_edb9301() || \ | ||
| 32 | machine_is_edb9302() || \ | ||
| 33 | machine_is_edb9302a() || \ | ||
| 34 | machine_is_edb9307a() || \ | ||
| 35 | machine_is_edb9315a()) | ||
| 36 | |||
| 37 | static int edb93xx_hw_params(struct snd_pcm_substream *substream, | 31 | static int edb93xx_hw_params(struct snd_pcm_substream *substream, |
| 38 | struct snd_pcm_hw_params *params) | 32 | struct snd_pcm_hw_params *params) |
| 39 | { | 33 | { |
| @@ -94,49 +88,61 @@ static struct snd_soc_card snd_soc_edb93xx = { | |||
| 94 | .num_links = 1, | 88 | .num_links = 1, |
| 95 | }; | 89 | }; |
| 96 | 90 | ||
| 97 | static struct platform_device *edb93xx_snd_device; | 91 | static int __devinit edb93xx_probe(struct platform_device *pdev) |
| 98 | |||
| 99 | static int __init edb93xx_init(void) | ||
| 100 | { | 92 | { |
| 93 | struct snd_soc_card *card = &snd_soc_edb93xx; | ||
| 101 | int ret; | 94 | int ret; |
| 102 | 95 | ||
| 103 | if (!edb93xx_has_audio()) | ||
| 104 | return -ENODEV; | ||
| 105 | |||
| 106 | ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, | 96 | ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, |
| 107 | EP93XX_SYSCON_I2SCLKDIV_ORIDE | | 97 | EP93XX_SYSCON_I2SCLKDIV_ORIDE | |
| 108 | EP93XX_SYSCON_I2SCLKDIV_SPOL); | 98 | EP93XX_SYSCON_I2SCLKDIV_SPOL); |
| 109 | if (ret) | 99 | if (ret) |
| 110 | return ret; | 100 | return ret; |
| 111 | 101 | ||
| 112 | edb93xx_snd_device = platform_device_alloc("soc-audio", -1); | 102 | card->dev = &pdev->dev; |
| 113 | if (!edb93xx_snd_device) { | 103 | |
| 114 | ret = -ENOMEM; | 104 | ret = snd_soc_register_card(card); |
| 115 | goto free_i2s; | 105 | if (ret) { |
| 106 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", | ||
| 107 | ret); | ||
| 108 | ep93xx_i2s_release(); | ||
| 116 | } | 109 | } |
| 117 | 110 | ||
| 118 | platform_set_drvdata(edb93xx_snd_device, &snd_soc_edb93xx); | 111 | return ret; |
| 119 | ret = platform_device_add(edb93xx_snd_device); | 112 | } |
| 120 | if (ret) | ||
| 121 | goto device_put; | ||
| 122 | 113 | ||
| 123 | return 0; | 114 | static int __devexit edb93xx_remove(struct platform_device *pdev) |
| 115 | { | ||
| 116 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 124 | 117 | ||
| 125 | device_put: | 118 | snd_soc_unregister_card(card); |
| 126 | platform_device_put(edb93xx_snd_device); | ||
| 127 | free_i2s: | ||
| 128 | ep93xx_i2s_release(); | 119 | ep93xx_i2s_release(); |
| 129 | return ret; | 120 | |
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static struct platform_driver edb93xx_driver = { | ||
| 125 | .driver = { | ||
| 126 | .name = "edb93xx-audio", | ||
| 127 | .owner = THIS_MODULE, | ||
| 128 | }, | ||
| 129 | .probe = edb93xx_probe, | ||
| 130 | .remove = __devexit_p(edb93xx_remove), | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int __init edb93xx_init(void) | ||
| 134 | { | ||
| 135 | return platform_driver_register(&edb93xx_driver); | ||
| 130 | } | 136 | } |
| 131 | module_init(edb93xx_init); | 137 | module_init(edb93xx_init); |
| 132 | 138 | ||
| 133 | static void __exit edb93xx_exit(void) | 139 | static void __exit edb93xx_exit(void) |
| 134 | { | 140 | { |
| 135 | platform_device_unregister(edb93xx_snd_device); | 141 | platform_driver_unregister(&edb93xx_driver); |
| 136 | ep93xx_i2s_release(); | ||
| 137 | } | 142 | } |
| 138 | module_exit(edb93xx_exit); | 143 | module_exit(edb93xx_exit); |
| 139 | 144 | ||
| 140 | MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); | 145 | MODULE_AUTHOR("Alexander Sverdlin <subaparts@yandex.ru>"); |
| 141 | MODULE_DESCRIPTION("ALSA SoC EDB93xx"); | 146 | MODULE_DESCRIPTION("ALSA SoC EDB93xx"); |
| 142 | MODULE_LICENSE("GPL"); | 147 | MODULE_LICENSE("GPL"); |
| 148 | MODULE_ALIAS("platform:edb93xx-audio"); | ||
diff --git a/sound/soc/ep93xx/ep93xx-ac97.c b/sound/soc/ep93xx/ep93xx-ac97.c index c7417c76552b..3cd6158d83e1 100644 --- a/sound/soc/ep93xx/ep93xx-ac97.c +++ b/sound/soc/ep93xx/ep93xx-ac97.c | |||
| @@ -335,7 +335,7 @@ static struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { | |||
| 335 | .trigger = ep93xx_ac97_trigger, | 335 | .trigger = ep93xx_ac97_trigger, |
| 336 | }; | 336 | }; |
| 337 | 337 | ||
| 338 | struct snd_soc_dai_driver ep93xx_ac97_dai = { | 338 | static struct snd_soc_dai_driver ep93xx_ac97_dai = { |
| 339 | .name = "ep93xx-ac97", | 339 | .name = "ep93xx-ac97", |
| 340 | .id = 0, | 340 | .id = 0, |
| 341 | .ac97_control = 1, | 341 | .ac97_control = 1, |
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index 8dfd3ad84b19..d00230a591b1 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c | |||
| @@ -355,3 +355,4 @@ module_exit(ep93xx_soc_platform_exit); | |||
| 355 | MODULE_AUTHOR("Ryan Mallon"); | 355 | MODULE_AUTHOR("Ryan Mallon"); |
| 356 | MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); | 356 | MODULE_DESCRIPTION("EP93xx ALSA PCM interface"); |
| 357 | MODULE_LICENSE("GPL"); | 357 | MODULE_LICENSE("GPL"); |
| 358 | MODULE_ALIAS("platform:ep93xx-pcm-audio"); | ||
diff --git a/sound/soc/ep93xx/simone.c b/sound/soc/ep93xx/simone.c index 286817946c56..968cb316d511 100644 --- a/sound/soc/ep93xx/simone.c +++ b/sound/soc/ep93xx/simone.c | |||
| @@ -39,53 +39,61 @@ static struct snd_soc_card snd_soc_simone = { | |||
| 39 | }; | 39 | }; |
| 40 | 40 | ||
| 41 | static struct platform_device *simone_snd_ac97_device; | 41 | static struct platform_device *simone_snd_ac97_device; |
| 42 | static struct platform_device *simone_snd_device; | ||
| 43 | 42 | ||
| 44 | static int __init simone_init(void) | 43 | static int __devinit simone_probe(struct platform_device *pdev) |
| 45 | { | 44 | { |
| 45 | struct snd_soc_card *card = &snd_soc_simone; | ||
| 46 | int ret; | 46 | int ret; |
| 47 | 47 | ||
| 48 | if (!machine_is_sim_one()) | 48 | simone_snd_ac97_device = platform_device_register_simple("ac97-codec", |
| 49 | return -ENODEV; | 49 | -1, NULL, 0); |
| 50 | 50 | if (IS_ERR(simone_snd_ac97_device)) | |
| 51 | simone_snd_ac97_device = platform_device_alloc("ac97-codec", -1); | 51 | return PTR_ERR(simone_snd_ac97_device); |
| 52 | if (!simone_snd_ac97_device) | ||
| 53 | return -ENOMEM; | ||
| 54 | 52 | ||
| 55 | ret = platform_device_add(simone_snd_ac97_device); | 53 | card->dev = &pdev->dev; |
| 56 | if (ret) | ||
| 57 | goto fail1; | ||
| 58 | 54 | ||
| 59 | simone_snd_device = platform_device_alloc("soc-audio", -1); | 55 | ret = snd_soc_register_card(card); |
| 60 | if (!simone_snd_device) { | 56 | if (ret) { |
| 61 | ret = -ENOMEM; | 57 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
| 62 | goto fail2; | 58 | ret); |
| 59 | platform_device_unregister(simone_snd_ac97_device); | ||
| 63 | } | 60 | } |
| 64 | 61 | ||
| 65 | platform_set_drvdata(simone_snd_device, &snd_soc_simone); | 62 | return ret; |
| 66 | ret = platform_device_add(simone_snd_device); | 63 | } |
| 67 | if (ret) | 64 | |
| 68 | goto fail3; | 65 | static int __devexit simone_remove(struct platform_device *pdev) |
| 66 | { | ||
| 67 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 68 | |||
| 69 | snd_soc_unregister_card(card); | ||
| 70 | platform_device_unregister(simone_snd_ac97_device); | ||
| 69 | 71 | ||
| 70 | return 0; | 72 | return 0; |
| 73 | } | ||
| 71 | 74 | ||
| 72 | fail3: | 75 | static struct platform_driver simone_driver = { |
| 73 | platform_device_put(simone_snd_device); | 76 | .driver = { |
| 74 | fail2: | 77 | .name = "simone-audio", |
| 75 | platform_device_del(simone_snd_ac97_device); | 78 | .owner = THIS_MODULE, |
| 76 | fail1: | 79 | }, |
| 77 | platform_device_put(simone_snd_ac97_device); | 80 | .probe = simone_probe, |
| 78 | return ret; | 81 | .remove = __devexit_p(simone_remove), |
| 82 | }; | ||
| 83 | |||
| 84 | static int __init simone_init(void) | ||
| 85 | { | ||
| 86 | return platform_driver_register(&simone_driver); | ||
| 79 | } | 87 | } |
| 80 | module_init(simone_init); | 88 | module_init(simone_init); |
| 81 | 89 | ||
| 82 | static void __exit simone_exit(void) | 90 | static void __exit simone_exit(void) |
| 83 | { | 91 | { |
| 84 | platform_device_unregister(simone_snd_device); | 92 | platform_driver_unregister(&simone_driver); |
| 85 | platform_device_unregister(simone_snd_ac97_device); | ||
| 86 | } | 93 | } |
| 87 | module_exit(simone_exit); | 94 | module_exit(simone_exit); |
| 88 | 95 | ||
| 89 | MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); | 96 | MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); |
| 90 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); | 97 | MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); |
| 91 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
| 99 | MODULE_ALIAS("platform:simone-audio"); | ||
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index c8aa8a5003ca..f74ac54c285a 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c | |||
| @@ -104,37 +104,56 @@ static struct snd_soc_card snd_soc_snappercl15 = { | |||
| 104 | .num_links = 1, | 104 | .num_links = 1, |
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | static struct platform_device *snappercl15_snd_device; | 107 | static int __devinit snappercl15_probe(struct platform_device *pdev) |
| 108 | |||
| 109 | static int __init snappercl15_init(void) | ||
| 110 | { | 108 | { |
| 109 | struct snd_soc_card *card = &snd_soc_snappercl15; | ||
| 111 | int ret; | 110 | int ret; |
| 112 | 111 | ||
| 113 | if (!machine_is_snapper_cl15()) | ||
| 114 | return -ENODEV; | ||
| 115 | |||
| 116 | ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, | 112 | ret = ep93xx_i2s_acquire(EP93XX_SYSCON_DEVCFG_I2SONAC97, |
| 117 | EP93XX_SYSCON_I2SCLKDIV_ORIDE | | 113 | EP93XX_SYSCON_I2SCLKDIV_ORIDE | |
| 118 | EP93XX_SYSCON_I2SCLKDIV_SPOL); | 114 | EP93XX_SYSCON_I2SCLKDIV_SPOL); |
| 119 | if (ret) | 115 | if (ret) |
| 120 | return ret; | 116 | return ret; |
| 121 | 117 | ||
| 122 | snappercl15_snd_device = platform_device_alloc("soc-audio", -1); | 118 | card->dev = &pdev->dev; |
| 123 | if (!snappercl15_snd_device) | 119 | |
| 124 | return -ENOMEM; | 120 | ret = snd_soc_register_card(card); |
| 125 | 121 | if (ret) { | |
| 126 | platform_set_drvdata(snappercl15_snd_device, &snd_soc_snappercl15); | 122 | dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", |
| 127 | ret = platform_device_add(snappercl15_snd_device); | 123 | ret); |
| 128 | if (ret) | 124 | ep93xx_i2s_release(); |
| 129 | platform_device_put(snappercl15_snd_device); | 125 | } |
| 130 | 126 | ||
| 131 | return ret; | 127 | return ret; |
| 132 | } | 128 | } |
| 133 | 129 | ||
| 134 | static void __exit snappercl15_exit(void) | 130 | static int __devexit snappercl15_remove(struct platform_device *pdev) |
| 135 | { | 131 | { |
| 136 | platform_device_unregister(snappercl15_snd_device); | 132 | struct snd_soc_card *card = platform_get_drvdata(pdev); |
| 133 | |||
| 134 | snd_soc_unregister_card(card); | ||
| 137 | ep93xx_i2s_release(); | 135 | ep93xx_i2s_release(); |
| 136 | |||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | static struct platform_driver snappercl15_driver = { | ||
| 141 | .driver = { | ||
| 142 | .name = "snappercl15-audio", | ||
| 143 | .owner = THIS_MODULE, | ||
| 144 | }, | ||
| 145 | .probe = snappercl15_probe, | ||
| 146 | .remove = __devexit_p(snappercl15_remove), | ||
| 147 | }; | ||
| 148 | |||
| 149 | static int __init snappercl15_init(void) | ||
| 150 | { | ||
| 151 | return platform_driver_register(&snappercl15_driver); | ||
| 152 | } | ||
| 153 | |||
| 154 | static void __exit snappercl15_exit(void) | ||
| 155 | { | ||
| 156 | platform_driver_unregister(&snappercl15_driver); | ||
| 138 | } | 157 | } |
| 139 | 158 | ||
| 140 | module_init(snappercl15_init); | 159 | module_init(snappercl15_init); |
| @@ -143,4 +162,4 @@ module_exit(snappercl15_exit); | |||
| 143 | MODULE_AUTHOR("Ryan Mallon"); | 162 | MODULE_AUTHOR("Ryan Mallon"); |
| 144 | MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); | 163 | MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); |
| 145 | MODULE_LICENSE("GPL"); | 164 | MODULE_LICENSE("GPL"); |
| 146 | 165 | MODULE_ALIAS("platform:snappercl15-audio"); | |
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c index cb50598338e9..ef15402a3bc4 100644 --- a/sound/soc/fsl/fsl_dma.c +++ b/sound/soc/fsl/fsl_dma.c | |||
| @@ -297,7 +297,6 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id) | |||
| 297 | static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) | 297 | static int fsl_dma_new(struct snd_soc_pcm_runtime *rtd) |
| 298 | { | 298 | { |
| 299 | struct snd_card *card = rtd->card->snd_card; | 299 | struct snd_card *card = rtd->card->snd_card; |
| 300 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
| 301 | struct snd_pcm *pcm = rtd->pcm; | 300 | struct snd_pcm *pcm = rtd->pcm; |
| 302 | static u64 fsl_dma_dmamask = DMA_BIT_MASK(36); | 301 | static u64 fsl_dma_dmamask = DMA_BIT_MASK(36); |
| 303 | int ret; | 302 | int ret; |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index d48afea5d93d..0268cf989736 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
| @@ -78,7 +78,6 @@ | |||
| 78 | * @second_stream: pointer to second stream | 78 | * @second_stream: pointer to second stream |
| 79 | * @playback: the number of playback streams opened | 79 | * @playback: the number of playback streams opened |
| 80 | * @capture: the number of capture streams opened | 80 | * @capture: the number of capture streams opened |
| 81 | * @asynchronous: 0=synchronous mode, 1=asynchronous mode | ||
| 82 | * @cpu_dai: the CPU DAI for this device | 81 | * @cpu_dai: the CPU DAI for this device |
| 83 | * @dev_attr: the sysfs device attribute structure | 82 | * @dev_attr: the sysfs device attribute structure |
| 84 | * @stats: SSI statistics | 83 | * @stats: SSI statistics |
| @@ -90,9 +89,6 @@ struct fsl_ssi_private { | |||
| 90 | unsigned int irq; | 89 | unsigned int irq; |
| 91 | struct snd_pcm_substream *first_stream; | 90 | struct snd_pcm_substream *first_stream; |
| 92 | struct snd_pcm_substream *second_stream; | 91 | struct snd_pcm_substream *second_stream; |
| 93 | unsigned int playback; | ||
| 94 | unsigned int capture; | ||
| 95 | int asynchronous; | ||
| 96 | unsigned int fifo_depth; | 92 | unsigned int fifo_depth; |
| 97 | struct snd_soc_dai_driver cpu_dai_drv; | 93 | struct snd_soc_dai_driver cpu_dai_drv; |
| 98 | struct device_attribute dev_attr; | 94 | struct device_attribute dev_attr; |
| @@ -281,24 +277,18 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
| 281 | struct snd_soc_dai *dai) | 277 | struct snd_soc_dai *dai) |
| 282 | { | 278 | { |
| 283 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 279 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 284 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); | 280 | struct fsl_ssi_private *ssi_private = |
| 281 | snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
| 282 | int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; | ||
| 285 | 283 | ||
| 286 | /* | 284 | /* |
| 287 | * If this is the first stream opened, then request the IRQ | 285 | * If this is the first stream opened, then request the IRQ |
| 288 | * and initialize the SSI registers. | 286 | * and initialize the SSI registers. |
| 289 | */ | 287 | */ |
| 290 | if (!ssi_private->playback && !ssi_private->capture) { | 288 | if (!ssi_private->first_stream) { |
| 291 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 289 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
| 292 | int ret; | 290 | |
| 293 | 291 | ssi_private->first_stream = substream; | |
| 294 | /* The 'name' should not have any slashes in it. */ | ||
| 295 | ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, | ||
| 296 | ssi_private->name, ssi_private); | ||
| 297 | if (ret < 0) { | ||
| 298 | dev_err(substream->pcm->card->dev, | ||
| 299 | "could not claim irq %u\n", ssi_private->irq); | ||
| 300 | return ret; | ||
| 301 | } | ||
| 302 | 292 | ||
| 303 | /* | 293 | /* |
| 304 | * Section 16.5 of the MPC8610 reference manual says that the | 294 | * Section 16.5 of the MPC8610 reference manual says that the |
| @@ -316,7 +306,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
| 316 | clrsetbits_be32(&ssi->scr, | 306 | clrsetbits_be32(&ssi->scr, |
| 317 | CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, | 307 | CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, |
| 318 | CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE | 308 | CCSR_SSI_SCR_TFR_CLK_DIS | CCSR_SSI_SCR_I2S_MODE_SLAVE |
| 319 | | (ssi_private->asynchronous ? 0 : CCSR_SSI_SCR_SYN)); | 309 | | (synchronous ? CCSR_SSI_SCR_SYN : 0)); |
| 320 | 310 | ||
| 321 | out_be32(&ssi->stcr, | 311 | out_be32(&ssi->stcr, |
| 322 | CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | | 312 | CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | |
| @@ -333,7 +323,7 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
| 333 | * master. | 323 | * master. |
| 334 | */ | 324 | */ |
| 335 | 325 | ||
| 336 | /* 4. Enable the interrupts and DMA requests */ | 326 | /* Enable the interrupts and DMA requests */ |
| 337 | out_be32(&ssi->sier, SIER_FLAGS); | 327 | out_be32(&ssi->sier, SIER_FLAGS); |
| 338 | 328 | ||
| 339 | /* | 329 | /* |
| @@ -362,58 +352,47 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream, | |||
| 362 | * this is bad is because at this point, the PCM driver has not | 352 | * this is bad is because at this point, the PCM driver has not |
| 363 | * finished initializing the DMA controller. | 353 | * finished initializing the DMA controller. |
| 364 | */ | 354 | */ |
| 365 | } | 355 | } else { |
| 356 | if (synchronous) { | ||
| 357 | struct snd_pcm_runtime *first_runtime = | ||
| 358 | ssi_private->first_stream->runtime; | ||
| 359 | /* | ||
| 360 | * This is the second stream open, and we're in | ||
| 361 | * synchronous mode, so we need to impose sample | ||
| 362 | * sample size constraints. This is because STCCR is | ||
| 363 | * used for playback and capture in synchronous mode, | ||
| 364 | * so there's no way to specify different word | ||
| 365 | * lengths. | ||
| 366 | * | ||
| 367 | * Note that this can cause a race condition if the | ||
| 368 | * second stream is opened before the first stream is | ||
| 369 | * fully initialized. We provide some protection by | ||
| 370 | * checking to make sure the first stream is | ||
| 371 | * initialized, but it's not perfect. ALSA sometimes | ||
| 372 | * re-initializes the driver with a different sample | ||
| 373 | * rate or size. If the second stream is opened | ||
| 374 | * before the first stream has received its final | ||
| 375 | * parameters, then the second stream may be | ||
| 376 | * constrained to the wrong sample rate or size. | ||
| 377 | */ | ||
| 378 | if (!first_runtime->sample_bits) { | ||
| 379 | dev_err(substream->pcm->card->dev, | ||
| 380 | "set sample size in %s stream first\n", | ||
| 381 | substream->stream == | ||
| 382 | SNDRV_PCM_STREAM_PLAYBACK | ||
| 383 | ? "capture" : "playback"); | ||
| 384 | return -EAGAIN; | ||
| 385 | } | ||
| 366 | 386 | ||
| 367 | if (!ssi_private->first_stream) | ||
| 368 | ssi_private->first_stream = substream; | ||
| 369 | else { | ||
| 370 | /* This is the second stream open, so we need to impose sample | ||
| 371 | * rate and maybe sample size constraints. Note that this can | ||
| 372 | * cause a race condition if the second stream is opened before | ||
| 373 | * the first stream is fully initialized. | ||
| 374 | * | ||
| 375 | * We provide some protection by checking to make sure the first | ||
| 376 | * stream is initialized, but it's not perfect. ALSA sometimes | ||
| 377 | * re-initializes the driver with a different sample rate or | ||
| 378 | * size. If the second stream is opened before the first stream | ||
| 379 | * has received its final parameters, then the second stream may | ||
| 380 | * be constrained to the wrong sample rate or size. | ||
| 381 | * | ||
| 382 | * FIXME: This code does not handle opening and closing streams | ||
| 383 | * repeatedly. If you open two streams and then close the first | ||
| 384 | * one, you may not be able to open another stream until you | ||
| 385 | * close the second one as well. | ||
| 386 | */ | ||
| 387 | struct snd_pcm_runtime *first_runtime = | ||
| 388 | ssi_private->first_stream->runtime; | ||
| 389 | |||
| 390 | if (!first_runtime->sample_bits) { | ||
| 391 | dev_err(substream->pcm->card->dev, | ||
| 392 | "set sample size in %s stream first\n", | ||
| 393 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK | ||
| 394 | ? "capture" : "playback"); | ||
| 395 | return -EAGAIN; | ||
| 396 | } | ||
| 397 | |||
| 398 | /* If we're in synchronous mode, then we need to constrain | ||
| 399 | * the sample size as well. We don't support independent sample | ||
| 400 | * rates in asynchronous mode. | ||
| 401 | */ | ||
| 402 | if (!ssi_private->asynchronous) | ||
| 403 | snd_pcm_hw_constraint_minmax(substream->runtime, | 387 | snd_pcm_hw_constraint_minmax(substream->runtime, |
| 404 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | 388 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, |
| 405 | first_runtime->sample_bits, | 389 | first_runtime->sample_bits, |
| 406 | first_runtime->sample_bits); | 390 | first_runtime->sample_bits); |
| 391 | } | ||
| 407 | 392 | ||
| 408 | ssi_private->second_stream = substream; | 393 | ssi_private->second_stream = substream; |
| 409 | } | 394 | } |
| 410 | 395 | ||
| 411 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 412 | ssi_private->playback++; | ||
| 413 | |||
| 414 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
| 415 | ssi_private->capture++; | ||
| 416 | |||
| 417 | return 0; | 396 | return 0; |
| 418 | } | 397 | } |
| 419 | 398 | ||
| @@ -434,24 +413,35 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream, | |||
| 434 | struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) | 413 | struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *cpu_dai) |
| 435 | { | 414 | { |
| 436 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); | 415 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); |
| 416 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | ||
| 417 | unsigned int sample_size = | ||
| 418 | snd_pcm_format_width(params_format(hw_params)); | ||
| 419 | u32 wl = CCSR_SSI_SxCCR_WL(sample_size); | ||
| 420 | int enabled = in_be32(&ssi->scr) & CCSR_SSI_SCR_SSIEN; | ||
| 437 | 421 | ||
| 438 | if (substream == ssi_private->first_stream) { | 422 | /* |
| 439 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 423 | * If we're in synchronous mode, and the SSI is already enabled, |
| 440 | unsigned int sample_size = | 424 | * then STCCR is already set properly. |
| 441 | snd_pcm_format_width(params_format(hw_params)); | 425 | */ |
| 442 | u32 wl = CCSR_SSI_SxCCR_WL(sample_size); | 426 | if (enabled && ssi_private->cpu_dai_drv.symmetric_rates) |
| 427 | return 0; | ||
| 443 | 428 | ||
| 444 | /* The SSI should always be disabled at this points (SSIEN=0) */ | 429 | /* |
| 430 | * FIXME: The documentation says that SxCCR[WL] should not be | ||
| 431 | * modified while the SSI is enabled. The only time this can | ||
| 432 | * happen is if we're trying to do simultaneous playback and | ||
| 433 | * capture in asynchronous mode. Unfortunately, I have been enable | ||
| 434 | * to get that to work at all on the P1022DS. Therefore, we don't | ||
| 435 | * bother to disable/enable the SSI when setting SxCCR[WL], because | ||
| 436 | * the SSI will stop anyway. Maybe one day, this will get fixed. | ||
| 437 | */ | ||
| 445 | 438 | ||
| 446 | /* In synchronous mode, the SSI uses STCCR for capture */ | 439 | /* In synchronous mode, the SSI uses STCCR for capture */ |
| 447 | if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || | 440 | if ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) || |
| 448 | !ssi_private->asynchronous) | 441 | ssi_private->cpu_dai_drv.symmetric_rates) |
| 449 | clrsetbits_be32(&ssi->stccr, | 442 | clrsetbits_be32(&ssi->stccr, CCSR_SSI_SxCCR_WL_MASK, wl); |
| 450 | CCSR_SSI_SxCCR_WL_MASK, wl); | 443 | else |
| 451 | else | 444 | clrsetbits_be32(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); |
| 452 | clrsetbits_be32(&ssi->srccr, | ||
| 453 | CCSR_SSI_SxCCR_WL_MASK, wl); | ||
| 454 | } | ||
| 455 | 445 | ||
| 456 | return 0; | 446 | return 0; |
| 457 | } | 447 | } |
| @@ -474,7 +464,6 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd, | |||
| 474 | 464 | ||
| 475 | switch (cmd) { | 465 | switch (cmd) { |
| 476 | case SNDRV_PCM_TRIGGER_START: | 466 | case SNDRV_PCM_TRIGGER_START: |
| 477 | clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); | ||
| 478 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 467 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 479 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 468 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
| 480 | setbits32(&ssi->scr, | 469 | setbits32(&ssi->scr, |
| @@ -510,27 +499,18 @@ static void fsl_ssi_shutdown(struct snd_pcm_substream *substream, | |||
| 510 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 499 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 511 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); | 500 | struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); |
| 512 | 501 | ||
| 513 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 514 | ssi_private->playback--; | ||
| 515 | |||
| 516 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | ||
| 517 | ssi_private->capture--; | ||
| 518 | |||
| 519 | if (ssi_private->first_stream == substream) | 502 | if (ssi_private->first_stream == substream) |
| 520 | ssi_private->first_stream = ssi_private->second_stream; | 503 | ssi_private->first_stream = ssi_private->second_stream; |
| 521 | 504 | ||
| 522 | ssi_private->second_stream = NULL; | 505 | ssi_private->second_stream = NULL; |
| 523 | 506 | ||
| 524 | /* | 507 | /* |
| 525 | * If this is the last active substream, disable the SSI and release | 508 | * If this is the last active substream, disable the SSI. |
| 526 | * the IRQ. | ||
| 527 | */ | 509 | */ |
| 528 | if (!ssi_private->playback && !ssi_private->capture) { | 510 | if (!ssi_private->first_stream) { |
| 529 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; | 511 | struct ccsr_ssi __iomem *ssi = ssi_private->ssi; |
| 530 | 512 | ||
| 531 | clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); | 513 | clrbits32(&ssi->scr, CCSR_SSI_SCR_SSIEN); |
| 532 | |||
| 533 | free_irq(ssi_private->irq, ssi_private); | ||
| 534 | } | 514 | } |
| 535 | } | 515 | } |
| 536 | 516 | ||
| @@ -675,22 +655,33 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
| 675 | ret = of_address_to_resource(np, 0, &res); | 655 | ret = of_address_to_resource(np, 0, &res); |
| 676 | if (ret) { | 656 | if (ret) { |
| 677 | dev_err(&pdev->dev, "could not determine device resources\n"); | 657 | dev_err(&pdev->dev, "could not determine device resources\n"); |
| 678 | kfree(ssi_private); | 658 | goto error_kmalloc; |
| 679 | return ret; | ||
| 680 | } | 659 | } |
| 681 | ssi_private->ssi = of_iomap(np, 0); | 660 | ssi_private->ssi = of_iomap(np, 0); |
| 682 | if (!ssi_private->ssi) { | 661 | if (!ssi_private->ssi) { |
| 683 | dev_err(&pdev->dev, "could not map device resources\n"); | 662 | dev_err(&pdev->dev, "could not map device resources\n"); |
| 684 | kfree(ssi_private); | 663 | ret = -ENOMEM; |
| 685 | return -ENOMEM; | 664 | goto error_kmalloc; |
| 686 | } | 665 | } |
| 687 | ssi_private->ssi_phys = res.start; | 666 | ssi_private->ssi_phys = res.start; |
| 667 | |||
| 688 | ssi_private->irq = irq_of_parse_and_map(np, 0); | 668 | ssi_private->irq = irq_of_parse_and_map(np, 0); |
| 669 | if (ssi_private->irq == NO_IRQ) { | ||
| 670 | dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); | ||
| 671 | ret = -ENXIO; | ||
| 672 | goto error_iomap; | ||
| 673 | } | ||
| 674 | |||
| 675 | /* The 'name' should not have any slashes in it. */ | ||
| 676 | ret = request_irq(ssi_private->irq, fsl_ssi_isr, 0, ssi_private->name, | ||
| 677 | ssi_private); | ||
| 678 | if (ret < 0) { | ||
| 679 | dev_err(&pdev->dev, "could not claim irq %u\n", ssi_private->irq); | ||
| 680 | goto error_irqmap; | ||
| 681 | } | ||
| 689 | 682 | ||
| 690 | /* Are the RX and the TX clocks locked? */ | 683 | /* Are the RX and the TX clocks locked? */ |
| 691 | if (of_find_property(np, "fsl,ssi-asynchronous", NULL)) | 684 | if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) |
| 692 | ssi_private->asynchronous = 1; | ||
| 693 | else | ||
| 694 | ssi_private->cpu_dai_drv.symmetric_rates = 1; | 685 | ssi_private->cpu_dai_drv.symmetric_rates = 1; |
| 695 | 686 | ||
| 696 | /* Determine the FIFO depth. */ | 687 | /* Determine the FIFO depth. */ |
| @@ -711,7 +702,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
| 711 | if (ret) { | 702 | if (ret) { |
| 712 | dev_err(&pdev->dev, "could not create sysfs %s file\n", | 703 | dev_err(&pdev->dev, "could not create sysfs %s file\n", |
| 713 | ssi_private->dev_attr.attr.name); | 704 | ssi_private->dev_attr.attr.name); |
| 714 | goto error; | 705 | goto error_irq; |
| 715 | } | 706 | } |
| 716 | 707 | ||
| 717 | /* Register with ASoC */ | 708 | /* Register with ASoC */ |
| @@ -720,7 +711,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
| 720 | ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); | 711 | ret = snd_soc_register_dai(&pdev->dev, &ssi_private->cpu_dai_drv); |
| 721 | if (ret) { | 712 | if (ret) { |
| 722 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); | 713 | dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); |
| 723 | goto error; | 714 | goto error_dev; |
| 724 | } | 715 | } |
| 725 | 716 | ||
| 726 | /* Trigger the machine driver's probe function. The platform driver | 717 | /* Trigger the machine driver's probe function. The platform driver |
| @@ -741,18 +732,28 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
| 741 | if (IS_ERR(ssi_private->pdev)) { | 732 | if (IS_ERR(ssi_private->pdev)) { |
| 742 | ret = PTR_ERR(ssi_private->pdev); | 733 | ret = PTR_ERR(ssi_private->pdev); |
| 743 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); | 734 | dev_err(&pdev->dev, "failed to register platform: %d\n", ret); |
| 744 | goto error; | 735 | goto error_dai; |
| 745 | } | 736 | } |
| 746 | 737 | ||
| 747 | return 0; | 738 | return 0; |
| 748 | 739 | ||
| 749 | error: | 740 | error_dai: |
| 750 | snd_soc_unregister_dai(&pdev->dev); | 741 | snd_soc_unregister_dai(&pdev->dev); |
| 742 | |||
| 743 | error_dev: | ||
| 751 | dev_set_drvdata(&pdev->dev, NULL); | 744 | dev_set_drvdata(&pdev->dev, NULL); |
| 752 | if (dev_attr) | 745 | device_remove_file(&pdev->dev, dev_attr); |
| 753 | device_remove_file(&pdev->dev, dev_attr); | 746 | |
| 747 | error_irq: | ||
| 748 | free_irq(ssi_private->irq, ssi_private); | ||
| 749 | |||
| 750 | error_irqmap: | ||
| 754 | irq_dispose_mapping(ssi_private->irq); | 751 | irq_dispose_mapping(ssi_private->irq); |
| 752 | |||
| 753 | error_iomap: | ||
| 755 | iounmap(ssi_private->ssi); | 754 | iounmap(ssi_private->ssi); |
| 755 | |||
| 756 | error_kmalloc: | ||
| 756 | kfree(ssi_private); | 757 | kfree(ssi_private); |
| 757 | 758 | ||
| 758 | return ret; | 759 | return ret; |
| @@ -766,6 +767,9 @@ static int fsl_ssi_remove(struct platform_device *pdev) | |||
| 766 | snd_soc_unregister_dai(&pdev->dev); | 767 | snd_soc_unregister_dai(&pdev->dev); |
| 767 | device_remove_file(&pdev->dev, &ssi_private->dev_attr); | 768 | device_remove_file(&pdev->dev, &ssi_private->dev_attr); |
| 768 | 769 | ||
| 770 | free_irq(ssi_private->irq, ssi_private); | ||
| 771 | irq_dispose_mapping(ssi_private->irq); | ||
| 772 | |||
| 769 | kfree(ssi_private); | 773 | kfree(ssi_private); |
| 770 | dev_set_drvdata(&pdev->dev, NULL); | 774 | dev_set_drvdata(&pdev->dev, NULL); |
| 771 | 775 | ||
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 358f0baaf71b..31af405bda84 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c | |||
| @@ -505,7 +505,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
| 505 | return 0; | 505 | return 0; |
| 506 | 506 | ||
| 507 | error_sound: | 507 | error_sound: |
| 508 | platform_device_unregister(sound_device); | 508 | platform_device_put(sound_device); |
| 509 | error: | 509 | error: |
| 510 | kfree(machine_data); | 510 | kfree(machine_data); |
| 511 | error_alloc: | 511 | error_alloc: |
diff --git a/sound/soc/fsl/p1022_ds.c b/sound/soc/fsl/p1022_ds.c index fcb862eb0c73..2c064a9824ad 100644 --- a/sound/soc/fsl/p1022_ds.c +++ b/sound/soc/fsl/p1022_ds.c | |||
| @@ -267,7 +267,7 @@ static int codec_node_dev_name(struct device_node *np, char *buf, size_t len) | |||
| 267 | if (bus < 0) | 267 | if (bus < 0) |
| 268 | return bus; | 268 | return bus; |
| 269 | 269 | ||
| 270 | snprintf(buf, len, "%s-codec.%u-%04x", temp, bus, addr); | 270 | snprintf(buf, len, "%s.%u-%04x", temp, bus, addr); |
| 271 | 271 | ||
| 272 | return 0; | 272 | return 0; |
| 273 | } | 273 | } |
| @@ -506,7 +506,7 @@ static int p1022_ds_probe(struct platform_device *pdev) | |||
| 506 | 506 | ||
| 507 | error: | 507 | error: |
| 508 | if (sound_device) | 508 | if (sound_device) |
| 509 | platform_device_unregister(sound_device); | 509 | platform_device_put(sound_device); |
| 510 | 510 | ||
| 511 | kfree(mdata); | 511 | kfree(mdata); |
| 512 | error_put: | 512 | error_put: |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index bb699bb55a50..b133bfcc5848 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig | |||
| @@ -29,7 +29,7 @@ config SND_MXC_SOC_WM1133_EV1 | |||
| 29 | config SND_SOC_MX27VIS_AIC32X4 | 29 | config SND_SOC_MX27VIS_AIC32X4 |
| 30 | tristate "SoC audio support for Visstrim M10 boards" | 30 | tristate "SoC audio support for Visstrim M10 boards" |
| 31 | depends on MACH_IMX27_VISSTRIM_M10 | 31 | depends on MACH_IMX27_VISSTRIM_M10 |
| 32 | select SND_SOC_TVL320AIC32X4 | 32 | select SND_SOC_TLV320AIC32X4 |
| 33 | select SND_MXC_SOC_MX2 | 33 | select SND_MXC_SOC_MX2 |
| 34 | help | 34 | help |
| 35 | Say Y if you want to add support for SoC audio on Visstrim SM10 | 35 | Say Y if you want to add support for SoC audio on Visstrim SM10 |
| @@ -50,6 +50,7 @@ config SND_SOC_EUKREA_TLV320 | |||
| 50 | || MACH_EUKREA_MBIMXSD25_BASEBOARD \ | 50 | || MACH_EUKREA_MBIMXSD25_BASEBOARD \ |
| 51 | || MACH_EUKREA_MBIMXSD35_BASEBOARD \ | 51 | || MACH_EUKREA_MBIMXSD35_BASEBOARD \ |
| 52 | || MACH_EUKREA_MBIMXSD51_BASEBOARD | 52 | || MACH_EUKREA_MBIMXSD51_BASEBOARD |
| 53 | depends on I2C | ||
| 53 | select SND_SOC_TLV320AIC23 | 54 | select SND_SOC_TLV320AIC23 |
| 54 | select SND_MXC_SOC_FIQ | 55 | select SND_MXC_SOC_FIQ |
| 55 | help | 56 | help |
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index 7945625e0e08..8df0fae21943 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c | |||
| @@ -240,25 +240,23 @@ static int ssi_irq = 0; | |||
| 240 | 240 | ||
| 241 | static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) | 241 | static int imx_pcm_fiq_new(struct snd_soc_pcm_runtime *rtd) |
| 242 | { | 242 | { |
| 243 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
| 244 | struct snd_pcm *pcm = rtd->pcm; | 243 | struct snd_pcm *pcm = rtd->pcm; |
| 244 | struct snd_pcm_substream *substream; | ||
| 245 | int ret; | 245 | int ret; |
| 246 | 246 | ||
| 247 | ret = imx_pcm_new(rtd); | 247 | ret = imx_pcm_new(rtd); |
| 248 | if (ret) | 248 | if (ret) |
| 249 | return ret; | 249 | return ret; |
| 250 | 250 | ||
| 251 | if (dai->driver->playback.channels_min) { | 251 | substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; |
| 252 | struct snd_pcm_substream *substream = | 252 | if (substream) { |
| 253 | pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; | ||
| 254 | struct snd_dma_buffer *buf = &substream->dma_buffer; | 253 | struct snd_dma_buffer *buf = &substream->dma_buffer; |
| 255 | 254 | ||
| 256 | imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; | 255 | imx_ssi_fiq_tx_buffer = (unsigned long)buf->area; |
| 257 | } | 256 | } |
| 258 | 257 | ||
| 259 | if (dai->driver->capture.channels_min) { | 258 | substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; |
| 260 | struct snd_pcm_substream *substream = | 259 | if (substream) { |
| 261 | pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; | ||
| 262 | struct snd_dma_buffer *buf = &substream->dma_buffer; | 260 | struct snd_dma_buffer *buf = &substream->dma_buffer; |
| 263 | 261 | ||
| 264 | imx_ssi_fiq_rx_buffer = (unsigned long)buf->area; | 262 | imx_ssi_fiq_rx_buffer = (unsigned long)buf->area; |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 10a8e2783751..4c05e2b8f4d2 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
| @@ -357,8 +357,8 @@ int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, | |||
| 357 | struct snd_pcm_runtime *runtime = substream->runtime; | 357 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 358 | int ret; | 358 | int ret; |
| 359 | 359 | ||
| 360 | ret = dma_mmap_coherent(NULL, vma, runtime->dma_area, | 360 | ret = dma_mmap_writecombine(substream->pcm->card->dev, vma, |
| 361 | runtime->dma_addr, runtime->dma_bytes); | 361 | runtime->dma_area, runtime->dma_addr, runtime->dma_bytes); |
| 362 | 362 | ||
| 363 | pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, | 363 | pr_debug("%s: ret: %d %p 0x%08x 0x%08x\n", __func__, ret, |
| 364 | runtime->dma_area, | 364 | runtime->dma_area, |
| @@ -391,7 +391,6 @@ static u64 imx_pcm_dmamask = DMA_BIT_MASK(32); | |||
| 391 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) | 391 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) |
| 392 | { | 392 | { |
| 393 | struct snd_card *card = rtd->card->snd_card; | 393 | struct snd_card *card = rtd->card->snd_card; |
| 394 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
| 395 | struct snd_pcm *pcm = rtd->pcm; | 394 | struct snd_pcm *pcm = rtd->pcm; |
| 396 | int ret = 0; | 395 | int ret = 0; |
| 397 | 396 | ||
| @@ -399,14 +398,14 @@ int imx_pcm_new(struct snd_soc_pcm_runtime *rtd) | |||
| 399 | card->dev->dma_mask = &imx_pcm_dmamask; | 398 | card->dev->dma_mask = &imx_pcm_dmamask; |
| 400 | if (!card->dev->coherent_dma_mask) | 399 | if (!card->dev->coherent_dma_mask) |
| 401 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | 400 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); |
| 402 | if (dai->driver->playback.channels_min) { | 401 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { |
| 403 | ret = imx_pcm_preallocate_dma_buffer(pcm, | 402 | ret = imx_pcm_preallocate_dma_buffer(pcm, |
| 404 | SNDRV_PCM_STREAM_PLAYBACK); | 403 | SNDRV_PCM_STREAM_PLAYBACK); |
| 405 | if (ret) | 404 | if (ret) |
| 406 | goto out; | 405 | goto out; |
| 407 | } | 406 | } |
| 408 | 407 | ||
| 409 | if (dai->driver->capture.channels_min) { | 408 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { |
| 410 | ret = imx_pcm_preallocate_dma_buffer(pcm, | 409 | ret = imx_pcm_preallocate_dma_buffer(pcm, |
| 411 | SNDRV_PCM_STREAM_CAPTURE); | 410 | SNDRV_PCM_STREAM_CAPTURE); |
| 412 | if (ret) | 411 | if (ret) |
diff --git a/sound/soc/imx/imx-ssi.h b/sound/soc/imx/imx-ssi.h index 0a84cec3599e..1072dfb53e47 100644 --- a/sound/soc/imx/imx-ssi.h +++ b/sound/soc/imx/imx-ssi.h | |||
| @@ -218,12 +218,6 @@ struct imx_ssi { | |||
| 218 | struct platform_device *soc_platform_pdev_fiq; | 218 | struct platform_device *soc_platform_pdev_fiq; |
| 219 | }; | 219 | }; |
| 220 | 220 | ||
| 221 | struct snd_soc_platform *imx_ssi_fiq_init(struct platform_device *pdev, | ||
| 222 | struct imx_ssi *ssi); | ||
| 223 | void imx_ssi_fiq_exit(struct platform_device *pdev, struct imx_ssi *ssi); | ||
| 224 | struct snd_soc_platform *imx_ssi_dma_mx2_init(struct platform_device *pdev, | ||
| 225 | struct imx_ssi *ssi); | ||
| 226 | |||
| 227 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); | 221 | int snd_imx_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma); |
| 228 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); | 222 | int imx_pcm_new(struct snd_soc_pcm_runtime *rtd); |
| 229 | void imx_pcm_free(struct snd_pcm *pcm); | 223 | void imx_pcm_free(struct snd_pcm *pcm); |
diff --git a/sound/soc/jz4740/jz4740-pcm.c b/sound/soc/jz4740/jz4740-pcm.c index a7c9578be983..d1989cde9f14 100644 --- a/sound/soc/jz4740/jz4740-pcm.c +++ b/sound/soc/jz4740/jz4740-pcm.c | |||
| @@ -299,7 +299,7 @@ static void jz4740_pcm_free(struct snd_pcm *pcm) | |||
| 299 | 299 | ||
| 300 | static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32); | 300 | static u64 jz4740_pcm_dmamask = DMA_BIT_MASK(32); |
| 301 | 301 | ||
| 302 | int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) | 302 | static int jz4740_pcm_new(struct snd_soc_pcm_runtime *rtd) |
| 303 | { | 303 | { |
| 304 | struct snd_card *card = rtd->card->snd_card; | 304 | struct snd_card *card = rtd->card->snd_card; |
| 305 | struct snd_soc_dai *dai = rtd->cpu_dai; | 305 | struct snd_soc_dai *dai = rtd->cpu_dai; |
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c index d0bcf3fcea01..715e841c0507 100644 --- a/sound/soc/kirkwood/kirkwood-i2s.c +++ b/sound/soc/kirkwood/kirkwood-i2s.c | |||
| @@ -476,7 +476,7 @@ static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev) | |||
| 476 | 476 | ||
| 477 | static struct platform_driver kirkwood_i2s_driver = { | 477 | static struct platform_driver kirkwood_i2s_driver = { |
| 478 | .probe = kirkwood_i2s_dev_probe, | 478 | .probe = kirkwood_i2s_dev_probe, |
| 479 | .remove = kirkwood_i2s_dev_remove, | 479 | .remove = __devexit_p(kirkwood_i2s_dev_remove), |
| 480 | .driver = { | 480 | .driver = { |
| 481 | .name = DRV_NAME, | 481 | .name = DRV_NAME, |
| 482 | .owner = THIS_MODULE, | 482 | .owner = THIS_MODULE, |
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index c8d21956ab52..c772b3cf4039 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c | |||
| @@ -79,8 +79,6 @@ static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd) | |||
| 79 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 79 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 80 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | 80 | snd_soc_dapm_enable_pin(dapm, "Speaker"); |
| 81 | 81 | ||
| 82 | snd_soc_dapm_sync(dapm); | ||
| 83 | |||
| 84 | return 0; | 82 | return 0; |
| 85 | } | 83 | } |
| 86 | 84 | ||
diff --git a/sound/soc/mid-x86/mfld_machine.c b/sound/soc/mid-x86/mfld_machine.c index 429aa1be2cff..598f48c0d8f5 100644 --- a/sound/soc/mid-x86/mfld_machine.c +++ b/sound/soc/mid-x86/mfld_machine.c | |||
| @@ -54,9 +54,7 @@ static unsigned int hs_switch; | |||
| 54 | static unsigned int lo_dac; | 54 | static unsigned int lo_dac; |
| 55 | 55 | ||
| 56 | struct mfld_mc_private { | 56 | struct mfld_mc_private { |
| 57 | struct platform_device *socdev; | ||
| 58 | void __iomem *int_base; | 57 | void __iomem *int_base; |
| 59 | struct snd_soc_codec *codec; | ||
| 60 | u8 interrupt_status; | 58 | u8 interrupt_status; |
| 61 | }; | 59 | }; |
| 62 | 60 | ||
| @@ -235,7 +233,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) | |||
| 235 | /* always connected */ | 233 | /* always connected */ |
| 236 | snd_soc_dapm_enable_pin(dapm, "Headphones"); | 234 | snd_soc_dapm_enable_pin(dapm, "Headphones"); |
| 237 | snd_soc_dapm_enable_pin(dapm, "Mic"); | 235 | snd_soc_dapm_enable_pin(dapm, "Mic"); |
| 238 | snd_soc_dapm_sync(dapm); | ||
| 239 | 236 | ||
| 240 | ret_val = snd_soc_add_controls(codec, mfld_snd_controls, | 237 | ret_val = snd_soc_add_controls(codec, mfld_snd_controls, |
| 241 | ARRAY_SIZE(mfld_snd_controls)); | 238 | ARRAY_SIZE(mfld_snd_controls)); |
| @@ -253,7 +250,6 @@ static int mfld_init(struct snd_soc_pcm_runtime *runtime) | |||
| 253 | /* we dont use linein in this so set to NC */ | 250 | /* we dont use linein in this so set to NC */ |
| 254 | snd_soc_dapm_disable_pin(dapm, "LINEINL"); | 251 | snd_soc_dapm_disable_pin(dapm, "LINEINL"); |
| 255 | snd_soc_dapm_disable_pin(dapm, "LINEINR"); | 252 | snd_soc_dapm_disable_pin(dapm, "LINEINR"); |
| 256 | snd_soc_dapm_sync(dapm); | ||
| 257 | 253 | ||
| 258 | /* Headset and button jack detection */ | 254 | /* Headset and button jack detection */ |
| 259 | ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", | 255 | ret_val = snd_soc_jack_new(codec, "Intel(R) MID Audio Jack", |
diff --git a/sound/soc/mid-x86/sst_platform.c b/sound/soc/mid-x86/sst_platform.c index 3e7826058efe..7df8c58ba50a 100644 --- a/sound/soc/mid-x86/sst_platform.c +++ b/sound/soc/mid-x86/sst_platform.c | |||
| @@ -63,7 +63,7 @@ static struct snd_pcm_hardware sst_platform_pcm_hw = { | |||
| 63 | }; | 63 | }; |
| 64 | 64 | ||
| 65 | /* MFLD - MSIC */ | 65 | /* MFLD - MSIC */ |
| 66 | struct snd_soc_dai_driver sst_platform_dai[] = { | 66 | static struct snd_soc_dai_driver sst_platform_dai[] = { |
| 67 | { | 67 | { |
| 68 | .name = "Headset-cpu-dai", | 68 | .name = "Headset-cpu-dai", |
| 69 | .id = 0, | 69 | .id = 0, |
| @@ -226,13 +226,18 @@ static int sst_platform_init_stream(struct snd_pcm_substream *substream) | |||
| 226 | 226 | ||
| 227 | static int sst_platform_open(struct snd_pcm_substream *substream) | 227 | static int sst_platform_open(struct snd_pcm_substream *substream) |
| 228 | { | 228 | { |
| 229 | struct snd_pcm_runtime *runtime; | 229 | struct snd_pcm_runtime *runtime = substream->runtime; |
| 230 | struct sst_runtime_stream *stream; | 230 | struct sst_runtime_stream *stream; |
| 231 | int ret_val = 0; | 231 | int ret_val = 0; |
| 232 | 232 | ||
| 233 | pr_debug("sst_platform_open called\n"); | 233 | pr_debug("sst_platform_open called\n"); |
| 234 | runtime = substream->runtime; | 234 | |
| 235 | runtime->hw = sst_platform_pcm_hw; | 235 | snd_soc_set_runtime_hwparams(substream, &sst_platform_pcm_hw); |
| 236 | ret_val = snd_pcm_hw_constraint_integer(runtime, | ||
| 237 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
| 238 | if (ret_val < 0) | ||
| 239 | return ret_val; | ||
| 240 | |||
| 236 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); | 241 | stream = kzalloc(sizeof(*stream), GFP_KERNEL); |
| 237 | if (!stream) | 242 | if (!stream) |
| 238 | return -ENOMEM; | 243 | return -ENOMEM; |
| @@ -259,8 +264,8 @@ static int sst_platform_open(struct snd_pcm_substream *substream) | |||
| 259 | return ret_val; | 264 | return ret_val; |
| 260 | } | 265 | } |
| 261 | runtime->private_data = stream; | 266 | runtime->private_data = stream; |
| 262 | return snd_pcm_hw_constraint_integer(runtime, | 267 | |
| 263 | SNDRV_PCM_HW_PARAM_PERIODS); | 268 | return 0; |
| 264 | } | 269 | } |
| 265 | 270 | ||
| 266 | static int sst_platform_close(struct snd_pcm_substream *substream) | 271 | static int sst_platform_close(struct snd_pcm_substream *substream) |
| @@ -469,7 +474,7 @@ static struct platform_driver sst_platform_driver = { | |||
| 469 | static int __init sst_soc_platform_init(void) | 474 | static int __init sst_soc_platform_init(void) |
| 470 | { | 475 | { |
| 471 | pr_debug("sst_soc_platform_init called\n"); | 476 | pr_debug("sst_soc_platform_init called\n"); |
| 472 | return platform_driver_register(&sst_platform_driver); | 477 | return platform_driver_register(&sst_platform_driver); |
| 473 | } | 478 | } |
| 474 | module_init(sst_soc_platform_init); | 479 | module_init(sst_soc_platform_init); |
| 475 | 480 | ||
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig new file mode 100644 index 000000000000..e4ba8d5f25fa --- /dev/null +++ b/sound/soc/mxs/Kconfig | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | menuconfig SND_MXS_SOC | ||
| 2 | tristate "SoC Audio for Freescale MXS CPUs" | ||
| 3 | depends on ARCH_MXS | ||
| 4 | select SND_PCM | ||
| 5 | help | ||
| 6 | Say Y or M if you want to add support for codecs attached to | ||
| 7 | the MXS SAIF interface. | ||
| 8 | |||
| 9 | |||
| 10 | if SND_MXS_SOC | ||
| 11 | |||
| 12 | config SND_SOC_MXS_SGTL5000 | ||
| 13 | tristate "SoC Audio support for i.MX boards with sgtl5000" | ||
| 14 | depends on I2C | ||
| 15 | select SND_SOC_SGTL5000 | ||
| 16 | help | ||
| 17 | Say Y if you want to add support for SoC audio on an MXS board with | ||
| 18 | a sgtl5000 codec. | ||
| 19 | |||
| 20 | endif # SND_MXS_SOC | ||
diff --git a/sound/soc/mxs/Makefile b/sound/soc/mxs/Makefile new file mode 100644 index 000000000000..565b5b51e8b7 --- /dev/null +++ b/sound/soc/mxs/Makefile | |||
| @@ -0,0 +1,10 @@ | |||
| 1 | # MXS Platform Support | ||
| 2 | snd-soc-mxs-objs := mxs-saif.o | ||
| 3 | snd-soc-mxs-pcm-objs := mxs-pcm.o | ||
| 4 | |||
| 5 | obj-$(CONFIG_SND_MXS_SOC) += snd-soc-mxs.o snd-soc-mxs-pcm.o | ||
| 6 | |||
| 7 | # i.MX Machine Support | ||
| 8 | snd-soc-mxs-sgtl5000-objs := mxs-sgtl5000.o | ||
| 9 | |||
| 10 | obj-$(CONFIG_SND_SOC_MXS_SGTL5000) += snd-soc-mxs-sgtl5000.o | ||
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c new file mode 100644 index 000000000000..dea5aa4aa647 --- /dev/null +++ b/sound/soc/mxs/mxs-pcm.c | |||
| @@ -0,0 +1,359 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * | ||
| 4 | * Based on sound/soc/imx/imx-pcm-dma-mx2.c | ||
| 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 | * You should have received a copy of the GNU General Public License along | ||
| 17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 19 | */ | ||
| 20 | |||
| 21 | #include <linux/clk.h> | ||
| 22 | #include <linux/delay.h> | ||
| 23 | #include <linux/device.h> | ||
| 24 | #include <linux/dma-mapping.h> | ||
| 25 | #include <linux/init.h> | ||
| 26 | #include <linux/interrupt.h> | ||
| 27 | #include <linux/module.h> | ||
| 28 | #include <linux/platform_device.h> | ||
| 29 | #include <linux/slab.h> | ||
| 30 | #include <linux/dmaengine.h> | ||
| 31 | |||
| 32 | #include <sound/core.h> | ||
| 33 | #include <sound/initval.h> | ||
| 34 | #include <sound/pcm.h> | ||
| 35 | #include <sound/pcm_params.h> | ||
| 36 | #include <sound/soc.h> | ||
| 37 | |||
| 38 | #include <mach/dma.h> | ||
| 39 | #include "mxs-pcm.h" | ||
| 40 | |||
| 41 | static struct snd_pcm_hardware snd_mxs_hardware = { | ||
| 42 | .info = SNDRV_PCM_INFO_MMAP | | ||
| 43 | SNDRV_PCM_INFO_MMAP_VALID | | ||
| 44 | SNDRV_PCM_INFO_PAUSE | | ||
| 45 | SNDRV_PCM_INFO_RESUME | | ||
| 46 | SNDRV_PCM_INFO_INTERLEAVED, | ||
| 47 | .formats = SNDRV_PCM_FMTBIT_S16_LE | | ||
| 48 | SNDRV_PCM_FMTBIT_S20_3LE | | ||
| 49 | SNDRV_PCM_FMTBIT_S24_LE, | ||
| 50 | .channels_min = 2, | ||
| 51 | .channels_max = 2, | ||
| 52 | .period_bytes_min = 32, | ||
| 53 | .period_bytes_max = 8192, | ||
| 54 | .periods_min = 1, | ||
| 55 | .periods_max = 52, | ||
| 56 | .buffer_bytes_max = 64 * 1024, | ||
| 57 | .fifo_size = 32, | ||
| 58 | |||
| 59 | }; | ||
| 60 | |||
| 61 | static void audio_dma_irq(void *data) | ||
| 62 | { | ||
| 63 | struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data; | ||
| 64 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 65 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 66 | |||
| 67 | iprtd->offset += iprtd->period_bytes; | ||
| 68 | iprtd->offset %= iprtd->period_bytes * iprtd->periods; | ||
| 69 | snd_pcm_period_elapsed(substream); | ||
| 70 | } | ||
| 71 | |||
| 72 | static bool filter(struct dma_chan *chan, void *param) | ||
| 73 | { | ||
| 74 | struct mxs_pcm_runtime_data *iprtd = param; | ||
| 75 | struct mxs_pcm_dma_params *dma_params = iprtd->dma_params; | ||
| 76 | |||
| 77 | if (!mxs_dma_is_apbx(chan)) | ||
| 78 | return false; | ||
| 79 | |||
| 80 | if (chan->chan_id != dma_params->chan_num) | ||
| 81 | return false; | ||
| 82 | |||
| 83 | chan->private = &iprtd->dma_data; | ||
| 84 | |||
| 85 | return true; | ||
| 86 | } | ||
| 87 | |||
| 88 | static int mxs_dma_alloc(struct snd_pcm_substream *substream, | ||
| 89 | struct snd_pcm_hw_params *params) | ||
| 90 | { | ||
| 91 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 92 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 93 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 94 | dma_cap_mask_t mask; | ||
| 95 | |||
| 96 | iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); | ||
| 97 | |||
| 98 | dma_cap_zero(mask); | ||
| 99 | dma_cap_set(DMA_SLAVE, mask); | ||
| 100 | iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq; | ||
| 101 | iprtd->dma_chan = dma_request_channel(mask, filter, iprtd); | ||
| 102 | if (!iprtd->dma_chan) | ||
| 103 | return -EINVAL; | ||
| 104 | |||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream, | ||
| 109 | struct snd_pcm_hw_params *params) | ||
| 110 | { | ||
| 111 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 112 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 113 | unsigned long dma_addr; | ||
| 114 | struct dma_chan *chan; | ||
| 115 | int ret; | ||
| 116 | |||
| 117 | ret = mxs_dma_alloc(substream, params); | ||
| 118 | if (ret) | ||
| 119 | return ret; | ||
| 120 | chan = iprtd->dma_chan; | ||
| 121 | |||
| 122 | iprtd->size = params_buffer_bytes(params); | ||
| 123 | iprtd->periods = params_periods(params); | ||
| 124 | iprtd->period_bytes = params_period_bytes(params); | ||
| 125 | iprtd->offset = 0; | ||
| 126 | iprtd->period_time = HZ / (params_rate(params) / | ||
| 127 | params_period_size(params)); | ||
| 128 | |||
| 129 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | ||
| 130 | |||
| 131 | dma_addr = runtime->dma_addr; | ||
| 132 | |||
| 133 | iprtd->buf = substream->dma_buffer.area; | ||
| 134 | |||
| 135 | iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr, | ||
| 136 | iprtd->period_bytes * iprtd->periods, | ||
| 137 | iprtd->period_bytes, | ||
| 138 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
| 139 | DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
| 140 | if (!iprtd->desc) { | ||
| 141 | dev_err(&chan->dev->device, "cannot prepare slave dma\n"); | ||
| 142 | return -EINVAL; | ||
| 143 | } | ||
| 144 | |||
| 145 | iprtd->desc->callback = audio_dma_irq; | ||
| 146 | iprtd->desc->callback_param = substream; | ||
| 147 | |||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream) | ||
| 152 | { | ||
| 153 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 154 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 155 | |||
| 156 | if (iprtd->dma_chan) { | ||
| 157 | dma_release_channel(iprtd->dma_chan); | ||
| 158 | iprtd->dma_chan = NULL; | ||
| 159 | } | ||
| 160 | |||
| 161 | return 0; | ||
| 162 | } | ||
| 163 | |||
| 164 | static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
| 165 | { | ||
| 166 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 167 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 168 | |||
| 169 | switch (cmd) { | ||
| 170 | case SNDRV_PCM_TRIGGER_START: | ||
| 171 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 172 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 173 | dmaengine_submit(iprtd->desc); | ||
| 174 | |||
| 175 | break; | ||
| 176 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 177 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 178 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 179 | dmaengine_terminate_all(iprtd->dma_chan); | ||
| 180 | |||
| 181 | break; | ||
| 182 | default: | ||
| 183 | return -EINVAL; | ||
| 184 | } | ||
| 185 | |||
| 186 | return 0; | ||
| 187 | } | ||
| 188 | |||
| 189 | static snd_pcm_uframes_t snd_mxs_pcm_pointer( | ||
| 190 | struct snd_pcm_substream *substream) | ||
| 191 | { | ||
| 192 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 193 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 194 | |||
| 195 | return bytes_to_frames(substream->runtime, iprtd->offset); | ||
| 196 | } | ||
| 197 | |||
| 198 | static int snd_mxs_open(struct snd_pcm_substream *substream) | ||
| 199 | { | ||
| 200 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 201 | struct mxs_pcm_runtime_data *iprtd; | ||
| 202 | int ret; | ||
| 203 | |||
| 204 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); | ||
| 205 | if (iprtd == NULL) | ||
| 206 | return -ENOMEM; | ||
| 207 | runtime->private_data = iprtd; | ||
| 208 | |||
| 209 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | ||
| 210 | SNDRV_PCM_HW_PARAM_PERIODS); | ||
| 211 | if (ret < 0) { | ||
| 212 | kfree(iprtd); | ||
| 213 | return ret; | ||
| 214 | } | ||
| 215 | |||
| 216 | snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware); | ||
| 217 | |||
| 218 | return 0; | ||
| 219 | } | ||
| 220 | |||
| 221 | static int snd_mxs_close(struct snd_pcm_substream *substream) | ||
| 222 | { | ||
| 223 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 224 | struct mxs_pcm_runtime_data *iprtd = runtime->private_data; | ||
| 225 | |||
| 226 | kfree(iprtd); | ||
| 227 | |||
| 228 | return 0; | ||
| 229 | } | ||
| 230 | |||
| 231 | static int snd_mxs_pcm_mmap(struct snd_pcm_substream *substream, | ||
| 232 | struct vm_area_struct *vma) | ||
| 233 | { | ||
| 234 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
| 235 | |||
| 236 | return dma_mmap_writecombine(substream->pcm->card->dev, vma, | ||
| 237 | runtime->dma_area, | ||
| 238 | runtime->dma_addr, | ||
| 239 | runtime->dma_bytes); | ||
| 240 | } | ||
| 241 | |||
| 242 | static struct snd_pcm_ops mxs_pcm_ops = { | ||
| 243 | .open = snd_mxs_open, | ||
| 244 | .close = snd_mxs_close, | ||
| 245 | .ioctl = snd_pcm_lib_ioctl, | ||
| 246 | .hw_params = snd_mxs_pcm_hw_params, | ||
| 247 | .hw_free = snd_mxs_pcm_hw_free, | ||
| 248 | .trigger = snd_mxs_pcm_trigger, | ||
| 249 | .pointer = snd_mxs_pcm_pointer, | ||
| 250 | .mmap = snd_mxs_pcm_mmap, | ||
| 251 | }; | ||
| 252 | |||
| 253 | static int mxs_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) | ||
| 254 | { | ||
| 255 | struct snd_pcm_substream *substream = pcm->streams[stream].substream; | ||
| 256 | struct snd_dma_buffer *buf = &substream->dma_buffer; | ||
| 257 | size_t size = snd_mxs_hardware.buffer_bytes_max; | ||
| 258 | |||
| 259 | buf->dev.type = SNDRV_DMA_TYPE_DEV; | ||
| 260 | buf->dev.dev = pcm->card->dev; | ||
| 261 | buf->private_data = NULL; | ||
| 262 | buf->area = dma_alloc_writecombine(pcm->card->dev, size, | ||
| 263 | &buf->addr, GFP_KERNEL); | ||
| 264 | if (!buf->area) | ||
| 265 | return -ENOMEM; | ||
| 266 | buf->bytes = size; | ||
| 267 | |||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | |||
| 271 | static u64 mxs_pcm_dmamask = DMA_BIT_MASK(32); | ||
| 272 | static int mxs_pcm_new(struct snd_soc_pcm_runtime *rtd) | ||
| 273 | { | ||
| 274 | struct snd_card *card = rtd->card->snd_card; | ||
| 275 | struct snd_pcm *pcm = rtd->pcm; | ||
| 276 | int ret = 0; | ||
| 277 | |||
| 278 | if (!card->dev->dma_mask) | ||
| 279 | card->dev->dma_mask = &mxs_pcm_dmamask; | ||
| 280 | if (!card->dev->coherent_dma_mask) | ||
| 281 | card->dev->coherent_dma_mask = DMA_BIT_MASK(32); | ||
| 282 | |||
| 283 | if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { | ||
| 284 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
| 285 | SNDRV_PCM_STREAM_PLAYBACK); | ||
| 286 | if (ret) | ||
| 287 | goto out; | ||
| 288 | } | ||
| 289 | |||
| 290 | if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { | ||
| 291 | ret = mxs_pcm_preallocate_dma_buffer(pcm, | ||
| 292 | SNDRV_PCM_STREAM_CAPTURE); | ||
| 293 | if (ret) | ||
| 294 | goto out; | ||
| 295 | } | ||
| 296 | |||
| 297 | out: | ||
| 298 | return ret; | ||
| 299 | } | ||
| 300 | |||
| 301 | static void mxs_pcm_free(struct snd_pcm *pcm) | ||
| 302 | { | ||
| 303 | struct snd_pcm_substream *substream; | ||
| 304 | struct snd_dma_buffer *buf; | ||
| 305 | int stream; | ||
| 306 | |||
| 307 | for (stream = 0; stream < 2; stream++) { | ||
| 308 | substream = pcm->streams[stream].substream; | ||
| 309 | if (!substream) | ||
| 310 | continue; | ||
| 311 | |||
| 312 | buf = &substream->dma_buffer; | ||
| 313 | if (!buf->area) | ||
| 314 | continue; | ||
| 315 | |||
| 316 | dma_free_writecombine(pcm->card->dev, buf->bytes, | ||
| 317 | buf->area, buf->addr); | ||
| 318 | buf->area = NULL; | ||
| 319 | } | ||
| 320 | } | ||
| 321 | |||
| 322 | static struct snd_soc_platform_driver mxs_soc_platform = { | ||
| 323 | .ops = &mxs_pcm_ops, | ||
| 324 | .pcm_new = mxs_pcm_new, | ||
| 325 | .pcm_free = mxs_pcm_free, | ||
| 326 | }; | ||
| 327 | |||
| 328 | static int __devinit mxs_soc_platform_probe(struct platform_device *pdev) | ||
| 329 | { | ||
| 330 | return snd_soc_register_platform(&pdev->dev, &mxs_soc_platform); | ||
| 331 | } | ||
| 332 | |||
| 333 | static int __devexit mxs_soc_platform_remove(struct platform_device *pdev) | ||
| 334 | { | ||
| 335 | snd_soc_unregister_platform(&pdev->dev); | ||
| 336 | |||
| 337 | return 0; | ||
| 338 | } | ||
| 339 | |||
| 340 | static struct platform_driver mxs_pcm_driver = { | ||
| 341 | .driver = { | ||
| 342 | .name = "mxs-pcm-audio", | ||
| 343 | .owner = THIS_MODULE, | ||
| 344 | }, | ||
| 345 | .probe = mxs_soc_platform_probe, | ||
| 346 | .remove = __devexit_p(mxs_soc_platform_remove), | ||
| 347 | }; | ||
| 348 | |||
| 349 | static int __init snd_mxs_pcm_init(void) | ||
| 350 | { | ||
| 351 | return platform_driver_register(&mxs_pcm_driver); | ||
| 352 | } | ||
| 353 | module_init(snd_mxs_pcm_init); | ||
| 354 | |||
| 355 | static void __exit snd_mxs_pcm_exit(void) | ||
| 356 | { | ||
| 357 | platform_driver_unregister(&mxs_pcm_driver); | ||
| 358 | } | ||
| 359 | module_exit(snd_mxs_pcm_exit); | ||
diff --git a/sound/soc/mxs/mxs-pcm.h b/sound/soc/mxs/mxs-pcm.h new file mode 100644 index 000000000000..f55ac4f7a76a --- /dev/null +++ b/sound/soc/mxs/mxs-pcm.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef _MXS_PCM_H | ||
| 20 | #define _MXS_PCM_H | ||
| 21 | |||
| 22 | #include <mach/dma.h> | ||
| 23 | |||
| 24 | struct mxs_pcm_dma_params { | ||
| 25 | int chan_irq; | ||
| 26 | int chan_num; | ||
| 27 | }; | ||
| 28 | |||
| 29 | struct mxs_pcm_runtime_data { | ||
| 30 | int period_bytes; | ||
| 31 | int periods; | ||
| 32 | int dma; | ||
| 33 | unsigned long offset; | ||
| 34 | unsigned long size; | ||
| 35 | void *buf; | ||
| 36 | int period_time; | ||
| 37 | struct dma_async_tx_descriptor *desc; | ||
| 38 | struct dma_chan *dma_chan; | ||
| 39 | struct mxs_dma_data dma_data; | ||
| 40 | struct mxs_pcm_dma_params *dma_params; | ||
| 41 | }; | ||
| 42 | |||
| 43 | #endif | ||
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c new file mode 100644 index 000000000000..76dc74d24fc2 --- /dev/null +++ b/sound/soc/mxs/mxs-saif.c | |||
| @@ -0,0 +1,798 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2011 Freescale Semiconductor, Inc. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/dma-mapping.h> | ||
| 24 | #include <linux/clk.h> | ||
| 25 | #include <linux/delay.h> | ||
| 26 | #include <linux/time.h> | ||
| 27 | #include <sound/core.h> | ||
| 28 | #include <sound/pcm.h> | ||
| 29 | #include <sound/pcm_params.h> | ||
| 30 | #include <sound/soc.h> | ||
| 31 | #include <sound/saif.h> | ||
| 32 | #include <mach/dma.h> | ||
| 33 | #include <asm/mach-types.h> | ||
| 34 | #include <mach/hardware.h> | ||
| 35 | #include <mach/mxs.h> | ||
| 36 | |||
| 37 | #include "mxs-saif.h" | ||
| 38 | |||
| 39 | static struct mxs_saif *mxs_saif[2]; | ||
| 40 | |||
| 41 | /* | ||
| 42 | * SAIF is a little different with other normal SOC DAIs on clock using. | ||
| 43 | * | ||
| 44 | * For MXS, two SAIF modules are instantiated on-chip. | ||
| 45 | * Each SAIF has a set of clock pins and can be operating in master | ||
| 46 | * mode simultaneously if they are connected to different off-chip codecs. | ||
| 47 | * Also, one of the two SAIFs can master or drive the clock pins while the | ||
| 48 | * other SAIF, in slave mode, receives clocking from the master SAIF. | ||
| 49 | * This also means that both SAIFs must operate at the same sample rate. | ||
| 50 | * | ||
| 51 | * We abstract this as each saif has a master, the master could be | ||
| 52 | * himself or other saifs. In the generic saif driver, saif does not need | ||
| 53 | * to know the different clkmux. Saif only needs to know who is his master | ||
| 54 | * and operating his master to generate the proper clock rate for him. | ||
| 55 | * The master id is provided in mach-specific layer according to different | ||
| 56 | * clkmux setting. | ||
| 57 | */ | ||
| 58 | |||
| 59 | static int mxs_saif_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | ||
| 60 | int clk_id, unsigned int freq, int dir) | ||
| 61 | { | ||
| 62 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 63 | |||
| 64 | switch (clk_id) { | ||
| 65 | case MXS_SAIF_MCLK: | ||
| 66 | saif->mclk = freq; | ||
| 67 | break; | ||
| 68 | default: | ||
| 69 | return -EINVAL; | ||
| 70 | } | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 75 | * Since SAIF may work on EXTMASTER mode, IOW, it's working BITCLK&LRCLK | ||
| 76 | * is provided by other SAIF, we provide a interface here to get its master | ||
| 77 | * from its master_id. | ||
| 78 | * Note that the master could be himself. | ||
| 79 | */ | ||
| 80 | static inline struct mxs_saif *mxs_saif_get_master(struct mxs_saif * saif) | ||
| 81 | { | ||
| 82 | return mxs_saif[saif->master_id]; | ||
| 83 | } | ||
| 84 | |||
| 85 | /* | ||
| 86 | * Set SAIF clock and MCLK | ||
| 87 | */ | ||
| 88 | static int mxs_saif_set_clk(struct mxs_saif *saif, | ||
| 89 | unsigned int mclk, | ||
| 90 | unsigned int rate) | ||
| 91 | { | ||
| 92 | u32 scr; | ||
| 93 | int ret; | ||
| 94 | struct mxs_saif *master_saif; | ||
| 95 | |||
| 96 | dev_dbg(saif->dev, "mclk %d rate %d\n", mclk, rate); | ||
| 97 | |||
| 98 | /* Set master saif to generate proper clock */ | ||
| 99 | master_saif = mxs_saif_get_master(saif); | ||
| 100 | if (!master_saif) | ||
| 101 | return -EINVAL; | ||
| 102 | |||
| 103 | dev_dbg(saif->dev, "master saif%d\n", master_saif->id); | ||
| 104 | |||
| 105 | /* Checking if can playback and capture simutaneously */ | ||
| 106 | if (master_saif->ongoing && rate != master_saif->cur_rate) { | ||
| 107 | dev_err(saif->dev, | ||
| 108 | "can not change clock, master saif%d(rate %d) is ongoing\n", | ||
| 109 | master_saif->id, master_saif->cur_rate); | ||
| 110 | return -EINVAL; | ||
| 111 | } | ||
| 112 | |||
| 113 | scr = __raw_readl(master_saif->base + SAIF_CTRL); | ||
| 114 | scr &= ~BM_SAIF_CTRL_BITCLK_MULT_RATE; | ||
| 115 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Set SAIF clock | ||
| 119 | * | ||
| 120 | * The SAIF clock should be either 384*fs or 512*fs. | ||
| 121 | * If MCLK is used, the SAIF clk ratio need to match mclk ratio. | ||
| 122 | * For 32x mclk, set saif clk as 512*fs. | ||
| 123 | * For 48x mclk, set saif clk as 384*fs. | ||
| 124 | * | ||
| 125 | * If MCLK is not used, we just set saif clk to 512*fs. | ||
| 126 | */ | ||
| 127 | if (master_saif->mclk_in_use) { | ||
| 128 | if (mclk % 32 == 0) { | ||
| 129 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | ||
| 130 | ret = clk_set_rate(master_saif->clk, 512 * rate); | ||
| 131 | } else if (mclk % 48 == 0) { | ||
| 132 | scr |= BM_SAIF_CTRL_BITCLK_BASE_RATE; | ||
| 133 | ret = clk_set_rate(master_saif->clk, 384 * rate); | ||
| 134 | } else { | ||
| 135 | /* SAIF MCLK should be either 32x or 48x */ | ||
| 136 | return -EINVAL; | ||
| 137 | } | ||
| 138 | } else { | ||
| 139 | ret = clk_set_rate(master_saif->clk, 512 * rate); | ||
| 140 | scr &= ~BM_SAIF_CTRL_BITCLK_BASE_RATE; | ||
| 141 | } | ||
| 142 | |||
| 143 | if (ret) | ||
| 144 | return ret; | ||
| 145 | |||
| 146 | master_saif->cur_rate = rate; | ||
| 147 | |||
| 148 | if (!master_saif->mclk_in_use) { | ||
| 149 | __raw_writel(scr, master_saif->base + SAIF_CTRL); | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Program the over-sample rate for MCLK output | ||
| 155 | * | ||
| 156 | * The available MCLK range is 32x, 48x... 512x. The rate | ||
| 157 | * could be from 8kHz to 192kH. | ||
| 158 | */ | ||
| 159 | switch (mclk / rate) { | ||
| 160 | case 32: | ||
| 161 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(4); | ||
| 162 | break; | ||
| 163 | case 64: | ||
| 164 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3); | ||
| 165 | break; | ||
| 166 | case 128: | ||
| 167 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2); | ||
| 168 | break; | ||
| 169 | case 256: | ||
| 170 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1); | ||
| 171 | break; | ||
| 172 | case 512: | ||
| 173 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0); | ||
| 174 | break; | ||
| 175 | case 48: | ||
| 176 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(3); | ||
| 177 | break; | ||
| 178 | case 96: | ||
| 179 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(2); | ||
| 180 | break; | ||
| 181 | case 192: | ||
| 182 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(1); | ||
| 183 | break; | ||
| 184 | case 384: | ||
| 185 | scr |= BF_SAIF_CTRL_BITCLK_MULT_RATE(0); | ||
| 186 | break; | ||
| 187 | default: | ||
| 188 | return -EINVAL; | ||
| 189 | } | ||
| 190 | |||
| 191 | __raw_writel(scr, master_saif->base + SAIF_CTRL); | ||
| 192 | |||
| 193 | return 0; | ||
| 194 | } | ||
| 195 | |||
| 196 | /* | ||
| 197 | * Put and disable MCLK. | ||
| 198 | */ | ||
| 199 | int mxs_saif_put_mclk(unsigned int saif_id) | ||
| 200 | { | ||
| 201 | struct mxs_saif *saif = mxs_saif[saif_id]; | ||
| 202 | u32 stat; | ||
| 203 | |||
| 204 | if (!saif) | ||
| 205 | return -EINVAL; | ||
| 206 | |||
| 207 | stat = __raw_readl(saif->base + SAIF_STAT); | ||
| 208 | if (stat & BM_SAIF_STAT_BUSY) { | ||
| 209 | dev_err(saif->dev, "error: busy\n"); | ||
| 210 | return -EBUSY; | ||
| 211 | } | ||
| 212 | |||
| 213 | clk_disable(saif->clk); | ||
| 214 | |||
| 215 | /* disable MCLK output */ | ||
| 216 | __raw_writel(BM_SAIF_CTRL_CLKGATE, | ||
| 217 | saif->base + SAIF_CTRL + MXS_SET_ADDR); | ||
| 218 | __raw_writel(BM_SAIF_CTRL_RUN, | ||
| 219 | saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 220 | |||
| 221 | saif->mclk_in_use = 0; | ||
| 222 | return 0; | ||
| 223 | } | ||
| 224 | |||
| 225 | /* | ||
| 226 | * Get MCLK and set clock rate, then enable it | ||
| 227 | * | ||
| 228 | * This interface is used for codecs who are using MCLK provided | ||
| 229 | * by saif. | ||
| 230 | */ | ||
| 231 | int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk, | ||
| 232 | unsigned int rate) | ||
| 233 | { | ||
| 234 | struct mxs_saif *saif = mxs_saif[saif_id]; | ||
| 235 | u32 stat; | ||
| 236 | int ret; | ||
| 237 | struct mxs_saif *master_saif; | ||
| 238 | |||
| 239 | if (!saif) | ||
| 240 | return -EINVAL; | ||
| 241 | |||
| 242 | /* Clear Reset */ | ||
| 243 | __raw_writel(BM_SAIF_CTRL_SFTRST, | ||
| 244 | saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 245 | |||
| 246 | /* FIXME: need clear clk gate for register r/w */ | ||
| 247 | __raw_writel(BM_SAIF_CTRL_CLKGATE, | ||
| 248 | saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 249 | |||
| 250 | master_saif = mxs_saif_get_master(saif); | ||
| 251 | if (saif != master_saif) { | ||
| 252 | dev_err(saif->dev, "can not get mclk from a non-master saif\n"); | ||
| 253 | return -EINVAL; | ||
| 254 | } | ||
| 255 | |||
| 256 | stat = __raw_readl(saif->base + SAIF_STAT); | ||
| 257 | if (stat & BM_SAIF_STAT_BUSY) { | ||
| 258 | dev_err(saif->dev, "error: busy\n"); | ||
| 259 | return -EBUSY; | ||
| 260 | } | ||
| 261 | |||
| 262 | saif->mclk_in_use = 1; | ||
| 263 | ret = mxs_saif_set_clk(saif, mclk, rate); | ||
| 264 | if (ret) | ||
| 265 | return ret; | ||
| 266 | |||
| 267 | ret = clk_enable(saif->clk); | ||
| 268 | if (ret) | ||
| 269 | return ret; | ||
| 270 | |||
| 271 | /* enable MCLK output */ | ||
| 272 | __raw_writel(BM_SAIF_CTRL_RUN, | ||
| 273 | saif->base + SAIF_CTRL + MXS_SET_ADDR); | ||
| 274 | |||
| 275 | return 0; | ||
| 276 | } | ||
| 277 | |||
| 278 | /* | ||
| 279 | * SAIF DAI format configuration. | ||
| 280 | * Should only be called when port is inactive. | ||
| 281 | */ | ||
| 282 | static int mxs_saif_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt) | ||
| 283 | { | ||
| 284 | u32 scr, stat; | ||
| 285 | u32 scr0; | ||
| 286 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 287 | |||
| 288 | stat = __raw_readl(saif->base + SAIF_STAT); | ||
| 289 | if (stat & BM_SAIF_STAT_BUSY) { | ||
| 290 | dev_err(cpu_dai->dev, "error: busy\n"); | ||
| 291 | return -EBUSY; | ||
| 292 | } | ||
| 293 | |||
| 294 | scr0 = __raw_readl(saif->base + SAIF_CTRL); | ||
| 295 | scr0 = scr0 & ~BM_SAIF_CTRL_BITCLK_EDGE & ~BM_SAIF_CTRL_LRCLK_POLARITY \ | ||
| 296 | & ~BM_SAIF_CTRL_JUSTIFY & ~BM_SAIF_CTRL_DELAY; | ||
| 297 | scr = 0; | ||
| 298 | |||
| 299 | /* DAI mode */ | ||
| 300 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | ||
| 301 | case SND_SOC_DAIFMT_I2S: | ||
| 302 | /* data frame low 1clk before data */ | ||
| 303 | scr |= BM_SAIF_CTRL_DELAY; | ||
| 304 | scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY; | ||
| 305 | break; | ||
| 306 | case SND_SOC_DAIFMT_LEFT_J: | ||
| 307 | /* data frame high with data */ | ||
| 308 | scr &= ~BM_SAIF_CTRL_DELAY; | ||
| 309 | scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY; | ||
| 310 | scr &= ~BM_SAIF_CTRL_JUSTIFY; | ||
| 311 | break; | ||
| 312 | default: | ||
| 313 | return -EINVAL; | ||
| 314 | } | ||
| 315 | |||
| 316 | /* DAI clock inversion */ | ||
| 317 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { | ||
| 318 | case SND_SOC_DAIFMT_IB_IF: | ||
| 319 | scr |= BM_SAIF_CTRL_BITCLK_EDGE; | ||
| 320 | scr |= BM_SAIF_CTRL_LRCLK_POLARITY; | ||
| 321 | break; | ||
| 322 | case SND_SOC_DAIFMT_IB_NF: | ||
| 323 | scr |= BM_SAIF_CTRL_BITCLK_EDGE; | ||
| 324 | scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY; | ||
| 325 | break; | ||
| 326 | case SND_SOC_DAIFMT_NB_IF: | ||
| 327 | scr &= ~BM_SAIF_CTRL_BITCLK_EDGE; | ||
| 328 | scr |= BM_SAIF_CTRL_LRCLK_POLARITY; | ||
| 329 | break; | ||
| 330 | case SND_SOC_DAIFMT_NB_NF: | ||
| 331 | scr &= ~BM_SAIF_CTRL_BITCLK_EDGE; | ||
| 332 | scr &= ~BM_SAIF_CTRL_LRCLK_POLARITY; | ||
| 333 | break; | ||
| 334 | } | ||
| 335 | |||
| 336 | /* | ||
| 337 | * Note: We simply just support master mode since SAIF TX can only | ||
| 338 | * work as master. | ||
| 339 | * Here the master is relative to codec side. | ||
| 340 | * Saif internally could be slave when working on EXTMASTER mode. | ||
| 341 | * We just hide this to machine driver. | ||
| 342 | */ | ||
| 343 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | ||
| 344 | case SND_SOC_DAIFMT_CBS_CFS: | ||
| 345 | if (saif->id == saif->master_id) | ||
| 346 | scr &= ~BM_SAIF_CTRL_SLAVE_MODE; | ||
| 347 | else | ||
| 348 | scr |= BM_SAIF_CTRL_SLAVE_MODE; | ||
| 349 | |||
| 350 | __raw_writel(scr | scr0, saif->base + SAIF_CTRL); | ||
| 351 | break; | ||
| 352 | default: | ||
| 353 | return -EINVAL; | ||
| 354 | } | ||
| 355 | |||
| 356 | return 0; | ||
| 357 | } | ||
| 358 | |||
| 359 | static int mxs_saif_startup(struct snd_pcm_substream *substream, | ||
| 360 | struct snd_soc_dai *cpu_dai) | ||
| 361 | { | ||
| 362 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 363 | snd_soc_dai_set_dma_data(cpu_dai, substream, &saif->dma_param); | ||
| 364 | |||
| 365 | /* clear error status to 0 for each re-open */ | ||
| 366 | saif->fifo_underrun = 0; | ||
| 367 | saif->fifo_overrun = 0; | ||
| 368 | |||
| 369 | /* Clear Reset for normal operations */ | ||
| 370 | __raw_writel(BM_SAIF_CTRL_SFTRST, | ||
| 371 | saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 372 | |||
| 373 | /* clear clock gate */ | ||
| 374 | __raw_writel(BM_SAIF_CTRL_CLKGATE, | ||
| 375 | saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 376 | |||
| 377 | return 0; | ||
| 378 | } | ||
| 379 | |||
| 380 | /* | ||
| 381 | * Should only be called when port is inactive. | ||
| 382 | * although can be called multiple times by upper layers. | ||
| 383 | */ | ||
| 384 | static int mxs_saif_hw_params(struct snd_pcm_substream *substream, | ||
| 385 | struct snd_pcm_hw_params *params, | ||
| 386 | struct snd_soc_dai *cpu_dai) | ||
| 387 | { | ||
| 388 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 389 | u32 scr, stat; | ||
| 390 | int ret; | ||
| 391 | |||
| 392 | /* mclk should already be set */ | ||
| 393 | if (!saif->mclk && saif->mclk_in_use) { | ||
| 394 | dev_err(cpu_dai->dev, "set mclk first\n"); | ||
| 395 | return -EINVAL; | ||
| 396 | } | ||
| 397 | |||
| 398 | stat = __raw_readl(saif->base + SAIF_STAT); | ||
| 399 | if (stat & BM_SAIF_STAT_BUSY) { | ||
| 400 | dev_err(cpu_dai->dev, "error: busy\n"); | ||
| 401 | return -EBUSY; | ||
| 402 | } | ||
| 403 | |||
| 404 | /* | ||
| 405 | * Set saif clk based on sample rate. | ||
| 406 | * If mclk is used, we also set mclk, if not, saif->mclk is | ||
| 407 | * default 0, means not used. | ||
| 408 | */ | ||
| 409 | ret = mxs_saif_set_clk(saif, saif->mclk, params_rate(params)); | ||
| 410 | if (ret) { | ||
| 411 | dev_err(cpu_dai->dev, "unable to get proper clk\n"); | ||
| 412 | return ret; | ||
| 413 | } | ||
| 414 | |||
| 415 | scr = __raw_readl(saif->base + SAIF_CTRL); | ||
| 416 | |||
| 417 | scr &= ~BM_SAIF_CTRL_WORD_LENGTH; | ||
| 418 | scr &= ~BM_SAIF_CTRL_BITCLK_48XFS_ENABLE; | ||
| 419 | switch (params_format(params)) { | ||
| 420 | case SNDRV_PCM_FORMAT_S16_LE: | ||
| 421 | scr |= BF_SAIF_CTRL_WORD_LENGTH(0); | ||
| 422 | break; | ||
| 423 | case SNDRV_PCM_FORMAT_S20_3LE: | ||
| 424 | scr |= BF_SAIF_CTRL_WORD_LENGTH(4); | ||
| 425 | scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE; | ||
| 426 | break; | ||
| 427 | case SNDRV_PCM_FORMAT_S24_LE: | ||
| 428 | scr |= BF_SAIF_CTRL_WORD_LENGTH(8); | ||
| 429 | scr |= BM_SAIF_CTRL_BITCLK_48XFS_ENABLE; | ||
| 430 | break; | ||
| 431 | default: | ||
| 432 | return -EINVAL; | ||
| 433 | } | ||
| 434 | |||
| 435 | /* Tx/Rx config */ | ||
| 436 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 437 | /* enable TX mode */ | ||
| 438 | scr &= ~BM_SAIF_CTRL_READ_MODE; | ||
| 439 | } else { | ||
| 440 | /* enable RX mode */ | ||
| 441 | scr |= BM_SAIF_CTRL_READ_MODE; | ||
| 442 | } | ||
| 443 | |||
| 444 | __raw_writel(scr, saif->base + SAIF_CTRL); | ||
| 445 | return 0; | ||
| 446 | } | ||
| 447 | |||
| 448 | static int mxs_saif_prepare(struct snd_pcm_substream *substream, | ||
| 449 | struct snd_soc_dai *cpu_dai) | ||
| 450 | { | ||
| 451 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 452 | |||
| 453 | /* enable FIFO error irqs */ | ||
| 454 | __raw_writel(BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN, | ||
| 455 | saif->base + SAIF_CTRL + MXS_SET_ADDR); | ||
| 456 | |||
| 457 | return 0; | ||
| 458 | } | ||
| 459 | |||
| 460 | static int mxs_saif_trigger(struct snd_pcm_substream *substream, int cmd, | ||
| 461 | struct snd_soc_dai *cpu_dai) | ||
| 462 | { | ||
| 463 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 464 | struct mxs_saif *master_saif; | ||
| 465 | u32 delay; | ||
| 466 | |||
| 467 | master_saif = mxs_saif_get_master(saif); | ||
| 468 | if (!master_saif) | ||
| 469 | return -EINVAL; | ||
| 470 | |||
| 471 | switch (cmd) { | ||
| 472 | case SNDRV_PCM_TRIGGER_START: | ||
| 473 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 474 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 475 | dev_dbg(cpu_dai->dev, "start\n"); | ||
| 476 | |||
| 477 | clk_enable(master_saif->clk); | ||
| 478 | if (!master_saif->mclk_in_use) | ||
| 479 | __raw_writel(BM_SAIF_CTRL_RUN, | ||
| 480 | master_saif->base + SAIF_CTRL + MXS_SET_ADDR); | ||
| 481 | |||
| 482 | /* | ||
| 483 | * If the saif's master is not himself, we also need to enable | ||
| 484 | * itself clk for its internal basic logic to work. | ||
| 485 | */ | ||
| 486 | if (saif != master_saif) { | ||
| 487 | clk_enable(saif->clk); | ||
| 488 | __raw_writel(BM_SAIF_CTRL_RUN, | ||
| 489 | saif->base + SAIF_CTRL + MXS_SET_ADDR); | ||
| 490 | } | ||
| 491 | |||
| 492 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 493 | /* | ||
| 494 | * write a data to saif data register to trigger | ||
| 495 | * the transfer | ||
| 496 | */ | ||
| 497 | __raw_writel(0, saif->base + SAIF_DATA); | ||
| 498 | } else { | ||
| 499 | /* | ||
| 500 | * read a data from saif data register to trigger | ||
| 501 | * the receive | ||
| 502 | */ | ||
| 503 | __raw_readl(saif->base + SAIF_DATA); | ||
| 504 | } | ||
| 505 | |||
| 506 | master_saif->ongoing = 1; | ||
| 507 | |||
| 508 | dev_dbg(saif->dev, "CTRL 0x%x STAT 0x%x\n", | ||
| 509 | __raw_readl(saif->base + SAIF_CTRL), | ||
| 510 | __raw_readl(saif->base + SAIF_STAT)); | ||
| 511 | |||
| 512 | dev_dbg(master_saif->dev, "CTRL 0x%x STAT 0x%x\n", | ||
| 513 | __raw_readl(master_saif->base + SAIF_CTRL), | ||
| 514 | __raw_readl(master_saif->base + SAIF_STAT)); | ||
| 515 | break; | ||
| 516 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
| 517 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 518 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 519 | dev_dbg(cpu_dai->dev, "stop\n"); | ||
| 520 | |||
| 521 | /* wait a while for the current sample to complete */ | ||
| 522 | delay = USEC_PER_SEC / master_saif->cur_rate; | ||
| 523 | |||
| 524 | if (!master_saif->mclk_in_use) { | ||
| 525 | __raw_writel(BM_SAIF_CTRL_RUN, | ||
| 526 | master_saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 527 | udelay(delay); | ||
| 528 | } | ||
| 529 | clk_disable(master_saif->clk); | ||
| 530 | |||
| 531 | if (saif != master_saif) { | ||
| 532 | __raw_writel(BM_SAIF_CTRL_RUN, | ||
| 533 | saif->base + SAIF_CTRL + MXS_CLR_ADDR); | ||
| 534 | udelay(delay); | ||
| 535 | clk_disable(saif->clk); | ||
| 536 | } | ||
| 537 | |||
| 538 | master_saif->ongoing = 0; | ||
| 539 | |||
| 540 | break; | ||
| 541 | default: | ||
| 542 | return -EINVAL; | ||
| 543 | } | ||
| 544 | |||
| 545 | return 0; | ||
| 546 | } | ||
| 547 | |||
| 548 | #define MXS_SAIF_RATES SNDRV_PCM_RATE_8000_192000 | ||
| 549 | #define MXS_SAIF_FORMATS \ | ||
| 550 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ | ||
| 551 | SNDRV_PCM_FMTBIT_S24_LE) | ||
| 552 | |||
| 553 | static struct snd_soc_dai_ops mxs_saif_dai_ops = { | ||
| 554 | .startup = mxs_saif_startup, | ||
| 555 | .trigger = mxs_saif_trigger, | ||
| 556 | .prepare = mxs_saif_prepare, | ||
| 557 | .hw_params = mxs_saif_hw_params, | ||
| 558 | .set_sysclk = mxs_saif_set_dai_sysclk, | ||
| 559 | .set_fmt = mxs_saif_set_dai_fmt, | ||
| 560 | }; | ||
| 561 | |||
| 562 | static int mxs_saif_dai_probe(struct snd_soc_dai *dai) | ||
| 563 | { | ||
| 564 | struct mxs_saif *saif = dev_get_drvdata(dai->dev); | ||
| 565 | |||
| 566 | snd_soc_dai_set_drvdata(dai, saif); | ||
| 567 | |||
| 568 | return 0; | ||
| 569 | } | ||
| 570 | |||
| 571 | static struct snd_soc_dai_driver mxs_saif_dai = { | ||
| 572 | .name = "mxs-saif", | ||
| 573 | .probe = mxs_saif_dai_probe, | ||
| 574 | .playback = { | ||
| 575 | .channels_min = 2, | ||
| 576 | .channels_max = 2, | ||
| 577 | .rates = MXS_SAIF_RATES, | ||
| 578 | .formats = MXS_SAIF_FORMATS, | ||
| 579 | }, | ||
| 580 | .capture = { | ||
| 581 | .channels_min = 2, | ||
| 582 | .channels_max = 2, | ||
| 583 | .rates = MXS_SAIF_RATES, | ||
| 584 | .formats = MXS_SAIF_FORMATS, | ||
| 585 | }, | ||
| 586 | .ops = &mxs_saif_dai_ops, | ||
| 587 | }; | ||
| 588 | |||
| 589 | static irqreturn_t mxs_saif_irq(int irq, void *dev_id) | ||
| 590 | { | ||
| 591 | struct mxs_saif *saif = dev_id; | ||
| 592 | unsigned int stat; | ||
| 593 | |||
| 594 | stat = __raw_readl(saif->base + SAIF_STAT); | ||
| 595 | if (!(stat & (BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ | | ||
| 596 | BM_SAIF_STAT_FIFO_OVERFLOW_IRQ))) | ||
| 597 | return IRQ_NONE; | ||
| 598 | |||
| 599 | if (stat & BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ) { | ||
| 600 | dev_dbg(saif->dev, "underrun!!! %d\n", ++saif->fifo_underrun); | ||
| 601 | __raw_writel(BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ, | ||
| 602 | saif->base + SAIF_STAT + MXS_CLR_ADDR); | ||
| 603 | } | ||
| 604 | |||
| 605 | if (stat & BM_SAIF_STAT_FIFO_OVERFLOW_IRQ) { | ||
| 606 | dev_dbg(saif->dev, "overrun!!! %d\n", ++saif->fifo_overrun); | ||
| 607 | __raw_writel(BM_SAIF_STAT_FIFO_OVERFLOW_IRQ, | ||
| 608 | saif->base + SAIF_STAT + MXS_CLR_ADDR); | ||
| 609 | } | ||
| 610 | |||
| 611 | dev_dbg(saif->dev, "SAIF_CTRL %x SAIF_STAT %x\n", | ||
| 612 | __raw_readl(saif->base + SAIF_CTRL), | ||
| 613 | __raw_readl(saif->base + SAIF_STAT)); | ||
| 614 | |||
| 615 | return IRQ_HANDLED; | ||
| 616 | } | ||
| 617 | |||
| 618 | static int mxs_saif_probe(struct platform_device *pdev) | ||
| 619 | { | ||
| 620 | struct resource *iores, *dmares; | ||
| 621 | struct mxs_saif *saif; | ||
| 622 | struct mxs_saif_platform_data *pdata; | ||
| 623 | int ret = 0; | ||
| 624 | |||
| 625 | if (pdev->id >= ARRAY_SIZE(mxs_saif)) | ||
| 626 | return -EINVAL; | ||
| 627 | |||
| 628 | pdata = pdev->dev.platform_data; | ||
| 629 | if (pdata && pdata->init) { | ||
| 630 | ret = pdata->init(); | ||
| 631 | if (ret) | ||
| 632 | return ret; | ||
| 633 | } | ||
| 634 | |||
| 635 | saif = kzalloc(sizeof(*saif), GFP_KERNEL); | ||
| 636 | if (!saif) | ||
| 637 | return -ENOMEM; | ||
| 638 | |||
| 639 | mxs_saif[pdev->id] = saif; | ||
| 640 | saif->id = pdev->id; | ||
| 641 | |||
| 642 | saif->master_id = saif->id; | ||
| 643 | if (pdata && pdata->get_master_id) { | ||
| 644 | saif->master_id = pdata->get_master_id(saif->id); | ||
| 645 | if (saif->master_id < 0 || | ||
| 646 | saif->master_id >= ARRAY_SIZE(mxs_saif)) | ||
| 647 | return -EINVAL; | ||
| 648 | } | ||
| 649 | |||
| 650 | saif->clk = clk_get(&pdev->dev, NULL); | ||
| 651 | if (IS_ERR(saif->clk)) { | ||
| 652 | ret = PTR_ERR(saif->clk); | ||
| 653 | dev_err(&pdev->dev, "Cannot get the clock: %d\n", | ||
| 654 | ret); | ||
| 655 | goto failed_clk; | ||
| 656 | } | ||
| 657 | |||
| 658 | iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 659 | if (!iores) { | ||
| 660 | ret = -ENODEV; | ||
| 661 | dev_err(&pdev->dev, "failed to get io resource: %d\n", | ||
| 662 | ret); | ||
| 663 | goto failed_get_resource; | ||
| 664 | } | ||
| 665 | |||
| 666 | if (!request_mem_region(iores->start, resource_size(iores), | ||
| 667 | "mxs-saif")) { | ||
| 668 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
| 669 | ret = -EBUSY; | ||
| 670 | goto failed_get_resource; | ||
| 671 | } | ||
| 672 | |||
| 673 | saif->base = ioremap(iores->start, resource_size(iores)); | ||
| 674 | if (!saif->base) { | ||
| 675 | dev_err(&pdev->dev, "ioremap failed\n"); | ||
| 676 | ret = -ENODEV; | ||
| 677 | goto failed_ioremap; | ||
| 678 | } | ||
| 679 | |||
| 680 | dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0); | ||
| 681 | if (!dmares) { | ||
| 682 | ret = -ENODEV; | ||
| 683 | dev_err(&pdev->dev, "failed to get dma resource: %d\n", | ||
| 684 | ret); | ||
| 685 | goto failed_ioremap; | ||
| 686 | } | ||
| 687 | saif->dma_param.chan_num = dmares->start; | ||
| 688 | |||
| 689 | saif->irq = platform_get_irq(pdev, 0); | ||
| 690 | if (saif->irq < 0) { | ||
| 691 | ret = saif->irq; | ||
| 692 | dev_err(&pdev->dev, "failed to get irq resource: %d\n", | ||
| 693 | ret); | ||
| 694 | goto failed_get_irq1; | ||
| 695 | } | ||
| 696 | |||
| 697 | saif->dev = &pdev->dev; | ||
| 698 | ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif); | ||
| 699 | if (ret) { | ||
| 700 | dev_err(&pdev->dev, "failed to request irq\n"); | ||
| 701 | goto failed_get_irq1; | ||
| 702 | } | ||
| 703 | |||
| 704 | saif->dma_param.chan_irq = platform_get_irq(pdev, 1); | ||
| 705 | if (saif->dma_param.chan_irq < 0) { | ||
| 706 | ret = saif->dma_param.chan_irq; | ||
| 707 | dev_err(&pdev->dev, "failed to get dma irq resource: %d\n", | ||
| 708 | ret); | ||
| 709 | goto failed_get_irq2; | ||
| 710 | } | ||
| 711 | |||
| 712 | platform_set_drvdata(pdev, saif); | ||
| 713 | |||
| 714 | ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai); | ||
| 715 | if (ret) { | ||
| 716 | dev_err(&pdev->dev, "register DAI failed\n"); | ||
| 717 | goto failed_register; | ||
| 718 | } | ||
| 719 | |||
| 720 | saif->soc_platform_pdev = platform_device_alloc( | ||
| 721 | "mxs-pcm-audio", pdev->id); | ||
| 722 | if (!saif->soc_platform_pdev) { | ||
| 723 | ret = -ENOMEM; | ||
| 724 | goto failed_pdev_alloc; | ||
| 725 | } | ||
| 726 | |||
| 727 | platform_set_drvdata(saif->soc_platform_pdev, saif); | ||
| 728 | ret = platform_device_add(saif->soc_platform_pdev); | ||
| 729 | if (ret) { | ||
| 730 | dev_err(&pdev->dev, "failed to add soc platform device\n"); | ||
| 731 | goto failed_pdev_add; | ||
| 732 | } | ||
| 733 | |||
| 734 | return 0; | ||
| 735 | |||
| 736 | failed_pdev_add: | ||
| 737 | platform_device_put(saif->soc_platform_pdev); | ||
| 738 | failed_pdev_alloc: | ||
| 739 | snd_soc_unregister_dai(&pdev->dev); | ||
| 740 | failed_register: | ||
| 741 | failed_get_irq2: | ||
| 742 | free_irq(saif->irq, saif); | ||
| 743 | failed_get_irq1: | ||
| 744 | iounmap(saif->base); | ||
| 745 | failed_ioremap: | ||
| 746 | release_mem_region(iores->start, resource_size(iores)); | ||
| 747 | failed_get_resource: | ||
| 748 | clk_put(saif->clk); | ||
| 749 | failed_clk: | ||
| 750 | kfree(saif); | ||
| 751 | |||
| 752 | return ret; | ||
| 753 | } | ||
| 754 | |||
| 755 | static int __devexit mxs_saif_remove(struct platform_device *pdev) | ||
| 756 | { | ||
| 757 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 758 | struct mxs_saif *saif = platform_get_drvdata(pdev); | ||
| 759 | |||
| 760 | platform_device_unregister(saif->soc_platform_pdev); | ||
| 761 | |||
| 762 | snd_soc_unregister_dai(&pdev->dev); | ||
| 763 | |||
| 764 | iounmap(saif->base); | ||
| 765 | release_mem_region(res->start, resource_size(res)); | ||
| 766 | free_irq(saif->irq, saif); | ||
| 767 | |||
| 768 | clk_put(saif->clk); | ||
| 769 | kfree(saif); | ||
| 770 | |||
| 771 | return 0; | ||
| 772 | } | ||
| 773 | |||
| 774 | static struct platform_driver mxs_saif_driver = { | ||
| 775 | .probe = mxs_saif_probe, | ||
| 776 | .remove = __devexit_p(mxs_saif_remove), | ||
| 777 | |||
| 778 | .driver = { | ||
| 779 | .name = "mxs-saif", | ||
| 780 | .owner = THIS_MODULE, | ||
| 781 | }, | ||
| 782 | }; | ||
| 783 | |||
| 784 | static int __init mxs_saif_init(void) | ||
| 785 | { | ||
| 786 | return platform_driver_register(&mxs_saif_driver); | ||
| 787 | } | ||
| 788 | |||
| 789 | static void __exit mxs_saif_exit(void) | ||
| 790 | { | ||
| 791 | platform_driver_unregister(&mxs_saif_driver); | ||
| 792 | } | ||
| 793 | |||
| 794 | module_init(mxs_saif_init); | ||
| 795 | module_exit(mxs_saif_exit); | ||
| 796 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
| 797 | MODULE_DESCRIPTION("MXS ASoC SAIF driver"); | ||
| 798 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/mxs/mxs-saif.h b/sound/soc/mxs/mxs-saif.h new file mode 100644 index 000000000000..12c91e4eb941 --- /dev/null +++ b/sound/soc/mxs/mxs-saif.h | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | |||
| 20 | #ifndef _MXS_SAIF_H | ||
| 21 | #define _MXS_SAIF_H | ||
| 22 | |||
| 23 | #define SAIF_CTRL 0x0 | ||
| 24 | #define SAIF_STAT 0x10 | ||
| 25 | #define SAIF_DATA 0x20 | ||
| 26 | #define SAIF_VERSION 0X30 | ||
| 27 | |||
| 28 | /* SAIF_CTRL */ | ||
| 29 | #define BM_SAIF_CTRL_SFTRST 0x80000000 | ||
| 30 | #define BM_SAIF_CTRL_CLKGATE 0x40000000 | ||
| 31 | #define BP_SAIF_CTRL_BITCLK_MULT_RATE 27 | ||
| 32 | #define BM_SAIF_CTRL_BITCLK_MULT_RATE 0x38000000 | ||
| 33 | #define BF_SAIF_CTRL_BITCLK_MULT_RATE(v) \ | ||
| 34 | (((v) << 27) & BM_SAIF_CTRL_BITCLK_MULT_RATE) | ||
| 35 | #define BM_SAIF_CTRL_BITCLK_BASE_RATE 0x04000000 | ||
| 36 | #define BM_SAIF_CTRL_FIFO_ERROR_IRQ_EN 0x02000000 | ||
| 37 | #define BM_SAIF_CTRL_FIFO_SERVICE_IRQ_EN 0x01000000 | ||
| 38 | #define BP_SAIF_CTRL_RSRVD2 21 | ||
| 39 | #define BM_SAIF_CTRL_RSRVD2 0x00E00000 | ||
| 40 | |||
| 41 | #define BP_SAIF_CTRL_DMAWAIT_COUNT 16 | ||
| 42 | #define BM_SAIF_CTRL_DMAWAIT_COUNT 0x001F0000 | ||
| 43 | #define BF_SAIF_CTRL_DMAWAIT_COUNT(v) \ | ||
| 44 | (((v) << 16) & BM_SAIF_CTRL_DMAWAIT_COUNT) | ||
| 45 | #define BP_SAIF_CTRL_CHANNEL_NUM_SELECT 14 | ||
| 46 | #define BM_SAIF_CTRL_CHANNEL_NUM_SELECT 0x0000C000 | ||
| 47 | #define BF_SAIF_CTRL_CHANNEL_NUM_SELECT(v) \ | ||
| 48 | (((v) << 14) & BM_SAIF_CTRL_CHANNEL_NUM_SELECT) | ||
| 49 | #define BM_SAIF_CTRL_LRCLK_PULSE 0x00002000 | ||
| 50 | #define BM_SAIF_CTRL_BIT_ORDER 0x00001000 | ||
| 51 | #define BM_SAIF_CTRL_DELAY 0x00000800 | ||
| 52 | #define BM_SAIF_CTRL_JUSTIFY 0x00000400 | ||
| 53 | #define BM_SAIF_CTRL_LRCLK_POLARITY 0x00000200 | ||
| 54 | #define BM_SAIF_CTRL_BITCLK_EDGE 0x00000100 | ||
| 55 | #define BP_SAIF_CTRL_WORD_LENGTH 4 | ||
| 56 | #define BM_SAIF_CTRL_WORD_LENGTH 0x000000F0 | ||
| 57 | #define BF_SAIF_CTRL_WORD_LENGTH(v) \ | ||
| 58 | (((v) << 4) & BM_SAIF_CTRL_WORD_LENGTH) | ||
| 59 | #define BM_SAIF_CTRL_BITCLK_48XFS_ENABLE 0x00000008 | ||
| 60 | #define BM_SAIF_CTRL_SLAVE_MODE 0x00000004 | ||
| 61 | #define BM_SAIF_CTRL_READ_MODE 0x00000002 | ||
| 62 | #define BM_SAIF_CTRL_RUN 0x00000001 | ||
| 63 | |||
| 64 | /* SAIF_STAT */ | ||
| 65 | #define BM_SAIF_STAT_PRESENT 0x80000000 | ||
| 66 | #define BP_SAIF_STAT_RSRVD2 17 | ||
| 67 | #define BM_SAIF_STAT_RSRVD2 0x7FFE0000 | ||
| 68 | #define BF_SAIF_STAT_RSRVD2(v) \ | ||
| 69 | (((v) << 17) & BM_SAIF_STAT_RSRVD2) | ||
| 70 | #define BM_SAIF_STAT_DMA_PREQ 0x00010000 | ||
| 71 | #define BP_SAIF_STAT_RSRVD1 7 | ||
| 72 | #define BM_SAIF_STAT_RSRVD1 0x0000FF80 | ||
| 73 | #define BF_SAIF_STAT_RSRVD1(v) \ | ||
| 74 | (((v) << 7) & BM_SAIF_STAT_RSRVD1) | ||
| 75 | |||
| 76 | #define BM_SAIF_STAT_FIFO_UNDERFLOW_IRQ 0x00000040 | ||
| 77 | #define BM_SAIF_STAT_FIFO_OVERFLOW_IRQ 0x00000020 | ||
| 78 | #define BM_SAIF_STAT_FIFO_SERVICE_IRQ 0x00000010 | ||
| 79 | #define BP_SAIF_STAT_RSRVD0 1 | ||
| 80 | #define BM_SAIF_STAT_RSRVD0 0x0000000E | ||
| 81 | #define BF_SAIF_STAT_RSRVD0(v) \ | ||
| 82 | (((v) << 1) & BM_SAIF_STAT_RSRVD0) | ||
| 83 | #define BM_SAIF_STAT_BUSY 0x00000001 | ||
| 84 | |||
| 85 | /* SAFI_DATA */ | ||
| 86 | #define BP_SAIF_DATA_PCM_RIGHT 16 | ||
| 87 | #define BM_SAIF_DATA_PCM_RIGHT 0xFFFF0000 | ||
| 88 | #define BF_SAIF_DATA_PCM_RIGHT(v) \ | ||
| 89 | (((v) << 16) & BM_SAIF_DATA_PCM_RIGHT) | ||
| 90 | #define BP_SAIF_DATA_PCM_LEFT 0 | ||
| 91 | #define BM_SAIF_DATA_PCM_LEFT 0x0000FFFF | ||
| 92 | #define BF_SAIF_DATA_PCM_LEFT(v) \ | ||
| 93 | (((v) << 0) & BM_SAIF_DATA_PCM_LEFT) | ||
| 94 | |||
| 95 | /* SAIF_VERSION */ | ||
| 96 | #define BP_SAIF_VERSION_MAJOR 24 | ||
| 97 | #define BM_SAIF_VERSION_MAJOR 0xFF000000 | ||
| 98 | #define BF_SAIF_VERSION_MAJOR(v) \ | ||
| 99 | (((v) << 24) & BM_SAIF_VERSION_MAJOR) | ||
| 100 | #define BP_SAIF_VERSION_MINOR 16 | ||
| 101 | #define BM_SAIF_VERSION_MINOR 0x00FF0000 | ||
| 102 | #define BF_SAIF_VERSION_MINOR(v) \ | ||
| 103 | (((v) << 16) & BM_SAIF_VERSION_MINOR) | ||
| 104 | #define BP_SAIF_VERSION_STEP 0 | ||
| 105 | #define BM_SAIF_VERSION_STEP 0x0000FFFF | ||
| 106 | #define BF_SAIF_VERSION_STEP(v) \ | ||
| 107 | (((v) << 0) & BM_SAIF_VERSION_STEP) | ||
| 108 | |||
| 109 | #define MXS_SAIF_MCLK 0 | ||
| 110 | |||
| 111 | #include "mxs-pcm.h" | ||
| 112 | |||
| 113 | struct mxs_saif { | ||
| 114 | struct device *dev; | ||
| 115 | struct clk *clk; | ||
| 116 | unsigned int mclk; | ||
| 117 | unsigned int mclk_in_use; | ||
| 118 | void __iomem *base; | ||
| 119 | int irq; | ||
| 120 | struct mxs_pcm_dma_params dma_param; | ||
| 121 | unsigned int id; | ||
| 122 | unsigned int master_id; | ||
| 123 | unsigned int cur_rate; | ||
| 124 | unsigned int ongoing; | ||
| 125 | |||
| 126 | struct platform_device *soc_platform_pdev; | ||
| 127 | u32 fifo_underrun; | ||
| 128 | u32 fifo_overrun; | ||
| 129 | }; | ||
| 130 | |||
| 131 | extern int mxs_saif_put_mclk(unsigned int saif_id); | ||
| 132 | extern int mxs_saif_get_mclk(unsigned int saif_id, unsigned int mclk, | ||
| 133 | unsigned int rate); | ||
| 134 | #endif | ||
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c new file mode 100644 index 000000000000..7fbeaec06eb4 --- /dev/null +++ b/sound/soc/mxs/mxs-sgtl5000.c | |||
| @@ -0,0 +1,173 @@ | |||
| 1 | /* | ||
| 2 | * Copyright 2011 Freescale Semiconductor, Inc. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/device.h> | ||
| 21 | #include <sound/core.h> | ||
| 22 | #include <sound/pcm.h> | ||
| 23 | #include <sound/soc.h> | ||
| 24 | #include <sound/jack.h> | ||
| 25 | #include <sound/soc-dapm.h> | ||
| 26 | #include <asm/mach-types.h> | ||
| 27 | |||
| 28 | #include "../codecs/sgtl5000.h" | ||
| 29 | #include "mxs-saif.h" | ||
| 30 | |||
| 31 | static int mxs_sgtl5000_hw_params(struct snd_pcm_substream *substream, | ||
| 32 | struct snd_pcm_hw_params *params) | ||
| 33 | { | ||
| 34 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 35 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 36 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 37 | unsigned int rate = params_rate(params); | ||
| 38 | u32 dai_format, mclk; | ||
| 39 | int ret; | ||
| 40 | |||
| 41 | /* sgtl5000 does not support 512*rate when in 96000 fs */ | ||
| 42 | switch (rate) { | ||
| 43 | case 96000: | ||
| 44 | mclk = 256 * rate; | ||
| 45 | break; | ||
| 46 | default: | ||
| 47 | mclk = 512 * rate; | ||
| 48 | break; | ||
| 49 | } | ||
| 50 | |||
| 51 | /* Sgtl5000 sysclk should be >= 8MHz and <= 27M */ | ||
| 52 | if (mclk < 8000000 || mclk > 27000000) | ||
| 53 | return -EINVAL; | ||
| 54 | |||
| 55 | /* Set SGTL5000's SYSCLK (provided by SAIF MCLK) */ | ||
| 56 | ret = snd_soc_dai_set_sysclk(codec_dai, SGTL5000_SYSCLK, mclk, 0); | ||
| 57 | if (ret) | ||
| 58 | return ret; | ||
| 59 | |||
| 60 | /* The SAIF MCLK should be the same as SGTL5000_SYSCLK */ | ||
| 61 | ret = snd_soc_dai_set_sysclk(cpu_dai, MXS_SAIF_MCLK, mclk, 0); | ||
| 62 | if (ret) | ||
| 63 | return ret; | ||
| 64 | |||
| 65 | /* set codec to slave mode */ | ||
| 66 | dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 67 | SND_SOC_DAIFMT_CBS_CFS; | ||
| 68 | |||
| 69 | /* set codec DAI configuration */ | ||
| 70 | ret = snd_soc_dai_set_fmt(codec_dai, dai_format); | ||
| 71 | if (ret) | ||
| 72 | return ret; | ||
| 73 | |||
| 74 | /* set cpu DAI configuration */ | ||
| 75 | ret = snd_soc_dai_set_fmt(cpu_dai, dai_format); | ||
| 76 | if (ret) | ||
| 77 | return ret; | ||
| 78 | |||
| 79 | return 0; | ||
| 80 | } | ||
| 81 | |||
| 82 | static struct snd_soc_ops mxs_sgtl5000_hifi_ops = { | ||
| 83 | .hw_params = mxs_sgtl5000_hw_params, | ||
| 84 | }; | ||
| 85 | |||
| 86 | static struct snd_soc_dai_link mxs_sgtl5000_dai[] = { | ||
| 87 | { | ||
| 88 | .name = "HiFi Tx", | ||
| 89 | .stream_name = "HiFi Playback", | ||
| 90 | .codec_dai_name = "sgtl5000", | ||
| 91 | .codec_name = "sgtl5000.0-000a", | ||
| 92 | .cpu_dai_name = "mxs-saif.0", | ||
| 93 | .platform_name = "mxs-pcm-audio.0", | ||
| 94 | .ops = &mxs_sgtl5000_hifi_ops, | ||
| 95 | }, { | ||
| 96 | .name = "HiFi Rx", | ||
| 97 | .stream_name = "HiFi Capture", | ||
| 98 | .codec_dai_name = "sgtl5000", | ||
| 99 | .codec_name = "sgtl5000.0-000a", | ||
| 100 | .cpu_dai_name = "mxs-saif.1", | ||
| 101 | .platform_name = "mxs-pcm-audio.1", | ||
| 102 | .ops = &mxs_sgtl5000_hifi_ops, | ||
| 103 | }, | ||
| 104 | }; | ||
| 105 | |||
| 106 | static struct snd_soc_card mxs_sgtl5000 = { | ||
| 107 | .name = "mxs_sgtl5000", | ||
| 108 | .dai_link = mxs_sgtl5000_dai, | ||
| 109 | .num_links = ARRAY_SIZE(mxs_sgtl5000_dai), | ||
| 110 | }; | ||
| 111 | |||
| 112 | static int __devinit mxs_sgtl5000_probe(struct platform_device *pdev) | ||
| 113 | { | ||
| 114 | struct snd_soc_card *card = &mxs_sgtl5000; | ||
| 115 | int ret; | ||
| 116 | |||
| 117 | /* | ||
| 118 | * Set an init clock(11.28Mhz) for sgtl5000 initialization(i2c r/w). | ||
| 119 | * The Sgtl5000 sysclk is derived from saif0 mclk and it's range | ||
| 120 | * should be >= 8MHz and <= 27M. | ||
| 121 | */ | ||
| 122 | ret = mxs_saif_get_mclk(0, 44100 * 256, 44100); | ||
| 123 | if (ret) | ||
| 124 | return ret; | ||
| 125 | |||
| 126 | card->dev = &pdev->dev; | ||
| 127 | platform_set_drvdata(pdev, card); | ||
| 128 | |||
| 129 | ret = snd_soc_register_card(card); | ||
| 130 | if (ret) { | ||
| 131 | dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", | ||
| 132 | ret); | ||
| 133 | return ret; | ||
| 134 | } | ||
| 135 | |||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int __devexit mxs_sgtl5000_remove(struct platform_device *pdev) | ||
| 140 | { | ||
| 141 | struct snd_soc_card *card = platform_get_drvdata(pdev); | ||
| 142 | |||
| 143 | mxs_saif_put_mclk(0); | ||
| 144 | |||
| 145 | snd_soc_unregister_card(card); | ||
| 146 | |||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | static struct platform_driver mxs_sgtl5000_audio_driver = { | ||
| 151 | .driver = { | ||
| 152 | .name = "mxs-sgtl5000", | ||
| 153 | .owner = THIS_MODULE, | ||
| 154 | }, | ||
| 155 | .probe = mxs_sgtl5000_probe, | ||
| 156 | .remove = __devexit_p(mxs_sgtl5000_remove), | ||
| 157 | }; | ||
| 158 | |||
| 159 | static int __init mxs_sgtl5000_init(void) | ||
| 160 | { | ||
| 161 | return platform_driver_register(&mxs_sgtl5000_audio_driver); | ||
| 162 | } | ||
| 163 | module_init(mxs_sgtl5000_init); | ||
| 164 | |||
| 165 | static void __exit mxs_sgtl5000_exit(void) | ||
| 166 | { | ||
| 167 | platform_driver_unregister(&mxs_sgtl5000_audio_driver); | ||
| 168 | } | ||
| 169 | module_exit(mxs_sgtl5000_exit); | ||
| 170 | |||
| 171 | MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
| 172 | MODULE_DESCRIPTION("MXS ALSA SoC Machine driver"); | ||
| 173 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/nuc900/nuc900-pcm.c b/sound/soc/nuc900/nuc900-pcm.c index d589ef14e917..ae8d6806966b 100644 --- a/sound/soc/nuc900/nuc900-pcm.c +++ b/sound/soc/nuc900/nuc900-pcm.c | |||
| @@ -227,7 +227,7 @@ static int nuc900_dma_trigger(struct snd_pcm_substream *substream, int cmd) | |||
| 227 | return ret; | 227 | return ret; |
| 228 | } | 228 | } |
| 229 | 229 | ||
| 230 | int nuc900_dma_getposition(struct snd_pcm_substream *substream, | 230 | static int nuc900_dma_getposition(struct snd_pcm_substream *substream, |
| 231 | dma_addr_t *src, dma_addr_t *dst) | 231 | dma_addr_t *src, dma_addr_t *dst) |
| 232 | { | 232 | { |
| 233 | struct snd_pcm_runtime *runtime = substream->runtime; | 233 | struct snd_pcm_runtime *runtime = substream->runtime; |
| @@ -268,7 +268,7 @@ static int nuc900_dma_open(struct snd_pcm_substream *substream) | |||
| 268 | nuc900_audio = nuc900_ac97_data; | 268 | nuc900_audio = nuc900_ac97_data; |
| 269 | 269 | ||
| 270 | if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt, | 270 | if (request_irq(nuc900_audio->irq_num, nuc900_dma_interrupt, |
| 271 | IRQF_DISABLED, "nuc900-dma", substream)) | 271 | 0, "nuc900-dma", substream)) |
| 272 | return -EBUSY; | 272 | return -EBUSY; |
| 273 | 273 | ||
| 274 | runtime->private_data = nuc900_audio; | 274 | runtime->private_data = nuc900_audio; |
| @@ -318,7 +318,6 @@ static u64 nuc900_pcm_dmamask = DMA_BIT_MASK(32); | |||
| 318 | static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) | 318 | static int nuc900_dma_new(struct snd_soc_pcm_runtime *rtd) |
| 319 | { | 319 | { |
| 320 | struct snd_card *card = rtd->card->snd_card; | 320 | struct snd_card *card = rtd->card->snd_card; |
| 321 | struct snd_soc_dai *dai = rtd->cpu_dai; | ||
| 322 | struct snd_pcm *pcm = rtd->pcm; | 321 | struct snd_pcm *pcm = rtd->pcm; |
| 323 | 322 | ||
| 324 | if (!card->dev->dma_mask) | 323 | if (!card->dev->dma_mask) |
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index 59e2c8d1e38d..052fd758722e 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | # OMAP Platform Support | 1 | # OMAP Platform Support |
| 2 | snd-soc-omap-objs := omap-pcm.o | 2 | snd-soc-omap-objs := omap-pcm.o |
| 3 | snd-soc-omap-mcbsp-objs := omap-mcbsp.o | 3 | snd-soc-omap-mcbsp-objs := omap-mcbsp.o |
| 4 | snd-soc-omap-mcpdm-objs := omap-mcpdm.o mcpdm.o | 4 | snd-soc-omap-mcpdm-objs := omap-mcpdm.o |
| 5 | snd-soc-omap-hdmi-objs := omap-hdmi.o | 5 | snd-soc-omap-hdmi-objs := omap-hdmi.o |
| 6 | 6 | ||
| 7 | obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o | 7 | obj-$(CONFIG_SND_OMAP_SOC) += snd-soc-omap.o |
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 73dde4a1adc3..8da55e916451 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c | |||
| @@ -43,26 +43,6 @@ static int am3517evm_hw_params(struct snd_pcm_substream *substream, | |||
| 43 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 43 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 44 | int ret; | 44 | int ret; |
| 45 | 45 | ||
| 46 | /* Set codec DAI configuration */ | ||
| 47 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 48 | SND_SOC_DAIFMT_DSP_B | | ||
| 49 | SND_SOC_DAIFMT_NB_NF | | ||
| 50 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 51 | if (ret < 0) { | ||
| 52 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 53 | return ret; | ||
| 54 | } | ||
| 55 | |||
| 56 | /* Set cpu DAI configuration */ | ||
| 57 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 58 | SND_SOC_DAIFMT_DSP_B | | ||
| 59 | SND_SOC_DAIFMT_NB_NF | | ||
| 60 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 61 | if (ret < 0) { | ||
| 62 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 63 | return ret; | ||
| 64 | } | ||
| 65 | |||
| 66 | /* Set the codec system clock for DAC and ADC */ | 46 | /* Set the codec system clock for DAC and ADC */ |
| 67 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, | 47 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, |
| 68 | CODEC_CLOCK, SND_SOC_CLOCK_IN); | 48 | CODEC_CLOCK, SND_SOC_CLOCK_IN); |
| @@ -110,28 +90,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 110 | {"MICIN", NULL, "Mic In"}, | 90 | {"MICIN", NULL, "Mic In"}, |
| 111 | }; | 91 | }; |
| 112 | 92 | ||
| 113 | static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd) | ||
| 114 | { | ||
| 115 | struct snd_soc_codec *codec = rtd->codec; | ||
| 116 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 117 | |||
| 118 | /* Add am3517-evm specific widgets */ | ||
| 119 | snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, | ||
| 120 | ARRAY_SIZE(tlv320aic23_dapm_widgets)); | ||
| 121 | |||
| 122 | /* Set up davinci-evm specific audio path audio_map */ | ||
| 123 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 124 | |||
| 125 | /* always connected */ | ||
| 126 | snd_soc_dapm_enable_pin(dapm, "Line Out"); | ||
| 127 | snd_soc_dapm_enable_pin(dapm, "Line In"); | ||
| 128 | snd_soc_dapm_enable_pin(dapm, "Mic In"); | ||
| 129 | |||
| 130 | snd_soc_dapm_sync(dapm); | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | /* Digital audio interface glue - connects codec <--> CPU */ | 93 | /* Digital audio interface glue - connects codec <--> CPU */ |
| 136 | static struct snd_soc_dai_link am3517evm_dai = { | 94 | static struct snd_soc_dai_link am3517evm_dai = { |
| 137 | .name = "TLV320AIC23", | 95 | .name = "TLV320AIC23", |
| @@ -140,7 +98,8 @@ static struct snd_soc_dai_link am3517evm_dai = { | |||
| 140 | .codec_dai_name = "tlv320aic23-hifi", | 98 | .codec_dai_name = "tlv320aic23-hifi", |
| 141 | .platform_name = "omap-pcm-audio", | 99 | .platform_name = "omap-pcm-audio", |
| 142 | .codec_name = "tlv320aic23-codec.2-001a", | 100 | .codec_name = "tlv320aic23-codec.2-001a", |
| 143 | .init = am3517evm_aic23_init, | 101 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | |
| 102 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 144 | .ops = &am3517evm_ops, | 103 | .ops = &am3517evm_ops, |
| 145 | }; | 104 | }; |
| 146 | 105 | ||
| @@ -149,6 +108,11 @@ static struct snd_soc_card snd_soc_am3517evm = { | |||
| 149 | .name = "am3517evm", | 108 | .name = "am3517evm", |
| 150 | .dai_link = &am3517evm_dai, | 109 | .dai_link = &am3517evm_dai, |
| 151 | .num_links = 1, | 110 | .num_links = 1, |
| 111 | |||
| 112 | .dapm_widgets = tlv320aic23_dapm_widgets, | ||
| 113 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), | ||
| 114 | .dapm_routes = audio_map, | ||
| 115 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 152 | }; | 116 | }; |
| 153 | 117 | ||
| 154 | static struct platform_device *am3517evm_snd_device; | 118 | static struct platform_device *am3517evm_snd_device; |
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 0aa475f92efa..dcb7b689a4ea 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c | |||
| @@ -569,7 +569,6 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) | |||
| 569 | snd_soc_dapm_disable_pin(dapm, "Speaker"); | 569 | snd_soc_dapm_disable_pin(dapm, "Speaker"); |
| 570 | snd_soc_dapm_disable_pin(dapm, "AGCIN"); | 570 | snd_soc_dapm_disable_pin(dapm, "AGCIN"); |
| 571 | snd_soc_dapm_disable_pin(dapm, "AGCOUT"); | 571 | snd_soc_dapm_disable_pin(dapm, "AGCOUT"); |
| 572 | snd_soc_dapm_sync(dapm); | ||
| 573 | 572 | ||
| 574 | /* Add virtual switch */ | 573 | /* Add virtual switch */ |
| 575 | ret = snd_soc_add_controls(codec, ams_delta_audio_controls, | 574 | ret = snd_soc_add_controls(codec, ams_delta_audio_controls, |
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c index 0ae34702995b..84615a7de6ad 100644 --- a/sound/soc/omap/igep0020.c +++ b/sound/soc/omap/igep0020.c | |||
| @@ -38,29 +38,8 @@ static int igep2_hw_params(struct snd_pcm_substream *substream, | |||
| 38 | { | 38 | { |
| 39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 40 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 40 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 41 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 42 | int ret; | 41 | int ret; |
| 43 | 42 | ||
| 44 | /* Set codec DAI configuration */ | ||
| 45 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 46 | SND_SOC_DAIFMT_I2S | | ||
| 47 | SND_SOC_DAIFMT_NB_NF | | ||
| 48 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 49 | if (ret < 0) { | ||
| 50 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 51 | return ret; | ||
| 52 | } | ||
| 53 | |||
| 54 | /* Set cpu DAI configuration */ | ||
| 55 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 56 | SND_SOC_DAIFMT_I2S | | ||
| 57 | SND_SOC_DAIFMT_NB_NF | | ||
| 58 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 59 | if (ret < 0) { | ||
| 60 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 61 | return ret; | ||
| 62 | } | ||
| 63 | |||
| 64 | /* Set the codec system clock for DAC and ADC */ | 43 | /* Set the codec system clock for DAC and ADC */ |
| 65 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | 44 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, |
| 66 | SND_SOC_CLOCK_IN); | 45 | SND_SOC_CLOCK_IN); |
| @@ -84,6 +63,8 @@ static struct snd_soc_dai_link igep2_dai = { | |||
| 84 | .codec_dai_name = "twl4030-hifi", | 63 | .codec_dai_name = "twl4030-hifi", |
| 85 | .platform_name = "omap-pcm-audio", | 64 | .platform_name = "omap-pcm-audio", |
| 86 | .codec_name = "twl4030-codec", | 65 | .codec_name = "twl4030-codec", |
| 66 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 67 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 87 | .ops = &igep2_ops, | 68 | .ops = &igep2_ops, |
| 88 | }; | 69 | }; |
| 89 | 70 | ||
diff --git a/sound/soc/omap/mcpdm.c b/sound/soc/omap/mcpdm.c deleted file mode 100644 index 50e59194ad81..000000000000 --- a/sound/soc/omap/mcpdm.c +++ /dev/null | |||
| @@ -1,470 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * mcpdm.c -- McPDM interface driver | ||
| 3 | * | ||
| 4 | * Author: Jorge Eduardo Candelaria <x0107209@ti.com> | ||
| 5 | * Copyright (C) 2009 - Texas Instruments, Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * version 2 as published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, but | ||
| 12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 19 | * 02110-1301 USA | ||
| 20 | * | ||
| 21 | */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/device.h> | ||
| 26 | #include <linux/platform_device.h> | ||
| 27 | #include <linux/wait.h> | ||
| 28 | #include <linux/slab.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/err.h> | ||
| 31 | #include <linux/clk.h> | ||
| 32 | #include <linux/delay.h> | ||
| 33 | #include <linux/io.h> | ||
| 34 | #include <linux/irq.h> | ||
| 35 | |||
| 36 | #include "mcpdm.h" | ||
| 37 | |||
| 38 | static struct omap_mcpdm *mcpdm; | ||
| 39 | |||
| 40 | static inline void omap_mcpdm_write(u16 reg, u32 val) | ||
| 41 | { | ||
| 42 | __raw_writel(val, mcpdm->io_base + reg); | ||
| 43 | } | ||
| 44 | |||
| 45 | static inline int omap_mcpdm_read(u16 reg) | ||
| 46 | { | ||
| 47 | return __raw_readl(mcpdm->io_base + reg); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void omap_mcpdm_reg_dump(void) | ||
| 51 | { | ||
| 52 | dev_dbg(mcpdm->dev, "***********************\n"); | ||
| 53 | dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n", | ||
| 54 | omap_mcpdm_read(MCPDM_IRQSTATUS_RAW)); | ||
| 55 | dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n", | ||
| 56 | omap_mcpdm_read(MCPDM_IRQSTATUS)); | ||
| 57 | dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n", | ||
| 58 | omap_mcpdm_read(MCPDM_IRQENABLE_SET)); | ||
| 59 | dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n", | ||
| 60 | omap_mcpdm_read(MCPDM_IRQENABLE_CLR)); | ||
| 61 | dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n", | ||
| 62 | omap_mcpdm_read(MCPDM_IRQWAKE_EN)); | ||
| 63 | dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n", | ||
| 64 | omap_mcpdm_read(MCPDM_DMAENABLE_SET)); | ||
| 65 | dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n", | ||
| 66 | omap_mcpdm_read(MCPDM_DMAENABLE_CLR)); | ||
| 67 | dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n", | ||
| 68 | omap_mcpdm_read(MCPDM_DMAWAKEEN)); | ||
| 69 | dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n", | ||
| 70 | omap_mcpdm_read(MCPDM_CTRL)); | ||
| 71 | dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n", | ||
| 72 | omap_mcpdm_read(MCPDM_DN_DATA)); | ||
| 73 | dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n", | ||
| 74 | omap_mcpdm_read(MCPDM_UP_DATA)); | ||
| 75 | dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n", | ||
| 76 | omap_mcpdm_read(MCPDM_FIFO_CTRL_DN)); | ||
| 77 | dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n", | ||
| 78 | omap_mcpdm_read(MCPDM_FIFO_CTRL_UP)); | ||
| 79 | dev_dbg(mcpdm->dev, "DN_OFFSET: 0x%04x\n", | ||
| 80 | omap_mcpdm_read(MCPDM_DN_OFFSET)); | ||
| 81 | dev_dbg(mcpdm->dev, "***********************\n"); | ||
| 82 | } | ||
| 83 | |||
| 84 | /* | ||
| 85 | * Takes the McPDM module in and out of reset state. | ||
| 86 | * Uplink and downlink can be reset individually. | ||
| 87 | */ | ||
| 88 | static void omap_mcpdm_reset_capture(int reset) | ||
| 89 | { | ||
| 90 | int ctrl = omap_mcpdm_read(MCPDM_CTRL); | ||
| 91 | |||
| 92 | if (reset) | ||
| 93 | ctrl |= SW_UP_RST; | ||
| 94 | else | ||
| 95 | ctrl &= ~SW_UP_RST; | ||
| 96 | |||
| 97 | omap_mcpdm_write(MCPDM_CTRL, ctrl); | ||
| 98 | } | ||
| 99 | |||
| 100 | static void omap_mcpdm_reset_playback(int reset) | ||
| 101 | { | ||
| 102 | int ctrl = omap_mcpdm_read(MCPDM_CTRL); | ||
| 103 | |||
| 104 | if (reset) | ||
| 105 | ctrl |= SW_DN_RST; | ||
| 106 | else | ||
| 107 | ctrl &= ~SW_DN_RST; | ||
| 108 | |||
| 109 | omap_mcpdm_write(MCPDM_CTRL, ctrl); | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * Enables the transfer through the PDM interface to/from the Phoenix | ||
| 114 | * codec by enabling the corresponding UP or DN channels. | ||
| 115 | */ | ||
| 116 | void omap_mcpdm_start(int stream) | ||
| 117 | { | ||
| 118 | int ctrl = omap_mcpdm_read(MCPDM_CTRL); | ||
| 119 | |||
| 120 | if (stream) | ||
| 121 | ctrl |= mcpdm->up_channels; | ||
| 122 | else | ||
| 123 | ctrl |= mcpdm->dn_channels; | ||
| 124 | |||
| 125 | omap_mcpdm_write(MCPDM_CTRL, ctrl); | ||
| 126 | } | ||
| 127 | |||
| 128 | /* | ||
| 129 | * Disables the transfer through the PDM interface to/from the Phoenix | ||
| 130 | * codec by disabling the corresponding UP or DN channels. | ||
| 131 | */ | ||
| 132 | void omap_mcpdm_stop(int stream) | ||
| 133 | { | ||
| 134 | int ctrl = omap_mcpdm_read(MCPDM_CTRL); | ||
| 135 | |||
| 136 | if (stream) | ||
| 137 | ctrl &= ~mcpdm->up_channels; | ||
| 138 | else | ||
| 139 | ctrl &= ~mcpdm->dn_channels; | ||
| 140 | |||
| 141 | omap_mcpdm_write(MCPDM_CTRL, ctrl); | ||
| 142 | } | ||
| 143 | |||
| 144 | /* | ||
| 145 | * Configures McPDM uplink for audio recording. | ||
| 146 | * This function should be called before omap_mcpdm_start. | ||
| 147 | */ | ||
| 148 | int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink) | ||
| 149 | { | ||
| 150 | int irq_mask = 0; | ||
| 151 | int ctrl; | ||
| 152 | |||
| 153 | if (!uplink) | ||
| 154 | return -EINVAL; | ||
| 155 | |||
| 156 | mcpdm->uplink = uplink; | ||
| 157 | |||
| 158 | /* Enable irq request generation */ | ||
| 159 | irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; | ||
| 160 | omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); | ||
| 161 | |||
| 162 | /* Configure uplink threshold */ | ||
| 163 | if (uplink->threshold > UP_THRES_MAX) | ||
| 164 | uplink->threshold = UP_THRES_MAX; | ||
| 165 | |||
| 166 | omap_mcpdm_write(MCPDM_FIFO_CTRL_UP, uplink->threshold); | ||
| 167 | |||
| 168 | /* Configure DMA controller */ | ||
| 169 | omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_UP_ENABLE); | ||
| 170 | |||
| 171 | /* Set pdm out format */ | ||
| 172 | ctrl = omap_mcpdm_read(MCPDM_CTRL); | ||
| 173 | ctrl &= ~PDMOUTFORMAT; | ||
| 174 | ctrl |= uplink->format & PDMOUTFORMAT; | ||
| 175 | |||
| 176 | /* Uplink channels */ | ||
| 177 | mcpdm->up_channels = uplink->channels & (PDM_UP_MASK | PDM_STATUS_MASK); | ||
| 178 | |||
| 179 | omap_mcpdm_write(MCPDM_CTRL, ctrl); | ||
| 180 | |||
| 181 | return 0; | ||
| 182 | } | ||
| 183 | |||
| 184 | /* | ||
| 185 | * Configures McPDM downlink for audio playback. | ||
| 186 | * This function should be called before omap_mcpdm_start. | ||
| 187 | */ | ||
| 188 | int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink) | ||
| 189 | { | ||
| 190 | int irq_mask = 0; | ||
| 191 | int ctrl; | ||
| 192 | |||
| 193 | if (!downlink) | ||
| 194 | return -EINVAL; | ||
| 195 | |||
| 196 | mcpdm->downlink = downlink; | ||
| 197 | |||
| 198 | /* Enable irq request generation */ | ||
| 199 | irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; | ||
| 200 | omap_mcpdm_write(MCPDM_IRQENABLE_SET, irq_mask); | ||
| 201 | |||
| 202 | /* Configure uplink threshold */ | ||
| 203 | if (downlink->threshold > DN_THRES_MAX) | ||
| 204 | downlink->threshold = DN_THRES_MAX; | ||
| 205 | |||
| 206 | omap_mcpdm_write(MCPDM_FIFO_CTRL_DN, downlink->threshold); | ||
| 207 | |||
| 208 | /* Enable DMA request generation */ | ||
| 209 | omap_mcpdm_write(MCPDM_DMAENABLE_SET, DMA_DN_ENABLE); | ||
| 210 | |||
| 211 | /* Set pdm out format */ | ||
| 212 | ctrl = omap_mcpdm_read(MCPDM_CTRL); | ||
| 213 | ctrl &= ~PDMOUTFORMAT; | ||
| 214 | ctrl |= downlink->format & PDMOUTFORMAT; | ||
| 215 | |||
| 216 | /* Downlink channels */ | ||
| 217 | mcpdm->dn_channels = downlink->channels & (PDM_DN_MASK | PDM_CMD_MASK); | ||
| 218 | |||
| 219 | omap_mcpdm_write(MCPDM_CTRL, ctrl); | ||
| 220 | |||
| 221 | return 0; | ||
| 222 | } | ||
| 223 | |||
| 224 | /* | ||
| 225 | * Cleans McPDM uplink configuration. | ||
| 226 | * This function should be called when the stream is closed. | ||
| 227 | */ | ||
| 228 | int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink) | ||
| 229 | { | ||
| 230 | int irq_mask = 0; | ||
| 231 | |||
| 232 | if (!uplink) | ||
| 233 | return -EINVAL; | ||
| 234 | |||
| 235 | /* Disable irq request generation */ | ||
| 236 | irq_mask |= uplink->irq_mask & MCPDM_UPLINK_IRQ_MASK; | ||
| 237 | omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); | ||
| 238 | |||
| 239 | /* Disable DMA request generation */ | ||
| 240 | omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_UP_ENABLE); | ||
| 241 | |||
| 242 | /* Clear Downlink channels */ | ||
| 243 | mcpdm->up_channels = 0; | ||
| 244 | |||
| 245 | mcpdm->uplink = NULL; | ||
| 246 | |||
| 247 | return 0; | ||
| 248 | } | ||
| 249 | |||
| 250 | /* | ||
| 251 | * Cleans McPDM downlink configuration. | ||
| 252 | * This function should be called when the stream is closed. | ||
| 253 | */ | ||
| 254 | int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink) | ||
| 255 | { | ||
| 256 | int irq_mask = 0; | ||
| 257 | |||
| 258 | if (!downlink) | ||
| 259 | return -EINVAL; | ||
| 260 | |||
| 261 | /* Disable irq request generation */ | ||
| 262 | irq_mask |= downlink->irq_mask & MCPDM_DOWNLINK_IRQ_MASK; | ||
| 263 | omap_mcpdm_write(MCPDM_IRQENABLE_CLR, irq_mask); | ||
| 264 | |||
| 265 | /* Disable DMA request generation */ | ||
| 266 | omap_mcpdm_write(MCPDM_DMAENABLE_CLR, DMA_DN_ENABLE); | ||
| 267 | |||
| 268 | /* clear Downlink channels */ | ||
| 269 | mcpdm->dn_channels = 0; | ||
| 270 | |||
| 271 | mcpdm->downlink = NULL; | ||
| 272 | |||
| 273 | return 0; | ||
| 274 | } | ||
| 275 | |||
| 276 | static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id) | ||
| 277 | { | ||
| 278 | struct omap_mcpdm *mcpdm_irq = dev_id; | ||
| 279 | int irq_status; | ||
| 280 | |||
| 281 | irq_status = omap_mcpdm_read(MCPDM_IRQSTATUS); | ||
| 282 | |||
| 283 | /* Acknowledge irq event */ | ||
| 284 | omap_mcpdm_write(MCPDM_IRQSTATUS, irq_status); | ||
| 285 | |||
| 286 | if (irq & MCPDM_DN_IRQ_FULL) { | ||
| 287 | dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); | ||
| 288 | omap_mcpdm_reset_playback(1); | ||
| 289 | omap_mcpdm_playback_open(mcpdm_irq->downlink); | ||
| 290 | omap_mcpdm_reset_playback(0); | ||
| 291 | } | ||
| 292 | |||
| 293 | if (irq & MCPDM_DN_IRQ_EMPTY) { | ||
| 294 | dev_err(mcpdm_irq->dev, "DN FIFO error %x\n", irq_status); | ||
| 295 | omap_mcpdm_reset_playback(1); | ||
| 296 | omap_mcpdm_playback_open(mcpdm_irq->downlink); | ||
| 297 | omap_mcpdm_reset_playback(0); | ||
| 298 | } | ||
| 299 | |||
| 300 | if (irq & MCPDM_DN_IRQ) { | ||
| 301 | dev_dbg(mcpdm_irq->dev, "DN write request\n"); | ||
| 302 | } | ||
| 303 | |||
| 304 | if (irq & MCPDM_UP_IRQ_FULL) { | ||
| 305 | dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); | ||
| 306 | omap_mcpdm_reset_capture(1); | ||
| 307 | omap_mcpdm_capture_open(mcpdm_irq->uplink); | ||
| 308 | omap_mcpdm_reset_capture(0); | ||
| 309 | } | ||
| 310 | |||
| 311 | if (irq & MCPDM_UP_IRQ_EMPTY) { | ||
| 312 | dev_err(mcpdm_irq->dev, "UP FIFO error %x\n", irq_status); | ||
| 313 | omap_mcpdm_reset_capture(1); | ||
| 314 | omap_mcpdm_capture_open(mcpdm_irq->uplink); | ||
| 315 | omap_mcpdm_reset_capture(0); | ||
| 316 | } | ||
| 317 | |||
| 318 | if (irq & MCPDM_UP_IRQ) { | ||
| 319 | dev_dbg(mcpdm_irq->dev, "UP write request\n"); | ||
| 320 | } | ||
| 321 | |||
| 322 | return IRQ_HANDLED; | ||
| 323 | } | ||
| 324 | |||
| 325 | int omap_mcpdm_request(void) | ||
| 326 | { | ||
| 327 | int ret; | ||
| 328 | |||
| 329 | clk_enable(mcpdm->clk); | ||
| 330 | |||
| 331 | spin_lock(&mcpdm->lock); | ||
| 332 | |||
| 333 | if (!mcpdm->free) { | ||
| 334 | dev_err(mcpdm->dev, "McPDM interface is in use\n"); | ||
| 335 | spin_unlock(&mcpdm->lock); | ||
| 336 | ret = -EBUSY; | ||
| 337 | goto err; | ||
| 338 | } | ||
| 339 | mcpdm->free = 0; | ||
| 340 | |||
| 341 | spin_unlock(&mcpdm->lock); | ||
| 342 | |||
| 343 | /* Disable lines while request is ongoing */ | ||
| 344 | omap_mcpdm_write(MCPDM_CTRL, 0x00); | ||
| 345 | |||
| 346 | ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, | ||
| 347 | 0, "McPDM", (void *)mcpdm); | ||
| 348 | if (ret) { | ||
| 349 | dev_err(mcpdm->dev, "Request for McPDM IRQ failed\n"); | ||
| 350 | goto err; | ||
| 351 | } | ||
| 352 | |||
| 353 | return 0; | ||
| 354 | |||
| 355 | err: | ||
| 356 | clk_disable(mcpdm->clk); | ||
| 357 | return ret; | ||
| 358 | } | ||
| 359 | |||
| 360 | void omap_mcpdm_free(void) | ||
| 361 | { | ||
| 362 | spin_lock(&mcpdm->lock); | ||
| 363 | if (mcpdm->free) { | ||
| 364 | dev_err(mcpdm->dev, "McPDM interface is already free\n"); | ||
| 365 | spin_unlock(&mcpdm->lock); | ||
| 366 | return; | ||
| 367 | } | ||
| 368 | mcpdm->free = 1; | ||
| 369 | spin_unlock(&mcpdm->lock); | ||
| 370 | |||
| 371 | clk_disable(mcpdm->clk); | ||
| 372 | |||
| 373 | free_irq(mcpdm->irq, (void *)mcpdm); | ||
| 374 | } | ||
| 375 | |||
| 376 | /* Enable/disable DC offset cancelation for the analog | ||
| 377 | * headset path (PDM channels 1 and 2). | ||
| 378 | */ | ||
| 379 | int omap_mcpdm_set_offset(int offset1, int offset2) | ||
| 380 | { | ||
| 381 | int offset; | ||
| 382 | |||
| 383 | if ((offset1 > DN_OFST_MAX) || (offset2 > DN_OFST_MAX)) | ||
| 384 | return -EINVAL; | ||
| 385 | |||
| 386 | offset = (offset1 << DN_OFST_RX1) | (offset2 << DN_OFST_RX2); | ||
| 387 | |||
| 388 | /* offset cancellation for channel 1 */ | ||
| 389 | if (offset1) | ||
| 390 | offset |= DN_OFST_RX1_EN; | ||
| 391 | else | ||
| 392 | offset &= ~DN_OFST_RX1_EN; | ||
| 393 | |||
| 394 | /* offset cancellation for channel 2 */ | ||
| 395 | if (offset2) | ||
| 396 | offset |= DN_OFST_RX2_EN; | ||
| 397 | else | ||
| 398 | offset &= ~DN_OFST_RX2_EN; | ||
| 399 | |||
| 400 | omap_mcpdm_write(MCPDM_DN_OFFSET, offset); | ||
| 401 | |||
| 402 | return 0; | ||
| 403 | } | ||
| 404 | |||
| 405 | int __devinit omap_mcpdm_probe(struct platform_device *pdev) | ||
| 406 | { | ||
| 407 | struct resource *res; | ||
| 408 | int ret = 0; | ||
| 409 | |||
| 410 | mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); | ||
| 411 | if (!mcpdm) { | ||
| 412 | ret = -ENOMEM; | ||
| 413 | goto exit; | ||
| 414 | } | ||
| 415 | |||
| 416 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 417 | if (res == NULL) { | ||
| 418 | dev_err(&pdev->dev, "no resource\n"); | ||
| 419 | goto err_resource; | ||
| 420 | } | ||
| 421 | |||
| 422 | spin_lock_init(&mcpdm->lock); | ||
| 423 | mcpdm->free = 1; | ||
| 424 | mcpdm->io_base = ioremap(res->start, resource_size(res)); | ||
| 425 | if (!mcpdm->io_base) { | ||
| 426 | ret = -ENOMEM; | ||
| 427 | goto err_resource; | ||
| 428 | } | ||
| 429 | |||
| 430 | mcpdm->irq = platform_get_irq(pdev, 0); | ||
| 431 | |||
| 432 | mcpdm->clk = clk_get(&pdev->dev, "pdm_ck"); | ||
| 433 | if (IS_ERR(mcpdm->clk)) { | ||
| 434 | ret = PTR_ERR(mcpdm->clk); | ||
| 435 | dev_err(&pdev->dev, "unable to get pdm_ck: %d\n", ret); | ||
| 436 | goto err_clk; | ||
| 437 | } | ||
| 438 | |||
| 439 | mcpdm->dev = &pdev->dev; | ||
| 440 | platform_set_drvdata(pdev, mcpdm); | ||
| 441 | |||
| 442 | return 0; | ||
| 443 | |||
| 444 | err_clk: | ||
| 445 | iounmap(mcpdm->io_base); | ||
| 446 | err_resource: | ||
| 447 | kfree(mcpdm); | ||
| 448 | exit: | ||
| 449 | return ret; | ||
| 450 | } | ||
| 451 | |||
| 452 | int omap_mcpdm_remove(struct platform_device *pdev) | ||
| 453 | { | ||
| 454 | struct omap_mcpdm *mcpdm_ptr = platform_get_drvdata(pdev); | ||
| 455 | |||
| 456 | platform_set_drvdata(pdev, NULL); | ||
| 457 | |||
| 458 | clk_put(mcpdm_ptr->clk); | ||
| 459 | |||
| 460 | iounmap(mcpdm_ptr->io_base); | ||
| 461 | |||
| 462 | mcpdm_ptr->clk = NULL; | ||
| 463 | mcpdm_ptr->free = 0; | ||
| 464 | mcpdm_ptr->dev = NULL; | ||
| 465 | |||
| 466 | kfree(mcpdm_ptr); | ||
| 467 | |||
| 468 | return 0; | ||
| 469 | } | ||
| 470 | |||
diff --git a/sound/soc/omap/mcpdm.h b/sound/soc/omap/mcpdm.h deleted file mode 100644 index 20c20a8649fe..000000000000 --- a/sound/soc/omap/mcpdm.h +++ /dev/null | |||
| @@ -1,153 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * mcpdm.h -- Defines for McPDM driver | ||
| 3 | * | ||
| 4 | * Author: Jorge Eduardo Candelaria <x0107209@ti.com> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * version 2 as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, but | ||
| 11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 13 | * General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 18 | * 02110-1301 USA | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 22 | /* McPDM registers */ | ||
| 23 | |||
| 24 | #define MCPDM_REVISION 0x00 | ||
| 25 | #define MCPDM_SYSCONFIG 0x10 | ||
| 26 | #define MCPDM_IRQSTATUS_RAW 0x24 | ||
| 27 | #define MCPDM_IRQSTATUS 0x28 | ||
| 28 | #define MCPDM_IRQENABLE_SET 0x2C | ||
| 29 | #define MCPDM_IRQENABLE_CLR 0x30 | ||
| 30 | #define MCPDM_IRQWAKE_EN 0x34 | ||
| 31 | #define MCPDM_DMAENABLE_SET 0x38 | ||
| 32 | #define MCPDM_DMAENABLE_CLR 0x3C | ||
| 33 | #define MCPDM_DMAWAKEEN 0x40 | ||
| 34 | #define MCPDM_CTRL 0x44 | ||
| 35 | #define MCPDM_DN_DATA 0x48 | ||
| 36 | #define MCPDM_UP_DATA 0x4C | ||
| 37 | #define MCPDM_FIFO_CTRL_DN 0x50 | ||
| 38 | #define MCPDM_FIFO_CTRL_UP 0x54 | ||
| 39 | #define MCPDM_DN_OFFSET 0x58 | ||
| 40 | |||
| 41 | /* | ||
| 42 | * MCPDM_IRQ bit fields | ||
| 43 | * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR | ||
| 44 | */ | ||
| 45 | |||
| 46 | #define MCPDM_DN_IRQ (1 << 0) | ||
| 47 | #define MCPDM_DN_IRQ_EMPTY (1 << 1) | ||
| 48 | #define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2) | ||
| 49 | #define MCPDM_DN_IRQ_FULL (1 << 3) | ||
| 50 | |||
| 51 | #define MCPDM_UP_IRQ (1 << 8) | ||
| 52 | #define MCPDM_UP_IRQ_EMPTY (1 << 9) | ||
| 53 | #define MCPDM_UP_IRQ_ALMST_FULL (1 << 10) | ||
| 54 | #define MCPDM_UP_IRQ_FULL (1 << 11) | ||
| 55 | |||
| 56 | #define MCPDM_DOWNLINK_IRQ_MASK 0x00F | ||
| 57 | #define MCPDM_UPLINK_IRQ_MASK 0xF00 | ||
| 58 | |||
| 59 | /* | ||
| 60 | * MCPDM_DMAENABLE bit fields | ||
| 61 | */ | ||
| 62 | |||
| 63 | #define DMA_DN_ENABLE 0x1 | ||
| 64 | #define DMA_UP_ENABLE 0x2 | ||
| 65 | |||
| 66 | /* | ||
| 67 | * MCPDM_CTRL bit fields | ||
| 68 | */ | ||
| 69 | |||
| 70 | #define PDM_UP1_EN 0x0001 | ||
| 71 | #define PDM_UP2_EN 0x0002 | ||
| 72 | #define PDM_UP3_EN 0x0004 | ||
| 73 | #define PDM_DN1_EN 0x0008 | ||
| 74 | #define PDM_DN2_EN 0x0010 | ||
| 75 | #define PDM_DN3_EN 0x0020 | ||
| 76 | #define PDM_DN4_EN 0x0040 | ||
| 77 | #define PDM_DN5_EN 0x0080 | ||
| 78 | #define PDMOUTFORMAT 0x0100 | ||
| 79 | #define CMD_INT 0x0200 | ||
| 80 | #define STATUS_INT 0x0400 | ||
| 81 | #define SW_UP_RST 0x0800 | ||
| 82 | #define SW_DN_RST 0x1000 | ||
| 83 | #define PDM_UP_MASK 0x007 | ||
| 84 | #define PDM_DN_MASK 0x0F8 | ||
| 85 | #define PDM_CMD_MASK 0x200 | ||
| 86 | #define PDM_STATUS_MASK 0x400 | ||
| 87 | |||
| 88 | |||
| 89 | #define PDMOUTFORMAT_LJUST (0 << 8) | ||
| 90 | #define PDMOUTFORMAT_RJUST (1 << 8) | ||
| 91 | |||
| 92 | /* | ||
| 93 | * MCPDM_FIFO_CTRL bit fields | ||
| 94 | */ | ||
| 95 | |||
| 96 | #define UP_THRES_MAX 0xF | ||
| 97 | #define DN_THRES_MAX 0xF | ||
| 98 | |||
| 99 | /* | ||
| 100 | * MCPDM_DN_OFFSET bit fields | ||
| 101 | */ | ||
| 102 | |||
| 103 | #define DN_OFST_RX1_EN 0x0001 | ||
| 104 | #define DN_OFST_RX2_EN 0x0100 | ||
| 105 | |||
| 106 | #define DN_OFST_RX1 1 | ||
| 107 | #define DN_OFST_RX2 9 | ||
| 108 | #define DN_OFST_MAX 0x1F | ||
| 109 | |||
| 110 | #define MCPDM_UPLINK 1 | ||
| 111 | #define MCPDM_DOWNLINK 2 | ||
| 112 | |||
| 113 | struct omap_mcpdm_link { | ||
| 114 | int irq_mask; | ||
| 115 | int threshold; | ||
| 116 | int format; | ||
| 117 | int channels; | ||
| 118 | }; | ||
| 119 | |||
| 120 | struct omap_mcpdm_platform_data { | ||
| 121 | unsigned long phys_base; | ||
| 122 | u16 irq; | ||
| 123 | }; | ||
| 124 | |||
| 125 | struct omap_mcpdm { | ||
| 126 | struct device *dev; | ||
| 127 | unsigned long phys_base; | ||
| 128 | void __iomem *io_base; | ||
| 129 | u8 free; | ||
| 130 | int irq; | ||
| 131 | |||
| 132 | spinlock_t lock; | ||
| 133 | struct omap_mcpdm_platform_data *pdata; | ||
| 134 | struct clk *clk; | ||
| 135 | struct omap_mcpdm_link *downlink; | ||
| 136 | struct omap_mcpdm_link *uplink; | ||
| 137 | struct completion irq_completion; | ||
| 138 | |||
| 139 | int dn_channels; | ||
| 140 | int up_channels; | ||
| 141 | }; | ||
| 142 | |||
| 143 | extern void omap_mcpdm_start(int stream); | ||
| 144 | extern void omap_mcpdm_stop(int stream); | ||
| 145 | extern int omap_mcpdm_capture_open(struct omap_mcpdm_link *uplink); | ||
| 146 | extern int omap_mcpdm_playback_open(struct omap_mcpdm_link *downlink); | ||
| 147 | extern int omap_mcpdm_capture_close(struct omap_mcpdm_link *uplink); | ||
| 148 | extern int omap_mcpdm_playback_close(struct omap_mcpdm_link *downlink); | ||
| 149 | extern int omap_mcpdm_request(void); | ||
| 150 | extern void omap_mcpdm_free(void); | ||
| 151 | extern int omap_mcpdm_set_offset(int offset1, int offset2); | ||
| 152 | int __devinit omap_mcpdm_probe(struct platform_device *pdev); | ||
| 153 | int omap_mcpdm_remove(struct platform_device *pdev); | ||
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 62e292f49313..7e3c20c965c6 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c | |||
| @@ -115,25 +115,8 @@ static int n810_hw_params(struct snd_pcm_substream *substream, | |||
| 115 | { | 115 | { |
| 116 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 116 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 117 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 117 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 118 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 119 | int err; | 118 | int err; |
| 120 | 119 | ||
| 121 | /* Set codec DAI configuration */ | ||
| 122 | err = snd_soc_dai_set_fmt(codec_dai, | ||
| 123 | SND_SOC_DAIFMT_I2S | | ||
| 124 | SND_SOC_DAIFMT_NB_NF | | ||
| 125 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 126 | if (err < 0) | ||
| 127 | return err; | ||
| 128 | |||
| 129 | /* Set cpu DAI configuration */ | ||
| 130 | err = snd_soc_dai_set_fmt(cpu_dai, | ||
| 131 | SND_SOC_DAIFMT_I2S | | ||
| 132 | SND_SOC_DAIFMT_NB_NF | | ||
| 133 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 134 | if (err < 0) | ||
| 135 | return err; | ||
| 136 | |||
| 137 | /* Set the codec system clock for DAC and ADC */ | 120 | /* Set the codec system clock for DAC and ADC */ |
| 138 | err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000, | 121 | err = snd_soc_dai_set_sysclk(codec_dai, 0, 12000000, |
| 139 | SND_SOC_CLOCK_IN); | 122 | SND_SOC_CLOCK_IN); |
| @@ -274,7 +257,6 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) | |||
| 274 | { | 257 | { |
| 275 | struct snd_soc_codec *codec = rtd->codec; | 258 | struct snd_soc_codec *codec = rtd->codec; |
| 276 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 259 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 277 | int err; | ||
| 278 | 260 | ||
| 279 | /* Not connected */ | 261 | /* Not connected */ |
| 280 | snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); | 262 | snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); |
| @@ -286,21 +268,6 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) | |||
| 286 | snd_soc_dapm_nc_pin(dapm, "LINE2L"); | 268 | snd_soc_dapm_nc_pin(dapm, "LINE2L"); |
| 287 | snd_soc_dapm_nc_pin(dapm, "LINE2R"); | 269 | snd_soc_dapm_nc_pin(dapm, "LINE2R"); |
| 288 | 270 | ||
| 289 | /* Add N810 specific controls */ | ||
| 290 | err = snd_soc_add_controls(codec, aic33_n810_controls, | ||
| 291 | ARRAY_SIZE(aic33_n810_controls)); | ||
| 292 | if (err < 0) | ||
| 293 | return err; | ||
| 294 | |||
| 295 | /* Add N810 specific widgets */ | ||
| 296 | snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets, | ||
| 297 | ARRAY_SIZE(aic33_dapm_widgets)); | ||
| 298 | |||
| 299 | /* Set up N810 specific audio path audio_map */ | ||
| 300 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 301 | |||
| 302 | snd_soc_dapm_sync(dapm); | ||
| 303 | |||
| 304 | return 0; | 271 | return 0; |
| 305 | } | 272 | } |
| 306 | 273 | ||
| @@ -312,6 +279,8 @@ static struct snd_soc_dai_link n810_dai = { | |||
| 312 | .platform_name = "omap-pcm-audio", | 279 | .platform_name = "omap-pcm-audio", |
| 313 | .codec_name = "tlv320aic3x-codec.2-0018", | 280 | .codec_name = "tlv320aic3x-codec.2-0018", |
| 314 | .codec_dai_name = "tlv320aic3x-hifi", | 281 | .codec_dai_name = "tlv320aic3x-hifi", |
| 282 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 283 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 315 | .init = n810_aic33_init, | 284 | .init = n810_aic33_init, |
| 316 | .ops = &n810_ops, | 285 | .ops = &n810_ops, |
| 317 | }; | 286 | }; |
| @@ -321,6 +290,13 @@ static struct snd_soc_card snd_soc_n810 = { | |||
| 321 | .name = "N810", | 290 | .name = "N810", |
| 322 | .dai_link = &n810_dai, | 291 | .dai_link = &n810_dai, |
| 323 | .num_links = 1, | 292 | .num_links = 1, |
| 293 | |||
| 294 | .controls = aic33_n810_controls, | ||
| 295 | .num_controls = ARRAY_SIZE(aic33_n810_controls), | ||
| 296 | .dapm_widgets = aic33_dapm_widgets, | ||
| 297 | .num_dapm_widgets = ARRAY_SIZE(aic33_dapm_widgets), | ||
| 298 | .dapm_routes = audio_map, | ||
| 299 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 324 | }; | 300 | }; |
| 325 | 301 | ||
| 326 | static struct platform_device *n810_snd_device; | 302 | static struct platform_device *n810_snd_device; |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 478d60778453..4314647e735e 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
| @@ -317,6 +317,10 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
| 317 | return 0; | 317 | return 0; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | regs->rcr2 &= ~(RPHASE | RFRLEN2(0x7f) | RWDLEN2(7)); | ||
| 321 | regs->xcr2 &= ~(RPHASE | XFRLEN2(0x7f) | XWDLEN2(7)); | ||
| 322 | regs->rcr1 &= ~(RFRLEN1(0x7f) | RWDLEN1(7)); | ||
| 323 | regs->xcr1 &= ~(XFRLEN1(0x7f) | XWDLEN1(7)); | ||
| 320 | format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; | 324 | format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; |
| 321 | wpf = channels = params_channels(params); | 325 | wpf = channels = params_channels(params); |
| 322 | if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || | 326 | if (channels == 2 && (format == SND_SOC_DAIFMT_I2S || |
| @@ -369,6 +373,8 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
| 369 | framesize = wlen * channels; | 373 | framesize = wlen * channels; |
| 370 | 374 | ||
| 371 | /* Set FS period and length in terms of bit clock periods */ | 375 | /* Set FS period and length in terms of bit clock periods */ |
| 376 | regs->srgr2 &= ~FPER(0xfff); | ||
| 377 | regs->srgr1 &= ~FWID(0xff); | ||
| 372 | switch (format) { | 378 | switch (format) { |
| 373 | case SND_SOC_DAIFMT_I2S: | 379 | case SND_SOC_DAIFMT_I2S: |
| 374 | case SND_SOC_DAIFMT_LEFT_J: | 380 | case SND_SOC_DAIFMT_LEFT_J: |
| @@ -398,7 +404,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 398 | { | 404 | { |
| 399 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); | 405 | struct omap_mcbsp_data *mcbsp_data = snd_soc_dai_get_drvdata(cpu_dai); |
| 400 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 406 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; |
| 401 | unsigned int temp_fmt = fmt; | 407 | bool inv_fs = false; |
| 402 | 408 | ||
| 403 | if (mcbsp_data->configured) | 409 | if (mcbsp_data->configured) |
| 404 | return 0; | 410 | return 0; |
| @@ -430,21 +436,21 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 430 | regs->xcr2 |= XDATDLY(0); | 436 | regs->xcr2 |= XDATDLY(0); |
| 431 | regs->spcr1 |= RJUST(2); | 437 | regs->spcr1 |= RJUST(2); |
| 432 | /* Invert FS polarity configuration */ | 438 | /* Invert FS polarity configuration */ |
| 433 | temp_fmt ^= SND_SOC_DAIFMT_NB_IF; | 439 | inv_fs = true; |
| 434 | break; | 440 | break; |
| 435 | case SND_SOC_DAIFMT_DSP_A: | 441 | case SND_SOC_DAIFMT_DSP_A: |
| 436 | /* 1-bit data delay */ | 442 | /* 1-bit data delay */ |
| 437 | regs->rcr2 |= RDATDLY(1); | 443 | regs->rcr2 |= RDATDLY(1); |
| 438 | regs->xcr2 |= XDATDLY(1); | 444 | regs->xcr2 |= XDATDLY(1); |
| 439 | /* Invert FS polarity configuration */ | 445 | /* Invert FS polarity configuration */ |
| 440 | temp_fmt ^= SND_SOC_DAIFMT_NB_IF; | 446 | inv_fs = true; |
| 441 | break; | 447 | break; |
| 442 | case SND_SOC_DAIFMT_DSP_B: | 448 | case SND_SOC_DAIFMT_DSP_B: |
| 443 | /* 0-bit data delay */ | 449 | /* 0-bit data delay */ |
| 444 | regs->rcr2 |= RDATDLY(0); | 450 | regs->rcr2 |= RDATDLY(0); |
| 445 | regs->xcr2 |= XDATDLY(0); | 451 | regs->xcr2 |= XDATDLY(0); |
| 446 | /* Invert FS polarity configuration */ | 452 | /* Invert FS polarity configuration */ |
| 447 | temp_fmt ^= SND_SOC_DAIFMT_NB_IF; | 453 | inv_fs = true; |
| 448 | break; | 454 | break; |
| 449 | default: | 455 | default: |
| 450 | /* Unsupported data format */ | 456 | /* Unsupported data format */ |
| @@ -468,7 +474,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 468 | } | 474 | } |
| 469 | 475 | ||
| 470 | /* Set bit clock (CLKX/CLKR) and FS polarities */ | 476 | /* Set bit clock (CLKX/CLKR) and FS polarities */ |
| 471 | switch (temp_fmt & SND_SOC_DAIFMT_INV_MASK) { | 477 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
| 472 | case SND_SOC_DAIFMT_NB_NF: | 478 | case SND_SOC_DAIFMT_NB_NF: |
| 473 | /* | 479 | /* |
| 474 | * Normal BCLK + FS. | 480 | * Normal BCLK + FS. |
| @@ -489,6 +495,8 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, | |||
| 489 | default: | 495 | default: |
| 490 | return -EINVAL; | 496 | return -EINVAL; |
| 491 | } | 497 | } |
| 498 | if (inv_fs == true) | ||
| 499 | regs->pcr0 ^= FSXP | FSRP; | ||
| 492 | 500 | ||
| 493 | return 0; | 501 | return 0; |
| 494 | } | 502 | } |
| @@ -503,6 +511,7 @@ static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai, | |||
| 503 | return -ENODEV; | 511 | return -ENODEV; |
| 504 | 512 | ||
| 505 | mcbsp_data->clk_div = div; | 513 | mcbsp_data->clk_div = div; |
| 514 | regs->srgr1 &= ~CLKGDV(0xff); | ||
| 506 | regs->srgr1 |= CLKGDV(div - 1); | 515 | regs->srgr1 |= CLKGDV(div - 1); |
| 507 | 516 | ||
| 508 | return 0; | 517 | return 0; |
| @@ -516,11 +525,12 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
| 516 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; | 525 | struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; |
| 517 | int err = 0; | 526 | int err = 0; |
| 518 | 527 | ||
| 519 | if (mcbsp_data->active) | 528 | if (mcbsp_data->active) { |
| 520 | if (freq == mcbsp_data->in_freq) | 529 | if (freq == mcbsp_data->in_freq) |
| 521 | return 0; | 530 | return 0; |
| 522 | else | 531 | else |
| 523 | return -EBUSY; | 532 | return -EBUSY; |
| 533 | } | ||
| 524 | 534 | ||
| 525 | /* The McBSP signal muxing functions are only available on McBSP1 */ | 535 | /* The McBSP signal muxing functions are only available on McBSP1 */ |
| 526 | if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR || | 536 | if (clk_id == OMAP_MCBSP_CLKR_SRC_CLKR || |
| @@ -531,6 +541,8 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai, | |||
| 531 | return -EINVAL; | 541 | return -EINVAL; |
| 532 | 542 | ||
| 533 | mcbsp_data->in_freq = freq; | 543 | mcbsp_data->in_freq = freq; |
| 544 | regs->srgr2 &= ~CLKSM; | ||
| 545 | regs->pcr0 &= ~SCLKME; | ||
| 534 | 546 | ||
| 535 | switch (clk_id) { | 547 | switch (clk_id) { |
| 536 | case OMAP_MCBSP_SYSCLK_CLK: | 548 | case OMAP_MCBSP_SYSCLK_CLK: |
| @@ -605,8 +617,7 @@ static int mcbsp_dai_probe(struct snd_soc_dai *dai) | |||
| 605 | return 0; | 617 | return 0; |
| 606 | } | 618 | } |
| 607 | 619 | ||
| 608 | static struct snd_soc_dai_driver omap_mcbsp_dai = | 620 | static struct snd_soc_dai_driver omap_mcbsp_dai = { |
| 609 | { | ||
| 610 | .probe = mcbsp_dai_probe, | 621 | .probe = mcbsp_dai_probe, |
| 611 | .playback = { | 622 | .playback = { |
| 612 | .channels_min = 1, | 623 | .channels_min = 1, |
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index bed09c27e44c..41d17067cc73 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port | 2 | * omap-mcpdm.c -- OMAP ALSA SoC DAI driver using McPDM port |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2009 Texas Instruments | 4 | * Copyright (C) 2009 - 2011 Texas Instruments |
| 5 | * | 5 | * |
| 6 | * Author: Misael Lopez Cruz <x0052729@ti.com> | 6 | * Author: Misael Lopez Cruz <misael.lopez@ti.com> |
| 7 | * Contact: Jorge Eduardo Candelaria <x0107209@ti.com> | 7 | * Contact: Jorge Eduardo Candelaria <x0107209@ti.com> |
| 8 | * Margarita Olaya <magi.olaya@ti.com> | 8 | * Margarita Olaya <magi.olaya@ti.com> |
| 9 | * Peter Ujfalusi <peter.ujfalusi@ti.com> | ||
| 9 | * | 10 | * |
| 10 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
| 11 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
| @@ -25,41 +26,42 @@ | |||
| 25 | 26 | ||
| 26 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 27 | #include <linux/module.h> | 28 | #include <linux/module.h> |
| 28 | #include <linux/device.h> | 29 | #include <linux/platform_device.h> |
| 30 | #include <linux/interrupt.h> | ||
| 31 | #include <linux/err.h> | ||
| 32 | #include <linux/io.h> | ||
| 33 | #include <linux/irq.h> | ||
| 34 | #include <linux/slab.h> | ||
| 35 | #include <linux/pm_runtime.h> | ||
| 36 | |||
| 29 | #include <sound/core.h> | 37 | #include <sound/core.h> |
| 30 | #include <sound/pcm.h> | 38 | #include <sound/pcm.h> |
| 31 | #include <sound/pcm_params.h> | 39 | #include <sound/pcm_params.h> |
| 32 | #include <sound/initval.h> | ||
| 33 | #include <sound/soc.h> | 40 | #include <sound/soc.h> |
| 34 | 41 | ||
| 35 | #include <plat/dma.h> | 42 | #include <plat/dma.h> |
| 36 | #include <plat/mcbsp.h> | 43 | #include <plat/omap_hwmod.h> |
| 37 | #include "mcpdm.h" | 44 | #include "omap-mcpdm.h" |
| 38 | #include "omap-pcm.h" | 45 | #include "omap-pcm.h" |
| 39 | 46 | ||
| 40 | struct omap_mcpdm_data { | 47 | struct omap_mcpdm { |
| 41 | struct omap_mcpdm_link *links; | 48 | struct device *dev; |
| 42 | int active; | 49 | unsigned long phys_base; |
| 43 | }; | 50 | void __iomem *io_base; |
| 51 | int irq; | ||
| 44 | 52 | ||
| 45 | static struct omap_mcpdm_link omap_mcpdm_links[] = { | 53 | struct mutex mutex; |
| 46 | /* downlink */ | 54 | |
| 47 | { | 55 | /* channel data */ |
| 48 | .irq_mask = MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL, | 56 | u32 dn_channels; |
| 49 | .threshold = 1, | 57 | u32 up_channels; |
| 50 | .format = PDMOUTFORMAT_LJUST, | 58 | |
| 51 | }, | 59 | /* McPDM FIFO thresholds */ |
| 52 | /* uplink */ | 60 | u32 dn_threshold; |
| 53 | { | 61 | u32 up_threshold; |
| 54 | .irq_mask = MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL, | ||
| 55 | .threshold = 1, | ||
| 56 | .format = PDMOUTFORMAT_LJUST, | ||
| 57 | }, | ||
| 58 | }; | ||
| 59 | 62 | ||
| 60 | static struct omap_mcpdm_data mcpdm_data = { | 63 | /* McPDM dn offsets for rx1, and 2 channels */ |
| 61 | .links = omap_mcpdm_links, | 64 | u32 dn_rx_offset; |
| 62 | .active = 0, | ||
| 63 | }; | 65 | }; |
| 64 | 66 | ||
| 65 | /* | 67 | /* |
| @@ -71,88 +73,259 @@ static struct omap_pcm_dma_data omap_mcpdm_dai_dma_params[] = { | |||
| 71 | .dma_req = OMAP44XX_DMA_MCPDM_DL, | 73 | .dma_req = OMAP44XX_DMA_MCPDM_DL, |
| 72 | .data_type = OMAP_DMA_DATA_TYPE_S32, | 74 | .data_type = OMAP_DMA_DATA_TYPE_S32, |
| 73 | .sync_mode = OMAP_DMA_SYNC_PACKET, | 75 | .sync_mode = OMAP_DMA_SYNC_PACKET, |
| 74 | .packet_size = 16, | 76 | .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_DN_DATA, |
| 75 | .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_DN_DATA, | ||
| 76 | }, | 77 | }, |
| 77 | { | 78 | { |
| 78 | .name = "Audio capture", | 79 | .name = "Audio capture", |
| 79 | .dma_req = OMAP44XX_DMA_MCPDM_UP, | 80 | .dma_req = OMAP44XX_DMA_MCPDM_UP, |
| 80 | .data_type = OMAP_DMA_DATA_TYPE_S32, | 81 | .data_type = OMAP_DMA_DATA_TYPE_S32, |
| 81 | .sync_mode = OMAP_DMA_SYNC_PACKET, | 82 | .sync_mode = OMAP_DMA_SYNC_PACKET, |
| 82 | .packet_size = 16, | 83 | .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_REG_UP_DATA, |
| 83 | .port_addr = OMAP44XX_MCPDM_L3_BASE + MCPDM_UP_DATA, | ||
| 84 | }, | 84 | }, |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, | 87 | static inline void omap_mcpdm_write(struct omap_mcpdm *mcpdm, u16 reg, u32 val) |
| 88 | struct snd_soc_dai *dai) | ||
| 89 | { | 88 | { |
| 90 | int err = 0; | 89 | __raw_writel(val, mcpdm->io_base + reg); |
| 90 | } | ||
| 91 | 91 | ||
| 92 | if (!dai->active) | 92 | static inline int omap_mcpdm_read(struct omap_mcpdm *mcpdm, u16 reg) |
| 93 | err = omap_mcpdm_request(); | 93 | { |
| 94 | return __raw_readl(mcpdm->io_base + reg); | ||
| 95 | } | ||
| 94 | 96 | ||
| 95 | return err; | 97 | #ifdef DEBUG |
| 98 | static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) | ||
| 99 | { | ||
| 100 | dev_dbg(mcpdm->dev, "***********************\n"); | ||
| 101 | dev_dbg(mcpdm->dev, "IRQSTATUS_RAW: 0x%04x\n", | ||
| 102 | omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS_RAW)); | ||
| 103 | dev_dbg(mcpdm->dev, "IRQSTATUS: 0x%04x\n", | ||
| 104 | omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS)); | ||
| 105 | dev_dbg(mcpdm->dev, "IRQENABLE_SET: 0x%04x\n", | ||
| 106 | omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_SET)); | ||
| 107 | dev_dbg(mcpdm->dev, "IRQENABLE_CLR: 0x%04x\n", | ||
| 108 | omap_mcpdm_read(mcpdm, MCPDM_REG_IRQENABLE_CLR)); | ||
| 109 | dev_dbg(mcpdm->dev, "IRQWAKE_EN: 0x%04x\n", | ||
| 110 | omap_mcpdm_read(mcpdm, MCPDM_REG_IRQWAKE_EN)); | ||
| 111 | dev_dbg(mcpdm->dev, "DMAENABLE_SET: 0x%04x\n", | ||
| 112 | omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_SET)); | ||
| 113 | dev_dbg(mcpdm->dev, "DMAENABLE_CLR: 0x%04x\n", | ||
| 114 | omap_mcpdm_read(mcpdm, MCPDM_REG_DMAENABLE_CLR)); | ||
| 115 | dev_dbg(mcpdm->dev, "DMAWAKEEN: 0x%04x\n", | ||
| 116 | omap_mcpdm_read(mcpdm, MCPDM_REG_DMAWAKEEN)); | ||
| 117 | dev_dbg(mcpdm->dev, "CTRL: 0x%04x\n", | ||
| 118 | omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL)); | ||
| 119 | dev_dbg(mcpdm->dev, "DN_DATA: 0x%04x\n", | ||
| 120 | omap_mcpdm_read(mcpdm, MCPDM_REG_DN_DATA)); | ||
| 121 | dev_dbg(mcpdm->dev, "UP_DATA: 0x%04x\n", | ||
| 122 | omap_mcpdm_read(mcpdm, MCPDM_REG_UP_DATA)); | ||
| 123 | dev_dbg(mcpdm->dev, "FIFO_CTRL_DN: 0x%04x\n", | ||
| 124 | omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_DN)); | ||
| 125 | dev_dbg(mcpdm->dev, "FIFO_CTRL_UP: 0x%04x\n", | ||
| 126 | omap_mcpdm_read(mcpdm, MCPDM_REG_FIFO_CTRL_UP)); | ||
| 127 | dev_dbg(mcpdm->dev, "***********************\n"); | ||
| 96 | } | 128 | } |
| 129 | #else | ||
| 130 | static void omap_mcpdm_reg_dump(struct omap_mcpdm *mcpdm) {} | ||
| 131 | #endif | ||
| 97 | 132 | ||
| 98 | static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, | 133 | /* |
| 99 | struct snd_soc_dai *dai) | 134 | * Enables the transfer through the PDM interface to/from the Phoenix |
| 135 | * codec by enabling the corresponding UP or DN channels. | ||
| 136 | */ | ||
| 137 | static void omap_mcpdm_start(struct omap_mcpdm *mcpdm) | ||
| 138 | { | ||
| 139 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); | ||
| 140 | |||
| 141 | ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | ||
| 142 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | ||
| 143 | |||
| 144 | ctrl |= mcpdm->dn_channels | mcpdm->up_channels; | ||
| 145 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | ||
| 146 | |||
| 147 | ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | ||
| 148 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | ||
| 149 | } | ||
| 150 | |||
| 151 | /* | ||
| 152 | * Disables the transfer through the PDM interface to/from the Phoenix | ||
| 153 | * codec by disabling the corresponding UP or DN channels. | ||
| 154 | */ | ||
| 155 | static void omap_mcpdm_stop(struct omap_mcpdm *mcpdm) | ||
| 156 | { | ||
| 157 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); | ||
| 158 | |||
| 159 | ctrl |= (MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | ||
| 160 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | ||
| 161 | |||
| 162 | ctrl &= ~(mcpdm->dn_channels | mcpdm->up_channels); | ||
| 163 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | ||
| 164 | |||
| 165 | ctrl &= ~(MCPDM_SW_DN_RST | MCPDM_SW_UP_RST); | ||
| 166 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl); | ||
| 167 | |||
| 168 | } | ||
| 169 | |||
| 170 | /* | ||
| 171 | * Is the physical McPDM interface active. | ||
| 172 | */ | ||
| 173 | static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm) | ||
| 174 | { | ||
| 175 | return omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL) & | ||
| 176 | (MCPDM_PDM_DN_MASK | MCPDM_PDM_UP_MASK); | ||
| 177 | } | ||
| 178 | |||
| 179 | /* | ||
| 180 | * Configures McPDM uplink, and downlink for audio. | ||
| 181 | * This function should be called before omap_mcpdm_start. | ||
| 182 | */ | ||
| 183 | static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) | ||
| 184 | { | ||
| 185 | omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET, | ||
| 186 | MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL | | ||
| 187 | MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL); | ||
| 188 | |||
| 189 | /* Enable DN RX1/2 offset cancellation feature, if configured */ | ||
| 190 | if (mcpdm->dn_rx_offset) { | ||
| 191 | u32 dn_offset = mcpdm->dn_rx_offset; | ||
| 192 | |||
| 193 | omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); | ||
| 194 | dn_offset |= (MCPDM_DN_OFST_RX1_EN | MCPDM_DN_OFST_RX2_EN); | ||
| 195 | omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, dn_offset); | ||
| 196 | } | ||
| 197 | |||
| 198 | omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_DN, mcpdm->dn_threshold); | ||
| 199 | omap_mcpdm_write(mcpdm, MCPDM_REG_FIFO_CTRL_UP, mcpdm->up_threshold); | ||
| 200 | |||
| 201 | omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_SET, | ||
| 202 | MCPDM_DMA_DN_ENABLE | MCPDM_DMA_UP_ENABLE); | ||
| 203 | } | ||
| 204 | |||
| 205 | /* | ||
| 206 | * Cleans McPDM uplink, and downlink configuration. | ||
| 207 | * This function should be called when the stream is closed. | ||
| 208 | */ | ||
| 209 | static void omap_mcpdm_close_streams(struct omap_mcpdm *mcpdm) | ||
| 210 | { | ||
| 211 | /* Disable irq request generation for downlink */ | ||
| 212 | omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR, | ||
| 213 | MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL); | ||
| 214 | |||
| 215 | /* Disable DMA request generation for downlink */ | ||
| 216 | omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_DN_ENABLE); | ||
| 217 | |||
| 218 | /* Disable irq request generation for uplink */ | ||
| 219 | omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_CLR, | ||
| 220 | MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL); | ||
| 221 | |||
| 222 | /* Disable DMA request generation for uplink */ | ||
| 223 | omap_mcpdm_write(mcpdm, MCPDM_REG_DMAENABLE_CLR, MCPDM_DMA_UP_ENABLE); | ||
| 224 | |||
| 225 | /* Disable RX1/2 offset cancellation */ | ||
| 226 | if (mcpdm->dn_rx_offset) | ||
| 227 | omap_mcpdm_write(mcpdm, MCPDM_REG_DN_OFFSET, 0); | ||
| 228 | } | ||
| 229 | |||
| 230 | static irqreturn_t omap_mcpdm_irq_handler(int irq, void *dev_id) | ||
| 231 | { | ||
| 232 | struct omap_mcpdm *mcpdm = dev_id; | ||
| 233 | int irq_status; | ||
| 234 | |||
| 235 | irq_status = omap_mcpdm_read(mcpdm, MCPDM_REG_IRQSTATUS); | ||
| 236 | |||
| 237 | /* Acknowledge irq event */ | ||
| 238 | omap_mcpdm_write(mcpdm, MCPDM_REG_IRQSTATUS, irq_status); | ||
| 239 | |||
| 240 | if (irq_status & MCPDM_DN_IRQ_FULL) | ||
| 241 | dev_dbg(mcpdm->dev, "DN (playback) FIFO Full\n"); | ||
| 242 | |||
| 243 | if (irq_status & MCPDM_DN_IRQ_EMPTY) | ||
| 244 | dev_dbg(mcpdm->dev, "DN (playback) FIFO Empty\n"); | ||
| 245 | |||
| 246 | if (irq_status & MCPDM_DN_IRQ) | ||
| 247 | dev_dbg(mcpdm->dev, "DN (playback) write request\n"); | ||
| 248 | |||
| 249 | if (irq_status & MCPDM_UP_IRQ_FULL) | ||
| 250 | dev_dbg(mcpdm->dev, "UP (capture) FIFO Full\n"); | ||
| 251 | |||
| 252 | if (irq_status & MCPDM_UP_IRQ_EMPTY) | ||
| 253 | dev_dbg(mcpdm->dev, "UP (capture) FIFO Empty\n"); | ||
| 254 | |||
| 255 | if (irq_status & MCPDM_UP_IRQ) | ||
| 256 | dev_dbg(mcpdm->dev, "UP (capture) write request\n"); | ||
| 257 | |||
| 258 | return IRQ_HANDLED; | ||
| 259 | } | ||
| 260 | |||
| 261 | static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, | ||
| 262 | struct snd_soc_dai *dai) | ||
| 100 | { | 263 | { |
| 101 | if (!dai->active) | 264 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
| 102 | omap_mcpdm_free(); | 265 | |
| 266 | mutex_lock(&mcpdm->mutex); | ||
| 267 | |||
| 268 | if (!dai->active) { | ||
| 269 | pm_runtime_get_sync(mcpdm->dev); | ||
| 270 | |||
| 271 | /* Enable watch dog for ES above ES 1.0 to avoid saturation */ | ||
| 272 | if (omap_rev() != OMAP4430_REV_ES1_0) { | ||
| 273 | u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL); | ||
| 274 | |||
| 275 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, | ||
| 276 | ctrl | MCPDM_WD_EN); | ||
| 277 | } | ||
| 278 | omap_mcpdm_open_streams(mcpdm); | ||
| 279 | } | ||
| 280 | |||
| 281 | mutex_unlock(&mcpdm->mutex); | ||
| 282 | |||
| 283 | return 0; | ||
| 103 | } | 284 | } |
| 104 | 285 | ||
| 105 | static int omap_mcpdm_dai_trigger(struct snd_pcm_substream *substream, int cmd, | 286 | static void omap_mcpdm_dai_shutdown(struct snd_pcm_substream *substream, |
| 106 | struct snd_soc_dai *dai) | 287 | struct snd_soc_dai *dai) |
| 107 | { | 288 | { |
| 108 | struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); | 289 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
| 109 | int stream = substream->stream; | ||
| 110 | int err = 0; | ||
| 111 | |||
| 112 | switch (cmd) { | ||
| 113 | case SNDRV_PCM_TRIGGER_START: | ||
| 114 | case SNDRV_PCM_TRIGGER_RESUME: | ||
| 115 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 116 | if (!mcpdm_priv->active++) | ||
| 117 | omap_mcpdm_start(stream); | ||
| 118 | break; | ||
| 119 | 290 | ||
| 120 | case SNDRV_PCM_TRIGGER_STOP: | 291 | mutex_lock(&mcpdm->mutex); |
| 121 | case SNDRV_PCM_TRIGGER_SUSPEND: | 292 | |
| 122 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 293 | if (!dai->active) { |
| 123 | if (!--mcpdm_priv->active) | 294 | if (omap_mcpdm_active(mcpdm)) { |
| 124 | omap_mcpdm_stop(stream); | 295 | omap_mcpdm_stop(mcpdm); |
| 125 | break; | 296 | omap_mcpdm_close_streams(mcpdm); |
| 126 | default: | 297 | } |
| 127 | err = -EINVAL; | 298 | |
| 299 | if (!omap_mcpdm_active(mcpdm)) | ||
| 300 | pm_runtime_put_sync(mcpdm->dev); | ||
| 128 | } | 301 | } |
| 129 | 302 | ||
| 130 | return err; | 303 | mutex_unlock(&mcpdm->mutex); |
| 131 | } | 304 | } |
| 132 | 305 | ||
| 133 | static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | 306 | static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, |
| 134 | struct snd_pcm_hw_params *params, | 307 | struct snd_pcm_hw_params *params, |
| 135 | struct snd_soc_dai *dai) | 308 | struct snd_soc_dai *dai) |
| 136 | { | 309 | { |
| 137 | struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); | 310 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
| 138 | struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; | ||
| 139 | int stream = substream->stream; | 311 | int stream = substream->stream; |
| 140 | int channels, err, link_mask = 0; | 312 | struct omap_pcm_dma_data *dma_data; |
| 141 | 313 | int channels; | |
| 142 | snd_soc_dai_set_dma_data(dai, substream, | 314 | int link_mask = 0; |
| 143 | &omap_mcpdm_dai_dma_params[stream]); | ||
| 144 | 315 | ||
| 145 | channels = params_channels(params); | 316 | channels = params_channels(params); |
| 146 | switch (channels) { | 317 | switch (channels) { |
| 318 | case 5: | ||
| 319 | if (stream == SNDRV_PCM_STREAM_CAPTURE) | ||
| 320 | /* up to 3 channels for capture */ | ||
| 321 | return -EINVAL; | ||
| 322 | link_mask |= 1 << 4; | ||
| 147 | case 4: | 323 | case 4: |
| 148 | if (stream == SNDRV_PCM_STREAM_CAPTURE) | 324 | if (stream == SNDRV_PCM_STREAM_CAPTURE) |
| 149 | /* up to 2 channels for capture */ | 325 | /* up to 3 channels for capture */ |
| 150 | return -EINVAL; | 326 | return -EINVAL; |
| 151 | link_mask |= 1 << 3; | 327 | link_mask |= 1 << 3; |
| 152 | case 3: | 328 | case 3: |
| 153 | if (stream == SNDRV_PCM_STREAM_CAPTURE) | ||
| 154 | /* up to 2 channels for capture */ | ||
| 155 | return -EINVAL; | ||
| 156 | link_mask |= 1 << 2; | 329 | link_mask |= 1 << 2; |
| 157 | case 2: | 330 | case 2: |
| 158 | link_mask |= 1 << 1; | 331 | link_mask |= 1 << 1; |
| @@ -164,95 +337,187 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | |||
| 164 | return -EINVAL; | 337 | return -EINVAL; |
| 165 | } | 338 | } |
| 166 | 339 | ||
| 340 | dma_data = &omap_mcpdm_dai_dma_params[stream]; | ||
| 341 | |||
| 342 | /* Configure McPDM channels, and DMA packet size */ | ||
| 167 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 343 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 168 | mcpdm_links[stream].channels = link_mask << 3; | 344 | mcpdm->dn_channels = link_mask << 3; |
| 169 | err = omap_mcpdm_playback_open(&mcpdm_links[stream]); | 345 | dma_data->packet_size = |
| 346 | (MCPDM_DN_THRES_MAX - mcpdm->dn_threshold) * channels; | ||
| 170 | } else { | 347 | } else { |
| 171 | mcpdm_links[stream].channels = link_mask << 0; | 348 | mcpdm->up_channels = link_mask << 0; |
| 172 | err = omap_mcpdm_capture_open(&mcpdm_links[stream]); | 349 | dma_data->packet_size = mcpdm->up_threshold * channels; |
| 173 | } | 350 | } |
| 174 | 351 | ||
| 175 | return err; | 352 | snd_soc_dai_set_dma_data(dai, substream, dma_data); |
| 353 | |||
| 354 | return 0; | ||
| 176 | } | 355 | } |
| 177 | 356 | ||
| 178 | static int omap_mcpdm_dai_hw_free(struct snd_pcm_substream *substream, | 357 | static int omap_mcpdm_prepare(struct snd_pcm_substream *substream, |
| 179 | struct snd_soc_dai *dai) | 358 | struct snd_soc_dai *dai) |
| 180 | { | 359 | { |
| 181 | struct omap_mcpdm_data *mcpdm_priv = snd_soc_dai_get_drvdata(dai); | 360 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
| 182 | struct omap_mcpdm_link *mcpdm_links = mcpdm_priv->links; | ||
| 183 | int stream = substream->stream; | ||
| 184 | int err; | ||
| 185 | 361 | ||
| 186 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 362 | if (!omap_mcpdm_active(mcpdm)) { |
| 187 | err = omap_mcpdm_playback_close(&mcpdm_links[stream]); | 363 | omap_mcpdm_start(mcpdm); |
| 188 | else | 364 | omap_mcpdm_reg_dump(mcpdm); |
| 189 | err = omap_mcpdm_capture_close(&mcpdm_links[stream]); | 365 | } |
| 190 | 366 | ||
| 191 | return err; | 367 | return 0; |
| 192 | } | 368 | } |
| 193 | 369 | ||
| 194 | static struct snd_soc_dai_ops omap_mcpdm_dai_ops = { | 370 | static struct snd_soc_dai_ops omap_mcpdm_dai_ops = { |
| 195 | .startup = omap_mcpdm_dai_startup, | 371 | .startup = omap_mcpdm_dai_startup, |
| 196 | .shutdown = omap_mcpdm_dai_shutdown, | 372 | .shutdown = omap_mcpdm_dai_shutdown, |
| 197 | .trigger = omap_mcpdm_dai_trigger, | ||
| 198 | .hw_params = omap_mcpdm_dai_hw_params, | 373 | .hw_params = omap_mcpdm_dai_hw_params, |
| 199 | .hw_free = omap_mcpdm_dai_hw_free, | 374 | .prepare = omap_mcpdm_prepare, |
| 200 | }; | 375 | }; |
| 201 | 376 | ||
| 202 | #define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | 377 | static int omap_mcpdm_probe(struct snd_soc_dai *dai) |
| 203 | #define OMAP_MCPDM_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) | 378 | { |
| 379 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); | ||
| 380 | int ret; | ||
| 204 | 381 | ||
| 205 | static int omap_mcpdm_dai_probe(struct snd_soc_dai *dai) | 382 | pm_runtime_enable(mcpdm->dev); |
| 383 | |||
| 384 | /* Disable lines while request is ongoing */ | ||
| 385 | pm_runtime_get_sync(mcpdm->dev); | ||
| 386 | omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, 0x00); | ||
| 387 | |||
| 388 | ret = request_irq(mcpdm->irq, omap_mcpdm_irq_handler, | ||
| 389 | 0, "McPDM", (void *)mcpdm); | ||
| 390 | |||
| 391 | pm_runtime_put_sync(mcpdm->dev); | ||
| 392 | |||
| 393 | if (ret) { | ||
| 394 | dev_err(mcpdm->dev, "Request for IRQ failed\n"); | ||
| 395 | pm_runtime_disable(mcpdm->dev); | ||
| 396 | } | ||
| 397 | |||
| 398 | /* Configure McPDM threshold values */ | ||
| 399 | mcpdm->dn_threshold = 2; | ||
| 400 | mcpdm->up_threshold = MCPDM_UP_THRES_MAX - 3; | ||
| 401 | return ret; | ||
| 402 | } | ||
| 403 | |||
| 404 | static int omap_mcpdm_remove(struct snd_soc_dai *dai) | ||
| 206 | { | 405 | { |
| 207 | snd_soc_dai_set_drvdata(dai, &mcpdm_data); | 406 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); |
| 407 | |||
| 408 | free_irq(mcpdm->irq, (void *)mcpdm); | ||
| 409 | pm_runtime_disable(mcpdm->dev); | ||
| 410 | |||
| 208 | return 0; | 411 | return 0; |
| 209 | } | 412 | } |
| 210 | 413 | ||
| 414 | #define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) | ||
| 415 | #define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE | ||
| 416 | |||
| 211 | static struct snd_soc_dai_driver omap_mcpdm_dai = { | 417 | static struct snd_soc_dai_driver omap_mcpdm_dai = { |
| 212 | .probe = omap_mcpdm_dai_probe, | 418 | .probe = omap_mcpdm_probe, |
| 419 | .remove = omap_mcpdm_remove, | ||
| 420 | .probe_order = SND_SOC_COMP_ORDER_LATE, | ||
| 421 | .remove_order = SND_SOC_COMP_ORDER_EARLY, | ||
| 213 | .playback = { | 422 | .playback = { |
| 214 | .channels_min = 1, | 423 | .channels_min = 1, |
| 215 | .channels_max = 4, | 424 | .channels_max = 5, |
| 216 | .rates = OMAP_MCPDM_RATES, | 425 | .rates = OMAP_MCPDM_RATES, |
| 217 | .formats = OMAP_MCPDM_FORMATS, | 426 | .formats = OMAP_MCPDM_FORMATS, |
| 218 | }, | 427 | }, |
| 219 | .capture = { | 428 | .capture = { |
| 220 | .channels_min = 1, | 429 | .channels_min = 1, |
| 221 | .channels_max = 2, | 430 | .channels_max = 3, |
| 222 | .rates = OMAP_MCPDM_RATES, | 431 | .rates = OMAP_MCPDM_RATES, |
| 223 | .formats = OMAP_MCPDM_FORMATS, | 432 | .formats = OMAP_MCPDM_FORMATS, |
| 224 | }, | 433 | }, |
| 225 | .ops = &omap_mcpdm_dai_ops, | 434 | .ops = &omap_mcpdm_dai_ops, |
| 226 | }; | 435 | }; |
| 227 | 436 | ||
| 437 | void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, | ||
| 438 | u8 rx1, u8 rx2) | ||
| 439 | { | ||
| 440 | struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(rtd->cpu_dai); | ||
| 441 | |||
| 442 | mcpdm->dn_rx_offset = MCPDM_DNOFST_RX1(rx1) | MCPDM_DNOFST_RX2(rx2); | ||
| 443 | } | ||
| 444 | EXPORT_SYMBOL_GPL(omap_mcpdm_configure_dn_offsets); | ||
| 445 | |||
| 228 | static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) | 446 | static __devinit int asoc_mcpdm_probe(struct platform_device *pdev) |
| 229 | { | 447 | { |
| 230 | int ret; | 448 | struct omap_mcpdm *mcpdm; |
| 449 | struct resource *res; | ||
| 450 | int ret = 0; | ||
| 451 | |||
| 452 | mcpdm = kzalloc(sizeof(struct omap_mcpdm), GFP_KERNEL); | ||
| 453 | if (!mcpdm) | ||
| 454 | return -ENOMEM; | ||
| 455 | |||
| 456 | platform_set_drvdata(pdev, mcpdm); | ||
| 457 | |||
| 458 | mutex_init(&mcpdm->mutex); | ||
| 459 | |||
| 460 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 461 | if (res == NULL) { | ||
| 462 | dev_err(&pdev->dev, "no resource\n"); | ||
| 463 | goto err_res; | ||
| 464 | } | ||
| 465 | |||
| 466 | if (!request_mem_region(res->start, resource_size(res), "McPDM")) { | ||
| 467 | ret = -EBUSY; | ||
| 468 | goto err_res; | ||
| 469 | } | ||
| 470 | |||
| 471 | mcpdm->io_base = ioremap(res->start, resource_size(res)); | ||
| 472 | if (!mcpdm->io_base) { | ||
| 473 | ret = -ENOMEM; | ||
| 474 | goto err_iomap; | ||
| 475 | } | ||
| 476 | |||
| 477 | mcpdm->irq = platform_get_irq(pdev, 0); | ||
| 478 | if (mcpdm->irq < 0) { | ||
| 479 | ret = mcpdm->irq; | ||
| 480 | goto err_irq; | ||
| 481 | } | ||
| 482 | |||
| 483 | mcpdm->dev = &pdev->dev; | ||
| 231 | 484 | ||
| 232 | ret = omap_mcpdm_probe(pdev); | ||
| 233 | if (ret < 0) | ||
| 234 | return ret; | ||
| 235 | ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); | 485 | ret = snd_soc_register_dai(&pdev->dev, &omap_mcpdm_dai); |
| 236 | if (ret < 0) | 486 | if (!ret) |
| 237 | omap_mcpdm_remove(pdev); | 487 | return 0; |
| 488 | |||
| 489 | err_irq: | ||
| 490 | iounmap(mcpdm->io_base); | ||
| 491 | err_iomap: | ||
| 492 | release_mem_region(res->start, resource_size(res)); | ||
| 493 | err_res: | ||
| 494 | kfree(mcpdm); | ||
| 238 | return ret; | 495 | return ret; |
| 239 | } | 496 | } |
| 240 | 497 | ||
| 241 | static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) | 498 | static int __devexit asoc_mcpdm_remove(struct platform_device *pdev) |
| 242 | { | 499 | { |
| 500 | struct omap_mcpdm *mcpdm = platform_get_drvdata(pdev); | ||
| 501 | struct resource *res; | ||
| 502 | |||
| 243 | snd_soc_unregister_dai(&pdev->dev); | 503 | snd_soc_unregister_dai(&pdev->dev); |
| 244 | omap_mcpdm_remove(pdev); | 504 | |
| 505 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 506 | iounmap(mcpdm->io_base); | ||
| 507 | release_mem_region(res->start, resource_size(res)); | ||
| 508 | |||
| 509 | kfree(mcpdm); | ||
| 245 | return 0; | 510 | return 0; |
| 246 | } | 511 | } |
| 247 | 512 | ||
| 248 | static struct platform_driver asoc_mcpdm_driver = { | 513 | static struct platform_driver asoc_mcpdm_driver = { |
| 249 | .driver = { | 514 | .driver = { |
| 250 | .name = "omap-mcpdm-dai", | 515 | .name = "omap-mcpdm", |
| 251 | .owner = THIS_MODULE, | 516 | .owner = THIS_MODULE, |
| 252 | }, | 517 | }, |
| 253 | 518 | ||
| 254 | .probe = asoc_mcpdm_probe, | 519 | .probe = asoc_mcpdm_probe, |
| 255 | .remove = __devexit_p(asoc_mcpdm_remove), | 520 | .remove = __devexit_p(asoc_mcpdm_remove), |
| 256 | }; | 521 | }; |
| 257 | 522 | ||
| 258 | static int __init snd_omap_mcpdm_init(void) | 523 | static int __init snd_omap_mcpdm_init(void) |
| @@ -267,6 +532,6 @@ static void __exit snd_omap_mcpdm_exit(void) | |||
| 267 | } | 532 | } |
| 268 | module_exit(snd_omap_mcpdm_exit); | 533 | module_exit(snd_omap_mcpdm_exit); |
| 269 | 534 | ||
| 270 | MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>"); | 535 | MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); |
| 271 | MODULE_DESCRIPTION("OMAP PDM SoC Interface"); | 536 | MODULE_DESCRIPTION("OMAP PDM SoC Interface"); |
| 272 | MODULE_LICENSE("GPL"); | 537 | MODULE_LICENSE("GPL"); |
diff --git a/sound/soc/omap/omap-mcpdm.h b/sound/soc/omap/omap-mcpdm.h new file mode 100644 index 000000000000..de8cf26595b1 --- /dev/null +++ b/sound/soc/omap/omap-mcpdm.h | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /* | ||
| 2 | * omap-mcpdm.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 - 2011 Texas Instruments | ||
| 5 | * | ||
| 6 | * Contact: Misael Lopez Cruz <misael.lopez@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 | * You should have received a copy of the GNU General Public License | ||
| 18 | * along with this program; if not, write to the Free Software | ||
| 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
| 20 | * 02110-1301 USA | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef __OMAP_MCPDM_H__ | ||
| 25 | #define __OMAP_MCPDM_H__ | ||
| 26 | |||
| 27 | #define MCPDM_REG_REVISION 0x00 | ||
| 28 | #define MCPDM_REG_SYSCONFIG 0x10 | ||
| 29 | #define MCPDM_REG_IRQSTATUS_RAW 0x24 | ||
| 30 | #define MCPDM_REG_IRQSTATUS 0x28 | ||
| 31 | #define MCPDM_REG_IRQENABLE_SET 0x2C | ||
| 32 | #define MCPDM_REG_IRQENABLE_CLR 0x30 | ||
| 33 | #define MCPDM_REG_IRQWAKE_EN 0x34 | ||
| 34 | #define MCPDM_REG_DMAENABLE_SET 0x38 | ||
| 35 | #define MCPDM_REG_DMAENABLE_CLR 0x3C | ||
| 36 | #define MCPDM_REG_DMAWAKEEN 0x40 | ||
| 37 | #define MCPDM_REG_CTRL 0x44 | ||
| 38 | #define MCPDM_REG_DN_DATA 0x48 | ||
| 39 | #define MCPDM_REG_UP_DATA 0x4C | ||
| 40 | #define MCPDM_REG_FIFO_CTRL_DN 0x50 | ||
| 41 | #define MCPDM_REG_FIFO_CTRL_UP 0x54 | ||
| 42 | #define MCPDM_REG_DN_OFFSET 0x58 | ||
| 43 | |||
| 44 | /* | ||
| 45 | * MCPDM_IRQ bit fields | ||
| 46 | * IRQSTATUS_RAW, IRQSTATUS, IRQENABLE_SET, IRQENABLE_CLR | ||
| 47 | */ | ||
| 48 | |||
| 49 | #define MCPDM_DN_IRQ (1 << 0) | ||
| 50 | #define MCPDM_DN_IRQ_EMPTY (1 << 1) | ||
| 51 | #define MCPDM_DN_IRQ_ALMST_EMPTY (1 << 2) | ||
| 52 | #define MCPDM_DN_IRQ_FULL (1 << 3) | ||
| 53 | |||
| 54 | #define MCPDM_UP_IRQ (1 << 8) | ||
| 55 | #define MCPDM_UP_IRQ_EMPTY (1 << 9) | ||
| 56 | #define MCPDM_UP_IRQ_ALMST_FULL (1 << 10) | ||
| 57 | #define MCPDM_UP_IRQ_FULL (1 << 11) | ||
| 58 | |||
| 59 | #define MCPDM_DOWNLINK_IRQ_MASK 0x00F | ||
| 60 | #define MCPDM_UPLINK_IRQ_MASK 0xF00 | ||
| 61 | |||
| 62 | /* | ||
| 63 | * MCPDM_DMAENABLE bit fields | ||
| 64 | */ | ||
| 65 | |||
| 66 | #define MCPDM_DMA_DN_ENABLE (1 << 0) | ||
| 67 | #define MCPDM_DMA_UP_ENABLE (1 << 1) | ||
| 68 | |||
| 69 | /* | ||
| 70 | * MCPDM_CTRL bit fields | ||
| 71 | */ | ||
| 72 | |||
| 73 | #define MCPDM_PDM_UPLINK_EN(x) (1 << (x - 1)) /* ch1 is at bit 0 */ | ||
| 74 | #define MCPDM_PDM_DOWNLINK_EN(x) (1 << (x + 2)) /* ch1 is at bit 3 */ | ||
| 75 | #define MCPDM_PDMOUTFORMAT (1 << 8) | ||
| 76 | #define MCPDM_CMD_INT (1 << 9) | ||
| 77 | #define MCPDM_STATUS_INT (1 << 10) | ||
| 78 | #define MCPDM_SW_UP_RST (1 << 11) | ||
| 79 | #define MCPDM_SW_DN_RST (1 << 12) | ||
| 80 | #define MCPDM_WD_EN (1 << 14) | ||
| 81 | #define MCPDM_PDM_UP_MASK 0x7 | ||
| 82 | #define MCPDM_PDM_DN_MASK (0x1f << 3) | ||
| 83 | |||
| 84 | |||
| 85 | #define MCPDM_PDMOUTFORMAT_LJUST (0 << 8) | ||
| 86 | #define MCPDM_PDMOUTFORMAT_RJUST (1 << 8) | ||
| 87 | |||
| 88 | /* | ||
| 89 | * MCPDM_FIFO_CTRL bit fields | ||
| 90 | */ | ||
| 91 | |||
| 92 | #define MCPDM_UP_THRES_MAX 0xF | ||
| 93 | #define MCPDM_DN_THRES_MAX 0xF | ||
| 94 | |||
| 95 | /* | ||
| 96 | * MCPDM_DN_OFFSET bit fields | ||
| 97 | */ | ||
| 98 | |||
| 99 | #define MCPDM_DN_OFST_RX1_EN (1 << 0) | ||
| 100 | #define MCPDM_DNOFST_RX1(x) ((x & 0x1f) << 1) | ||
| 101 | #define MCPDM_DN_OFST_RX2_EN (1 << 8) | ||
| 102 | #define MCPDM_DNOFST_RX2(x) ((x & 0x1f) << 9) | ||
| 103 | |||
| 104 | void omap_mcpdm_configure_dn_offsets(struct snd_soc_pcm_runtime *rtd, | ||
| 105 | u8 rx1, u8 rx2); | ||
| 106 | |||
| 107 | #endif /* End of __OMAP_MCPDM_H__ */ | ||
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 9b5c88ac35b9..5e37ec915de2 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
| @@ -198,6 +198,14 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
| 198 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); | 198 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); |
| 199 | else if (!substream->runtime->no_period_wakeup) | 199 | else if (!substream->runtime->no_period_wakeup) |
| 200 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); | 200 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); |
| 201 | else { | ||
| 202 | /* | ||
| 203 | * No period wakeup: | ||
| 204 | * we need to disable BLOCK_IRQ, which is enabled by the omap | ||
| 205 | * dma core at request dma time. | ||
| 206 | */ | ||
| 207 | omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ); | ||
| 208 | } | ||
| 201 | 209 | ||
| 202 | if (!(cpu_class_is_omap1())) { | 210 | if (!(cpu_class_is_omap1())) { |
| 203 | omap_set_dma_src_burst_mode(prtd->dma_ch, | 211 | omap_set_dma_src_burst_mode(prtd->dma_ch, |
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c index 0daa04469836..bf9ae2a6f901 100644 --- a/sound/soc/omap/omap3evm.c +++ b/sound/soc/omap/omap3evm.c | |||
| @@ -36,29 +36,8 @@ static int omap3evm_hw_params(struct snd_pcm_substream *substream, | |||
| 36 | { | 36 | { |
| 37 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 37 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 38 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 38 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 39 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 40 | int ret; | 39 | int ret; |
| 41 | 40 | ||
| 42 | /* Set codec DAI configuration */ | ||
| 43 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 44 | SND_SOC_DAIFMT_I2S | | ||
| 45 | SND_SOC_DAIFMT_NB_NF | | ||
| 46 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 47 | if (ret < 0) { | ||
| 48 | printk(KERN_ERR "Can't set codec DAI configuration\n"); | ||
| 49 | return ret; | ||
| 50 | } | ||
| 51 | |||
| 52 | /* Set cpu DAI configuration */ | ||
| 53 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 54 | SND_SOC_DAIFMT_I2S | | ||
| 55 | SND_SOC_DAIFMT_NB_NF | | ||
| 56 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 57 | if (ret < 0) { | ||
| 58 | printk(KERN_ERR "Can't set cpu DAI configuration\n"); | ||
| 59 | return ret; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* Set the codec system clock for DAC and ADC */ | 41 | /* Set the codec system clock for DAC and ADC */ |
| 63 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | 42 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, |
| 64 | SND_SOC_CLOCK_IN); | 43 | SND_SOC_CLOCK_IN); |
| @@ -82,6 +61,8 @@ static struct snd_soc_dai_link omap3evm_dai = { | |||
| 82 | .codec_dai_name = "twl4030-hifi", | 61 | .codec_dai_name = "twl4030-hifi", |
| 83 | .platform_name = "omap-pcm-audio", | 62 | .platform_name = "omap-pcm-audio", |
| 84 | .codec_name = "twl4030-codec", | 63 | .codec_name = "twl4030-codec", |
| 64 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 65 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 85 | .ops = &omap3evm_ops, | 66 | .ops = &omap3evm_ops, |
| 86 | }; | 67 | }; |
| 87 | 68 | ||
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 8047c521e318..30a75b406aea 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c | |||
| @@ -48,24 +48,8 @@ static int omap3pandora_hw_params(struct snd_pcm_substream *substream, | |||
| 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_dai *cpu_dai = rtd->cpu_dai; | 50 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 51 | int fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 52 | SND_SOC_DAIFMT_CBS_CFS; | ||
| 53 | int ret; | 51 | int ret; |
| 54 | 52 | ||
| 55 | /* Set codec DAI configuration */ | ||
| 56 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
| 57 | if (ret < 0) { | ||
| 58 | pr_err(PREFIX "can't set codec DAI configuration\n"); | ||
| 59 | return ret; | ||
| 60 | } | ||
| 61 | |||
| 62 | /* Set cpu DAI configuration */ | ||
| 63 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
| 64 | if (ret < 0) { | ||
| 65 | pr_err(PREFIX "can't set cpu DAI configuration\n"); | ||
| 66 | return ret; | ||
| 67 | } | ||
| 68 | |||
| 69 | /* Set the codec system clock for DAC and ADC */ | 53 | /* Set the codec system clock for DAC and ADC */ |
| 70 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | 54 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, |
| 71 | SND_SOC_CLOCK_IN); | 55 | SND_SOC_CLOCK_IN); |
| @@ -189,10 +173,8 @@ static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) | |||
| 189 | if (ret < 0) | 173 | if (ret < 0) |
| 190 | return ret; | 174 | return ret; |
| 191 | 175 | ||
| 192 | snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, | 176 | return snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, |
| 193 | ARRAY_SIZE(omap3pandora_out_map)); | 177 | ARRAY_SIZE(omap3pandora_out_map)); |
| 194 | |||
| 195 | return snd_soc_dapm_sync(dapm); | ||
| 196 | } | 178 | } |
| 197 | 179 | ||
| 198 | static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) | 180 | static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) |
| @@ -212,10 +194,8 @@ static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) | |||
| 212 | if (ret < 0) | 194 | if (ret < 0) |
| 213 | return ret; | 195 | return ret; |
| 214 | 196 | ||
| 215 | snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, | 197 | return snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, |
| 216 | ARRAY_SIZE(omap3pandora_in_map)); | 198 | ARRAY_SIZE(omap3pandora_in_map)); |
| 217 | |||
| 218 | return snd_soc_dapm_sync(dapm); | ||
| 219 | } | 199 | } |
| 220 | 200 | ||
| 221 | static struct snd_soc_ops omap3pandora_ops = { | 201 | static struct snd_soc_ops omap3pandora_ops = { |
| @@ -231,6 +211,8 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
| 231 | .codec_dai_name = "twl4030-hifi", | 211 | .codec_dai_name = "twl4030-hifi", |
| 232 | .platform_name = "omap-pcm-audio", | 212 | .platform_name = "omap-pcm-audio", |
| 233 | .codec_name = "twl4030-codec", | 213 | .codec_name = "twl4030-codec", |
| 214 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 215 | SND_SOC_DAIFMT_CBS_CFS, | ||
| 234 | .ops = &omap3pandora_ops, | 216 | .ops = &omap3pandora_ops, |
| 235 | .init = omap3pandora_out_init, | 217 | .init = omap3pandora_out_init, |
| 236 | }, { | 218 | }, { |
| @@ -240,6 +222,8 @@ static struct snd_soc_dai_link omap3pandora_dai[] = { | |||
| 240 | .codec_dai_name = "twl4030-hifi", | 222 | .codec_dai_name = "twl4030-hifi", |
| 241 | .platform_name = "omap-pcm-audio", | 223 | .platform_name = "omap-pcm-audio", |
| 242 | .codec_name = "twl4030-codec", | 224 | .codec_name = "twl4030-codec", |
| 225 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 226 | SND_SOC_DAIFMT_CBS_CFS, | ||
| 243 | .ops = &omap3pandora_ops, | 227 | .ops = &omap3pandora_ops, |
| 244 | .init = omap3pandora_in_init, | 228 | .init = omap3pandora_in_init, |
| 245 | } | 229 | } |
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index 7e75e775fb4a..db91ccaf6c97 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c | |||
| @@ -55,29 +55,8 @@ static int osk_hw_params(struct snd_pcm_substream *substream, | |||
| 55 | { | 55 | { |
| 56 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 56 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 57 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 57 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 58 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 59 | int err; | 58 | int err; |
| 60 | 59 | ||
| 61 | /* Set codec DAI configuration */ | ||
| 62 | err = snd_soc_dai_set_fmt(codec_dai, | ||
| 63 | SND_SOC_DAIFMT_DSP_B | | ||
| 64 | SND_SOC_DAIFMT_NB_NF | | ||
| 65 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 66 | if (err < 0) { | ||
| 67 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 68 | return err; | ||
| 69 | } | ||
| 70 | |||
| 71 | /* Set cpu DAI configuration */ | ||
| 72 | err = snd_soc_dai_set_fmt(cpu_dai, | ||
| 73 | SND_SOC_DAIFMT_DSP_B | | ||
| 74 | SND_SOC_DAIFMT_NB_NF | | ||
| 75 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 76 | if (err < 0) { | ||
| 77 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 78 | return err; | ||
| 79 | } | ||
| 80 | |||
| 81 | /* Set the codec system clock for DAC and ADC */ | 60 | /* Set the codec system clock for DAC and ADC */ |
| 82 | err = | 61 | err = |
| 83 | snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); | 62 | snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, SND_SOC_CLOCK_IN); |
| @@ -112,27 +91,6 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 112 | {"MICIN", NULL, "Mic Jack"}, | 91 | {"MICIN", NULL, "Mic Jack"}, |
| 113 | }; | 92 | }; |
| 114 | 93 | ||
| 115 | static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | ||
| 116 | { | ||
| 117 | struct snd_soc_codec *codec = rtd->codec; | ||
| 118 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 119 | |||
| 120 | /* Add osk5912 specific widgets */ | ||
| 121 | snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, | ||
| 122 | ARRAY_SIZE(tlv320aic23_dapm_widgets)); | ||
| 123 | |||
| 124 | /* Set up osk5912 specific audio path audio_map */ | ||
| 125 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 126 | |||
| 127 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | ||
| 128 | snd_soc_dapm_enable_pin(dapm, "Line In"); | ||
| 129 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | ||
| 130 | |||
| 131 | snd_soc_dapm_sync(dapm); | ||
| 132 | |||
| 133 | return 0; | ||
| 134 | } | ||
| 135 | |||
| 136 | /* Digital audio interface glue - connects codec <--> CPU */ | 94 | /* Digital audio interface glue - connects codec <--> CPU */ |
| 137 | static struct snd_soc_dai_link osk_dai = { | 95 | static struct snd_soc_dai_link osk_dai = { |
| 138 | .name = "TLV320AIC23", | 96 | .name = "TLV320AIC23", |
| @@ -141,7 +99,8 @@ static struct snd_soc_dai_link osk_dai = { | |||
| 141 | .codec_dai_name = "tlv320aic23-hifi", | 99 | .codec_dai_name = "tlv320aic23-hifi", |
| 142 | .platform_name = "omap-pcm-audio", | 100 | .platform_name = "omap-pcm-audio", |
| 143 | .codec_name = "tlv320aic23-codec", | 101 | .codec_name = "tlv320aic23-codec", |
| 144 | .init = osk_tlv320aic23_init, | 102 | .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | |
| 103 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 145 | .ops = &osk_ops, | 104 | .ops = &osk_ops, |
| 146 | }; | 105 | }; |
| 147 | 106 | ||
| @@ -150,6 +109,11 @@ static struct snd_soc_card snd_soc_card_osk = { | |||
| 150 | .name = "OSK5912", | 109 | .name = "OSK5912", |
| 151 | .dai_link = &osk_dai, | 110 | .dai_link = &osk_dai, |
| 152 | .num_links = 1, | 111 | .num_links = 1, |
| 112 | |||
| 113 | .dapm_widgets = tlv320aic23_dapm_widgets, | ||
| 114 | .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), | ||
| 115 | .dapm_routes = audio_map, | ||
| 116 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 153 | }; | 117 | }; |
| 154 | 118 | ||
| 155 | static struct platform_device *osk_snd_device; | 119 | static struct platform_device *osk_snd_device; |
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index bbcf380bfb56..739efe9e327a 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c | |||
| @@ -38,29 +38,8 @@ static int overo_hw_params(struct snd_pcm_substream *substream, | |||
| 38 | { | 38 | { |
| 39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 39 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 40 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 40 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 41 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 42 | int ret; | 41 | int ret; |
| 43 | 42 | ||
| 44 | /* Set codec DAI configuration */ | ||
| 45 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 46 | SND_SOC_DAIFMT_I2S | | ||
| 47 | SND_SOC_DAIFMT_NB_NF | | ||
| 48 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 49 | if (ret < 0) { | ||
| 50 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 51 | return ret; | ||
| 52 | } | ||
| 53 | |||
| 54 | /* Set cpu DAI configuration */ | ||
| 55 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 56 | SND_SOC_DAIFMT_I2S | | ||
| 57 | SND_SOC_DAIFMT_NB_NF | | ||
| 58 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 59 | if (ret < 0) { | ||
| 60 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 61 | return ret; | ||
| 62 | } | ||
| 63 | |||
| 64 | /* Set the codec system clock for DAC and ADC */ | 43 | /* Set the codec system clock for DAC and ADC */ |
| 65 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | 44 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, |
| 66 | SND_SOC_CLOCK_IN); | 45 | SND_SOC_CLOCK_IN); |
| @@ -84,6 +63,8 @@ static struct snd_soc_dai_link overo_dai = { | |||
| 84 | .codec_dai_name = "twl4030-hifi", | 63 | .codec_dai_name = "twl4030-hifi", |
| 85 | .platform_name = "omap-pcm-audio", | 64 | .platform_name = "omap-pcm-audio", |
| 86 | .codec_name = "twl4030-codec", | 65 | .codec_name = "twl4030-codec", |
| 66 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 67 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 87 | .ops = &overo_ops, | 68 | .ops = &overo_ops, |
| 88 | }; | 69 | }; |
| 89 | 70 | ||
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 893300a53bab..a56842380c72 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c | |||
| @@ -115,24 +115,6 @@ static int rx51_hw_params(struct snd_pcm_substream *substream, | |||
| 115 | { | 115 | { |
| 116 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 116 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 117 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 117 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 118 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 119 | int err; | ||
| 120 | |||
| 121 | /* Set codec DAI configuration */ | ||
| 122 | err = snd_soc_dai_set_fmt(codec_dai, | ||
| 123 | SND_SOC_DAIFMT_DSP_A | | ||
| 124 | SND_SOC_DAIFMT_IB_NF | | ||
| 125 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 126 | if (err < 0) | ||
| 127 | return err; | ||
| 128 | |||
| 129 | /* Set cpu DAI configuration */ | ||
| 130 | err = snd_soc_dai_set_fmt(cpu_dai, | ||
| 131 | SND_SOC_DAIFMT_DSP_A | | ||
| 132 | SND_SOC_DAIFMT_IB_NF | | ||
| 133 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 134 | if (err < 0) | ||
| 135 | return err; | ||
| 136 | 118 | ||
| 137 | /* Set the codec system clock for DAC and ADC */ | 119 | /* Set the codec system clock for DAC and ADC */ |
| 138 | return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000, | 120 | return snd_soc_dai_set_sysclk(codec_dai, 0, 19200000, |
| @@ -335,8 +317,6 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) | |||
| 335 | if (err < 0) | 317 | if (err < 0) |
| 336 | return err; | 318 | return err; |
| 337 | 319 | ||
| 338 | snd_soc_dapm_sync(dapm); | ||
| 339 | |||
| 340 | /* AV jack detection */ | 320 | /* AV jack detection */ |
| 341 | err = snd_soc_jack_new(codec, "AV Jack", | 321 | err = snd_soc_jack_new(codec, "AV Jack", |
| 342 | SND_JACK_HEADSET | SND_JACK_VIDEOOUT, | 322 | SND_JACK_HEADSET | SND_JACK_VIDEOOUT, |
| @@ -377,6 +357,8 @@ static struct snd_soc_dai_link rx51_dai[] = { | |||
| 377 | .codec_dai_name = "tlv320aic3x-hifi", | 357 | .codec_dai_name = "tlv320aic3x-hifi", |
| 378 | .platform_name = "omap-pcm-audio", | 358 | .platform_name = "omap-pcm-audio", |
| 379 | .codec_name = "tlv320aic3x-codec.2-0018", | 359 | .codec_name = "tlv320aic3x-codec.2-0018", |
| 360 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | | ||
| 361 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 380 | .init = rx51_aic34_init, | 362 | .init = rx51_aic34_init, |
| 381 | .ops = &rx51_ops, | 363 | .ops = &rx51_ops, |
| 382 | }, | 364 | }, |
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 9f6a758029d1..4f1969de91a7 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c | |||
| @@ -53,29 +53,8 @@ static int sdp3430_hw_params(struct snd_pcm_substream *substream, | |||
| 53 | { | 53 | { |
| 54 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 54 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 55 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 55 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 56 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 57 | int ret; | 56 | int ret; |
| 58 | 57 | ||
| 59 | /* Set codec DAI configuration */ | ||
| 60 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 61 | SND_SOC_DAIFMT_I2S | | ||
| 62 | SND_SOC_DAIFMT_NB_NF | | ||
| 63 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 64 | if (ret < 0) { | ||
| 65 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 66 | return ret; | ||
| 67 | } | ||
| 68 | |||
| 69 | /* Set cpu DAI configuration */ | ||
| 70 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 71 | SND_SOC_DAIFMT_I2S | | ||
| 72 | SND_SOC_DAIFMT_NB_NF | | ||
| 73 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 74 | if (ret < 0) { | ||
| 75 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 76 | return ret; | ||
| 77 | } | ||
| 78 | |||
| 79 | /* Set the codec system clock for DAC and ADC */ | 58 | /* Set the codec system clock for DAC and ADC */ |
| 80 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | 59 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, |
| 81 | SND_SOC_CLOCK_IN); | 60 | SND_SOC_CLOCK_IN); |
| @@ -91,49 +70,6 @@ static struct snd_soc_ops sdp3430_ops = { | |||
| 91 | .hw_params = sdp3430_hw_params, | 70 | .hw_params = sdp3430_hw_params, |
| 92 | }; | 71 | }; |
| 93 | 72 | ||
| 94 | static int sdp3430_hw_voice_params(struct snd_pcm_substream *substream, | ||
| 95 | struct snd_pcm_hw_params *params) | ||
| 96 | { | ||
| 97 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 98 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 99 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 100 | int ret; | ||
| 101 | |||
| 102 | /* Set codec DAI configuration */ | ||
| 103 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 104 | SND_SOC_DAIFMT_DSP_A | | ||
| 105 | SND_SOC_DAIFMT_IB_NF | | ||
| 106 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 107 | if (ret) { | ||
| 108 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 112 | /* Set cpu DAI configuration */ | ||
| 113 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 114 | SND_SOC_DAIFMT_DSP_A | | ||
| 115 | SND_SOC_DAIFMT_IB_NF | | ||
| 116 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 117 | if (ret < 0) { | ||
| 118 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 119 | return ret; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* Set the codec system clock for DAC and ADC */ | ||
| 123 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
| 124 | SND_SOC_CLOCK_IN); | ||
| 125 | if (ret < 0) { | ||
| 126 | printk(KERN_ERR "can't set codec system clock\n"); | ||
| 127 | return ret; | ||
| 128 | } | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 133 | static struct snd_soc_ops sdp3430_voice_ops = { | ||
| 134 | .hw_params = sdp3430_hw_voice_params, | ||
| 135 | }; | ||
| 136 | |||
| 137 | /* Headset jack */ | 73 | /* Headset jack */ |
| 138 | static struct snd_soc_jack hs_jack; | 74 | static struct snd_soc_jack hs_jack; |
| 139 | 75 | ||
| @@ -193,15 +129,6 @@ static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd) | |||
| 193 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 129 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 194 | int ret; | 130 | int ret; |
| 195 | 131 | ||
| 196 | /* Add SDP3430 specific widgets */ | ||
| 197 | ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets, | ||
| 198 | ARRAY_SIZE(sdp3430_twl4030_dapm_widgets)); | ||
| 199 | if (ret) | ||
| 200 | return ret; | ||
| 201 | |||
| 202 | /* Set up SDP3430 specific audio path audio_map */ | ||
| 203 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 204 | |||
| 205 | /* SDP3430 connected pins */ | 132 | /* SDP3430 connected pins */ |
| 206 | snd_soc_dapm_enable_pin(dapm, "Ext Mic"); | 133 | snd_soc_dapm_enable_pin(dapm, "Ext Mic"); |
| 207 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 134 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); |
| @@ -223,10 +150,6 @@ static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd) | |||
| 223 | snd_soc_dapm_nc_pin(dapm, "CARKITL"); | 150 | snd_soc_dapm_nc_pin(dapm, "CARKITL"); |
| 224 | snd_soc_dapm_nc_pin(dapm, "CARKITR"); | 151 | snd_soc_dapm_nc_pin(dapm, "CARKITR"); |
| 225 | 152 | ||
| 226 | ret = snd_soc_dapm_sync(dapm); | ||
| 227 | if (ret) | ||
| 228 | return ret; | ||
| 229 | |||
| 230 | /* Headset jack detection */ | 153 | /* Headset jack detection */ |
| 231 | ret = snd_soc_jack_new(codec, "Headset Jack", | 154 | ret = snd_soc_jack_new(codec, "Headset Jack", |
| 232 | SND_JACK_HEADSET, &hs_jack); | 155 | SND_JACK_HEADSET, &hs_jack); |
| @@ -267,6 +190,8 @@ static struct snd_soc_dai_link sdp3430_dai[] = { | |||
| 267 | .codec_dai_name = "twl4030-hifi", | 190 | .codec_dai_name = "twl4030-hifi", |
| 268 | .platform_name = "omap-pcm-audio", | 191 | .platform_name = "omap-pcm-audio", |
| 269 | .codec_name = "twl4030-codec", | 192 | .codec_name = "twl4030-codec", |
| 193 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 194 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 270 | .init = sdp3430_twl4030_init, | 195 | .init = sdp3430_twl4030_init, |
| 271 | .ops = &sdp3430_ops, | 196 | .ops = &sdp3430_ops, |
| 272 | }, | 197 | }, |
| @@ -277,8 +202,10 @@ static struct snd_soc_dai_link sdp3430_dai[] = { | |||
| 277 | .codec_dai_name = "twl4030-voice", | 202 | .codec_dai_name = "twl4030-voice", |
| 278 | .platform_name = "omap-pcm-audio", | 203 | .platform_name = "omap-pcm-audio", |
| 279 | .codec_name = "twl4030-codec", | 204 | .codec_name = "twl4030-codec", |
| 205 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | | ||
| 206 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 280 | .init = sdp3430_twl4030_voice_init, | 207 | .init = sdp3430_twl4030_voice_init, |
| 281 | .ops = &sdp3430_voice_ops, | 208 | .ops = &sdp3430_ops, |
| 282 | }, | 209 | }, |
| 283 | }; | 210 | }; |
| 284 | 211 | ||
| @@ -287,6 +214,11 @@ static struct snd_soc_card snd_soc_sdp3430 = { | |||
| 287 | .name = "SDP3430", | 214 | .name = "SDP3430", |
| 288 | .dai_link = sdp3430_dai, | 215 | .dai_link = sdp3430_dai, |
| 289 | .num_links = ARRAY_SIZE(sdp3430_dai), | 216 | .num_links = ARRAY_SIZE(sdp3430_dai), |
| 217 | |||
| 218 | .dapm_widgets = sdp3430_twl4030_dapm_widgets, | ||
| 219 | .num_dapm_widgets = ARRAY_SIZE(sdp3430_twl4030_dapm_widgets), | ||
| 220 | .dapm_routes = audio_map, | ||
| 221 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 290 | }; | 222 | }; |
| 291 | 223 | ||
| 292 | static struct platform_device *sdp3430_snd_device; | 224 | static struct platform_device *sdp3430_snd_device; |
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index b80efb02bfca..cc3d792af5ea 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c | |||
| @@ -32,7 +32,7 @@ | |||
| 32 | #include <plat/hardware.h> | 32 | #include <plat/hardware.h> |
| 33 | #include <plat/mux.h> | 33 | #include <plat/mux.h> |
| 34 | 34 | ||
| 35 | #include "mcpdm.h" | 35 | #include "omap-mcpdm.h" |
| 36 | #include "omap-pcm.h" | 36 | #include "omap-pcm.h" |
| 37 | #include "../codecs/twl6040.h" | 37 | #include "../codecs/twl6040.h" |
| 38 | 38 | ||
| @@ -88,7 +88,7 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { | |||
| 88 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 88 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
| 89 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), | 89 | SND_SOC_DAPM_HP("Headset Stereophone", NULL), |
| 90 | SND_SOC_DAPM_SPK("Earphone Spk", NULL), | 90 | SND_SOC_DAPM_SPK("Earphone Spk", NULL), |
| 91 | SND_SOC_DAPM_INPUT("Aux/FM Stereo In"), | 91 | SND_SOC_DAPM_INPUT("FM Stereo In"), |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| 94 | static const struct snd_soc_dapm_route audio_map[] = { | 94 | static const struct snd_soc_dapm_route audio_map[] = { |
| @@ -113,36 +113,22 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 113 | {"Earphone Spk", NULL, "EP"}, | 113 | {"Earphone Spk", NULL, "EP"}, |
| 114 | 114 | ||
| 115 | /* Aux/FM Stereo In: AFML, AFMR */ | 115 | /* Aux/FM Stereo In: AFML, AFMR */ |
| 116 | {"AFML", NULL, "Aux/FM Stereo In"}, | 116 | {"AFML", NULL, "FM Stereo In"}, |
| 117 | {"AFMR", NULL, "Aux/FM Stereo In"}, | 117 | {"AFMR", NULL, "FM Stereo In"}, |
| 118 | }; | 118 | }; |
| 119 | 119 | ||
| 120 | static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) | 120 | static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) |
| 121 | { | 121 | { |
| 122 | struct snd_soc_codec *codec = rtd->codec; | 122 | struct snd_soc_codec *codec = rtd->codec; |
| 123 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 123 | int ret, hs_trim; |
| 124 | int ret; | ||
| 125 | |||
| 126 | /* Add SDP4430 specific widgets */ | ||
| 127 | ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, | ||
| 128 | ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); | ||
| 129 | if (ret) | ||
| 130 | return ret; | ||
| 131 | |||
| 132 | /* Set up SDP4430 specific audio path audio_map */ | ||
| 133 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 134 | 124 | ||
| 135 | /* SDP4430 connected pins */ | 125 | /* |
| 136 | snd_soc_dapm_enable_pin(dapm, "Ext Mic"); | 126 | * Configure McPDM offset cancellation based on the HSOTRIM value from |
| 137 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | 127 | * twl6040. |
| 138 | snd_soc_dapm_enable_pin(dapm, "AFML"); | 128 | */ |
| 139 | snd_soc_dapm_enable_pin(dapm, "AFMR"); | 129 | hs_trim = twl6040_get_trim_value(codec, TWL6040_TRIM_HSOTRIM); |
| 140 | snd_soc_dapm_enable_pin(dapm, "Headset Mic"); | 130 | omap_mcpdm_configure_dn_offsets(rtd, TWL6040_HSF_TRIM_LEFT(hs_trim), |
| 141 | snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); | 131 | TWL6040_HSF_TRIM_RIGHT(hs_trim)); |
| 142 | |||
| 143 | ret = snd_soc_dapm_sync(dapm); | ||
| 144 | if (ret) | ||
| 145 | return ret; | ||
| 146 | 132 | ||
| 147 | /* Headset jack detection */ | 133 | /* Headset jack detection */ |
| 148 | ret = snd_soc_jack_new(codec, "Headset Jack", | 134 | ret = snd_soc_jack_new(codec, "Headset Jack", |
| @@ -165,8 +151,8 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) | |||
| 165 | static struct snd_soc_dai_link sdp4430_dai = { | 151 | static struct snd_soc_dai_link sdp4430_dai = { |
| 166 | .name = "TWL6040", | 152 | .name = "TWL6040", |
| 167 | .stream_name = "TWL6040", | 153 | .stream_name = "TWL6040", |
| 168 | .cpu_dai_name ="omap-mcpdm-dai", | 154 | .cpu_dai_name = "omap-mcpdm", |
| 169 | .codec_dai_name = "twl6040-hifi", | 155 | .codec_dai_name = "twl6040-legacy", |
| 170 | .platform_name = "omap-pcm-audio", | 156 | .platform_name = "omap-pcm-audio", |
| 171 | .codec_name = "twl6040-codec", | 157 | .codec_name = "twl6040-codec", |
| 172 | .init = sdp4430_twl6040_init, | 158 | .init = sdp4430_twl6040_init, |
| @@ -178,6 +164,11 @@ static struct snd_soc_card snd_soc_sdp4430 = { | |||
| 178 | .name = "SDP4430", | 164 | .name = "SDP4430", |
| 179 | .dai_link = &sdp4430_dai, | 165 | .dai_link = &sdp4430_dai, |
| 180 | .num_links = 1, | 166 | .num_links = 1, |
| 167 | |||
| 168 | .dapm_widgets = sdp4430_twl6040_dapm_widgets, | ||
| 169 | .num_dapm_widgets = ARRAY_SIZE(sdp4430_twl6040_dapm_widgets), | ||
| 170 | .dapm_routes = audio_map, | ||
| 171 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 181 | }; | 172 | }; |
| 182 | 173 | ||
| 183 | static struct platform_device *sdp4430_snd_device; | 174 | static struct platform_device *sdp4430_snd_device; |
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 9a2666ffc16c..7cf35c82368a 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c | |||
| @@ -44,29 +44,8 @@ static int zoom2_hw_params(struct snd_pcm_substream *substream, | |||
| 44 | { | 44 | { |
| 45 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 45 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 46 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 46 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 47 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 48 | int ret; | 47 | int ret; |
| 49 | 48 | ||
| 50 | /* Set codec DAI configuration */ | ||
| 51 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 52 | SND_SOC_DAIFMT_I2S | | ||
| 53 | SND_SOC_DAIFMT_NB_NF | | ||
| 54 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 55 | if (ret < 0) { | ||
| 56 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 57 | return ret; | ||
| 58 | } | ||
| 59 | |||
| 60 | /* Set cpu DAI configuration */ | ||
| 61 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 62 | SND_SOC_DAIFMT_I2S | | ||
| 63 | SND_SOC_DAIFMT_NB_NF | | ||
| 64 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 65 | if (ret < 0) { | ||
| 66 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 67 | return ret; | ||
| 68 | } | ||
| 69 | |||
| 70 | /* Set the codec system clock for DAC and ADC */ | 49 | /* Set the codec system clock for DAC and ADC */ |
| 71 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | 50 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, |
| 72 | SND_SOC_CLOCK_IN); | 51 | SND_SOC_CLOCK_IN); |
| @@ -82,49 +61,6 @@ static struct snd_soc_ops zoom2_ops = { | |||
| 82 | .hw_params = zoom2_hw_params, | 61 | .hw_params = zoom2_hw_params, |
| 83 | }; | 62 | }; |
| 84 | 63 | ||
| 85 | static int zoom2_hw_voice_params(struct snd_pcm_substream *substream, | ||
| 86 | struct snd_pcm_hw_params *params) | ||
| 87 | { | ||
| 88 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 89 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 90 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 91 | int ret; | ||
| 92 | |||
| 93 | /* Set codec DAI configuration */ | ||
| 94 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
| 95 | SND_SOC_DAIFMT_DSP_A | | ||
| 96 | SND_SOC_DAIFMT_IB_NF | | ||
| 97 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 98 | if (ret) { | ||
| 99 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
| 100 | return ret; | ||
| 101 | } | ||
| 102 | |||
| 103 | /* Set cpu DAI configuration */ | ||
| 104 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
| 105 | SND_SOC_DAIFMT_DSP_A | | ||
| 106 | SND_SOC_DAIFMT_IB_NF | | ||
| 107 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 108 | if (ret < 0) { | ||
| 109 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
| 110 | return ret; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* Set the codec system clock for DAC and ADC */ | ||
| 114 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
| 115 | SND_SOC_CLOCK_IN); | ||
| 116 | if (ret < 0) { | ||
| 117 | printk(KERN_ERR "can't set codec system clock\n"); | ||
| 118 | return ret; | ||
| 119 | } | ||
| 120 | |||
| 121 | return 0; | ||
| 122 | } | ||
| 123 | |||
| 124 | static struct snd_soc_ops zoom2_voice_ops = { | ||
| 125 | .hw_params = zoom2_hw_voice_params, | ||
| 126 | }; | ||
| 127 | |||
| 128 | /* Zoom2 machine DAPM */ | 64 | /* Zoom2 machine DAPM */ |
| 129 | static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = { | 65 | static const struct snd_soc_dapm_widget zoom2_twl4030_dapm_widgets[] = { |
| 130 | SND_SOC_DAPM_MIC("Ext Mic", NULL), | 66 | SND_SOC_DAPM_MIC("Ext Mic", NULL), |
| @@ -162,23 +98,6 @@ static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd) | |||
| 162 | { | 98 | { |
| 163 | struct snd_soc_codec *codec = rtd->codec; | 99 | struct snd_soc_codec *codec = rtd->codec; |
| 164 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 100 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 165 | int ret; | ||
| 166 | |||
| 167 | /* Add Zoom2 specific widgets */ | ||
| 168 | ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets, | ||
| 169 | ARRAY_SIZE(zoom2_twl4030_dapm_widgets)); | ||
| 170 | if (ret) | ||
| 171 | return ret; | ||
| 172 | |||
| 173 | /* Set up Zoom2 specific audio path audio_map */ | ||
| 174 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 175 | |||
| 176 | /* Zoom2 connected pins */ | ||
| 177 | snd_soc_dapm_enable_pin(dapm, "Ext Mic"); | ||
| 178 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | ||
| 179 | snd_soc_dapm_enable_pin(dapm, "Headset Mic"); | ||
| 180 | snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); | ||
| 181 | snd_soc_dapm_enable_pin(dapm, "Aux In"); | ||
| 182 | 101 | ||
| 183 | /* TWL4030 not connected pins */ | 102 | /* TWL4030 not connected pins */ |
| 184 | snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); | 103 | snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); |
| @@ -190,9 +109,7 @@ static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd) | |||
| 190 | snd_soc_dapm_nc_pin(dapm, "CARKITL"); | 109 | snd_soc_dapm_nc_pin(dapm, "CARKITL"); |
| 191 | snd_soc_dapm_nc_pin(dapm, "CARKITR"); | 110 | snd_soc_dapm_nc_pin(dapm, "CARKITR"); |
| 192 | 111 | ||
| 193 | ret = snd_soc_dapm_sync(dapm); | 112 | return 0; |
| 194 | |||
| 195 | return ret; | ||
| 196 | } | 113 | } |
| 197 | 114 | ||
| 198 | static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd) | 115 | static int zoom2_twl4030_voice_init(struct snd_soc_pcm_runtime *rtd) |
| @@ -217,6 +134,8 @@ static struct snd_soc_dai_link zoom2_dai[] = { | |||
| 217 | .codec_dai_name = "twl4030-hifi", | 134 | .codec_dai_name = "twl4030-hifi", |
| 218 | .platform_name = "omap-pcm-audio", | 135 | .platform_name = "omap-pcm-audio", |
| 219 | .codec_name = "twl4030-codec", | 136 | .codec_name = "twl4030-codec", |
| 137 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | | ||
| 138 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 220 | .init = zoom2_twl4030_init, | 139 | .init = zoom2_twl4030_init, |
| 221 | .ops = &zoom2_ops, | 140 | .ops = &zoom2_ops, |
| 222 | }, | 141 | }, |
| @@ -227,8 +146,10 @@ static struct snd_soc_dai_link zoom2_dai[] = { | |||
| 227 | .codec_dai_name = "twl4030-voice", | 146 | .codec_dai_name = "twl4030-voice", |
| 228 | .platform_name = "omap-pcm-audio", | 147 | .platform_name = "omap-pcm-audio", |
| 229 | .codec_name = "twl4030-codec", | 148 | .codec_name = "twl4030-codec", |
| 149 | .dai_fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF | | ||
| 150 | SND_SOC_DAIFMT_CBM_CFM, | ||
| 230 | .init = zoom2_twl4030_voice_init, | 151 | .init = zoom2_twl4030_voice_init, |
| 231 | .ops = &zoom2_voice_ops, | 152 | .ops = &zoom2_ops, |
| 232 | }, | 153 | }, |
| 233 | }; | 154 | }; |
| 234 | 155 | ||
| @@ -237,6 +158,11 @@ static struct snd_soc_card snd_soc_zoom2 = { | |||
| 237 | .name = "Zoom2", | 158 | .name = "Zoom2", |
| 238 | .dai_link = zoom2_dai, | 159 | .dai_link = zoom2_dai, |
| 239 | .num_links = ARRAY_SIZE(zoom2_dai), | 160 | .num_links = ARRAY_SIZE(zoom2_dai), |
| 161 | |||
| 162 | .dapm_widgets = zoom2_twl4030_dapm_widgets, | ||
| 163 | .num_dapm_widgets = ARRAY_SIZE(zoom2_twl4030_dapm_widgets), | ||
| 164 | .dapm_routes = audio_map, | ||
| 165 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 240 | }; | 166 | }; |
| 241 | 167 | ||
| 242 | static struct platform_device *zoom2_snd_device; | 168 | static struct platform_device *zoom2_snd_device; |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 33ebc46b45b5..ffd2242e305f 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
| @@ -121,6 +121,7 @@ config SND_PXA2XX_SOC_PALM27X | |||
| 121 | config SND_SOC_SAARB | 121 | config SND_SOC_SAARB |
| 122 | tristate "SoC Audio support for Marvell Saarb" | 122 | tristate "SoC Audio support for Marvell Saarb" |
| 123 | depends on SND_PXA2XX_SOC && MACH_SAARB | 123 | depends on SND_PXA2XX_SOC && MACH_SAARB |
| 124 | select MFD_88PM860X | ||
| 124 | select SND_PXA_SOC_SSP | 125 | select SND_PXA_SOC_SSP |
| 125 | select SND_SOC_88PM860X | 126 | select SND_SOC_88PM860X |
| 126 | help | 127 | help |
| @@ -130,6 +131,7 @@ config SND_SOC_SAARB | |||
| 130 | config SND_SOC_TAVOREVB3 | 131 | config SND_SOC_TAVOREVB3 |
| 131 | tristate "SoC Audio support for Marvell Tavor EVB3" | 132 | tristate "SoC Audio support for Marvell Tavor EVB3" |
| 132 | depends on SND_PXA2XX_SOC && MACH_TAVOREVB3 | 133 | depends on SND_PXA2XX_SOC && MACH_TAVOREVB3 |
| 134 | select MFD_88PM860X | ||
| 133 | select SND_PXA_SOC_SSP | 135 | select SND_PXA_SOC_SSP |
| 134 | select SND_SOC_88PM860X | 136 | select SND_SOC_88PM860X |
| 135 | help | 137 | help |
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 28757fb9df31..b0e2fb720910 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c | |||
| @@ -299,7 +299,6 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
| 299 | /* Set up corgi specific audio path audio_map */ | 299 | /* Set up corgi specific audio path audio_map */ |
| 300 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 300 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 301 | 301 | ||
| 302 | snd_soc_dapm_sync(dapm); | ||
| 303 | return 0; | 302 | return 0; |
| 304 | } | 303 | } |
| 305 | 304 | ||
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index dc65650a6fa1..35ed7eb8cff2 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c | |||
| @@ -108,8 +108,6 @@ static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
| 108 | 108 | ||
| 109 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 109 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 110 | 110 | ||
| 111 | snd_soc_dapm_sync(dapm); | ||
| 112 | |||
| 113 | return 0; | 111 | return 0; |
| 114 | } | 112 | } |
| 115 | 113 | ||
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 51897fcd911b..ce5f056009a7 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c | |||
| @@ -90,8 +90,6 @@ static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
| 90 | 90 | ||
| 91 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 91 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 92 | 92 | ||
| 93 | snd_soc_dapm_sync(dapm); | ||
| 94 | |||
| 95 | return 0; | 93 | return 0; |
| 96 | } | 94 | } |
| 97 | 95 | ||
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index 053ed208e59f..6a8f38b6c379 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c | |||
| @@ -80,7 +80,6 @@ static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
| 80 | ARRAY_SIZE(e800_dapm_widgets)); | 80 | ARRAY_SIZE(e800_dapm_widgets)); |
| 81 | 81 | ||
| 82 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 82 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 83 | snd_soc_dapm_sync(dapm); | ||
| 84 | 83 | ||
| 85 | return 0; | 84 | return 0; |
| 86 | } | 85 | } |
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 67dcc36cd621..e79f516c400e 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c | |||
| @@ -92,11 +92,10 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream, | |||
| 92 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 92 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 93 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 93 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 94 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | 94 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; |
| 95 | unsigned int acps, acds, width, rate; | 95 | unsigned int acps, acds, width; |
| 96 | unsigned int div4 = PXA_SSP_CLK_SCDB_4; | 96 | unsigned int div4 = PXA_SSP_CLK_SCDB_4; |
| 97 | int ret = 0; | 97 | int ret = 0; |
| 98 | 98 | ||
| 99 | rate = params_rate(params); | ||
| 100 | width = snd_pcm_format_physical_width(params_format(params)); | 99 | width = snd_pcm_format_physical_width(params_format(params)); |
| 101 | 100 | ||
| 102 | /* | 101 | /* |
| @@ -424,7 +423,6 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) | |||
| 424 | /* Set up magician specific audio path interconnects */ | 423 | /* Set up magician specific audio path interconnects */ |
| 425 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 424 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 426 | 425 | ||
| 427 | snd_soc_dapm_sync(dapm); | ||
| 428 | return 0; | 426 | return 0; |
| 429 | } | 427 | } |
| 430 | 428 | ||
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index 38ca6759907e..0b8d1ee738a4 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c | |||
| @@ -151,7 +151,6 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) | |||
| 151 | snd_soc_dapm_enable_pin(dapm, "Front Mic"); | 151 | snd_soc_dapm_enable_pin(dapm, "Front Mic"); |
| 152 | snd_soc_dapm_enable_pin(dapm, "GSM Line In"); | 152 | snd_soc_dapm_enable_pin(dapm, "GSM Line In"); |
| 153 | snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); | 153 | snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); |
| 154 | snd_soc_dapm_sync(dapm); | ||
| 155 | 154 | ||
| 156 | return 0; | 155 | return 0; |
| 157 | } | 156 | } |
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 504e4004f004..7edc1fb71fae 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c | |||
| @@ -107,10 +107,6 @@ static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
| 107 | snd_soc_dapm_nc_pin(dapm, "PHONE"); | 107 | snd_soc_dapm_nc_pin(dapm, "PHONE"); |
| 108 | snd_soc_dapm_nc_pin(dapm, "MIC2"); | 108 | snd_soc_dapm_nc_pin(dapm, "MIC2"); |
| 109 | 109 | ||
| 110 | err = snd_soc_dapm_sync(dapm); | ||
| 111 | if (err) | ||
| 112 | return err; | ||
| 113 | |||
| 114 | /* Jack detection API stuff */ | 110 | /* Jack detection API stuff */ |
| 115 | err = snd_soc_jack_new(codec, "Headphone Jack", | 111 | err = snd_soc_jack_new(codec, "Headphone Jack", |
| 116 | SND_JACK_HEADPHONE, &hs_jack); | 112 | SND_JACK_HEADPHONE, &hs_jack); |
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index da3ae4316cf2..4c29bc1f9cfe 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c | |||
| @@ -265,7 +265,6 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) | |||
| 265 | /* Set up poodle specific audio path audio_map */ | 265 | /* Set up poodle specific audio path audio_map */ |
| 266 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 266 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 267 | 267 | ||
| 268 | snd_soc_dapm_sync(dapm); | ||
| 269 | return 0; | 268 | return 0; |
| 270 | } | 269 | } |
| 271 | 270 | ||
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index 1a591f1ebfbd..b899a3bc8f42 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c | |||
| @@ -306,8 +306,10 @@ static int __init raumfeld_audio_init(void) | |||
| 306 | &snd_soc_raumfeld_connector); | 306 | &snd_soc_raumfeld_connector); |
| 307 | 307 | ||
| 308 | ret = platform_device_add(raumfeld_audio_device); | 308 | ret = platform_device_add(raumfeld_audio_device); |
| 309 | if (ret < 0) | 309 | if (ret < 0) { |
| 310 | platform_device_put(raumfeld_audio_device); | ||
| 310 | return ret; | 311 | return ret; |
| 312 | } | ||
| 311 | 313 | ||
| 312 | raumfeld_enable_audio(true); | 314 | raumfeld_enable_audio(true); |
| 313 | return 0; | 315 | return 0; |
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c index 9595189fc681..d9467a2c6de0 100644 --- a/sound/soc/pxa/saarb.c +++ b/sound/soc/pxa/saarb.c | |||
| @@ -146,10 +146,6 @@ static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd) | |||
| 146 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); | 146 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); |
| 147 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); | 147 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); |
| 148 | 148 | ||
| 149 | ret = snd_soc_dapm_sync(dapm); | ||
| 150 | if (ret) | ||
| 151 | return ret; | ||
| 152 | |||
| 153 | /* Headset jack detection */ | 149 | /* Headset jack detection */ |
| 154 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE | 150 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE |
| 155 | | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, | 151 | | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, |
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index b253d864868a..c2d6ff9b1588 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c | |||
| @@ -301,7 +301,6 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) | |||
| 301 | /* Set up spitz specific audio paths */ | 301 | /* Set up spitz specific audio paths */ |
| 302 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 302 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 303 | 303 | ||
| 304 | snd_soc_dapm_sync(dapm); | ||
| 305 | return 0; | 304 | return 0; |
| 306 | } | 305 | } |
| 307 | 306 | ||
| @@ -312,7 +311,7 @@ static struct snd_soc_dai_link spitz_dai = { | |||
| 312 | .cpu_dai_name = "pxa2xx-i2s", | 311 | .cpu_dai_name = "pxa2xx-i2s", |
| 313 | .codec_dai_name = "wm8750-hifi", | 312 | .codec_dai_name = "wm8750-hifi", |
| 314 | .platform_name = "pxa-pcm-audio", | 313 | .platform_name = "pxa-pcm-audio", |
| 315 | .codec_name = "wm8750-codec.0-001b", | 314 | .codec_name = "wm8750.0-001b", |
| 316 | .init = spitz_wm8750_init, | 315 | .init = spitz_wm8750_init, |
| 317 | .ops = &spitz_ops, | 316 | .ops = &spitz_ops, |
| 318 | }; | 317 | }; |
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c index f881f65ec172..eeec892e0e04 100644 --- a/sound/soc/pxa/tavorevb3.c +++ b/sound/soc/pxa/tavorevb3.c | |||
| @@ -146,10 +146,6 @@ static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd) | |||
| 146 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); | 146 | snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); |
| 147 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); | 147 | snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); |
| 148 | 148 | ||
| 149 | ret = snd_soc_dapm_sync(dapm); | ||
| 150 | if (ret) | ||
| 151 | return ret; | ||
| 152 | |||
| 153 | /* Headset jack detection */ | 149 | /* Headset jack detection */ |
| 154 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE | 150 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE |
| 155 | | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, | 151 | | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2, |
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 9a2351366957..620fc69ae632 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c | |||
| @@ -211,7 +211,6 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) | |||
| 211 | /* set up tosa specific audio path audio_map */ | 211 | /* set up tosa specific audio path audio_map */ |
| 212 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 212 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 213 | 213 | ||
| 214 | snd_soc_dapm_sync(dapm); | ||
| 215 | return 0; | 214 | return 0; |
| 216 | } | 215 | } |
| 217 | 216 | ||
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c index d69d9fc32233..b311ffe04b71 100644 --- a/sound/soc/pxa/z2.c +++ b/sound/soc/pxa/z2.c | |||
| @@ -161,10 +161,6 @@ static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) | |||
| 161 | /* Set up z2 specific audio paths */ | 161 | /* Set up z2 specific audio paths */ |
| 162 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | 162 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); |
| 163 | 163 | ||
| 164 | ret = snd_soc_dapm_sync(dapm); | ||
| 165 | if (ret) | ||
| 166 | goto err; | ||
| 167 | |||
| 168 | /* Jack detection API stuff */ | 164 | /* Jack detection API stuff */ |
| 169 | ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, | 165 | ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, |
| 170 | &hs_jack); | 166 | &hs_jack); |
| @@ -198,7 +194,7 @@ static struct snd_soc_dai_link z2_dai = { | |||
| 198 | .cpu_dai_name = "pxa2xx-i2s", | 194 | .cpu_dai_name = "pxa2xx-i2s", |
| 199 | .codec_dai_name = "wm8750-hifi", | 195 | .codec_dai_name = "wm8750-hifi", |
| 200 | .platform_name = "pxa-pcm-audio", | 196 | .platform_name = "pxa-pcm-audio", |
| 201 | .codec_name = "wm8750-codec.0-001b", | 197 | .codec_name = "wm8750.0-001b", |
| 202 | .init = z2_wm8750_init, | 198 | .init = z2_wm8750_init, |
| 203 | .ops = &z2_ops, | 199 | .ops = &z2_ops, |
| 204 | }; | 200 | }; |
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index 2b8350b52232..580aae38e502 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c | |||
| @@ -87,7 +87,6 @@ static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd) | |||
| 87 | snd_soc_dapm_enable_pin(dapm, "Headphone"); | 87 | snd_soc_dapm_enable_pin(dapm, "Headphone"); |
| 88 | snd_soc_dapm_enable_pin(dapm, "Headset Earpiece"); | 88 | snd_soc_dapm_enable_pin(dapm, "Headset Earpiece"); |
| 89 | 89 | ||
| 90 | snd_soc_dapm_sync(dapm); | ||
| 91 | return 0; | 90 | return 0; |
| 92 | } | 91 | } |
| 93 | 92 | ||
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 80c85fd64e1a..55efc2bdf0bd 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c | |||
| @@ -446,7 +446,6 @@ static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32); | |||
| 446 | static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) | 446 | static int s6000_pcm_new(struct snd_soc_pcm_runtime *runtime) |
| 447 | { | 447 | { |
| 448 | struct snd_card *card = runtime->card->snd_card; | 448 | struct snd_card *card = runtime->card->snd_card; |
| 449 | struct snd_soc_dai *dai = runtime->cpu_dai; | ||
| 450 | struct snd_pcm *pcm = runtime->pcm; | 449 | struct snd_pcm *pcm = runtime->pcm; |
| 451 | struct s6000_pcm_dma_params *params; | 450 | struct s6000_pcm_dma_params *params; |
| 452 | int res; | 451 | int res; |
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 65f980ef2870..53aaa69eda03 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
| @@ -63,7 +63,9 @@ config SND_SOC_SAMSUNG_SMDK_WM8580 | |||
| 63 | 63 | ||
| 64 | config SND_SOC_SAMSUNG_SMDK_WM8994 | 64 | config SND_SOC_SAMSUNG_SMDK_WM8994 |
| 65 | tristate "SoC I2S Audio support for WM8994 on SMDK" | 65 | tristate "SoC I2S Audio support for WM8994 on SMDK" |
| 66 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210) | 66 | depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210 || MACH_SMDK4212) |
| 67 | depends on I2C=y && GENERIC_HARDIRQS | ||
| 68 | select MFD_WM8994 | ||
| 67 | select SND_SOC_WM8994 | 69 | select SND_SOC_WM8994 |
| 68 | select SND_SAMSUNG_I2S | 70 | select SND_SAMSUNG_I2S |
| 69 | help | 71 | help |
| @@ -150,7 +152,9 @@ config SND_SOC_SMARTQ | |||
| 150 | config SND_SOC_GONI_AQUILA_WM8994 | 152 | config SND_SOC_GONI_AQUILA_WM8994 |
| 151 | tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" | 153 | tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" |
| 152 | depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) | 154 | depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) |
| 155 | depends on I2C=y && GENERIC_HARDIRQS | ||
| 153 | select SND_SAMSUNG_I2S | 156 | select SND_SAMSUNG_I2S |
| 157 | select MFD_WM8994 | ||
| 154 | select SND_SOC_WM8994 | 158 | select SND_SOC_WM8994 |
| 155 | help | 159 | help |
| 156 | Say Y if you want to add support for SoC audio on goni or aquila | 160 | Say Y if you want to add support for SoC audio on goni or aquila |
| @@ -158,7 +162,7 @@ config SND_SOC_GONI_AQUILA_WM8994 | |||
| 158 | 162 | ||
| 159 | config SND_SOC_SAMSUNG_SMDK_SPDIF | 163 | config SND_SOC_SAMSUNG_SMDK_SPDIF |
| 160 | tristate "SoC S/PDIF Audio support for SMDK" | 164 | tristate "SoC S/PDIF Audio support for SMDK" |
| 161 | depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310) | 165 | depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210 || MACH_SMDKV310 || MACH_SMDK4212) |
| 162 | select SND_SAMSUNG_SPDIF | 166 | select SND_SAMSUNG_SPDIF |
| 163 | help | 167 | help |
| 164 | Say Y if you want to add support for SoC S/PDIF audio on the SMDK. | 168 | Say Y if you want to add support for SoC S/PDIF audio on the SMDK. |
| @@ -173,7 +177,9 @@ config SND_SOC_SMDK_WM8580_PCM | |||
| 173 | 177 | ||
| 174 | config SND_SOC_SMDK_WM8994_PCM | 178 | config SND_SOC_SMDK_WM8994_PCM |
| 175 | tristate "SoC PCM Audio support for WM8994 on SMDK" | 179 | tristate "SoC PCM Audio support for WM8994 on SMDK" |
| 176 | depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310) | 180 | depends on SND_SOC_SAMSUNG && (MACH_SMDKC210 || MACH_SMDKV310 || MACH_SMDK4212) |
| 181 | depends on I2C=y && GENERIC_HARDIRQS | ||
| 182 | select MFD_WM8994 | ||
| 177 | select SND_SOC_WM8994 | 183 | select SND_SOC_WM8994 |
| 178 | select SND_SAMSUNG_PCM | 184 | select SND_SAMSUNG_PCM |
| 179 | help | 185 | help |
diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c index f97110e72e85..b5e922f469d5 100644 --- a/sound/soc/samsung/ac97.c +++ b/sound/soc/samsung/ac97.c | |||
| @@ -444,7 +444,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev) | |||
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | ret = request_irq(irq_res->start, s3c_ac97_irq, | 446 | ret = request_irq(irq_res->start, s3c_ac97_irq, |
| 447 | IRQF_DISABLED, "AC97", NULL); | 447 | 0, "AC97", NULL); |
| 448 | if (ret < 0) { | 448 | if (ret < 0) { |
| 449 | dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); | 449 | dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); |
| 450 | goto err4; | 450 | goto err4; |
| @@ -495,7 +495,7 @@ static __devexit int s3c_ac97_remove(struct platform_device *pdev) | |||
| 495 | 495 | ||
| 496 | static struct platform_driver s3c_ac97_driver = { | 496 | static struct platform_driver s3c_ac97_driver = { |
| 497 | .probe = s3c_ac97_probe, | 497 | .probe = s3c_ac97_probe, |
| 498 | .remove = s3c_ac97_remove, | 498 | .remove = __devexit_p(s3c_ac97_remove), |
| 499 | .driver = { | 499 | .driver = { |
| 500 | .name = "samsung-ac97", | 500 | .name = "samsung-ac97", |
| 501 | .owner = THIS_MODULE, | 501 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index eb6d72ed55a7..4a34f608e131 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c | |||
| @@ -99,14 +99,6 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) | |||
| 99 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 99 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 100 | int ret; | 100 | int ret; |
| 101 | 101 | ||
| 102 | /* add goni specific widgets */ | ||
| 103 | snd_soc_dapm_new_controls(dapm, goni_dapm_widgets, | ||
| 104 | ARRAY_SIZE(goni_dapm_widgets)); | ||
| 105 | |||
| 106 | /* set up goni specific audio routes */ | ||
| 107 | snd_soc_dapm_add_routes(dapm, goni_dapm_routes, | ||
| 108 | ARRAY_SIZE(goni_dapm_routes)); | ||
| 109 | |||
| 110 | /* set endpoints to not connected */ | 102 | /* set endpoints to not connected */ |
| 111 | snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); | 103 | snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); |
| 112 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); | 104 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); |
| @@ -120,8 +112,6 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) | |||
| 120 | snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); | 112 | snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); |
| 121 | } | 113 | } |
| 122 | 114 | ||
| 123 | snd_soc_dapm_sync(dapm); | ||
| 124 | |||
| 125 | /* Headset jack detection */ | 115 | /* Headset jack detection */ |
| 126 | ret = snd_soc_jack_new(codec, "Headset Jack", | 116 | ret = snd_soc_jack_new(codec, "Headset Jack", |
| 127 | SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, | 117 | SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, |
| @@ -255,6 +245,11 @@ static struct snd_soc_card goni = { | |||
| 255 | .name = "goni", | 245 | .name = "goni", |
| 256 | .dai_link = goni_dai, | 246 | .dai_link = goni_dai, |
| 257 | .num_links = ARRAY_SIZE(goni_dai), | 247 | .num_links = ARRAY_SIZE(goni_dai), |
| 248 | |||
| 249 | .dapm_widgets = goni_dapm_widgets, | ||
| 250 | .num_dapm_widgets = ARRAY_SIZE(goni_dapm_widgets), | ||
| 251 | .dapm_routes = goni_dapm_routes, | ||
| 252 | .num_dapm_routes = ARRAY_SIZE(goni_dapm_routes), | ||
| 258 | }; | 253 | }; |
| 259 | 254 | ||
| 260 | static int __init goni_init(void) | 255 | static int __init goni_init(void) |
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c index c6c65892294e..f75a4b60cf38 100644 --- a/sound/soc/samsung/h1940_uda1380.c +++ b/sound/soc/samsung/h1940_uda1380.c | |||
| @@ -182,24 +182,10 @@ static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) | |||
| 182 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 182 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 183 | int err; | 183 | int err; |
| 184 | 184 | ||
| 185 | /* Add h1940 specific widgets */ | ||
| 186 | err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, | ||
| 187 | ARRAY_SIZE(uda1380_dapm_widgets)); | ||
| 188 | if (err) | ||
| 189 | return err; | ||
| 190 | |||
| 191 | /* Set up h1940 specific audio path audio_mapnects */ | ||
| 192 | err = snd_soc_dapm_add_routes(dapm, audio_map, | ||
| 193 | ARRAY_SIZE(audio_map)); | ||
| 194 | if (err) | ||
| 195 | return err; | ||
| 196 | |||
| 197 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 185 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 198 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | 186 | snd_soc_dapm_enable_pin(dapm, "Speaker"); |
| 199 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 187 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 200 | 188 | ||
| 201 | snd_soc_dapm_sync(dapm); | ||
| 202 | |||
| 203 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | 189 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, |
| 204 | &hp_jack); | 190 | &hp_jack); |
| 205 | 191 | ||
| @@ -230,6 +216,11 @@ static struct snd_soc_card h1940_asoc = { | |||
| 230 | .name = "h1940", | 216 | .name = "h1940", |
| 231 | .dai_link = h1940_uda1380_dai, | 217 | .dai_link = h1940_uda1380_dai, |
| 232 | .num_links = ARRAY_SIZE(h1940_uda1380_dai), | 218 | .num_links = ARRAY_SIZE(h1940_uda1380_dai), |
| 219 | |||
| 220 | .dapm_widgets = uda1380_dapm_widgets, | ||
| 221 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), | ||
| 222 | .dapm_routes = audio_map, | ||
| 223 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 233 | }; | 224 | }; |
| 234 | 225 | ||
| 235 | static int __init h1940_init(void) | 226 | static int __init h1940_init(void) |
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index c086b78539ee..0c9ac20d2223 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c | |||
| @@ -1136,7 +1136,7 @@ static __devexit int samsung_i2s_remove(struct platform_device *pdev) | |||
| 1136 | 1136 | ||
| 1137 | static struct platform_driver samsung_i2s_driver = { | 1137 | static struct platform_driver samsung_i2s_driver = { |
| 1138 | .probe = samsung_i2s_probe, | 1138 | .probe = samsung_i2s_probe, |
| 1139 | .remove = samsung_i2s_remove, | 1139 | .remove = __devexit_p(samsung_i2s_remove), |
| 1140 | .driver = { | 1140 | .driver = { |
| 1141 | .name = "samsung-i2s", | 1141 | .name = "samsung-i2s", |
| 1142 | .owner = THIS_MODULE, | 1142 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c index 14eb6ea69e7c..f5f7c6f822d5 100644 --- a/sound/soc/samsung/jive_wm8750.c +++ b/sound/soc/samsung/jive_wm8750.c | |||
| @@ -110,18 +110,6 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) | |||
| 110 | snd_soc_dapm_nc_pin(dapm, "OUT3"); | 110 | snd_soc_dapm_nc_pin(dapm, "OUT3"); |
| 111 | snd_soc_dapm_nc_pin(dapm, "MONO"); | 111 | snd_soc_dapm_nc_pin(dapm, "MONO"); |
| 112 | 112 | ||
| 113 | /* Add jive specific widgets */ | ||
| 114 | err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, | ||
| 115 | ARRAY_SIZE(wm8750_dapm_widgets)); | ||
| 116 | if (err) { | ||
| 117 | printk(KERN_ERR "%s: failed to add widgets (%d)\n", | ||
| 118 | __func__, err); | ||
| 119 | return err; | ||
| 120 | } | ||
| 121 | |||
| 122 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 123 | snd_soc_dapm_sync(dapm); | ||
| 124 | |||
| 125 | return 0; | 113 | return 0; |
| 126 | } | 114 | } |
| 127 | 115 | ||
| @@ -131,7 +119,7 @@ static struct snd_soc_dai_link jive_dai = { | |||
| 131 | .cpu_dai_name = "s3c2412-i2s", | 119 | .cpu_dai_name = "s3c2412-i2s", |
| 132 | .codec_dai_name = "wm8750-hifi", | 120 | .codec_dai_name = "wm8750-hifi", |
| 133 | .platform_name = "samsung-audio", | 121 | .platform_name = "samsung-audio", |
| 134 | .codec_name = "wm8750-codec.0-001a", | 122 | .codec_name = "wm8750.0-001a", |
| 135 | .init = jive_wm8750_init, | 123 | .init = jive_wm8750_init, |
| 136 | .ops = &jive_ops, | 124 | .ops = &jive_ops, |
| 137 | }; | 125 | }; |
| @@ -141,6 +129,11 @@ static struct snd_soc_card snd_soc_machine_jive = { | |||
| 141 | .name = "Jive", | 129 | .name = "Jive", |
| 142 | .dai_link = &jive_dai, | 130 | .dai_link = &jive_dai, |
| 143 | .num_links = 1, | 131 | .num_links = 1, |
| 132 | |||
| 133 | .dapm_widgtets = wm8750_dapm_widgets, | ||
| 134 | .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), | ||
| 135 | .dapm_routes = audio_map, | ||
| 136 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 144 | }; | 137 | }; |
| 145 | 138 | ||
| 146 | static struct platform_device *jive_snd_device; | 139 | static struct platform_device *jive_snd_device; |
diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c index 16152ed08648..7207189cd211 100644 --- a/sound/soc/samsung/neo1973_wm8753.c +++ b/sound/soc/samsung/neo1973_wm8753.c | |||
| @@ -367,8 +367,6 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) | |||
| 367 | return ret; | 367 | return ret; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | snd_soc_dapm_sync(dapm); | ||
| 371 | |||
| 372 | return 0; | 370 | return 0; |
| 373 | } | 371 | } |
| 374 | 372 | ||
| @@ -409,8 +407,6 @@ static int neo1973_lm4857_init(struct snd_soc_dapm_context *dapm) | |||
| 409 | snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); | 407 | snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); |
| 410 | snd_soc_dapm_ignore_suspend(dapm, "Headphone"); | 408 | snd_soc_dapm_ignore_suspend(dapm, "Headphone"); |
| 411 | 409 | ||
| 412 | snd_soc_dapm_sync(dapm); | ||
| 413 | |||
| 414 | return 0; | 410 | return 0; |
| 415 | } | 411 | } |
| 416 | 412 | ||
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index 9c7e8b48aed6..e55d7a5c4bdc 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
| @@ -624,7 +624,7 @@ static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) | |||
| 624 | 624 | ||
| 625 | static struct platform_driver s3c_pcm_driver = { | 625 | static struct platform_driver s3c_pcm_driver = { |
| 626 | .probe = s3c_pcm_dev_probe, | 626 | .probe = s3c_pcm_dev_probe, |
| 627 | .remove = s3c_pcm_dev_remove, | 627 | .remove = __devexit_p(s3c_pcm_dev_remove), |
| 628 | .driver = { | 628 | .driver = { |
| 629 | .name = "samsung-pcm", | 629 | .name = "samsung-pcm", |
| 630 | .owner = THIS_MODULE, | 630 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c index bc8c1676459f..aea7f1b24e6b 100644 --- a/sound/soc/samsung/rx1950_uda1380.c +++ b/sound/soc/samsung/rx1950_uda1380.c | |||
| @@ -90,12 +90,6 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { | |||
| 90 | }, | 90 | }, |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | static struct snd_soc_card rx1950_asoc = { | ||
| 94 | .name = "rx1950", | ||
| 95 | .dai_link = rx1950_uda1380_dai, | ||
| 96 | .num_links = ARRAY_SIZE(rx1950_uda1380_dai), | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* rx1950 machine dapm widgets */ | 93 | /* rx1950 machine dapm widgets */ |
| 100 | static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { | 94 | static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { |
| 101 | SND_SOC_DAPM_HP("Headphone Jack", NULL), | 95 | SND_SOC_DAPM_HP("Headphone Jack", NULL), |
| @@ -117,6 +111,17 @@ static const struct snd_soc_dapm_route audio_map[] = { | |||
| 117 | {"VINM", NULL, "Mic Jack"}, | 111 | {"VINM", NULL, "Mic Jack"}, |
| 118 | }; | 112 | }; |
| 119 | 113 | ||
| 114 | static struct snd_soc_card rx1950_asoc = { | ||
| 115 | .name = "rx1950", | ||
| 116 | .dai_link = rx1950_uda1380_dai, | ||
| 117 | .num_links = ARRAY_SIZE(rx1950_uda1380_dai), | ||
| 118 | |||
| 119 | .dapm_widgets = uda1380_dapm_widgets, | ||
| 120 | .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), | ||
| 121 | .dapm_routes = audio_map, | ||
| 122 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 123 | }; | ||
| 124 | |||
| 120 | static struct platform_device *s3c24xx_snd_device; | 125 | static struct platform_device *s3c24xx_snd_device; |
| 121 | 126 | ||
| 122 | static int rx1950_startup(struct snd_pcm_substream *substream) | 127 | static int rx1950_startup(struct snd_pcm_substream *substream) |
| @@ -220,26 +225,10 @@ static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) | |||
| 220 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 225 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 221 | int err; | 226 | int err; |
| 222 | 227 | ||
| 223 | /* Add rx1950 specific widgets */ | ||
| 224 | err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, | ||
| 225 | ARRAY_SIZE(uda1380_dapm_widgets)); | ||
| 226 | |||
| 227 | if (err) | ||
| 228 | return err; | ||
| 229 | |||
| 230 | /* Set up rx1950 specific audio path audio_mapnects */ | ||
| 231 | err = snd_soc_dapm_add_routes(dapm, audio_map, | ||
| 232 | ARRAY_SIZE(audio_map)); | ||
| 233 | |||
| 234 | if (err) | ||
| 235 | return err; | ||
| 236 | |||
| 237 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 228 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 238 | snd_soc_dapm_enable_pin(dapm, "Speaker"); | 229 | snd_soc_dapm_enable_pin(dapm, "Speaker"); |
| 239 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 230 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 240 | 231 | ||
| 241 | snd_soc_dapm_sync(dapm); | ||
| 242 | |||
| 243 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, | 232 | snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, |
| 244 | &hp_jack); | 233 | &hp_jack); |
| 245 | 234 | ||
diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c index 52074a2b0696..7a73380b3560 100644 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ b/sound/soc/samsung/s3c-i2s-v2.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | * option) any later version. | 16 | * option) any later version. |
| 17 | */ | 17 | */ |
| 18 | 18 | ||
| 19 | #include <linux/module.h> | ||
| 19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 20 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 21 | #include <linux/io.h> | 22 | #include <linux/io.h> |
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c index 841ab14c1100..f26a8bfb2357 100644 --- a/sound/soc/samsung/s3c2412-i2s.c +++ b/sound/soc/samsung/s3c2412-i2s.c | |||
| @@ -69,10 +69,10 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai) | |||
| 69 | s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; | 69 | s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; |
| 70 | 70 | ||
| 71 | s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); | 71 | s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); |
| 72 | if (s3c2412_i2s.iis_cclk == NULL) { | 72 | if (IS_ERR(s3c2412_i2s.iis_cclk)) { |
| 73 | pr_err("failed to get i2sclk clock\n"); | 73 | pr_err("failed to get i2sclk clock\n"); |
| 74 | iounmap(s3c2412_i2s.regs); | 74 | iounmap(s3c2412_i2s.regs); |
| 75 | return -ENODEV; | 75 | return PTR_ERR(s3c2412_i2s.iis_cclk); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | /* Set MPLL as the source for IIS CLK */ | 78 | /* Set MPLL as the source for IIS CLK */ |
| @@ -176,7 +176,7 @@ static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) | |||
| 176 | 176 | ||
| 177 | static struct platform_driver s3c2412_iis_driver = { | 177 | static struct platform_driver s3c2412_iis_driver = { |
| 178 | .probe = s3c2412_iis_dev_probe, | 178 | .probe = s3c2412_iis_dev_probe, |
| 179 | .remove = s3c2412_iis_dev_remove, | 179 | .remove = __devexit_p(s3c2412_iis_dev_remove), |
| 180 | .driver = { | 180 | .driver = { |
| 181 | .name = "s3c2412-iis", | 181 | .name = "s3c2412-iis", |
| 182 | .owner = THIS_MODULE, | 182 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c index 63d8849d80bd..c08117e658db 100644 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ b/sound/soc/samsung/s3c24xx-i2s.c | |||
| @@ -383,10 +383,10 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) | |||
| 383 | return -ENXIO; | 383 | return -ENXIO; |
| 384 | 384 | ||
| 385 | s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); | 385 | s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); |
| 386 | if (s3c24xx_i2s.iis_clk == NULL) { | 386 | if (IS_ERR(s3c24xx_i2s.iis_clk)) { |
| 387 | pr_err("failed to get iis_clock\n"); | 387 | pr_err("failed to get iis_clock\n"); |
| 388 | iounmap(s3c24xx_i2s.regs); | 388 | iounmap(s3c24xx_i2s.regs); |
| 389 | return -ENODEV; | 389 | return PTR_ERR(s3c24xx_i2s.iis_clk); |
| 390 | } | 390 | } |
| 391 | clk_enable(s3c24xx_i2s.iis_clk); | 391 | clk_enable(s3c24xx_i2s.iis_clk); |
| 392 | 392 | ||
| @@ -481,7 +481,7 @@ static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) | |||
| 481 | 481 | ||
| 482 | static struct platform_driver s3c24xx_iis_driver = { | 482 | static struct platform_driver s3c24xx_iis_driver = { |
| 483 | .probe = s3c24xx_iis_dev_probe, | 483 | .probe = s3c24xx_iis_dev_probe, |
| 484 | .remove = s3c24xx_iis_dev_remove, | 484 | .remove = __devexit_p(s3c24xx_iis_dev_remove), |
| 485 | .driver = { | 485 | .driver = { |
| 486 | .name = "s3c24xx-iis", | 486 | .name = "s3c24xx-iis", |
| 487 | .owner = THIS_MODULE, | 487 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c index 349566f0686b..c8d525bf6122 100644 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ b/sound/soc/samsung/s3c24xx_simtec.c | |||
| @@ -300,7 +300,7 @@ static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd) | |||
| 300 | } | 300 | } |
| 301 | 301 | ||
| 302 | #ifdef CONFIG_PM | 302 | #ifdef CONFIG_PM |
| 303 | int simtec_audio_resume(struct device *dev) | 303 | static int simtec_audio_resume(struct device *dev) |
| 304 | { | 304 | { |
| 305 | simtec_call_startup(pdata); | 305 | simtec_call_startup(pdata); |
| 306 | return 0; | 306 | return 0; |
diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c index ce6aef604179..6bc5a36af1d9 100644 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c | |||
| @@ -65,18 +65,12 @@ static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) | |||
| 65 | struct snd_soc_codec *codec = rtd->codec; | 65 | struct snd_soc_codec *codec = rtd->codec; |
| 66 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 66 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 67 | 67 | ||
| 68 | snd_soc_dapm_new_controls(dapm, dapm_widgets, | ||
| 69 | ARRAY_SIZE(dapm_widgets)); | ||
| 70 | |||
| 71 | snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); | ||
| 72 | |||
| 73 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 68 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 74 | snd_soc_dapm_enable_pin(dapm, "Line In"); | 69 | snd_soc_dapm_enable_pin(dapm, "Line In"); |
| 75 | snd_soc_dapm_enable_pin(dapm, "Line Out"); | 70 | snd_soc_dapm_enable_pin(dapm, "Line Out"); |
| 76 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 71 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 77 | 72 | ||
| 78 | simtec_audio_init(rtd); | 73 | simtec_audio_init(rtd); |
| 79 | snd_soc_dapm_sync(dapm); | ||
| 80 | 74 | ||
| 81 | return 0; | 75 | return 0; |
| 82 | } | 76 | } |
| @@ -96,6 +90,11 @@ static struct snd_soc_card snd_soc_machine_simtec_aic33 = { | |||
| 96 | .name = "Simtec-Hermes", | 90 | .name = "Simtec-Hermes", |
| 97 | .dai_link = &simtec_dai_aic33, | 91 | .dai_link = &simtec_dai_aic33, |
| 98 | .num_links = 1, | 92 | .num_links = 1, |
| 93 | |||
| 94 | .dapm_widgets = dapm_widgets, | ||
| 95 | .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), | ||
| 96 | .dapm_routes = base_map, | ||
| 97 | .num_dapm_routes = ARRAY_SIZE(base_map), | ||
| 99 | }; | 98 | }; |
| 100 | 99 | ||
| 101 | static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) | 100 | static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) |
diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c index a7ef7db54687..7bdda7674008 100644 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c | |||
| @@ -54,18 +54,12 @@ static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) | |||
| 54 | struct snd_soc_codec *codec = rtd->codec; | 54 | struct snd_soc_codec *codec = rtd->codec; |
| 55 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 55 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 56 | 56 | ||
| 57 | snd_soc_dapm_new_controls(dapm, dapm_widgets, | ||
| 58 | ARRAY_SIZE(dapm_widgets)); | ||
| 59 | |||
| 60 | snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); | ||
| 61 | |||
| 62 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); | 57 | snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); |
| 63 | snd_soc_dapm_enable_pin(dapm, "Line In"); | 58 | snd_soc_dapm_enable_pin(dapm, "Line In"); |
| 64 | snd_soc_dapm_enable_pin(dapm, "Line Out"); | 59 | snd_soc_dapm_enable_pin(dapm, "Line Out"); |
| 65 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); | 60 | snd_soc_dapm_enable_pin(dapm, "Mic Jack"); |
| 66 | 61 | ||
| 67 | simtec_audio_init(rtd); | 62 | simtec_audio_init(rtd); |
| 68 | snd_soc_dapm_sync(dapm); | ||
| 69 | 63 | ||
| 70 | return 0; | 64 | return 0; |
| 71 | } | 65 | } |
| @@ -85,6 +79,11 @@ static struct snd_soc_card snd_soc_machine_simtec_aic23 = { | |||
| 85 | .name = "Simtec", | 79 | .name = "Simtec", |
| 86 | .dai_link = &simtec_dai_aic23, | 80 | .dai_link = &simtec_dai_aic23, |
| 87 | .num_links = 1, | 81 | .num_links = 1, |
| 82 | |||
| 83 | .dapm_widgets = dapm_widgets, | ||
| 84 | .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), | ||
| 85 | .dapm_routes = base_map, | ||
| 86 | .num_dapm_routes = ARRAY_SIZE(base_map), | ||
| 88 | }; | 87 | }; |
| 89 | 88 | ||
| 90 | static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) | 89 | static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) |
diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c index dc9d551f6788..65c1cfd47d8a 100644 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ b/sound/soc/samsung/s3c24xx_uda134x.c | |||
| @@ -66,17 +66,17 @@ static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) | |||
| 66 | pr_debug("%s %d\n", __func__, clk_users); | 66 | pr_debug("%s %d\n", __func__, clk_users); |
| 67 | if (clk_users == 0) { | 67 | if (clk_users == 0) { |
| 68 | xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); | 68 | xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); |
| 69 | if (!xtal) { | 69 | if (IS_ERR(xtal)) { |
| 70 | printk(KERN_ERR "%s cannot get xtal\n", __func__); | 70 | printk(KERN_ERR "%s cannot get xtal\n", __func__); |
| 71 | ret = -EBUSY; | 71 | ret = PTR_ERR(xtal); |
| 72 | } else { | 72 | } else { |
| 73 | pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, | 73 | pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, |
| 74 | "pclk"); | 74 | "pclk"); |
| 75 | if (!pclk) { | 75 | if (IS_ERR(pclk)) { |
| 76 | printk(KERN_ERR "%s cannot get pclk\n", | 76 | printk(KERN_ERR "%s cannot get pclk\n", |
| 77 | __func__); | 77 | __func__); |
| 78 | clk_put(xtal); | 78 | clk_put(xtal); |
| 79 | ret = -EBUSY; | 79 | ret = PTR_ERR(pclk); |
| 80 | } | 80 | } |
| 81 | } | 81 | } |
| 82 | if (!ret) { | 82 | if (!ret) { |
diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 0a2c4f223038..6ac6bc2bcc4e 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c | |||
| @@ -153,20 +153,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) | |||
| 153 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 153 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 154 | int err = 0; | 154 | int err = 0; |
| 155 | 155 | ||
| 156 | /* Add SmartQ specific widgets */ | ||
| 157 | snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets, | ||
| 158 | ARRAY_SIZE(wm8987_dapm_widgets)); | ||
| 159 | |||
| 160 | /* add SmartQ specific controls */ | ||
| 161 | err = snd_soc_add_controls(codec, wm8987_smartq_controls, | ||
| 162 | ARRAY_SIZE(wm8987_smartq_controls)); | ||
| 163 | |||
| 164 | if (err < 0) | ||
| 165 | return err; | ||
| 166 | |||
| 167 | /* setup SmartQ specific audio path */ | ||
| 168 | snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); | ||
| 169 | |||
| 170 | /* set endpoints to not connected */ | 156 | /* set endpoints to not connected */ |
| 171 | snd_soc_dapm_nc_pin(dapm, "LINPUT1"); | 157 | snd_soc_dapm_nc_pin(dapm, "LINPUT1"); |
| 172 | snd_soc_dapm_nc_pin(dapm, "RINPUT1"); | 158 | snd_soc_dapm_nc_pin(dapm, "RINPUT1"); |
| @@ -178,10 +164,6 @@ static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) | |||
| 178 | snd_soc_dapm_enable_pin(dapm, "Internal Mic"); | 164 | snd_soc_dapm_enable_pin(dapm, "Internal Mic"); |
| 179 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); | 165 | snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); |
| 180 | 166 | ||
| 181 | err = snd_soc_dapm_sync(dapm); | ||
| 182 | if (err) | ||
| 183 | return err; | ||
| 184 | |||
| 185 | /* Headphone jack detection */ | 167 | /* Headphone jack detection */ |
| 186 | err = snd_soc_jack_new(codec, "Headphone Jack", | 168 | err = snd_soc_jack_new(codec, "Headphone Jack", |
| 187 | SND_JACK_HEADPHONE, &smartq_jack); | 169 | SND_JACK_HEADPHONE, &smartq_jack); |
| @@ -207,7 +189,7 @@ static struct snd_soc_dai_link smartq_dai[] = { | |||
| 207 | .cpu_dai_name = "samsung-i2s.0", | 189 | .cpu_dai_name = "samsung-i2s.0", |
| 208 | .codec_dai_name = "wm8750-hifi", | 190 | .codec_dai_name = "wm8750-hifi", |
| 209 | .platform_name = "samsung-audio", | 191 | .platform_name = "samsung-audio", |
| 210 | .codec_name = "wm8750-codec.0-0x1a", | 192 | .codec_name = "wm8750.0-0x1a", |
| 211 | .init = smartq_wm8987_init, | 193 | .init = smartq_wm8987_init, |
| 212 | .ops = &smartq_hifi_ops, | 194 | .ops = &smartq_hifi_ops, |
| 213 | }, | 195 | }, |
| @@ -217,6 +199,13 @@ static struct snd_soc_card snd_soc_smartq = { | |||
| 217 | .name = "SmartQ", | 199 | .name = "SmartQ", |
| 218 | .dai_link = smartq_dai, | 200 | .dai_link = smartq_dai, |
| 219 | .num_links = ARRAY_SIZE(smartq_dai), | 201 | .num_links = ARRAY_SIZE(smartq_dai), |
| 202 | |||
| 203 | .dapm_widgets = wm8987_dapm_widgets, | ||
| 204 | .num_dapm_widgets = ARRAY_SIZE(wm8987_dapm_widgets), | ||
| 205 | .dapm_routes = audio_map, | ||
| 206 | .num_dapm_routes = ARRAY_SIZE(audio_map), | ||
| 207 | .controls = wm8987_smartq_controls, | ||
| 208 | .num_controls = ARRAY_SIZE(wm8987_smartq_controls), | ||
| 220 | }; | 209 | }; |
| 221 | 210 | ||
| 222 | static struct platform_device *smartq_snd_device; | 211 | static struct platform_device *smartq_snd_device; |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 3d26f6607aa4..8f92ffceb5ca 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
| @@ -119,30 +119,24 @@ static struct snd_soc_ops smdk_ops = { | |||
| 119 | }; | 119 | }; |
| 120 | 120 | ||
| 121 | /* SMDK Playback widgets */ | 121 | /* SMDK Playback widgets */ |
| 122 | static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { | 122 | static const struct snd_soc_dapm_widget smdk_wm8580_dapm_widgets[] = { |
| 123 | SND_SOC_DAPM_HP("Front", NULL), | 123 | SND_SOC_DAPM_HP("Front", NULL), |
| 124 | SND_SOC_DAPM_HP("Center+Sub", NULL), | 124 | SND_SOC_DAPM_HP("Center+Sub", NULL), |
| 125 | SND_SOC_DAPM_HP("Rear", NULL), | 125 | SND_SOC_DAPM_HP("Rear", NULL), |
| 126 | }; | ||
| 127 | 126 | ||
| 128 | /* SMDK Capture widgets */ | ||
| 129 | static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { | ||
| 130 | SND_SOC_DAPM_MIC("MicIn", NULL), | 127 | SND_SOC_DAPM_MIC("MicIn", NULL), |
| 131 | SND_SOC_DAPM_LINE("LineIn", NULL), | 128 | SND_SOC_DAPM_LINE("LineIn", NULL), |
| 132 | }; | 129 | }; |
| 133 | 130 | ||
| 134 | /* SMDK-PAIFTX connections */ | 131 | /* SMDK-PAIFTX connections */ |
| 135 | static const struct snd_soc_dapm_route audio_map_tx[] = { | 132 | static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = { |
| 136 | /* MicIn feeds AINL */ | 133 | /* MicIn feeds AINL */ |
| 137 | {"AINL", NULL, "MicIn"}, | 134 | {"AINL", NULL, "MicIn"}, |
| 138 | 135 | ||
| 139 | /* LineIn feeds AINL/R */ | 136 | /* LineIn feeds AINL/R */ |
| 140 | {"AINL", NULL, "LineIn"}, | 137 | {"AINL", NULL, "LineIn"}, |
| 141 | {"AINR", NULL, "LineIn"}, | 138 | {"AINR", NULL, "LineIn"}, |
| 142 | }; | ||
| 143 | 139 | ||
| 144 | /* SMDK-PAIFRX connections */ | ||
| 145 | static const struct snd_soc_dapm_route audio_map_rx[] = { | ||
| 146 | /* Front Left/Right are fed VOUT1L/R */ | 140 | /* Front Left/Right are fed VOUT1L/R */ |
| 147 | {"Front", NULL, "VOUT1L"}, | 141 | {"Front", NULL, "VOUT1L"}, |
| 148 | {"Front", NULL, "VOUT1R"}, | 142 | {"Front", NULL, "VOUT1R"}, |
| @@ -161,39 +155,11 @@ static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) | |||
| 161 | struct snd_soc_codec *codec = rtd->codec; | 155 | struct snd_soc_codec *codec = rtd->codec; |
| 162 | struct snd_soc_dapm_context *dapm = &codec->dapm; | 156 | struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 163 | 157 | ||
| 164 | /* Add smdk specific Capture widgets */ | ||
| 165 | snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, | ||
| 166 | ARRAY_SIZE(wm8580_dapm_widgets_cpt)); | ||
| 167 | |||
| 168 | /* Set up PAIFTX audio path */ | ||
| 169 | snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); | ||
| 170 | |||
| 171 | /* Enabling the microphone requires the fitting of a 0R | 158 | /* Enabling the microphone requires the fitting of a 0R |
| 172 | * resistor to connect the line from the microphone jack. | 159 | * resistor to connect the line from the microphone jack. |
| 173 | */ | 160 | */ |
| 174 | snd_soc_dapm_disable_pin(dapm, "MicIn"); | 161 | snd_soc_dapm_disable_pin(dapm, "MicIn"); |
| 175 | 162 | ||
| 176 | /* signal a DAPM event */ | ||
| 177 | snd_soc_dapm_sync(dapm); | ||
| 178 | |||
| 179 | return 0; | ||
| 180 | } | ||
| 181 | |||
| 182 | static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) | ||
| 183 | { | ||
| 184 | struct snd_soc_codec *codec = rtd->codec; | ||
| 185 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 186 | |||
| 187 | /* Add smdk specific Playback widgets */ | ||
| 188 | snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, | ||
| 189 | ARRAY_SIZE(wm8580_dapm_widgets_pbk)); | ||
| 190 | |||
| 191 | /* Set up PAIFRX audio path */ | ||
| 192 | snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); | ||
| 193 | |||
| 194 | /* signal a DAPM event */ | ||
| 195 | snd_soc_dapm_sync(dapm); | ||
| 196 | |||
| 197 | return 0; | 163 | return 0; |
| 198 | } | 164 | } |
| 199 | 165 | ||
| @@ -210,8 +176,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
| 210 | .cpu_dai_name = "samsung-i2s.0", | 176 | .cpu_dai_name = "samsung-i2s.0", |
| 211 | .codec_dai_name = "wm8580-hifi-playback", | 177 | .codec_dai_name = "wm8580-hifi-playback", |
| 212 | .platform_name = "samsung-audio", | 178 | .platform_name = "samsung-audio", |
| 213 | .codec_name = "wm8580-codec.0-001b", | 179 | .codec_name = "wm8580.0-001b", |
| 214 | .init = smdk_wm8580_init_paifrx, | ||
| 215 | .ops = &smdk_ops, | 180 | .ops = &smdk_ops, |
| 216 | }, | 181 | }, |
| 217 | [PRI_CAPTURE] = { /* Primary Capture i/f */ | 182 | [PRI_CAPTURE] = { /* Primary Capture i/f */ |
| @@ -220,7 +185,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
| 220 | .cpu_dai_name = "samsung-i2s.0", | 185 | .cpu_dai_name = "samsung-i2s.0", |
| 221 | .codec_dai_name = "wm8580-hifi-capture", | 186 | .codec_dai_name = "wm8580-hifi-capture", |
| 222 | .platform_name = "samsung-audio", | 187 | .platform_name = "samsung-audio", |
| 223 | .codec_name = "wm8580-codec.0-001b", | 188 | .codec_name = "wm8580.0-001b", |
| 224 | .init = smdk_wm8580_init_paiftx, | 189 | .init = smdk_wm8580_init_paiftx, |
| 225 | .ops = &smdk_ops, | 190 | .ops = &smdk_ops, |
| 226 | }, | 191 | }, |
| @@ -230,8 +195,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
| 230 | .cpu_dai_name = "samsung-i2s.x", | 195 | .cpu_dai_name = "samsung-i2s.x", |
| 231 | .codec_dai_name = "wm8580-hifi-playback", | 196 | .codec_dai_name = "wm8580-hifi-playback", |
| 232 | .platform_name = "samsung-audio", | 197 | .platform_name = "samsung-audio", |
| 233 | .codec_name = "wm8580-codec.0-001b", | 198 | .codec_name = "wm8580.0-001b", |
| 234 | .init = smdk_wm8580_init_paifrx, | ||
| 235 | .ops = &smdk_ops, | 199 | .ops = &smdk_ops, |
| 236 | }, | 200 | }, |
| 237 | }; | 201 | }; |
| @@ -240,6 +204,11 @@ static struct snd_soc_card smdk = { | |||
| 240 | .name = "SMDK-I2S", | 204 | .name = "SMDK-I2S", |
| 241 | .dai_link = smdk_dai, | 205 | .dai_link = smdk_dai, |
| 242 | .num_links = 2, | 206 | .num_links = 2, |
| 207 | |||
| 208 | .dapm_widgets = smdk_wm8580_dapm_widgets, | ||
| 209 | .num_dapm_widgets = ARRAY_SIZE(smdk_wm8580_dapm_widgets), | ||
| 210 | .dapm_routes = smdk_wm8580_audio_map, | ||
| 211 | .num_dapm_routes = ARRAY_SIZE(smdk_wm8580_audio_map), | ||
| 243 | }; | 212 | }; |
| 244 | 213 | ||
| 245 | static struct platform_device *smdk_snd_device; | 214 | static struct platform_device *smdk_snd_device; |
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c index 0d12092df164..4b9c73477ce0 100644 --- a/sound/soc/samsung/smdk_wm8580pcm.c +++ b/sound/soc/samsung/smdk_wm8580pcm.c | |||
| @@ -127,7 +127,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
| 127 | .cpu_dai_name = "samsung-pcm.0", | 127 | .cpu_dai_name = "samsung-pcm.0", |
| 128 | .codec_dai_name = "wm8580-hifi-playback", | 128 | .codec_dai_name = "wm8580-hifi-playback", |
| 129 | .platform_name = "samsung-audio", | 129 | .platform_name = "samsung-audio", |
| 130 | .codec_name = "wm8580-codec.0-001b", | 130 | .codec_name = "wm8580.0-001b", |
| 131 | .ops = &smdk_wm8580_pcm_ops, | 131 | .ops = &smdk_wm8580_pcm_ops, |
| 132 | }, { | 132 | }, { |
| 133 | .name = "WM8580 PAIF PCM TX", | 133 | .name = "WM8580 PAIF PCM TX", |
| @@ -135,7 +135,7 @@ static struct snd_soc_dai_link smdk_dai[] = { | |||
| 135 | .cpu_dai_name = "samsung-pcm.0", | 135 | .cpu_dai_name = "samsung-pcm.0", |
| 136 | .codec_dai_name = "wm8580-hifi-capture", | 136 | .codec_dai_name = "wm8580-hifi-capture", |
| 137 | .platform_name = "samsung-audio", | 137 | .platform_name = "samsung-audio", |
| 138 | .codec_name = "wm8580-codec.0-001b", | 138 | .codec_name = "wm8580.0-001b", |
| 139 | .ops = &smdk_wm8580_pcm_ops, | 139 | .ops = &smdk_wm8580_pcm_ops, |
| 140 | }, | 140 | }, |
| 141 | }; | 141 | }; |
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index 45fbe2b3727f..f75e43997d5b 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c | |||
| @@ -117,8 +117,6 @@ static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd) | |||
| 117 | snd_soc_dapm_nc_pin(dapm, "IN1RP"); | 117 | snd_soc_dapm_nc_pin(dapm, "IN1RP"); |
| 118 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); | 118 | snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); |
| 119 | 119 | ||
| 120 | snd_soc_dapm_sync(dapm); | ||
| 121 | |||
| 122 | return 0; | 120 | return 0; |
| 123 | } | 121 | } |
| 124 | 122 | ||
diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c index 28c491dacf7a..3122f3154bfa 100644 --- a/sound/soc/samsung/spdif.c +++ b/sound/soc/samsung/spdif.c | |||
| @@ -340,7 +340,7 @@ static struct snd_soc_dai_ops spdif_dai_ops = { | |||
| 340 | .shutdown = spdif_shutdown, | 340 | .shutdown = spdif_shutdown, |
| 341 | }; | 341 | }; |
| 342 | 342 | ||
| 343 | struct snd_soc_dai_driver samsung_spdif_dai = { | 343 | static struct snd_soc_dai_driver samsung_spdif_dai = { |
| 344 | .name = "samsung-spdif", | 344 | .name = "samsung-spdif", |
| 345 | .playback = { | 345 | .playback = { |
| 346 | .stream_name = "S/PDIF Playback", | 346 | .stream_name = "S/PDIF Playback", |
| @@ -475,7 +475,7 @@ static __devexit int spdif_remove(struct platform_device *pdev) | |||
| 475 | 475 | ||
| 476 | static struct platform_driver samsung_spdif_driver = { | 476 | static struct platform_driver samsung_spdif_driver = { |
| 477 | .probe = spdif_probe, | 477 | .probe = spdif_probe, |
| 478 | .remove = spdif_remove, | 478 | .remove = __devexit_p(spdif_remove), |
| 479 | .driver = { | 479 | .driver = { |
| 480 | .name = "samsung-spdif", | 480 | .name = "samsung-spdif", |
| 481 | .owner = THIS_MODULE, | 481 | .owner = THIS_MODULE, |
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 590e9274b062..b9e213f6cc06 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c | |||
| @@ -125,10 +125,6 @@ static struct snd_soc_jack_pin speyside_headset_pins[] = { | |||
| 125 | .pin = "Headset Mic", | 125 | .pin = "Headset Mic", |
| 126 | .mask = SND_JACK_MICROPHONE, | 126 | .mask = SND_JACK_MICROPHONE, |
| 127 | }, | 127 | }, |
| 128 | { | ||
| 129 | .pin = "Headphone", | ||
| 130 | .mask = SND_JACK_HEADPHONE, | ||
| 131 | }, | ||
| 132 | }; | 128 | }; |
| 133 | 129 | ||
| 134 | /* Default the headphone selection to active high */ | 130 | /* Default the headphone selection to active high */ |
| @@ -171,7 +167,8 @@ static int speyside_wm8996_init(struct snd_soc_pcm_runtime *rtd) | |||
| 171 | gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); | 167 | gpio_direction_output(WM8996_HPSEL_GPIO, speyside_jack_polarity); |
| 172 | 168 | ||
| 173 | ret = snd_soc_jack_new(codec, "Headset", | 169 | ret = snd_soc_jack_new(codec, "Headset", |
| 174 | SND_JACK_HEADSET | SND_JACK_BTN_0, | 170 | SND_JACK_LINEOUT | SND_JACK_HEADSET | |
| 171 | SND_JACK_BTN_0, | ||
| 175 | &speyside_headset); | 172 | &speyside_headset); |
| 176 | if (ret) | 173 | if (ret) |
| 177 | return ret; | 174 | return ret; |
| @@ -227,7 +224,7 @@ static int speyside_wm9081_init(struct snd_soc_dapm_context *dapm) | |||
| 227 | snd_soc_dapm_nc_pin(dapm, "LINEOUT"); | 224 | snd_soc_dapm_nc_pin(dapm, "LINEOUT"); |
| 228 | 225 | ||
| 229 | /* At any time the WM9081 is active it will have this clock */ | 226 | /* At any time the WM9081 is active it will have this clock */ |
| 230 | return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, | 227 | return snd_soc_codec_set_sysclk(dapm->codec, WM9081_SYSCLK_MCLK, 0, |
| 231 | 48000 * 256, 0); | 228 | 48000 * 256, 0); |
| 232 | } | 229 | } |
| 233 | 230 | ||
| @@ -252,6 +249,7 @@ static const struct snd_kcontrol_new controls[] = { | |||
| 252 | SOC_DAPM_PIN_SWITCH("Main AMIC"), | 249 | SOC_DAPM_PIN_SWITCH("Main AMIC"), |
| 253 | SOC_DAPM_PIN_SWITCH("WM1250 Input"), | 250 | SOC_DAPM_PIN_SWITCH("WM1250 Input"), |
| 254 | SOC_DAPM_PIN_SWITCH("WM1250 Output"), | 251 | SOC_DAPM_PIN_SWITCH("WM1250 Output"), |
| 252 | SOC_DAPM_PIN_SWITCH("Headphone"), | ||
| 255 | }; | 253 | }; |
| 256 | 254 | ||
| 257 | static struct snd_soc_dapm_widget widgets[] = { | 255 | static struct snd_soc_dapm_widget widgets[] = { |
diff --git a/sound/soc/samsung/speyside_wm8962.c b/sound/soc/samsung/speyside_wm8962.c index 72535f2daaf2..8a082044436e 100644 --- a/sound/soc/samsung/speyside_wm8962.c +++ b/sound/soc/samsung/speyside_wm8962.c | |||
| @@ -16,6 +16,8 @@ | |||
| 16 | 16 | ||
| 17 | #include "../codecs/wm8962.h" | 17 | #include "../codecs/wm8962.h" |
| 18 | 18 | ||
| 19 | static int sample_rate = 44100; | ||
| 20 | |||
| 19 | static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, | 21 | static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, |
| 20 | struct snd_soc_dapm_context *dapm, | 22 | struct snd_soc_dapm_context *dapm, |
| 21 | enum snd_soc_bias_level level) | 23 | enum snd_soc_bias_level level) |
| @@ -31,13 +33,13 @@ static int speyside_wm8962_set_bias_level(struct snd_soc_card *card, | |||
| 31 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { | 33 | if (dapm->bias_level == SND_SOC_BIAS_STANDBY) { |
| 32 | ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, | 34 | ret = snd_soc_dai_set_pll(codec_dai, WM8962_FLL, |
| 33 | WM8962_FLL_MCLK, 32768, | 35 | WM8962_FLL_MCLK, 32768, |
| 34 | 44100 * 256); | 36 | sample_rate * 512); |
| 35 | if (ret < 0) | 37 | if (ret < 0) |
| 36 | pr_err("Failed to start FLL: %d\n", ret); | 38 | pr_err("Failed to start FLL: %d\n", ret); |
| 37 | 39 | ||
| 38 | ret = snd_soc_dai_set_sysclk(codec_dai, | 40 | ret = snd_soc_dai_set_sysclk(codec_dai, |
| 39 | WM8962_SYSCLK_FLL, | 41 | WM8962_SYSCLK_FLL, |
| 40 | 44100 * 256, | 42 | sample_rate * 512, |
| 41 | SND_SOC_CLOCK_IN); | 43 | SND_SOC_CLOCK_IN); |
| 42 | if (ret < 0) { | 44 | if (ret < 0) { |
| 43 | pr_err("Failed to set SYSCLK: %d\n", ret); | 45 | pr_err("Failed to set SYSCLK: %d\n", ret); |
| @@ -92,22 +94,7 @@ static int speyside_wm8962_set_bias_level_post(struct snd_soc_card *card, | |||
| 92 | static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream, | 94 | static int speyside_wm8962_hw_params(struct snd_pcm_substream *substream, |
| 93 | struct snd_pcm_hw_params *params) | 95 | struct snd_pcm_hw_params *params) |
| 94 | { | 96 | { |
| 95 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 97 | sample_rate = params_rate(params); |
| 96 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 97 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 98 | int ret; | ||
| 99 | |||
| 100 | ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | ||
| 101 | | SND_SOC_DAIFMT_NB_NF | ||
| 102 | | SND_SOC_DAIFMT_CBM_CFM); | ||
| 103 | if (ret < 0) | ||
| 104 | return ret; | ||
| 105 | |||
| 106 | ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | ||
| 107 | | SND_SOC_DAIFMT_NB_NF | ||
| 108 | | SND_SOC_DAIFMT_CBM_CFM); | ||
| 109 | if (ret < 0) | ||
| 110 | return ret; | ||
| 111 | 98 | ||
| 112 | return 0; | 99 | return 0; |
| 113 | } | 100 | } |
| @@ -124,12 +111,15 @@ static struct snd_soc_dai_link speyside_wm8962_dai[] = { | |||
| 124 | .codec_dai_name = "wm8962", | 111 | .codec_dai_name = "wm8962", |
| 125 | .platform_name = "samsung-audio", | 112 | .platform_name = "samsung-audio", |
| 126 | .codec_name = "wm8962.1-001a", | 113 | .codec_name = "wm8962.1-001a", |
| 114 | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | ||
| 115 | | SND_SOC_DAIFMT_CBM_CFM, | ||
| 127 | .ops = &speyside_wm8962_ops, | 116 | .ops = &speyside_wm8962_ops, |
| 128 | }, | 117 | }, |
| 129 | }; | 118 | }; |
| 130 | 119 | ||
| 131 | static const struct snd_kcontrol_new controls[] = { | 120 | static const struct snd_kcontrol_new controls[] = { |
| 132 | SOC_DAPM_PIN_SWITCH("Main Speaker"), | 121 | SOC_DAPM_PIN_SWITCH("Main Speaker"), |
| 122 | SOC_DAPM_PIN_SWITCH("DMIC"), | ||
| 133 | }; | 123 | }; |
| 134 | 124 | ||
| 135 | static struct snd_soc_dapm_widget widgets[] = { | 125 | static struct snd_soc_dapm_widget widgets[] = { |
| @@ -137,6 +127,7 @@ static struct snd_soc_dapm_widget widgets[] = { | |||
| 137 | SND_SOC_DAPM_MIC("Headset Mic", NULL), | 127 | SND_SOC_DAPM_MIC("Headset Mic", NULL), |
| 138 | 128 | ||
| 139 | SND_SOC_DAPM_MIC("DMIC", NULL), | 129 | SND_SOC_DAPM_MIC("DMIC", NULL), |
| 130 | SND_SOC_DAPM_MIC("AMIC", NULL), | ||
| 140 | 131 | ||
| 141 | SND_SOC_DAPM_SPK("Main Speaker", NULL), | 132 | SND_SOC_DAPM_SPK("Main Speaker", NULL), |
| 142 | }; | 133 | }; |
| @@ -148,12 +139,16 @@ static struct snd_soc_dapm_route audio_paths[] = { | |||
| 148 | { "Main Speaker", NULL, "SPKOUTL" }, | 139 | { "Main Speaker", NULL, "SPKOUTL" }, |
| 149 | { "Main Speaker", NULL, "SPKOUTR" }, | 140 | { "Main Speaker", NULL, "SPKOUTR" }, |
| 150 | 141 | ||
| 151 | { "MICBIAS", NULL, "Headset Mic" }, | 142 | { "Headset Mic", NULL, "MICBIAS" }, |
| 152 | { "IN4L", NULL, "MICBIAS" }, | 143 | { "IN4L", NULL, "Headset Mic" }, |
| 153 | { "IN4R", NULL, "MICBIAS" }, | 144 | { "IN4R", NULL, "Headset Mic" }, |
| 145 | |||
| 146 | { "AMIC", NULL, "MICBIAS" }, | ||
| 147 | { "IN1L", NULL, "AMIC" }, | ||
| 148 | { "IN1R", NULL, "AMIC" }, | ||
| 154 | 149 | ||
| 155 | { "MICBIAS", NULL, "DMIC" }, | 150 | { "DMIC", NULL, "MICBIAS" }, |
| 156 | { "DMICDAT", NULL, "MICBIAS" }, | 151 | { "DMICDAT", NULL, "DMIC" }, |
| 157 | }; | 152 | }; |
| 158 | 153 | ||
| 159 | static struct snd_soc_jack speyside_wm8962_headset; | 154 | static struct snd_soc_jack speyside_wm8962_headset; |
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 8e112ccffb13..a32fd16ad668 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
| @@ -210,7 +210,7 @@ struct fsi_master { | |||
| 210 | * basic read write function | 210 | * basic read write function |
| 211 | */ | 211 | */ |
| 212 | 212 | ||
| 213 | static void __fsi_reg_write(u32 reg, u32 data) | 213 | static void __fsi_reg_write(u32 __iomem *reg, u32 data) |
| 214 | { | 214 | { |
| 215 | /* valid data area is 24bit */ | 215 | /* valid data area is 24bit */ |
| 216 | data &= 0x00ffffff; | 216 | data &= 0x00ffffff; |
| @@ -218,12 +218,12 @@ static void __fsi_reg_write(u32 reg, u32 data) | |||
| 218 | __raw_writel(data, reg); | 218 | __raw_writel(data, reg); |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | static u32 __fsi_reg_read(u32 reg) | 221 | static u32 __fsi_reg_read(u32 __iomem *reg) |
| 222 | { | 222 | { |
| 223 | return __raw_readl(reg); | 223 | return __raw_readl(reg); |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) | 226 | static void __fsi_reg_mask_set(u32 __iomem *reg, u32 mask, u32 data) |
| 227 | { | 227 | { |
| 228 | u32 val = __fsi_reg_read(reg); | 228 | u32 val = __fsi_reg_read(reg); |
| 229 | 229 | ||
| @@ -250,7 +250,7 @@ static u32 _fsi_master_read(struct fsi_master *master, u32 reg) | |||
| 250 | unsigned long flags; | 250 | unsigned long flags; |
| 251 | 251 | ||
| 252 | spin_lock_irqsave(&master->lock, flags); | 252 | spin_lock_irqsave(&master->lock, flags); |
| 253 | ret = __fsi_reg_read((u32)(master->base + reg)); | 253 | ret = __fsi_reg_read(master->base + reg); |
| 254 | spin_unlock_irqrestore(&master->lock, flags); | 254 | spin_unlock_irqrestore(&master->lock, flags); |
| 255 | 255 | ||
| 256 | return ret; | 256 | return ret; |
| @@ -264,7 +264,7 @@ static void _fsi_master_mask_set(struct fsi_master *master, | |||
| 264 | unsigned long flags; | 264 | unsigned long flags; |
| 265 | 265 | ||
| 266 | spin_lock_irqsave(&master->lock, flags); | 266 | spin_lock_irqsave(&master->lock, flags); |
| 267 | __fsi_reg_mask_set((u32)(master->base + reg), mask, data); | 267 | __fsi_reg_mask_set(master->base + reg, mask, data); |
| 268 | spin_unlock_irqrestore(&master->lock, flags); | 268 | spin_unlock_irqrestore(&master->lock, flags); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| @@ -1285,7 +1285,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
| 1285 | pm_runtime_enable(&pdev->dev); | 1285 | pm_runtime_enable(&pdev->dev); |
| 1286 | dev_set_drvdata(&pdev->dev, master); | 1286 | dev_set_drvdata(&pdev->dev, master); |
| 1287 | 1287 | ||
| 1288 | ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, | 1288 | ret = request_irq(irq, &fsi_interrupt, 0, |
| 1289 | id_entry->name, master); | 1289 | id_entry->name, master); |
| 1290 | if (ret) { | 1290 | if (ret) { |
| 1291 | dev_err(&pdev->dev, "irq request err\n"); | 1291 | dev_err(&pdev->dev, "irq request err\n"); |
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index 917d3ceadc9d..c62ae689c4a1 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c | |||
| @@ -20,12 +20,6 @@ | |||
| 20 | extern struct snd_soc_dai_driver sh4_hac_dai[2]; | 20 | extern struct snd_soc_dai_driver sh4_hac_dai[2]; |
| 21 | extern struct snd_soc_platform_driver sh7760_soc_platform; | 21 | extern struct snd_soc_platform_driver sh7760_soc_platform; |
| 22 | 22 | ||
| 23 | static int machine_init(struct snd_soc_pcm_runtime *rtd) | ||
| 24 | { | ||
| 25 | snd_soc_dapm_sync(&rtd->codec->dapm); | ||
| 26 | return 0; | ||
| 27 | } | ||
| 28 | |||
| 29 | static struct snd_soc_dai_link sh7760_ac97_dai = { | 23 | static struct snd_soc_dai_link sh7760_ac97_dai = { |
| 30 | .name = "AC97", | 24 | .name = "AC97", |
| 31 | .stream_name = "AC97 HiFi", | 25 | .stream_name = "AC97 HiFi", |
| @@ -33,7 +27,6 @@ static struct snd_soc_dai_link sh7760_ac97_dai = { | |||
| 33 | .codec_dai_name = "ac97-hifi", | 27 | .codec_dai_name = "ac97-hifi", |
| 34 | .platform_name = "sh7760-pcm-audio", | 28 | .platform_name = "sh7760-pcm-audio", |
| 35 | .codec_name = "ac97-codec", | 29 | .codec_name = "ac97-codec", |
| 36 | .init = machine_init, | ||
| 37 | .ops = NULL, | 30 | .ops = NULL, |
| 38 | }; | 31 | }; |
| 39 | 32 | ||
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index 05192d97b377..e0c621c0553b 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c | |||
| @@ -342,7 +342,7 @@ static struct snd_soc_dai_ops ssi_dai_ops = { | |||
| 342 | .set_fmt = ssi_set_fmt, | 342 | .set_fmt = ssi_set_fmt, |
| 343 | }; | 343 | }; |
| 344 | 344 | ||
| 345 | struct snd_soc_dai_driver sh4_ssi_dai[] = { | 345 | static struct snd_soc_dai_driver sh4_ssi_dai[] = { |
| 346 | { | 346 | { |
| 347 | .name = "ssi-dai.0", | 347 | .name = "ssi-dai.0", |
| 348 | .playback = { | 348 | .playback = { |
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 20b7f3b003a3..143c705ac27b 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c | |||
| @@ -548,9 +548,6 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, | |||
| 548 | 548 | ||
| 549 | static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) | 549 | static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) |
| 550 | { | 550 | { |
| 551 | const struct snd_soc_codec_driver *codec_drv; | ||
| 552 | |||
| 553 | codec_drv = codec->driver; | ||
| 554 | return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); | 551 | return DIV_ROUND_UP(codec->reg_size, snd_soc_lzo_block_count()); |
| 555 | } | 552 | } |
| 556 | 553 | ||
| @@ -868,10 +865,6 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec) | |||
| 868 | 865 | ||
| 869 | static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) | 866 | static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) |
| 870 | { | 867 | { |
| 871 | const struct snd_soc_codec_driver *codec_drv; | ||
| 872 | |||
| 873 | codec_drv = codec->driver; | ||
| 874 | |||
| 875 | if (codec->reg_def_copy) | 868 | if (codec->reg_def_copy) |
| 876 | codec->reg_cache = kmemdup(codec->reg_def_copy, | 869 | codec->reg_cache = kmemdup(codec->reg_def_copy, |
| 877 | codec->reg_size, GFP_KERNEL); | 870 | codec->reg_size, GFP_KERNEL); |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index ef69f5a02709..a5d3685a5d38 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -106,7 +106,7 @@ static int format_register_str(struct snd_soc_codec *codec, | |||
| 106 | if (wordsize + regsize + 2 + 1 != len) | 106 | if (wordsize + regsize + 2 + 1 != len) |
| 107 | return -EINVAL; | 107 | return -EINVAL; |
| 108 | 108 | ||
| 109 | ret = snd_soc_read(codec , reg); | 109 | ret = snd_soc_read(codec, reg); |
| 110 | if (ret < 0) { | 110 | if (ret < 0) { |
| 111 | memset(regbuf, 'X', regsize); | 111 | memset(regbuf, 'X', regsize); |
| 112 | regbuf[regsize] = '\0'; | 112 | regbuf[regsize] = '\0'; |
| @@ -144,7 +144,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf, | |||
| 144 | step = codec->driver->reg_cache_step; | 144 | step = codec->driver->reg_cache_step; |
| 145 | 145 | ||
| 146 | for (i = 0; i < codec->driver->reg_cache_size; i += step) { | 146 | for (i = 0; i < codec->driver->reg_cache_size; i += step) { |
| 147 | if (codec->readable_register && !codec->readable_register(codec, i)) | 147 | if (!snd_soc_codec_readable_register(codec, i)) |
| 148 | continue; | 148 | continue; |
| 149 | if (codec->driver->display_register) { | 149 | if (codec->driver->display_register) { |
| 150 | count += codec->driver->display_register(codec, buf + count, | 150 | count += codec->driver->display_register(codec, buf + count, |
| @@ -245,7 +245,6 @@ static ssize_t codec_reg_write_file(struct file *file, | |||
| 245 | size_t buf_size; | 245 | size_t buf_size; |
| 246 | char *start = buf; | 246 | char *start = buf; |
| 247 | unsigned long reg, value; | 247 | unsigned long reg, value; |
| 248 | int step = 1; | ||
| 249 | struct snd_soc_codec *codec = file->private_data; | 248 | struct snd_soc_codec *codec = file->private_data; |
| 250 | 249 | ||
| 251 | buf_size = min(count, (sizeof(buf)-1)); | 250 | buf_size = min(count, (sizeof(buf)-1)); |
| @@ -253,9 +252,6 @@ static ssize_t codec_reg_write_file(struct file *file, | |||
| 253 | return -EFAULT; | 252 | return -EFAULT; |
| 254 | buf[buf_size] = 0; | 253 | buf[buf_size] = 0; |
| 255 | 254 | ||
| 256 | if (codec->driver->reg_cache_step) | ||
| 257 | step = codec->driver->reg_cache_step; | ||
| 258 | |||
| 259 | while (*start == ' ') | 255 | while (*start == ' ') |
| 260 | start++; | 256 | start++; |
| 261 | reg = simple_strtoul(start, &start, 16); | 257 | reg = simple_strtoul(start, &start, 16); |
| @@ -957,6 +953,8 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
| 957 | snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, | 953 | snd_soc_dapm_new_controls(&codec->dapm, driver->dapm_widgets, |
| 958 | driver->num_dapm_widgets); | 954 | driver->num_dapm_widgets); |
| 959 | 955 | ||
| 956 | codec->dapm.idle_bias_off = driver->idle_bias_off; | ||
| 957 | |||
| 960 | if (driver->probe) { | 958 | if (driver->probe) { |
| 961 | ret = driver->probe(codec); | 959 | ret = driver->probe(codec); |
| 962 | if (ret < 0) { | 960 | if (ret < 0) { |
| @@ -1057,6 +1055,9 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
| 1057 | } | 1055 | } |
| 1058 | rtd->card = card; | 1056 | rtd->card = card; |
| 1059 | 1057 | ||
| 1058 | /* Make sure all DAPM widgets are instantiated */ | ||
| 1059 | snd_soc_dapm_new_widgets(&codec->dapm); | ||
| 1060 | |||
| 1060 | /* machine controls, routes and widgets are not prefixed */ | 1061 | /* machine controls, routes and widgets are not prefixed */ |
| 1061 | temp = codec->name_prefix; | 1062 | temp = codec->name_prefix; |
| 1062 | codec->name_prefix = NULL; | 1063 | codec->name_prefix = NULL; |
| @@ -1072,9 +1073,6 @@ static int soc_post_component_init(struct snd_soc_card *card, | |||
| 1072 | } | 1073 | } |
| 1073 | codec->name_prefix = temp; | 1074 | codec->name_prefix = temp; |
| 1074 | 1075 | ||
| 1075 | /* Make sure all DAPM widgets are instantiated */ | ||
| 1076 | snd_soc_dapm_new_widgets(&codec->dapm); | ||
| 1077 | |||
| 1078 | /* register the rtd device */ | 1076 | /* register the rtd device */ |
| 1079 | rtd->codec = codec; | 1077 | rtd->codec = codec; |
| 1080 | rtd->dev.parent = card->dev; | 1078 | rtd->dev.parent = card->dev; |
| @@ -1319,6 +1317,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
| 1319 | struct snd_soc_codec *codec; | 1317 | struct snd_soc_codec *codec; |
| 1320 | struct snd_soc_codec_conf *codec_conf; | 1318 | struct snd_soc_codec_conf *codec_conf; |
| 1321 | enum snd_soc_compress_type compress_type; | 1319 | enum snd_soc_compress_type compress_type; |
| 1320 | struct snd_soc_dai_link *dai_link; | ||
| 1322 | int ret, i, order; | 1321 | int ret, i, order; |
| 1323 | 1322 | ||
| 1324 | mutex_lock(&card->mutex); | 1323 | mutex_lock(&card->mutex); |
| @@ -1431,6 +1430,28 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
| 1431 | snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, | 1430 | snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, |
| 1432 | card->num_dapm_routes); | 1431 | card->num_dapm_routes); |
| 1433 | 1432 | ||
| 1433 | snd_soc_dapm_new_widgets(&card->dapm); | ||
| 1434 | |||
| 1435 | for (i = 0; i < card->num_links; i++) { | ||
| 1436 | dai_link = &card->dai_link[i]; | ||
| 1437 | |||
| 1438 | if (dai_link->dai_fmt) { | ||
| 1439 | ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai, | ||
| 1440 | dai_link->dai_fmt); | ||
| 1441 | if (ret != 0) | ||
| 1442 | dev_warn(card->rtd[i].codec_dai->dev, | ||
| 1443 | "Failed to set DAI format: %d\n", | ||
| 1444 | ret); | ||
| 1445 | |||
| 1446 | ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai, | ||
| 1447 | dai_link->dai_fmt); | ||
| 1448 | if (ret != 0) | ||
| 1449 | dev_warn(card->rtd[i].cpu_dai->dev, | ||
| 1450 | "Failed to set DAI format: %d\n", | ||
| 1451 | ret); | ||
| 1452 | } | ||
| 1453 | } | ||
| 1454 | |||
| 1434 | snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), | 1455 | snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), |
| 1435 | "%s", card->name); | 1456 | "%s", card->name); |
| 1436 | snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), | 1457 | snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), |
| @@ -1459,6 +1480,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
| 1459 | } | 1480 | } |
| 1460 | } | 1481 | } |
| 1461 | 1482 | ||
| 1483 | snd_soc_dapm_new_widgets(&card->dapm); | ||
| 1484 | |||
| 1462 | ret = snd_card_register(card->snd_card); | 1485 | ret = snd_card_register(card->snd_card); |
| 1463 | if (ret < 0) { | 1486 | if (ret < 0) { |
| 1464 | printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); | 1487 | printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); |
| @@ -1479,6 +1502,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
| 1479 | #endif | 1502 | #endif |
| 1480 | 1503 | ||
| 1481 | card->instantiated = 1; | 1504 | card->instantiated = 1; |
| 1505 | snd_soc_dapm_sync(&card->dapm); | ||
| 1482 | mutex_unlock(&card->mutex); | 1506 | mutex_unlock(&card->mutex); |
| 1483 | return; | 1507 | return; |
| 1484 | 1508 | ||
| @@ -2229,7 +2253,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext); | |||
| 2229 | * @kcontrol: mixer control | 2253 | * @kcontrol: mixer control |
| 2230 | * @uinfo: control element information | 2254 | * @uinfo: control element information |
| 2231 | * | 2255 | * |
| 2232 | * Callback to provide information about a single mixer control. | 2256 | * Callback to provide information about a single mixer control, or a double |
| 2257 | * mixer control that spans 2 registers. | ||
| 2233 | * | 2258 | * |
| 2234 | * Returns 0 for success. | 2259 | * Returns 0 for success. |
| 2235 | */ | 2260 | */ |
| @@ -2239,8 +2264,6 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | |||
| 2239 | struct soc_mixer_control *mc = | 2264 | struct soc_mixer_control *mc = |
| 2240 | (struct soc_mixer_control *)kcontrol->private_value; | 2265 | (struct soc_mixer_control *)kcontrol->private_value; |
| 2241 | int platform_max; | 2266 | int platform_max; |
| 2242 | unsigned int shift = mc->shift; | ||
| 2243 | unsigned int rshift = mc->rshift; | ||
| 2244 | 2267 | ||
| 2245 | if (!mc->platform_max) | 2268 | if (!mc->platform_max) |
| 2246 | mc->platform_max = mc->max; | 2269 | mc->platform_max = mc->max; |
| @@ -2251,7 +2274,7 @@ int snd_soc_info_volsw(struct snd_kcontrol *kcontrol, | |||
| 2251 | else | 2274 | else |
| 2252 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2275 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
| 2253 | 2276 | ||
| 2254 | uinfo->count = shift == rshift ? 1 : 2; | 2277 | uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1; |
| 2255 | uinfo->value.integer.min = 0; | 2278 | uinfo->value.integer.min = 0; |
| 2256 | uinfo->value.integer.max = platform_max; | 2279 | uinfo->value.integer.max = platform_max; |
| 2257 | return 0; | 2280 | return 0; |
| @@ -2263,7 +2286,8 @@ EXPORT_SYMBOL_GPL(snd_soc_info_volsw); | |||
| 2263 | * @kcontrol: mixer control | 2286 | * @kcontrol: mixer control |
| 2264 | * @ucontrol: control element information | 2287 | * @ucontrol: control element information |
| 2265 | * | 2288 | * |
| 2266 | * Callback to get the value of a single mixer control. | 2289 | * Callback to get the value of a single mixer control, or a double mixer |
| 2290 | * control that spans 2 registers. | ||
| 2267 | * | 2291 | * |
| 2268 | * Returns 0 for success. | 2292 | * Returns 0 for success. |
| 2269 | */ | 2293 | */ |
| @@ -2274,6 +2298,7 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
| 2274 | (struct soc_mixer_control *)kcontrol->private_value; | 2298 | (struct soc_mixer_control *)kcontrol->private_value; |
| 2275 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2299 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 2276 | unsigned int reg = mc->reg; | 2300 | unsigned int reg = mc->reg; |
| 2301 | unsigned int reg2 = mc->rreg; | ||
| 2277 | unsigned int shift = mc->shift; | 2302 | unsigned int shift = mc->shift; |
| 2278 | unsigned int rshift = mc->rshift; | 2303 | unsigned int rshift = mc->rshift; |
| 2279 | int max = mc->max; | 2304 | int max = mc->max; |
| @@ -2282,13 +2307,18 @@ int snd_soc_get_volsw(struct snd_kcontrol *kcontrol, | |||
| 2282 | 2307 | ||
| 2283 | ucontrol->value.integer.value[0] = | 2308 | ucontrol->value.integer.value[0] = |
| 2284 | (snd_soc_read(codec, reg) >> shift) & mask; | 2309 | (snd_soc_read(codec, reg) >> shift) & mask; |
| 2285 | if (shift != rshift) | 2310 | if (invert) |
| 2286 | ucontrol->value.integer.value[1] = | ||
| 2287 | (snd_soc_read(codec, reg) >> rshift) & mask; | ||
| 2288 | if (invert) { | ||
| 2289 | ucontrol->value.integer.value[0] = | 2311 | ucontrol->value.integer.value[0] = |
| 2290 | max - ucontrol->value.integer.value[0]; | 2312 | max - ucontrol->value.integer.value[0]; |
| 2291 | if (shift != rshift) | 2313 | |
| 2314 | if (snd_soc_volsw_is_stereo(mc)) { | ||
| 2315 | if (reg == reg2) | ||
| 2316 | ucontrol->value.integer.value[1] = | ||
| 2317 | (snd_soc_read(codec, reg) >> rshift) & mask; | ||
| 2318 | else | ||
| 2319 | ucontrol->value.integer.value[1] = | ||
| 2320 | (snd_soc_read(codec, reg2) >> shift) & mask; | ||
| 2321 | if (invert) | ||
| 2292 | ucontrol->value.integer.value[1] = | 2322 | ucontrol->value.integer.value[1] = |
| 2293 | max - ucontrol->value.integer.value[1]; | 2323 | max - ucontrol->value.integer.value[1]; |
| 2294 | } | 2324 | } |
| @@ -2302,7 +2332,8 @@ EXPORT_SYMBOL_GPL(snd_soc_get_volsw); | |||
| 2302 | * @kcontrol: mixer control | 2332 | * @kcontrol: mixer control |
| 2303 | * @ucontrol: control element information | 2333 | * @ucontrol: control element information |
| 2304 | * | 2334 | * |
| 2305 | * Callback to set the value of a single mixer control. | 2335 | * Callback to set the value of a single mixer control, or a double mixer |
| 2336 | * control that spans 2 registers. | ||
| 2306 | * | 2337 | * |
| 2307 | * Returns 0 for success. | 2338 | * Returns 0 for success. |
| 2308 | */ | 2339 | */ |
| @@ -2313,143 +2344,44 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol, | |||
| 2313 | (struct soc_mixer_control *)kcontrol->private_value; | 2344 | (struct soc_mixer_control *)kcontrol->private_value; |
| 2314 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2345 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 2315 | unsigned int reg = mc->reg; | 2346 | unsigned int reg = mc->reg; |
| 2347 | unsigned int reg2 = mc->rreg; | ||
| 2316 | unsigned int shift = mc->shift; | 2348 | unsigned int shift = mc->shift; |
| 2317 | unsigned int rshift = mc->rshift; | 2349 | unsigned int rshift = mc->rshift; |
| 2318 | int max = mc->max; | 2350 | int max = mc->max; |
| 2319 | unsigned int mask = (1 << fls(max)) - 1; | 2351 | unsigned int mask = (1 << fls(max)) - 1; |
| 2320 | unsigned int invert = mc->invert; | 2352 | unsigned int invert = mc->invert; |
| 2321 | unsigned int val, val2, val_mask; | 2353 | int err; |
| 2354 | bool type_2r = 0; | ||
| 2355 | unsigned int val2 = 0; | ||
| 2356 | unsigned int val, val_mask; | ||
| 2322 | 2357 | ||
| 2323 | val = (ucontrol->value.integer.value[0] & mask); | 2358 | val = (ucontrol->value.integer.value[0] & mask); |
| 2324 | if (invert) | 2359 | if (invert) |
| 2325 | val = max - val; | 2360 | val = max - val; |
| 2326 | val_mask = mask << shift; | 2361 | val_mask = mask << shift; |
| 2327 | val = val << shift; | 2362 | val = val << shift; |
| 2328 | if (shift != rshift) { | 2363 | if (snd_soc_volsw_is_stereo(mc)) { |
| 2329 | val2 = (ucontrol->value.integer.value[1] & mask); | 2364 | val2 = (ucontrol->value.integer.value[1] & mask); |
| 2330 | if (invert) | 2365 | if (invert) |
| 2331 | val2 = max - val2; | 2366 | val2 = max - val2; |
| 2332 | val_mask |= mask << rshift; | 2367 | if (reg == reg2) { |
| 2333 | val |= val2 << rshift; | 2368 | val_mask |= mask << rshift; |
| 2334 | } | 2369 | val |= val2 << rshift; |
| 2335 | return snd_soc_update_bits_locked(codec, reg, val_mask, val); | 2370 | } else { |
| 2336 | } | 2371 | val2 = val2 << shift; |
| 2337 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw); | 2372 | type_2r = 1; |
| 2338 | 2373 | } | |
| 2339 | /** | ||
| 2340 | * snd_soc_info_volsw_2r - double mixer info callback | ||
| 2341 | * @kcontrol: mixer control | ||
| 2342 | * @uinfo: control element information | ||
| 2343 | * | ||
| 2344 | * Callback to provide information about a double mixer control that | ||
| 2345 | * spans 2 codec registers. | ||
| 2346 | * | ||
| 2347 | * Returns 0 for success. | ||
| 2348 | */ | ||
| 2349 | int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol, | ||
| 2350 | struct snd_ctl_elem_info *uinfo) | ||
| 2351 | { | ||
| 2352 | struct soc_mixer_control *mc = | ||
| 2353 | (struct soc_mixer_control *)kcontrol->private_value; | ||
| 2354 | int platform_max; | ||
| 2355 | |||
| 2356 | if (!mc->platform_max) | ||
| 2357 | mc->platform_max = mc->max; | ||
| 2358 | platform_max = mc->platform_max; | ||
| 2359 | |||
| 2360 | if (platform_max == 1 && !strstr(kcontrol->id.name, " Volume")) | ||
| 2361 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
| 2362 | else | ||
| 2363 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
| 2364 | |||
| 2365 | uinfo->count = 2; | ||
| 2366 | uinfo->value.integer.min = 0; | ||
| 2367 | uinfo->value.integer.max = platform_max; | ||
| 2368 | return 0; | ||
| 2369 | } | ||
| 2370 | EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r); | ||
| 2371 | |||
| 2372 | /** | ||
| 2373 | * snd_soc_get_volsw_2r - double mixer get callback | ||
| 2374 | * @kcontrol: mixer control | ||
| 2375 | * @ucontrol: control element information | ||
| 2376 | * | ||
| 2377 | * Callback to get the value of a double mixer control that spans 2 registers. | ||
| 2378 | * | ||
| 2379 | * Returns 0 for success. | ||
| 2380 | */ | ||
| 2381 | int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol, | ||
| 2382 | struct snd_ctl_elem_value *ucontrol) | ||
| 2383 | { | ||
| 2384 | struct soc_mixer_control *mc = | ||
| 2385 | (struct soc_mixer_control *)kcontrol->private_value; | ||
| 2386 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 2387 | unsigned int reg = mc->reg; | ||
| 2388 | unsigned int reg2 = mc->rreg; | ||
| 2389 | unsigned int shift = mc->shift; | ||
| 2390 | int max = mc->max; | ||
| 2391 | unsigned int mask = (1 << fls(max)) - 1; | ||
| 2392 | unsigned int invert = mc->invert; | ||
| 2393 | |||
| 2394 | ucontrol->value.integer.value[0] = | ||
| 2395 | (snd_soc_read(codec, reg) >> shift) & mask; | ||
| 2396 | ucontrol->value.integer.value[1] = | ||
| 2397 | (snd_soc_read(codec, reg2) >> shift) & mask; | ||
| 2398 | if (invert) { | ||
| 2399 | ucontrol->value.integer.value[0] = | ||
| 2400 | max - ucontrol->value.integer.value[0]; | ||
| 2401 | ucontrol->value.integer.value[1] = | ||
| 2402 | max - ucontrol->value.integer.value[1]; | ||
| 2403 | } | ||
| 2404 | |||
| 2405 | return 0; | ||
| 2406 | } | ||
| 2407 | EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r); | ||
| 2408 | |||
| 2409 | /** | ||
| 2410 | * snd_soc_put_volsw_2r - double mixer set callback | ||
| 2411 | * @kcontrol: mixer control | ||
| 2412 | * @ucontrol: control element information | ||
| 2413 | * | ||
| 2414 | * Callback to set the value of a double mixer control that spans 2 registers. | ||
| 2415 | * | ||
| 2416 | * Returns 0 for success. | ||
| 2417 | */ | ||
| 2418 | int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol, | ||
| 2419 | struct snd_ctl_elem_value *ucontrol) | ||
| 2420 | { | ||
| 2421 | struct soc_mixer_control *mc = | ||
| 2422 | (struct soc_mixer_control *)kcontrol->private_value; | ||
| 2423 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
| 2424 | unsigned int reg = mc->reg; | ||
| 2425 | unsigned int reg2 = mc->rreg; | ||
| 2426 | unsigned int shift = mc->shift; | ||
| 2427 | int max = mc->max; | ||
| 2428 | unsigned int mask = (1 << fls(max)) - 1; | ||
| 2429 | unsigned int invert = mc->invert; | ||
| 2430 | int err; | ||
| 2431 | unsigned int val, val2, val_mask; | ||
| 2432 | |||
| 2433 | val_mask = mask << shift; | ||
| 2434 | val = (ucontrol->value.integer.value[0] & mask); | ||
| 2435 | val2 = (ucontrol->value.integer.value[1] & mask); | ||
| 2436 | |||
| 2437 | if (invert) { | ||
| 2438 | val = max - val; | ||
| 2439 | val2 = max - val2; | ||
| 2440 | } | 2374 | } |
| 2441 | |||
| 2442 | val = val << shift; | ||
| 2443 | val2 = val2 << shift; | ||
| 2444 | |||
| 2445 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); | 2375 | err = snd_soc_update_bits_locked(codec, reg, val_mask, val); |
| 2446 | if (err < 0) | 2376 | if (err < 0) |
| 2447 | return err; | 2377 | return err; |
| 2448 | 2378 | ||
| 2449 | err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2); | 2379 | if (type_2r) |
| 2380 | err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2); | ||
| 2381 | |||
| 2450 | return err; | 2382 | return err; |
| 2451 | } | 2383 | } |
| 2452 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); | 2384 | EXPORT_SYMBOL_GPL(snd_soc_put_volsw); |
| 2453 | 2385 | ||
| 2454 | /** | 2386 | /** |
| 2455 | * snd_soc_info_volsw_s8 - signed mixer info callback | 2387 | * snd_soc_info_volsw_s8 - signed mixer info callback |
| @@ -2680,7 +2612,7 @@ int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |||
| 2680 | if (dai->driver && dai->driver->ops->set_sysclk) | 2612 | if (dai->driver && dai->driver->ops->set_sysclk) |
| 2681 | return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); | 2613 | return dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); |
| 2682 | else if (dai->codec && dai->codec->driver->set_sysclk) | 2614 | else if (dai->codec && dai->codec->driver->set_sysclk) |
| 2683 | return dai->codec->driver->set_sysclk(dai->codec, clk_id, | 2615 | return dai->codec->driver->set_sysclk(dai->codec, clk_id, 0, |
| 2684 | freq, dir); | 2616 | freq, dir); |
| 2685 | else | 2617 | else |
| 2686 | return -EINVAL; | 2618 | return -EINVAL; |
| @@ -2691,16 +2623,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); | |||
| 2691 | * snd_soc_codec_set_sysclk - configure CODEC system or master clock. | 2623 | * snd_soc_codec_set_sysclk - configure CODEC system or master clock. |
| 2692 | * @codec: CODEC | 2624 | * @codec: CODEC |
| 2693 | * @clk_id: DAI specific clock ID | 2625 | * @clk_id: DAI specific clock ID |
| 2626 | * @source: Source for the clock | ||
| 2694 | * @freq: new clock frequency in Hz | 2627 | * @freq: new clock frequency in Hz |
| 2695 | * @dir: new clock direction - input/output. | 2628 | * @dir: new clock direction - input/output. |
| 2696 | * | 2629 | * |
| 2697 | * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. | 2630 | * Configures the CODEC master (MCLK) or system (SYSCLK) clocking. |
| 2698 | */ | 2631 | */ |
| 2699 | int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, | 2632 | int snd_soc_codec_set_sysclk(struct snd_soc_codec *codec, int clk_id, |
| 2700 | unsigned int freq, int dir) | 2633 | int source, unsigned int freq, int dir) |
| 2701 | { | 2634 | { |
| 2702 | if (codec->driver->set_sysclk) | 2635 | if (codec->driver->set_sysclk) |
| 2703 | return codec->driver->set_sysclk(codec, clk_id, freq, dir); | 2636 | return codec->driver->set_sysclk(codec, clk_id, source, |
| 2637 | freq, dir); | ||
| 2704 | else | 2638 | else |
| 2705 | return -EINVAL; | 2639 | return -EINVAL; |
| 2706 | } | 2640 | } |
| @@ -2895,6 +2829,7 @@ int snd_soc_register_card(struct snd_soc_card *card) | |||
| 2895 | card->rtd[i].dai_link = &card->dai_link[i]; | 2829 | card->rtd[i].dai_link = &card->dai_link[i]; |
| 2896 | 2830 | ||
| 2897 | INIT_LIST_HEAD(&card->list); | 2831 | INIT_LIST_HEAD(&card->list); |
| 2832 | INIT_LIST_HEAD(&card->dapm_dirty); | ||
| 2898 | card->instantiated = 0; | 2833 | card->instantiated = 0; |
| 2899 | mutex_init(&card->mutex); | 2834 | mutex_init(&card->mutex); |
| 2900 | 2835 | ||
| @@ -3153,6 +3088,7 @@ int snd_soc_register_platform(struct device *dev, | |||
| 3153 | platform->driver = platform_drv; | 3088 | platform->driver = platform_drv; |
| 3154 | platform->dapm.dev = dev; | 3089 | platform->dapm.dev = dev; |
| 3155 | platform->dapm.platform = platform; | 3090 | platform->dapm.platform = platform; |
| 3091 | platform->dapm.stream_event = platform_drv->stream_event; | ||
| 3156 | 3092 | ||
| 3157 | mutex_lock(&client_mutex); | 3093 | mutex_lock(&client_mutex); |
| 3158 | list_add(&platform->list, &platform_list); | 3094 | list_add(&platform->list, &platform_list); |
| @@ -3265,6 +3201,7 @@ int snd_soc_register_codec(struct device *dev, | |||
| 3265 | codec->dapm.dev = dev; | 3201 | codec->dapm.dev = dev; |
| 3266 | codec->dapm.codec = codec; | 3202 | codec->dapm.codec = codec; |
| 3267 | codec->dapm.seq_notifier = codec_drv->seq_notifier; | 3203 | codec->dapm.seq_notifier = codec_drv->seq_notifier; |
| 3204 | codec->dapm.stream_event = codec_drv->stream_event; | ||
| 3268 | codec->dev = dev; | 3205 | codec->dev = dev; |
| 3269 | codec->driver = codec_drv; | 3206 | codec->driver = codec_drv; |
| 3270 | codec->num_dai = num_dai; | 3207 | codec->num_dai = num_dai; |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d67c637557a7..f42e8b9fb17d 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
| @@ -48,6 +48,8 @@ | |||
| 48 | 48 | ||
| 49 | #include <trace/events/asoc.h> | 49 | #include <trace/events/asoc.h> |
| 50 | 50 | ||
| 51 | #define DAPM_UPDATE_STAT(widget, val) widget->dapm->card->dapm_stats.val++; | ||
| 52 | |||
| 51 | /* dapm power sequences - make this per codec in the future */ | 53 | /* dapm power sequences - make this per codec in the future */ |
| 52 | static int dapm_up_seq[] = { | 54 | static int dapm_up_seq[] = { |
| 53 | [snd_soc_dapm_pre] = 0, | 55 | [snd_soc_dapm_pre] = 0, |
| @@ -117,6 +119,21 @@ static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) | |||
| 117 | kfree(buf); | 119 | kfree(buf); |
| 118 | } | 120 | } |
| 119 | 121 | ||
| 122 | static bool dapm_dirty_widget(struct snd_soc_dapm_widget *w) | ||
| 123 | { | ||
| 124 | return !list_empty(&w->dirty); | ||
| 125 | } | ||
| 126 | |||
| 127 | void dapm_mark_dirty(struct snd_soc_dapm_widget *w, const char *reason) | ||
| 128 | { | ||
| 129 | if (!dapm_dirty_widget(w)) { | ||
| 130 | dev_vdbg(w->dapm->dev, "Marking %s dirty due to %s\n", | ||
| 131 | w->name, reason); | ||
| 132 | list_add_tail(&w->dirty, &w->dapm->card->dapm_dirty); | ||
| 133 | } | ||
| 134 | } | ||
| 135 | EXPORT_SYMBOL_GPL(dapm_mark_dirty); | ||
| 136 | |||
| 120 | /* create a new dapm widget */ | 137 | /* create a new dapm widget */ |
| 121 | static inline struct snd_soc_dapm_widget *dapm_cnew_widget( | 138 | static inline struct snd_soc_dapm_widget *dapm_cnew_widget( |
| 122 | const struct snd_soc_dapm_widget *_widget) | 139 | const struct snd_soc_dapm_widget *_widget) |
| @@ -316,7 +333,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
| 316 | } | 333 | } |
| 317 | } | 334 | } |
| 318 | break; | 335 | break; |
| 319 | /* does not effect routing - always connected */ | 336 | /* does not affect routing - always connected */ |
| 320 | case snd_soc_dapm_pga: | 337 | case snd_soc_dapm_pga: |
| 321 | case snd_soc_dapm_out_drv: | 338 | case snd_soc_dapm_out_drv: |
| 322 | case snd_soc_dapm_output: | 339 | case snd_soc_dapm_output: |
| @@ -328,13 +345,13 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, | |||
| 328 | case snd_soc_dapm_supply: | 345 | case snd_soc_dapm_supply: |
| 329 | case snd_soc_dapm_aif_in: | 346 | case snd_soc_dapm_aif_in: |
| 330 | case snd_soc_dapm_aif_out: | 347 | case snd_soc_dapm_aif_out: |
| 331 | p->connect = 1; | ||
| 332 | break; | ||
| 333 | /* does effect routing - dynamically connected */ | ||
| 334 | case snd_soc_dapm_hp: | 348 | case snd_soc_dapm_hp: |
| 335 | case snd_soc_dapm_mic: | 349 | case snd_soc_dapm_mic: |
| 336 | case snd_soc_dapm_spk: | 350 | case snd_soc_dapm_spk: |
| 337 | case snd_soc_dapm_line: | 351 | case snd_soc_dapm_line: |
| 352 | p->connect = 1; | ||
| 353 | break; | ||
| 354 | /* does affect routing - dynamically connected */ | ||
| 338 | case snd_soc_dapm_pre: | 355 | case snd_soc_dapm_pre: |
| 339 | case snd_soc_dapm_post: | 356 | case snd_soc_dapm_post: |
| 340 | p->connect = 0; | 357 | p->connect = 0; |
| @@ -443,6 +460,11 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w) | |||
| 443 | if (path->name != (char *)w->kcontrol_news[i].name) | 460 | if (path->name != (char *)w->kcontrol_news[i].name) |
| 444 | continue; | 461 | continue; |
| 445 | 462 | ||
| 463 | if (w->kcontrols[i]) { | ||
| 464 | path->kcontrol = w->kcontrols[i]; | ||
| 465 | continue; | ||
| 466 | } | ||
| 467 | |||
| 446 | wlistsize = sizeof(struct snd_soc_dapm_widget_list) + | 468 | wlistsize = sizeof(struct snd_soc_dapm_widget_list) + |
| 447 | sizeof(struct snd_soc_dapm_widget *), | 469 | sizeof(struct snd_soc_dapm_widget *), |
| 448 | wlist = kzalloc(wlistsize, GFP_KERNEL); | 470 | wlist = kzalloc(wlistsize, GFP_KERNEL); |
| @@ -579,8 +601,8 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w) | |||
| 579 | name + prefix_len, prefix); | 601 | name + prefix_len, prefix); |
| 580 | ret = snd_ctl_add(card, kcontrol); | 602 | ret = snd_ctl_add(card, kcontrol); |
| 581 | if (ret < 0) { | 603 | if (ret < 0) { |
| 582 | dev_err(dapm->dev, | 604 | dev_err(dapm->dev, "failed to add kcontrol %s: %d\n", |
| 583 | "asoc: failed to add kcontrol %s\n", w->name); | 605 | w->name, ret); |
| 584 | kfree(wlist); | 606 | kfree(wlist); |
| 585 | return ret; | 607 | return ret; |
| 586 | } | 608 | } |
| @@ -644,30 +666,45 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
| 644 | struct snd_soc_dapm_path *path; | 666 | struct snd_soc_dapm_path *path; |
| 645 | int con = 0; | 667 | int con = 0; |
| 646 | 668 | ||
| 669 | if (widget->outputs >= 0) | ||
| 670 | return widget->outputs; | ||
| 671 | |||
| 672 | DAPM_UPDATE_STAT(widget, path_checks); | ||
| 673 | |||
| 647 | if (widget->id == snd_soc_dapm_supply) | 674 | if (widget->id == snd_soc_dapm_supply) |
| 648 | return 0; | 675 | return 0; |
| 649 | 676 | ||
| 650 | switch (widget->id) { | 677 | switch (widget->id) { |
| 651 | case snd_soc_dapm_adc: | 678 | case snd_soc_dapm_adc: |
| 652 | case snd_soc_dapm_aif_out: | 679 | case snd_soc_dapm_aif_out: |
| 653 | if (widget->active) | 680 | if (widget->active) { |
| 654 | return snd_soc_dapm_suspend_check(widget); | 681 | widget->outputs = snd_soc_dapm_suspend_check(widget); |
| 682 | return widget->outputs; | ||
| 683 | } | ||
| 655 | default: | 684 | default: |
| 656 | break; | 685 | break; |
| 657 | } | 686 | } |
| 658 | 687 | ||
| 659 | if (widget->connected) { | 688 | if (widget->connected) { |
| 660 | /* connected pin ? */ | 689 | /* connected pin ? */ |
| 661 | if (widget->id == snd_soc_dapm_output && !widget->ext) | 690 | if (widget->id == snd_soc_dapm_output && !widget->ext) { |
| 662 | return snd_soc_dapm_suspend_check(widget); | 691 | widget->outputs = snd_soc_dapm_suspend_check(widget); |
| 692 | return widget->outputs; | ||
| 693 | } | ||
| 663 | 694 | ||
| 664 | /* connected jack or spk ? */ | 695 | /* connected jack or spk ? */ |
| 665 | if (widget->id == snd_soc_dapm_hp || widget->id == snd_soc_dapm_spk || | 696 | if (widget->id == snd_soc_dapm_hp || |
| 666 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sources))) | 697 | widget->id == snd_soc_dapm_spk || |
| 667 | return snd_soc_dapm_suspend_check(widget); | 698 | (widget->id == snd_soc_dapm_line && |
| 699 | !list_empty(&widget->sources))) { | ||
| 700 | widget->outputs = snd_soc_dapm_suspend_check(widget); | ||
| 701 | return widget->outputs; | ||
| 702 | } | ||
| 668 | } | 703 | } |
| 669 | 704 | ||
| 670 | list_for_each_entry(path, &widget->sinks, list_source) { | 705 | list_for_each_entry(path, &widget->sinks, list_source) { |
| 706 | DAPM_UPDATE_STAT(widget, neighbour_checks); | ||
| 707 | |||
| 671 | if (path->weak) | 708 | if (path->weak) |
| 672 | continue; | 709 | continue; |
| 673 | 710 | ||
| @@ -680,6 +717,8 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget) | |||
| 680 | } | 717 | } |
| 681 | } | 718 | } |
| 682 | 719 | ||
| 720 | widget->outputs = con; | ||
| 721 | |||
| 683 | return con; | 722 | return con; |
| 684 | } | 723 | } |
| 685 | 724 | ||
| @@ -692,6 +731,11 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
| 692 | struct snd_soc_dapm_path *path; | 731 | struct snd_soc_dapm_path *path; |
| 693 | int con = 0; | 732 | int con = 0; |
| 694 | 733 | ||
| 734 | if (widget->inputs >= 0) | ||
| 735 | return widget->inputs; | ||
| 736 | |||
| 737 | DAPM_UPDATE_STAT(widget, path_checks); | ||
| 738 | |||
| 695 | if (widget->id == snd_soc_dapm_supply) | 739 | if (widget->id == snd_soc_dapm_supply) |
| 696 | return 0; | 740 | return 0; |
| 697 | 741 | ||
| @@ -699,28 +743,40 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
| 699 | switch (widget->id) { | 743 | switch (widget->id) { |
| 700 | case snd_soc_dapm_dac: | 744 | case snd_soc_dapm_dac: |
| 701 | case snd_soc_dapm_aif_in: | 745 | case snd_soc_dapm_aif_in: |
| 702 | if (widget->active) | 746 | if (widget->active) { |
| 703 | return snd_soc_dapm_suspend_check(widget); | 747 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
| 748 | return widget->inputs; | ||
| 749 | } | ||
| 704 | default: | 750 | default: |
| 705 | break; | 751 | break; |
| 706 | } | 752 | } |
| 707 | 753 | ||
| 708 | if (widget->connected) { | 754 | if (widget->connected) { |
| 709 | /* connected pin ? */ | 755 | /* connected pin ? */ |
| 710 | if (widget->id == snd_soc_dapm_input && !widget->ext) | 756 | if (widget->id == snd_soc_dapm_input && !widget->ext) { |
| 711 | return snd_soc_dapm_suspend_check(widget); | 757 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
| 758 | return widget->inputs; | ||
| 759 | } | ||
| 712 | 760 | ||
| 713 | /* connected VMID/Bias for lower pops */ | 761 | /* connected VMID/Bias for lower pops */ |
| 714 | if (widget->id == snd_soc_dapm_vmid) | 762 | if (widget->id == snd_soc_dapm_vmid) { |
| 715 | return snd_soc_dapm_suspend_check(widget); | 763 | widget->inputs = snd_soc_dapm_suspend_check(widget); |
| 764 | return widget->inputs; | ||
| 765 | } | ||
| 716 | 766 | ||
| 717 | /* connected jack ? */ | 767 | /* connected jack ? */ |
| 718 | if (widget->id == snd_soc_dapm_mic || | 768 | if (widget->id == snd_soc_dapm_mic || |
| 719 | (widget->id == snd_soc_dapm_line && !list_empty(&widget->sinks))) | 769 | (widget->id == snd_soc_dapm_line && |
| 720 | return snd_soc_dapm_suspend_check(widget); | 770 | !list_empty(&widget->sinks))) { |
| 771 | widget->inputs = snd_soc_dapm_suspend_check(widget); | ||
| 772 | return widget->inputs; | ||
| 773 | } | ||
| 774 | |||
| 721 | } | 775 | } |
| 722 | 776 | ||
| 723 | list_for_each_entry(path, &widget->sources, list_sink) { | 777 | list_for_each_entry(path, &widget->sources, list_sink) { |
| 778 | DAPM_UPDATE_STAT(widget, neighbour_checks); | ||
| 779 | |||
| 724 | if (path->weak) | 780 | if (path->weak) |
| 725 | continue; | 781 | continue; |
| 726 | 782 | ||
| @@ -733,6 +789,8 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget) | |||
| 733 | } | 789 | } |
| 734 | } | 790 | } |
| 735 | 791 | ||
| 792 | widget->inputs = con; | ||
| 793 | |||
| 736 | return con; | 794 | return con; |
| 737 | } | 795 | } |
| 738 | 796 | ||
| @@ -756,12 +814,29 @@ int dapm_reg_event(struct snd_soc_dapm_widget *w, | |||
| 756 | } | 814 | } |
| 757 | EXPORT_SYMBOL_GPL(dapm_reg_event); | 815 | EXPORT_SYMBOL_GPL(dapm_reg_event); |
| 758 | 816 | ||
| 817 | static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) | ||
| 818 | { | ||
| 819 | if (w->power_checked) | ||
| 820 | return w->new_power; | ||
| 821 | |||
| 822 | if (w->force) | ||
| 823 | w->new_power = 1; | ||
| 824 | else | ||
| 825 | w->new_power = w->power_check(w); | ||
| 826 | |||
| 827 | w->power_checked = true; | ||
| 828 | |||
| 829 | return w->new_power; | ||
| 830 | } | ||
| 831 | |||
| 759 | /* Generic check to see if a widget should be powered. | 832 | /* Generic check to see if a widget should be powered. |
| 760 | */ | 833 | */ |
| 761 | static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) | 834 | static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) |
| 762 | { | 835 | { |
| 763 | int in, out; | 836 | int in, out; |
| 764 | 837 | ||
| 838 | DAPM_UPDATE_STAT(w, power_checks); | ||
| 839 | |||
| 765 | in = is_connected_input_ep(w); | 840 | in = is_connected_input_ep(w); |
| 766 | dapm_clear_walk(w->dapm); | 841 | dapm_clear_walk(w->dapm); |
| 767 | out = is_connected_output_ep(w); | 842 | out = is_connected_output_ep(w); |
| @@ -774,6 +849,8 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) | |||
| 774 | { | 849 | { |
| 775 | int in; | 850 | int in; |
| 776 | 851 | ||
| 852 | DAPM_UPDATE_STAT(w, power_checks); | ||
| 853 | |||
| 777 | if (w->active) { | 854 | if (w->active) { |
| 778 | in = is_connected_input_ep(w); | 855 | in = is_connected_input_ep(w); |
| 779 | dapm_clear_walk(w->dapm); | 856 | dapm_clear_walk(w->dapm); |
| @@ -788,6 +865,8 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) | |||
| 788 | { | 865 | { |
| 789 | int out; | 866 | int out; |
| 790 | 867 | ||
| 868 | DAPM_UPDATE_STAT(w, power_checks); | ||
| 869 | |||
| 791 | if (w->active) { | 870 | if (w->active) { |
| 792 | out = is_connected_output_ep(w); | 871 | out = is_connected_output_ep(w); |
| 793 | dapm_clear_walk(w->dapm); | 872 | dapm_clear_walk(w->dapm); |
| @@ -801,10 +880,13 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) | |||
| 801 | static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) | 880 | static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) |
| 802 | { | 881 | { |
| 803 | struct snd_soc_dapm_path *path; | 882 | struct snd_soc_dapm_path *path; |
| 804 | int power = 0; | 883 | |
| 884 | DAPM_UPDATE_STAT(w, power_checks); | ||
| 805 | 885 | ||
| 806 | /* Check if one of our outputs is connected */ | 886 | /* Check if one of our outputs is connected */ |
| 807 | list_for_each_entry(path, &w->sinks, list_source) { | 887 | list_for_each_entry(path, &w->sinks, list_source) { |
| 888 | DAPM_UPDATE_STAT(w, neighbour_checks); | ||
| 889 | |||
| 808 | if (path->weak) | 890 | if (path->weak) |
| 809 | continue; | 891 | continue; |
| 810 | 892 | ||
| @@ -815,21 +897,18 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) | |||
| 815 | if (!path->sink) | 897 | if (!path->sink) |
| 816 | continue; | 898 | continue; |
| 817 | 899 | ||
| 818 | if (path->sink->force) { | 900 | if (dapm_widget_power_check(path->sink)) |
| 819 | power = 1; | 901 | return 1; |
| 820 | break; | ||
| 821 | } | ||
| 822 | |||
| 823 | if (path->sink->power_check && | ||
| 824 | path->sink->power_check(path->sink)) { | ||
| 825 | power = 1; | ||
| 826 | break; | ||
| 827 | } | ||
| 828 | } | 902 | } |
| 829 | 903 | ||
| 830 | dapm_clear_walk(w->dapm); | 904 | dapm_clear_walk(w->dapm); |
| 831 | 905 | ||
| 832 | return power; | 906 | return 0; |
| 907 | } | ||
| 908 | |||
| 909 | static int dapm_always_on_check_power(struct snd_soc_dapm_widget *w) | ||
| 910 | { | ||
| 911 | return 1; | ||
| 833 | } | 912 | } |
| 834 | 913 | ||
| 835 | static int dapm_seq_compare(struct snd_soc_dapm_widget *a, | 914 | static int dapm_seq_compare(struct snd_soc_dapm_widget *a, |
| @@ -1172,6 +1251,85 @@ static void dapm_post_sequence_async(void *data, async_cookie_t cookie) | |||
| 1172 | } | 1251 | } |
| 1173 | } | 1252 | } |
| 1174 | 1253 | ||
| 1254 | static void dapm_widget_set_peer_power(struct snd_soc_dapm_widget *peer, | ||
| 1255 | bool power, bool connect) | ||
| 1256 | { | ||
| 1257 | /* If a connection is being made or broken then that update | ||
| 1258 | * will have marked the peer dirty, otherwise the widgets are | ||
| 1259 | * not connected and this update has no impact. */ | ||
| 1260 | if (!connect) | ||
| 1261 | return; | ||
| 1262 | |||
| 1263 | /* If the peer is already in the state we're moving to then we | ||
| 1264 | * won't have an impact on it. */ | ||
| 1265 | if (power != peer->power) | ||
| 1266 | dapm_mark_dirty(peer, "peer state change"); | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power, | ||
| 1270 | struct list_head *up_list, | ||
| 1271 | struct list_head *down_list) | ||
| 1272 | { | ||
| 1273 | struct snd_soc_dapm_path *path; | ||
| 1274 | |||
| 1275 | if (w->power == power) | ||
| 1276 | return; | ||
| 1277 | |||
| 1278 | trace_snd_soc_dapm_widget_power(w, power); | ||
| 1279 | |||
| 1280 | /* If we changed our power state perhaps our neigbours changed | ||
| 1281 | * also. | ||
| 1282 | */ | ||
| 1283 | list_for_each_entry(path, &w->sources, list_sink) { | ||
| 1284 | if (path->source) { | ||
| 1285 | dapm_widget_set_peer_power(path->source, power, | ||
| 1286 | path->connect); | ||
| 1287 | } | ||
| 1288 | } | ||
| 1289 | switch (w->id) { | ||
| 1290 | case snd_soc_dapm_supply: | ||
| 1291 | /* Supplies can't affect their outputs, only their inputs */ | ||
| 1292 | break; | ||
| 1293 | default: | ||
| 1294 | list_for_each_entry(path, &w->sinks, list_source) { | ||
| 1295 | if (path->sink) { | ||
| 1296 | dapm_widget_set_peer_power(path->sink, power, | ||
| 1297 | path->connect); | ||
| 1298 | } | ||
| 1299 | } | ||
| 1300 | break; | ||
| 1301 | } | ||
| 1302 | |||
| 1303 | if (power) | ||
| 1304 | dapm_seq_insert(w, up_list, true); | ||
| 1305 | else | ||
| 1306 | dapm_seq_insert(w, down_list, false); | ||
| 1307 | |||
| 1308 | w->power = power; | ||
| 1309 | } | ||
| 1310 | |||
| 1311 | static void dapm_power_one_widget(struct snd_soc_dapm_widget *w, | ||
| 1312 | struct list_head *up_list, | ||
| 1313 | struct list_head *down_list) | ||
| 1314 | { | ||
| 1315 | int power; | ||
| 1316 | |||
| 1317 | switch (w->id) { | ||
| 1318 | case snd_soc_dapm_pre: | ||
| 1319 | dapm_seq_insert(w, down_list, false); | ||
| 1320 | break; | ||
| 1321 | case snd_soc_dapm_post: | ||
| 1322 | dapm_seq_insert(w, up_list, true); | ||
| 1323 | break; | ||
| 1324 | |||
| 1325 | default: | ||
| 1326 | power = dapm_widget_power_check(w); | ||
| 1327 | |||
| 1328 | dapm_widget_set_power(w, power, up_list, down_list); | ||
| 1329 | break; | ||
| 1330 | } | ||
| 1331 | } | ||
| 1332 | |||
| 1175 | /* | 1333 | /* |
| 1176 | * Scan each dapm widget for complete audio path. | 1334 | * Scan each dapm widget for complete audio path. |
| 1177 | * A complete path is a route that has valid endpoints i.e.:- | 1335 | * A complete path is a route that has valid endpoints i.e.:- |
| @@ -1190,7 +1348,6 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
| 1190 | LIST_HEAD(down_list); | 1348 | LIST_HEAD(down_list); |
| 1191 | LIST_HEAD(async_domain); | 1349 | LIST_HEAD(async_domain); |
| 1192 | enum snd_soc_bias_level bias; | 1350 | enum snd_soc_bias_level bias; |
| 1193 | int power; | ||
| 1194 | 1351 | ||
| 1195 | trace_snd_soc_dapm_start(card); | 1352 | trace_snd_soc_dapm_start(card); |
| 1196 | 1353 | ||
| @@ -1203,61 +1360,47 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
| 1203 | } | 1360 | } |
| 1204 | } | 1361 | } |
| 1205 | 1362 | ||
| 1206 | /* Check which widgets we need to power and store them in | 1363 | memset(&card->dapm_stats, 0, sizeof(card->dapm_stats)); |
| 1207 | * lists indicating if they should be powered up or down. | 1364 | |
| 1208 | */ | ||
| 1209 | list_for_each_entry(w, &card->widgets, list) { | 1365 | list_for_each_entry(w, &card->widgets, list) { |
| 1210 | switch (w->id) { | 1366 | w->power_checked = false; |
| 1211 | case snd_soc_dapm_pre: | 1367 | w->inputs = -1; |
| 1212 | dapm_seq_insert(w, &down_list, false); | 1368 | w->outputs = -1; |
| 1213 | break; | 1369 | } |
| 1214 | case snd_soc_dapm_post: | ||
| 1215 | dapm_seq_insert(w, &up_list, true); | ||
| 1216 | break; | ||
| 1217 | 1370 | ||
| 1218 | default: | 1371 | /* Check which widgets we need to power and store them in |
| 1219 | if (!w->power_check) | 1372 | * lists indicating if they should be powered up or down. We |
| 1220 | continue; | 1373 | * only check widgets that have been flagged as dirty but note |
| 1374 | * that new widgets may be added to the dirty list while we | ||
| 1375 | * iterate. | ||
| 1376 | */ | ||
| 1377 | list_for_each_entry(w, &card->dapm_dirty, dirty) { | ||
| 1378 | dapm_power_one_widget(w, &up_list, &down_list); | ||
| 1379 | } | ||
| 1221 | 1380 | ||
| 1222 | if (!w->force) | 1381 | list_for_each_entry(w, &card->widgets, list) { |
| 1223 | power = w->power_check(w); | 1382 | list_del_init(&w->dirty); |
| 1224 | else | ||
| 1225 | power = 1; | ||
| 1226 | 1383 | ||
| 1227 | if (power) { | 1384 | if (w->power) { |
| 1228 | d = w->dapm; | 1385 | d = w->dapm; |
| 1229 | 1386 | ||
| 1230 | /* Supplies and micbiases only bring | 1387 | /* Supplies and micbiases only bring the |
| 1231 | * the context up to STANDBY as unless | 1388 | * context up to STANDBY as unless something |
| 1232 | * something else is active and | 1389 | * else is active and passing audio they |
| 1233 | * passing audio they generally don't | 1390 | * generally don't require full power. |
| 1234 | * require full power. | 1391 | */ |
| 1235 | */ | 1392 | switch (w->id) { |
| 1236 | switch (w->id) { | 1393 | case snd_soc_dapm_supply: |
| 1237 | case snd_soc_dapm_supply: | 1394 | case snd_soc_dapm_micbias: |
| 1238 | case snd_soc_dapm_micbias: | 1395 | if (d->target_bias_level < SND_SOC_BIAS_STANDBY) |
| 1239 | if (d->target_bias_level < SND_SOC_BIAS_STANDBY) | 1396 | d->target_bias_level = SND_SOC_BIAS_STANDBY; |
| 1240 | d->target_bias_level = SND_SOC_BIAS_STANDBY; | 1397 | break; |
| 1241 | break; | 1398 | default: |
| 1242 | default: | 1399 | d->target_bias_level = SND_SOC_BIAS_ON; |
| 1243 | d->target_bias_level = SND_SOC_BIAS_ON; | 1400 | break; |
| 1244 | break; | ||
| 1245 | } | ||
| 1246 | } | 1401 | } |
| 1247 | |||
| 1248 | if (w->power == power) | ||
| 1249 | continue; | ||
| 1250 | |||
| 1251 | trace_snd_soc_dapm_widget_power(w, power); | ||
| 1252 | |||
| 1253 | if (power) | ||
| 1254 | dapm_seq_insert(w, &up_list, true); | ||
| 1255 | else | ||
| 1256 | dapm_seq_insert(w, &down_list, false); | ||
| 1257 | |||
| 1258 | w->power = power; | ||
| 1259 | break; | ||
| 1260 | } | 1402 | } |
| 1403 | |||
| 1261 | } | 1404 | } |
| 1262 | 1405 | ||
| 1263 | /* If there are no DAPM widgets then try to figure out power from the | 1406 | /* If there are no DAPM widgets then try to figure out power from the |
| @@ -1286,14 +1429,18 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) | |||
| 1286 | } | 1429 | } |
| 1287 | } | 1430 | } |
| 1288 | 1431 | ||
| 1289 | /* Force all contexts in the card to the same bias state */ | 1432 | /* Force all contexts in the card to the same bias state if |
| 1433 | * they're not ground referenced. | ||
| 1434 | */ | ||
| 1290 | bias = SND_SOC_BIAS_OFF; | 1435 | bias = SND_SOC_BIAS_OFF; |
| 1291 | list_for_each_entry(d, &card->dapm_list, list) | 1436 | list_for_each_entry(d, &card->dapm_list, list) |
| 1292 | if (d->target_bias_level > bias) | 1437 | if (d->target_bias_level > bias) |
| 1293 | bias = d->target_bias_level; | 1438 | bias = d->target_bias_level; |
| 1294 | list_for_each_entry(d, &card->dapm_list, list) | 1439 | list_for_each_entry(d, &card->dapm_list, list) |
| 1295 | d->target_bias_level = bias; | 1440 | if (!d->idle_bias_off) |
| 1441 | d->target_bias_level = bias; | ||
| 1296 | 1442 | ||
| 1443 | trace_snd_soc_dapm_walk_done(card); | ||
| 1297 | 1444 | ||
| 1298 | /* Run all the bias changes in parallel */ | 1445 | /* Run all the bias changes in parallel */ |
| 1299 | list_for_each_entry(d, &dapm->card->dapm_list, list) | 1446 | list_for_each_entry(d, &dapm->card->dapm_list, list) |
| @@ -1524,14 +1671,21 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, | |||
| 1524 | 1671 | ||
| 1525 | found = 1; | 1672 | found = 1; |
| 1526 | /* we now need to match the string in the enum to the path */ | 1673 | /* we now need to match the string in the enum to the path */ |
| 1527 | if (!(strcmp(path->name, e->texts[mux]))) | 1674 | if (!(strcmp(path->name, e->texts[mux]))) { |
| 1528 | path->connect = 1; /* new connection */ | 1675 | path->connect = 1; /* new connection */ |
| 1529 | else | 1676 | dapm_mark_dirty(path->source, "mux connection"); |
| 1677 | } else { | ||
| 1678 | if (path->connect) | ||
| 1679 | dapm_mark_dirty(path->source, | ||
| 1680 | "mux disconnection"); | ||
| 1530 | path->connect = 0; /* old connection must be powered down */ | 1681 | path->connect = 0; /* old connection must be powered down */ |
| 1682 | } | ||
| 1531 | } | 1683 | } |
| 1532 | 1684 | ||
| 1533 | if (found) | 1685 | if (found) { |
| 1686 | dapm_mark_dirty(widget, "mux change"); | ||
| 1534 | dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); | 1687 | dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); |
| 1688 | } | ||
| 1535 | 1689 | ||
| 1536 | return 0; | 1690 | return 0; |
| 1537 | } | 1691 | } |
| @@ -1556,11 +1710,13 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, | |||
| 1556 | /* found, now check type */ | 1710 | /* found, now check type */ |
| 1557 | found = 1; | 1711 | found = 1; |
| 1558 | path->connect = connect; | 1712 | path->connect = connect; |
| 1559 | break; | 1713 | dapm_mark_dirty(path->source, "mixer connection"); |
| 1560 | } | 1714 | } |
| 1561 | 1715 | ||
| 1562 | if (found) | 1716 | if (found) { |
| 1717 | dapm_mark_dirty(widget, "mixer update"); | ||
| 1563 | dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); | 1718 | dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); |
| 1719 | } | ||
| 1564 | 1720 | ||
| 1565 | return 0; | 1721 | return 0; |
| 1566 | } | 1722 | } |
| @@ -1704,6 +1860,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
| 1704 | w->connected = status; | 1860 | w->connected = status; |
| 1705 | if (status == 0) | 1861 | if (status == 0) |
| 1706 | w->force = 0; | 1862 | w->force = 0; |
| 1863 | dapm_mark_dirty(w, "pin configuration"); | ||
| 1707 | 1864 | ||
| 1708 | return 0; | 1865 | return 0; |
| 1709 | } | 1866 | } |
| @@ -1719,6 +1876,13 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, | |||
| 1719 | */ | 1876 | */ |
| 1720 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) | 1877 | int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) |
| 1721 | { | 1878 | { |
| 1879 | /* | ||
| 1880 | * Suppress early reports (eg, jacks syncing their state) to avoid | ||
| 1881 | * silly DAPM runs during card startup. | ||
| 1882 | */ | ||
| 1883 | if (!dapm->card || !dapm->card->instantiated) | ||
| 1884 | return 0; | ||
| 1885 | |||
| 1722 | return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); | 1886 | return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); |
| 1723 | } | 1887 | } |
| 1724 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); | 1888 | EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); |
| @@ -2004,42 +2168,18 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) | |||
| 2004 | case snd_soc_dapm_switch: | 2168 | case snd_soc_dapm_switch: |
| 2005 | case snd_soc_dapm_mixer: | 2169 | case snd_soc_dapm_mixer: |
| 2006 | case snd_soc_dapm_mixer_named_ctl: | 2170 | case snd_soc_dapm_mixer_named_ctl: |
| 2007 | w->power_check = dapm_generic_check_power; | ||
| 2008 | dapm_new_mixer(w); | 2171 | dapm_new_mixer(w); |
| 2009 | break; | 2172 | break; |
| 2010 | case snd_soc_dapm_mux: | 2173 | case snd_soc_dapm_mux: |
| 2011 | case snd_soc_dapm_virt_mux: | 2174 | case snd_soc_dapm_virt_mux: |
| 2012 | case snd_soc_dapm_value_mux: | 2175 | case snd_soc_dapm_value_mux: |
| 2013 | w->power_check = dapm_generic_check_power; | ||
| 2014 | dapm_new_mux(w); | 2176 | dapm_new_mux(w); |
| 2015 | break; | 2177 | break; |
| 2016 | case snd_soc_dapm_adc: | ||
| 2017 | case snd_soc_dapm_aif_out: | ||
| 2018 | w->power_check = dapm_adc_check_power; | ||
| 2019 | break; | ||
| 2020 | case snd_soc_dapm_dac: | ||
| 2021 | case snd_soc_dapm_aif_in: | ||
| 2022 | w->power_check = dapm_dac_check_power; | ||
| 2023 | break; | ||
| 2024 | case snd_soc_dapm_pga: | 2178 | case snd_soc_dapm_pga: |
| 2025 | case snd_soc_dapm_out_drv: | 2179 | case snd_soc_dapm_out_drv: |
| 2026 | w->power_check = dapm_generic_check_power; | ||
| 2027 | dapm_new_pga(w); | 2180 | dapm_new_pga(w); |
| 2028 | break; | 2181 | break; |
| 2029 | case snd_soc_dapm_input: | 2182 | default: |
| 2030 | case snd_soc_dapm_output: | ||
| 2031 | case snd_soc_dapm_micbias: | ||
| 2032 | case snd_soc_dapm_spk: | ||
| 2033 | case snd_soc_dapm_hp: | ||
| 2034 | case snd_soc_dapm_mic: | ||
| 2035 | case snd_soc_dapm_line: | ||
| 2036 | w->power_check = dapm_generic_check_power; | ||
| 2037 | break; | ||
| 2038 | case snd_soc_dapm_supply: | ||
| 2039 | w->power_check = dapm_supply_check_power; | ||
| 2040 | case snd_soc_dapm_vmid: | ||
| 2041 | case snd_soc_dapm_pre: | ||
| 2042 | case snd_soc_dapm_post: | ||
| 2043 | break; | 2183 | break; |
| 2044 | } | 2184 | } |
| 2045 | 2185 | ||
| @@ -2056,6 +2196,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) | |||
| 2056 | 2196 | ||
| 2057 | w->new = 1; | 2197 | w->new = 1; |
| 2058 | 2198 | ||
| 2199 | dapm_mark_dirty(w, "new widget"); | ||
| 2059 | dapm_debugfs_add_widget(w); | 2200 | dapm_debugfs_add_widget(w); |
| 2060 | } | 2201 | } |
| 2061 | 2202 | ||
| @@ -2530,6 +2671,44 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
| 2530 | else | 2671 | else |
| 2531 | snprintf(w->name, name_len, "%s", widget->name); | 2672 | snprintf(w->name, name_len, "%s", widget->name); |
| 2532 | 2673 | ||
| 2674 | switch (w->id) { | ||
| 2675 | case snd_soc_dapm_switch: | ||
| 2676 | case snd_soc_dapm_mixer: | ||
| 2677 | case snd_soc_dapm_mixer_named_ctl: | ||
| 2678 | w->power_check = dapm_generic_check_power; | ||
| 2679 | break; | ||
| 2680 | case snd_soc_dapm_mux: | ||
| 2681 | case snd_soc_dapm_virt_mux: | ||
| 2682 | case snd_soc_dapm_value_mux: | ||
| 2683 | w->power_check = dapm_generic_check_power; | ||
| 2684 | break; | ||
| 2685 | case snd_soc_dapm_adc: | ||
| 2686 | case snd_soc_dapm_aif_out: | ||
| 2687 | w->power_check = dapm_adc_check_power; | ||
| 2688 | break; | ||
| 2689 | case snd_soc_dapm_dac: | ||
| 2690 | case snd_soc_dapm_aif_in: | ||
| 2691 | w->power_check = dapm_dac_check_power; | ||
| 2692 | break; | ||
| 2693 | case snd_soc_dapm_pga: | ||
| 2694 | case snd_soc_dapm_out_drv: | ||
| 2695 | case snd_soc_dapm_input: | ||
| 2696 | case snd_soc_dapm_output: | ||
| 2697 | case snd_soc_dapm_micbias: | ||
| 2698 | case snd_soc_dapm_spk: | ||
| 2699 | case snd_soc_dapm_hp: | ||
| 2700 | case snd_soc_dapm_mic: | ||
| 2701 | case snd_soc_dapm_line: | ||
| 2702 | w->power_check = dapm_generic_check_power; | ||
| 2703 | break; | ||
| 2704 | case snd_soc_dapm_supply: | ||
| 2705 | w->power_check = dapm_supply_check_power; | ||
| 2706 | break; | ||
| 2707 | default: | ||
| 2708 | w->power_check = dapm_always_on_check_power; | ||
| 2709 | break; | ||
| 2710 | } | ||
| 2711 | |||
| 2533 | dapm->n_widgets++; | 2712 | dapm->n_widgets++; |
| 2534 | w->dapm = dapm; | 2713 | w->dapm = dapm; |
| 2535 | w->codec = dapm->codec; | 2714 | w->codec = dapm->codec; |
| @@ -2537,6 +2716,7 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, | |||
| 2537 | INIT_LIST_HEAD(&w->sources); | 2716 | INIT_LIST_HEAD(&w->sources); |
| 2538 | INIT_LIST_HEAD(&w->sinks); | 2717 | INIT_LIST_HEAD(&w->sinks); |
| 2539 | INIT_LIST_HEAD(&w->list); | 2718 | INIT_LIST_HEAD(&w->list); |
| 2719 | INIT_LIST_HEAD(&w->dirty); | ||
| 2540 | list_add(&w->list, &dapm->card->widgets); | 2720 | list_add(&w->list, &dapm->card->widgets); |
| 2541 | 2721 | ||
| 2542 | /* machine layer set ups unconnected pins and insertions */ | 2722 | /* machine layer set ups unconnected pins and insertions */ |
| @@ -2584,9 +2764,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, | |||
| 2584 | { | 2764 | { |
| 2585 | if (!w->sname || w->dapm != dapm) | 2765 | if (!w->sname || w->dapm != dapm) |
| 2586 | continue; | 2766 | continue; |
| 2587 | dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", | 2767 | dev_vdbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", |
| 2588 | w->name, w->sname, stream, event); | 2768 | w->name, w->sname, stream, event); |
| 2589 | if (strstr(w->sname, stream)) { | 2769 | if (strstr(w->sname, stream)) { |
| 2770 | dapm_mark_dirty(w, "stream event"); | ||
| 2590 | switch(event) { | 2771 | switch(event) { |
| 2591 | case SND_SOC_DAPM_STREAM_START: | 2772 | case SND_SOC_DAPM_STREAM_START: |
| 2592 | w->active = 1; | 2773 | w->active = 1; |
| @@ -2604,6 +2785,10 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, | |||
| 2604 | } | 2785 | } |
| 2605 | 2786 | ||
| 2606 | dapm_power_widgets(dapm, event); | 2787 | dapm_power_widgets(dapm, event); |
| 2788 | |||
| 2789 | /* do we need to notify any clients that DAPM stream is complete */ | ||
| 2790 | if (dapm->stream_event) | ||
| 2791 | dapm->stream_event(dapm, event); | ||
| 2607 | } | 2792 | } |
| 2608 | 2793 | ||
| 2609 | /** | 2794 | /** |
| @@ -2672,6 +2857,7 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, | |||
| 2672 | dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); | 2857 | dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); |
| 2673 | w->connected = 1; | 2858 | w->connected = 1; |
| 2674 | w->force = 1; | 2859 | w->force = 1; |
| 2860 | dapm_mark_dirty(w, "force enable"); | ||
| 2675 | 2861 | ||
| 2676 | return 0; | 2862 | return 0; |
| 2677 | } | 2863 | } |
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c index a62f7dd4ba96..dd89933e2c72 100644 --- a/sound/soc/soc-io.c +++ b/sound/soc/soc-io.c | |||
| @@ -13,26 +13,14 @@ | |||
| 13 | 13 | ||
| 14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
| 15 | #include <linux/spi/spi.h> | 15 | #include <linux/spi/spi.h> |
| 16 | #include <linux/regmap.h> | ||
| 16 | #include <sound/soc.h> | 17 | #include <sound/soc.h> |
| 17 | 18 | ||
| 18 | #include <trace/events/asoc.h> | 19 | #include <trace/events/asoc.h> |
| 19 | 20 | ||
| 20 | #ifdef CONFIG_SPI_MASTER | 21 | #ifdef CONFIG_REGMAP |
| 21 | static int do_spi_write(void *control, const char *data, int len) | 22 | static int hw_write(struct snd_soc_codec *codec, unsigned int reg, |
| 22 | { | 23 | unsigned int value) |
| 23 | struct spi_device *spi = control; | ||
| 24 | int ret; | ||
| 25 | |||
| 26 | ret = spi_write(spi, data, len); | ||
| 27 | if (ret < 0) | ||
| 28 | return ret; | ||
| 29 | |||
| 30 | return len; | ||
| 31 | } | ||
| 32 | #endif | ||
| 33 | |||
| 34 | static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 35 | unsigned int value, const void *data, int len) | ||
| 36 | { | 24 | { |
| 37 | int ret; | 25 | int ret; |
| 38 | 26 | ||
| @@ -49,13 +37,7 @@ static int do_hw_write(struct snd_soc_codec *codec, unsigned int reg, | |||
| 49 | return 0; | 37 | return 0; |
| 50 | } | 38 | } |
| 51 | 39 | ||
| 52 | ret = codec->hw_write(codec->control_data, data, len); | 40 | return regmap_write(codec->control_data, reg, value); |
| 53 | if (ret == len) | ||
| 54 | return 0; | ||
| 55 | if (ret < 0) | ||
| 56 | return ret; | ||
| 57 | else | ||
| 58 | return -EIO; | ||
| 59 | } | 41 | } |
| 60 | 42 | ||
| 61 | static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) | 43 | static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) |
| @@ -69,8 +51,11 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) | |||
| 69 | if (codec->cache_only) | 51 | if (codec->cache_only) |
| 70 | return -1; | 52 | return -1; |
| 71 | 53 | ||
| 72 | BUG_ON(!codec->hw_read); | 54 | ret = regmap_read(codec->control_data, reg, &val); |
| 73 | return codec->hw_read(codec, reg); | 55 | if (ret == 0) |
| 56 | return val; | ||
| 57 | else | ||
| 58 | return -1; | ||
| 74 | } | 59 | } |
| 75 | 60 | ||
| 76 | ret = snd_soc_cache_read(codec, reg, &val); | 61 | ret = snd_soc_cache_read(codec, reg, &val); |
| @@ -79,202 +64,18 @@ static unsigned int hw_read(struct snd_soc_codec *codec, unsigned int reg) | |||
| 79 | return val; | 64 | return val; |
| 80 | } | 65 | } |
| 81 | 66 | ||
| 82 | static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 83 | unsigned int value) | ||
| 84 | { | ||
| 85 | u16 data; | ||
| 86 | |||
| 87 | data = cpu_to_be16((reg << 12) | (value & 0xffffff)); | ||
| 88 | |||
| 89 | return do_hw_write(codec, reg, value, &data, 2); | ||
| 90 | } | ||
| 91 | |||
| 92 | static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 93 | unsigned int value) | ||
| 94 | { | ||
| 95 | u16 data; | ||
| 96 | |||
| 97 | data = cpu_to_be16((reg << 9) | (value & 0x1ff)); | ||
| 98 | |||
| 99 | return do_hw_write(codec, reg, value, &data, 2); | ||
| 100 | } | ||
| 101 | |||
| 102 | static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 103 | unsigned int value) | ||
| 104 | { | ||
| 105 | u8 data[2]; | ||
| 106 | |||
| 107 | reg &= 0xff; | ||
| 108 | data[0] = reg; | ||
| 109 | data[1] = value & 0xff; | ||
| 110 | |||
| 111 | return do_hw_write(codec, reg, value, data, 2); | ||
| 112 | } | ||
| 113 | |||
| 114 | static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 115 | unsigned int value) | ||
| 116 | { | ||
| 117 | u8 data[3]; | ||
| 118 | u16 val = cpu_to_be16(value); | ||
| 119 | |||
| 120 | data[0] = reg; | ||
| 121 | memcpy(&data[1], &val, sizeof(val)); | ||
| 122 | |||
| 123 | return do_hw_write(codec, reg, value, data, 3); | ||
| 124 | } | ||
| 125 | |||
| 126 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 127 | static unsigned int do_i2c_read(struct snd_soc_codec *codec, | ||
| 128 | void *reg, int reglen, | ||
| 129 | void *data, int datalen) | ||
| 130 | { | ||
| 131 | struct i2c_msg xfer[2]; | ||
| 132 | int ret; | ||
| 133 | struct i2c_client *client = codec->control_data; | ||
| 134 | |||
| 135 | /* Write register */ | ||
| 136 | xfer[0].addr = client->addr; | ||
| 137 | xfer[0].flags = 0; | ||
| 138 | xfer[0].len = reglen; | ||
| 139 | xfer[0].buf = reg; | ||
| 140 | |||
| 141 | /* Read data */ | ||
| 142 | xfer[1].addr = client->addr; | ||
| 143 | xfer[1].flags = I2C_M_RD; | ||
| 144 | xfer[1].len = datalen; | ||
| 145 | xfer[1].buf = data; | ||
| 146 | |||
| 147 | ret = i2c_transfer(client->adapter, xfer, 2); | ||
| 148 | if (ret == 2) | ||
| 149 | return 0; | ||
| 150 | else if (ret < 0) | ||
| 151 | return ret; | ||
| 152 | else | ||
| 153 | return -EIO; | ||
| 154 | } | ||
| 155 | #endif | ||
| 156 | |||
| 157 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 158 | static unsigned int snd_soc_8_8_read_i2c(struct snd_soc_codec *codec, | ||
| 159 | unsigned int r) | ||
| 160 | { | ||
| 161 | u8 reg = r; | ||
| 162 | u8 data; | ||
| 163 | int ret; | ||
| 164 | |||
| 165 | ret = do_i2c_read(codec, ®, 1, &data, 1); | ||
| 166 | if (ret < 0) | ||
| 167 | return 0; | ||
| 168 | return data; | ||
| 169 | } | ||
| 170 | #else | ||
| 171 | #define snd_soc_8_8_read_i2c NULL | ||
| 172 | #endif | ||
| 173 | |||
| 174 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 175 | static unsigned int snd_soc_8_16_read_i2c(struct snd_soc_codec *codec, | ||
| 176 | unsigned int r) | ||
| 177 | { | ||
| 178 | u8 reg = r; | ||
| 179 | u16 data; | ||
| 180 | int ret; | ||
| 181 | |||
| 182 | ret = do_i2c_read(codec, ®, 1, &data, 2); | ||
| 183 | if (ret < 0) | ||
| 184 | return 0; | ||
| 185 | return (data >> 8) | ((data & 0xff) << 8); | ||
| 186 | } | ||
| 187 | #else | ||
| 188 | #define snd_soc_8_16_read_i2c NULL | ||
| 189 | #endif | ||
| 190 | |||
| 191 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 192 | static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, | ||
| 193 | unsigned int r) | ||
| 194 | { | ||
| 195 | u16 reg = r; | ||
| 196 | u8 data; | ||
| 197 | int ret; | ||
| 198 | |||
| 199 | ret = do_i2c_read(codec, ®, 2, &data, 1); | ||
| 200 | if (ret < 0) | ||
| 201 | return 0; | ||
| 202 | return data; | ||
| 203 | } | ||
| 204 | #else | ||
| 205 | #define snd_soc_16_8_read_i2c NULL | ||
| 206 | #endif | ||
| 207 | |||
| 208 | #if defined(CONFIG_SPI_MASTER) | ||
| 209 | static unsigned int snd_soc_16_8_read_spi(struct snd_soc_codec *codec, | ||
| 210 | unsigned int r) | ||
| 211 | { | ||
| 212 | struct spi_device *spi = codec->control_data; | ||
| 213 | |||
| 214 | const u16 reg = cpu_to_be16(r | 0x100); | ||
| 215 | u8 data; | ||
| 216 | int ret; | ||
| 217 | |||
| 218 | ret = spi_write_then_read(spi, ®, 2, &data, 1); | ||
| 219 | if (ret < 0) | ||
| 220 | return 0; | ||
| 221 | return data; | ||
| 222 | } | ||
| 223 | #else | ||
| 224 | #define snd_soc_16_8_read_spi NULL | ||
| 225 | #endif | ||
| 226 | |||
| 227 | static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 228 | unsigned int value) | ||
| 229 | { | ||
| 230 | u8 data[3]; | ||
| 231 | u16 rval = cpu_to_be16(reg); | ||
| 232 | |||
| 233 | memcpy(data, &rval, sizeof(rval)); | ||
| 234 | data[2] = value; | ||
| 235 | |||
| 236 | return do_hw_write(codec, reg, value, data, 3); | ||
| 237 | } | ||
| 238 | |||
| 239 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 240 | static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, | ||
| 241 | unsigned int r) | ||
| 242 | { | ||
| 243 | u16 reg = cpu_to_be16(r); | ||
| 244 | u16 data; | ||
| 245 | int ret; | ||
| 246 | |||
| 247 | ret = do_i2c_read(codec, ®, 2, &data, 2); | ||
| 248 | if (ret < 0) | ||
| 249 | return 0; | ||
| 250 | return be16_to_cpu(data); | ||
| 251 | } | ||
| 252 | #else | ||
| 253 | #define snd_soc_16_16_read_i2c NULL | ||
| 254 | #endif | ||
| 255 | |||
| 256 | static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, | ||
| 257 | unsigned int value) | ||
| 258 | { | ||
| 259 | u16 data[2]; | ||
| 260 | |||
| 261 | data[0] = cpu_to_be16(reg); | ||
| 262 | data[1] = cpu_to_be16(value); | ||
| 263 | |||
| 264 | return do_hw_write(codec, reg, value, data, sizeof(data)); | ||
| 265 | } | ||
| 266 | |||
| 267 | /* Primitive bulk write support for soc-cache. The data pointed to by | 67 | /* Primitive bulk write support for soc-cache. The data pointed to by |
| 268 | * `data' needs to already be in the form the hardware expects | 68 | * `data' needs to already be in the form the hardware expects. Any |
| 269 | * including any leading register specific data. Any data written | 69 | * data written through this function will not go through the cache as |
| 270 | * through this function will not go through the cache as it only | 70 | * it only handles writing to volatile or out of bounds registers. |
| 271 | * handles writing to volatile or out of bounds registers. | 71 | * |
| 72 | * This is currently only supported for devices using the regmap API | ||
| 73 | * wrappers. | ||
| 272 | */ | 74 | */ |
| 273 | static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int reg, | 75 | static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, |
| 76 | unsigned int reg, | ||
| 274 | const void *data, size_t len) | 77 | const void *data, size_t len) |
| 275 | { | 78 | { |
| 276 | int ret; | ||
| 277 | |||
| 278 | /* To ensure that we don't get out of sync with the cache, check | 79 | /* To ensure that we don't get out of sync with the cache, check |
| 279 | * whether the base register is volatile or if we've directly asked | 80 | * whether the base register is volatile or if we've directly asked |
| 280 | * to bypass the cache. Out of bounds registers are considered | 81 | * to bypass the cache. Out of bounds registers are considered |
| @@ -285,68 +86,9 @@ static int snd_soc_hw_bulk_write_raw(struct snd_soc_codec *codec, unsigned int r | |||
| 285 | && reg < codec->driver->reg_cache_size) | 86 | && reg < codec->driver->reg_cache_size) |
| 286 | return -EINVAL; | 87 | return -EINVAL; |
| 287 | 88 | ||
| 288 | switch (codec->control_type) { | 89 | return regmap_raw_write(codec->control_data, reg, data, len); |
| 289 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | ||
| 290 | case SND_SOC_I2C: | ||
| 291 | ret = i2c_master_send(to_i2c_client(codec->dev), data, len); | ||
| 292 | break; | ||
| 293 | #endif | ||
| 294 | #if defined(CONFIG_SPI_MASTER) | ||
| 295 | case SND_SOC_SPI: | ||
| 296 | ret = spi_write(to_spi_device(codec->dev), data, len); | ||
| 297 | break; | ||
| 298 | #endif | ||
| 299 | default: | ||
| 300 | BUG(); | ||
| 301 | } | ||
| 302 | |||
| 303 | if (ret == len) | ||
| 304 | return 0; | ||
| 305 | if (ret < 0) | ||
| 306 | return ret; | ||
| 307 | else | ||
| 308 | return -EIO; | ||
| 309 | } | 90 | } |
| 310 | 91 | ||
| 311 | static struct { | ||
| 312 | int addr_bits; | ||
| 313 | int data_bits; | ||
| 314 | int (*write)(struct snd_soc_codec *codec, unsigned int, unsigned int); | ||
| 315 | unsigned int (*read)(struct snd_soc_codec *, unsigned int); | ||
| 316 | unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); | ||
| 317 | unsigned int (*spi_read)(struct snd_soc_codec *, unsigned int); | ||
| 318 | } io_types[] = { | ||
| 319 | { | ||
| 320 | .addr_bits = 4, .data_bits = 12, | ||
| 321 | .write = snd_soc_4_12_write, | ||
| 322 | }, | ||
| 323 | { | ||
| 324 | .addr_bits = 7, .data_bits = 9, | ||
| 325 | .write = snd_soc_7_9_write, | ||
| 326 | }, | ||
| 327 | { | ||
| 328 | .addr_bits = 8, .data_bits = 8, | ||
| 329 | .write = snd_soc_8_8_write, | ||
| 330 | .i2c_read = snd_soc_8_8_read_i2c, | ||
| 331 | }, | ||
| 332 | { | ||
| 333 | .addr_bits = 8, .data_bits = 16, | ||
| 334 | .write = snd_soc_8_16_write, | ||
| 335 | .i2c_read = snd_soc_8_16_read_i2c, | ||
| 336 | }, | ||
| 337 | { | ||
| 338 | .addr_bits = 16, .data_bits = 8, | ||
| 339 | .write = snd_soc_16_8_write, | ||
| 340 | .i2c_read = snd_soc_16_8_read_i2c, | ||
| 341 | .spi_read = snd_soc_16_8_read_spi, | ||
| 342 | }, | ||
| 343 | { | ||
| 344 | .addr_bits = 16, .data_bits = 16, | ||
| 345 | .write = snd_soc_16_16_write, | ||
| 346 | .i2c_read = snd_soc_16_16_read_i2c, | ||
| 347 | }, | ||
| 348 | }; | ||
| 349 | |||
| 350 | /** | 92 | /** |
| 351 | * snd_soc_codec_set_cache_io: Set up standard I/O functions. | 93 | * snd_soc_codec_set_cache_io: Set up standard I/O functions. |
| 352 | * | 94 | * |
| @@ -370,50 +112,51 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | |||
| 370 | int addr_bits, int data_bits, | 112 | int addr_bits, int data_bits, |
| 371 | enum snd_soc_control_type control) | 113 | enum snd_soc_control_type control) |
| 372 | { | 114 | { |
| 373 | int i; | 115 | struct regmap_config config; |
| 374 | |||
| 375 | for (i = 0; i < ARRAY_SIZE(io_types); i++) | ||
| 376 | if (io_types[i].addr_bits == addr_bits && | ||
| 377 | io_types[i].data_bits == data_bits) | ||
| 378 | break; | ||
| 379 | if (i == ARRAY_SIZE(io_types)) { | ||
| 380 | printk(KERN_ERR | ||
| 381 | "No I/O functions for %d bit address %d bit data\n", | ||
| 382 | addr_bits, data_bits); | ||
| 383 | return -EINVAL; | ||
| 384 | } | ||
| 385 | 116 | ||
| 386 | codec->write = io_types[i].write; | 117 | memset(&config, 0, sizeof(config)); |
| 118 | codec->write = hw_write; | ||
| 387 | codec->read = hw_read; | 119 | codec->read = hw_read; |
| 388 | codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; | 120 | codec->bulk_write_raw = snd_soc_hw_bulk_write_raw; |
| 389 | 121 | ||
| 122 | config.reg_bits = addr_bits; | ||
| 123 | config.val_bits = data_bits; | ||
| 124 | |||
| 390 | switch (control) { | 125 | switch (control) { |
| 126 | #if defined(CONFIG_REGMAP_I2C) || defined(CONFIG_REGMAP_I2C_MODULE) | ||
| 391 | case SND_SOC_I2C: | 127 | case SND_SOC_I2C: |
| 392 | #if defined(CONFIG_I2C) || (defined(CONFIG_I2C_MODULE) && defined(MODULE)) | 128 | codec->control_data = regmap_init_i2c(to_i2c_client(codec->dev), |
| 393 | codec->hw_write = (hw_write_t)i2c_master_send; | 129 | &config); |
| 394 | #endif | ||
| 395 | if (io_types[i].i2c_read) | ||
| 396 | codec->hw_read = io_types[i].i2c_read; | ||
| 397 | |||
| 398 | codec->control_data = container_of(codec->dev, | ||
| 399 | struct i2c_client, | ||
| 400 | dev); | ||
| 401 | break; | 130 | break; |
| 131 | #endif | ||
| 402 | 132 | ||
| 133 | #if defined(CONFIG_REGMAP_SPI) || defined(CONFIG_REGMAP_SPI_MODULE) | ||
| 403 | case SND_SOC_SPI: | 134 | case SND_SOC_SPI: |
| 404 | #ifdef CONFIG_SPI_MASTER | 135 | codec->control_data = regmap_init_spi(to_spi_device(codec->dev), |
| 405 | codec->hw_write = do_spi_write; | 136 | &config); |
| 137 | break; | ||
| 406 | #endif | 138 | #endif |
| 407 | if (io_types[i].spi_read) | ||
| 408 | codec->hw_read = io_types[i].spi_read; | ||
| 409 | 139 | ||
| 410 | codec->control_data = container_of(codec->dev, | 140 | case SND_SOC_REGMAP: |
| 411 | struct spi_device, | 141 | /* Device has made its own regmap arrangements */ |
| 412 | dev); | ||
| 413 | break; | 142 | break; |
| 143 | |||
| 144 | default: | ||
| 145 | return -EINVAL; | ||
| 414 | } | 146 | } |
| 415 | 147 | ||
| 148 | if (IS_ERR(codec->control_data)) | ||
| 149 | return PTR_ERR(codec->control_data); | ||
| 150 | |||
| 416 | return 0; | 151 | return 0; |
| 417 | } | 152 | } |
| 418 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); | 153 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); |
| 419 | 154 | #else | |
| 155 | int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, | ||
| 156 | int addr_bits, int data_bits, | ||
| 157 | enum snd_soc_control_type control) | ||
| 158 | { | ||
| 159 | return -ENOTSUPP; | ||
| 160 | } | ||
| 161 | EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); | ||
| 162 | #endif | ||
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index fa31d9c2abd8..52db96636290 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
| @@ -188,6 +188,8 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count, | |||
| 188 | list_add(&(pins[i].list), &jack->pins); | 188 | list_add(&(pins[i].list), &jack->pins); |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | snd_soc_dapm_new_widgets(&jack->codec->card->dapm); | ||
| 192 | |||
| 191 | /* Update to reflect the last reported status; canned jack | 193 | /* Update to reflect the last reported status; canned jack |
| 192 | * implementations are likely to set their state before the | 194 | * implementations are likely to set their state before the |
| 193 | * card has an opportunity to associate pins. | 195 | * card has an opportunity to associate pins. |
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 2879c883eebc..ee15337353fa 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c | |||
| @@ -27,17 +27,13 @@ | |||
| 27 | #include <sound/soc.h> | 27 | #include <sound/soc.h> |
| 28 | #include <sound/initval.h> | 28 | #include <sound/initval.h> |
| 29 | 29 | ||
| 30 | static DEFINE_MUTEX(pcm_mutex); | 30 | static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream, |
| 31 | 31 | struct snd_soc_dai *soc_dai) | |
| 32 | static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) | ||
| 33 | { | 32 | { |
| 34 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 33 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 35 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 36 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 37 | int ret; | 34 | int ret; |
| 38 | 35 | ||
| 39 | if (!codec_dai->driver->symmetric_rates && | 36 | if (!soc_dai->driver->symmetric_rates && |
| 40 | !cpu_dai->driver->symmetric_rates && | ||
| 41 | !rtd->dai_link->symmetric_rates) | 37 | !rtd->dai_link->symmetric_rates) |
| 42 | return 0; | 38 | return 0; |
| 43 | 39 | ||
| @@ -45,19 +41,19 @@ static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) | |||
| 45 | * the second can need to get its constraints before the first has | 41 | * the second can need to get its constraints before the first has |
| 46 | * picked a rate. Complain and allow the application to carry on. | 42 | * picked a rate. Complain and allow the application to carry on. |
| 47 | */ | 43 | */ |
| 48 | if (!rtd->rate) { | 44 | if (!soc_dai->rate) { |
| 49 | dev_warn(&rtd->dev, | 45 | dev_warn(soc_dai->dev, |
| 50 | "Not enforcing symmetric_rates due to race\n"); | 46 | "Not enforcing symmetric_rates due to race\n"); |
| 51 | return 0; | 47 | return 0; |
| 52 | } | 48 | } |
| 53 | 49 | ||
| 54 | dev_dbg(&rtd->dev, "Symmetry forces %dHz rate\n", rtd->rate); | 50 | dev_dbg(soc_dai->dev, "Symmetry forces %dHz rate\n", soc_dai->rate); |
| 55 | 51 | ||
| 56 | ret = snd_pcm_hw_constraint_minmax(substream->runtime, | 52 | ret = snd_pcm_hw_constraint_minmax(substream->runtime, |
| 57 | SNDRV_PCM_HW_PARAM_RATE, | 53 | SNDRV_PCM_HW_PARAM_RATE, |
| 58 | rtd->rate, rtd->rate); | 54 | soc_dai->rate, soc_dai->rate); |
| 59 | if (ret < 0) { | 55 | if (ret < 0) { |
| 60 | dev_err(&rtd->dev, | 56 | dev_err(soc_dai->dev, |
| 61 | "Unable to apply rate symmetry constraint: %d\n", ret); | 57 | "Unable to apply rate symmetry constraint: %d\n", ret); |
| 62 | return ret; | 58 | return ret; |
| 63 | } | 59 | } |
| @@ -187,8 +183,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) | |||
| 187 | } | 183 | } |
| 188 | 184 | ||
| 189 | /* Symmetry only applies if we've already got an active stream. */ | 185 | /* Symmetry only applies if we've already got an active stream. */ |
| 190 | if (cpu_dai->active || codec_dai->active) { | 186 | if (cpu_dai->active) { |
| 191 | ret = soc_pcm_apply_symmetry(substream); | 187 | ret = soc_pcm_apply_symmetry(substream, cpu_dai); |
| 188 | if (ret != 0) | ||
| 189 | goto config_err; | ||
| 190 | } | ||
| 191 | |||
| 192 | if (codec_dai->active) { | ||
| 193 | ret = soc_pcm_apply_symmetry(substream, codec_dai); | ||
| 192 | if (ret != 0) | 194 | if (ret != 0) |
| 193 | goto config_err; | 195 | goto config_err; |
| 194 | } | 196 | } |
| @@ -290,8 +292,12 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
| 290 | codec_dai->active--; | 292 | codec_dai->active--; |
| 291 | codec->active--; | 293 | codec->active--; |
| 292 | 294 | ||
| 293 | if (!cpu_dai->active && !codec_dai->active) | 295 | /* clear the corresponding DAIs rate when inactive */ |
| 294 | rtd->rate = 0; | 296 | if (!cpu_dai->active) |
| 297 | cpu_dai->rate = 0; | ||
| 298 | |||
| 299 | if (!codec_dai->active) | ||
| 300 | codec_dai->rate = 0; | ||
| 295 | 301 | ||
| 296 | /* Muting the DAC suppresses artifacts caused during digital | 302 | /* Muting the DAC suppresses artifacts caused during digital |
| 297 | * shutdown, for example from stopping clocks. | 303 | * shutdown, for example from stopping clocks. |
| @@ -313,10 +319,17 @@ static int soc_pcm_close(struct snd_pcm_substream *substream) | |||
| 313 | cpu_dai->runtime = NULL; | 319 | cpu_dai->runtime = NULL; |
| 314 | 320 | ||
| 315 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 321 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
| 316 | /* start delayed pop wq here for playback streams */ | 322 | if (unlikely(codec->ignore_pmdown_time)) { |
| 317 | codec_dai->pop_wait = 1; | 323 | /* powered down playback stream now */ |
| 318 | schedule_delayed_work(&rtd->delayed_work, | 324 | snd_soc_dapm_stream_event(rtd, |
| 319 | msecs_to_jiffies(rtd->pmdown_time)); | 325 | codec_dai->driver->playback.stream_name, |
| 326 | SND_SOC_DAPM_STREAM_STOP); | ||
| 327 | } else { | ||
| 328 | /* start delayed pop wq here for playback streams */ | ||
| 329 | codec_dai->pop_wait = 1; | ||
| 330 | schedule_delayed_work(&rtd->delayed_work, | ||
| 331 | msecs_to_jiffies(rtd->pmdown_time)); | ||
| 332 | } | ||
| 320 | } else { | 333 | } else { |
| 321 | /* capture streams can be powered down now */ | 334 | /* capture streams can be powered down now */ |
| 322 | snd_soc_dapm_stream_event(rtd, | 335 | snd_soc_dapm_stream_event(rtd, |
| @@ -449,7 +462,9 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, | |||
| 449 | } | 462 | } |
| 450 | } | 463 | } |
| 451 | 464 | ||
| 452 | rtd->rate = params_rate(params); | 465 | /* store the rate for each DAIs */ |
| 466 | cpu_dai->rate = params_rate(params); | ||
| 467 | codec_dai->rate = params_rate(params); | ||
| 453 | 468 | ||
| 454 | out: | 469 | out: |
| 455 | mutex_unlock(&rtd->pcm_mutex); | 470 | mutex_unlock(&rtd->pcm_mutex); |
diff --git a/sound/soc/tegra/tegra_das.c b/sound/soc/tegra/tegra_das.c index 9f24ef73f2cb..3b55a44146af 100644 --- a/sound/soc/tegra/tegra_das.c +++ b/sound/soc/tegra/tegra_das.c | |||
| @@ -212,7 +212,7 @@ err_release: | |||
| 212 | release_mem_region(res->start, resource_size(res)); | 212 | release_mem_region(res->start, resource_size(res)); |
| 213 | err_free: | 213 | err_free: |
| 214 | kfree(das); | 214 | kfree(das); |
| 215 | das = 0; | 215 | das = NULL; |
| 216 | exit: | 216 | exit: |
| 217 | return ret; | 217 | return ret; |
| 218 | } | 218 | } |
| @@ -234,7 +234,7 @@ static int __devexit tegra_das_remove(struct platform_device *pdev) | |||
| 234 | release_mem_region(res->start, resource_size(res)); | 234 | release_mem_region(res->start, resource_size(res)); |
| 235 | 235 | ||
| 236 | kfree(das); | 236 | kfree(das); |
| 237 | das = 0; | 237 | das = NULL; |
| 238 | 238 | ||
| 239 | return 0; | 239 | return 0; |
| 240 | } | 240 | } |
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index f36b9969cfec..6728fab8c411 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c | |||
| @@ -312,7 +312,7 @@ static struct snd_soc_dai_ops tegra_i2s_dai_ops = { | |||
| 312 | .trigger = tegra_i2s_trigger, | 312 | .trigger = tegra_i2s_trigger, |
| 313 | }; | 313 | }; |
| 314 | 314 | ||
| 315 | struct snd_soc_dai_driver tegra_i2s_dai[] = { | 315 | static struct snd_soc_dai_driver tegra_i2s_dai[] = { |
| 316 | { | 316 | { |
| 317 | .name = DRV_NAME ".0", | 317 | .name = DRV_NAME ".0", |
| 318 | .probe = tegra_i2s_probe, | 318 | .probe = tegra_i2s_probe, |
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c index c7cfd96e991e..436def1dfa39 100644 --- a/sound/soc/tegra/tegra_pcm.c +++ b/sound/soc/tegra/tegra_pcm.c | |||
| @@ -367,7 +367,7 @@ static void tegra_pcm_free(struct snd_pcm *pcm) | |||
| 367 | tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); | 367 | tegra_pcm_deallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | struct snd_soc_platform_driver tegra_pcm_platform = { | 370 | static struct snd_soc_platform_driver tegra_pcm_platform = { |
| 371 | .ops = &tegra_pcm_ops, | 371 | .ops = &tegra_pcm_ops, |
| 372 | .pcm_new = tegra_pcm_new, | 372 | .pcm_new = tegra_pcm_new, |
| 373 | .pcm_free = tegra_pcm_free, | 373 | .pcm_free = tegra_pcm_free, |
diff --git a/sound/soc/tegra/tegra_spdif.c b/sound/soc/tegra/tegra_spdif.c index abe606b0a29e..dd11d0c63474 100644 --- a/sound/soc/tegra/tegra_spdif.c +++ b/sound/soc/tegra/tegra_spdif.c | |||
| @@ -127,7 +127,7 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream, | |||
| 127 | { | 127 | { |
| 128 | struct device *dev = substream->pcm->card->dev; | 128 | struct device *dev = substream->pcm->card->dev; |
| 129 | struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); | 129 | struct tegra_spdif *spdif = snd_soc_dai_get_drvdata(dai); |
| 130 | int ret, srate, spdifclock; | 130 | int ret, spdifclock; |
| 131 | 131 | ||
| 132 | spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK; | 132 | spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_PACK; |
| 133 | spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK; | 133 | spdif->reg_ctrl &= ~TEGRA_SPDIF_CTRL_BIT_MODE_MASK; |
| @@ -140,7 +140,6 @@ static int tegra_spdif_hw_params(struct snd_pcm_substream *substream, | |||
| 140 | return -EINVAL; | 140 | return -EINVAL; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | srate = params_rate(params); | ||
| 144 | switch (params_rate(params)) { | 143 | switch (params_rate(params)) { |
| 145 | case 32000: | 144 | case 32000: |
| 146 | spdifclock = 4096000; | 145 | spdifclock = 4096000; |
| @@ -232,7 +231,7 @@ static struct snd_soc_dai_ops tegra_spdif_dai_ops = { | |||
| 232 | .trigger = tegra_spdif_trigger, | 231 | .trigger = tegra_spdif_trigger, |
| 233 | }; | 232 | }; |
| 234 | 233 | ||
| 235 | struct snd_soc_dai_driver tegra_spdif_dai = { | 234 | static struct snd_soc_dai_driver tegra_spdif_dai = { |
| 236 | .name = DRV_NAME, | 235 | .name = DRV_NAME, |
| 237 | .probe = tegra_spdif_probe, | 236 | .probe = tegra_spdif_probe, |
| 238 | .playback = { | 237 | .playback = { |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index be27f1d229af..a81cf39257bf 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
| @@ -339,8 +339,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) | |||
| 339 | snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); | 339 | snd_soc_dapm_nc_pin(dapm, "LINEOUTL"); |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | snd_soc_dapm_sync(dapm); | ||
| 343 | |||
| 344 | return 0; | 342 | return 0; |
| 345 | } | 343 | } |
| 346 | 344 | ||
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c index 8fc07e9adf2e..b3a7efa6d960 100644 --- a/sound/soc/tegra/trimslice.c +++ b/sound/soc/tegra/trimslice.c | |||
| @@ -124,8 +124,6 @@ static int trimslice_asoc_init(struct snd_soc_pcm_runtime *rtd) | |||
| 124 | snd_soc_dapm_nc_pin(dapm, "RHPOUT"); | 124 | snd_soc_dapm_nc_pin(dapm, "RHPOUT"); |
| 125 | snd_soc_dapm_nc_pin(dapm, "MICIN"); | 125 | snd_soc_dapm_nc_pin(dapm, "MICIN"); |
| 126 | 126 | ||
| 127 | snd_soc_dapm_sync(dapm); | ||
| 128 | |||
| 129 | return 0; | 127 | return 0; |
| 130 | } | 128 | } |
| 131 | 129 | ||
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 743d07b82c06..a4e3f5501847 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c | |||
| @@ -201,7 +201,7 @@ static int __devinit txx9aclc_ac97_dev_probe(struct platform_device *pdev) | |||
| 201 | if (!drvdata->base) | 201 | if (!drvdata->base) |
| 202 | return -EBUSY; | 202 | return -EBUSY; |
| 203 | err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, | 203 | err = devm_request_irq(&pdev->dev, irq, txx9aclc_ac97_irq, |
| 204 | IRQF_DISABLED, dev_name(&pdev->dev), drvdata); | 204 | 0, dev_name(&pdev->dev), drvdata); |
| 205 | if (err < 0) | 205 | if (err < 0) |
| 206 | return err; | 206 | return err; |
| 207 | 207 | ||
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c index 6770e7166be4..9b5e283af51c 100644 --- a/sound/soc/txx9/txx9aclc-generic.c +++ b/sound/soc/txx9/txx9aclc-generic.c | |||
| @@ -62,7 +62,7 @@ static int __exit txx9aclc_generic_remove(struct platform_device *pdev) | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | static struct platform_driver txx9aclc_generic_driver = { | 64 | static struct platform_driver txx9aclc_generic_driver = { |
| 65 | .remove = txx9aclc_generic_remove, | 65 | .remove = __exit_p(txx9aclc_generic_remove), |
| 66 | .driver = { | 66 | .driver = { |
| 67 | .name = "txx9aclc-generic", | 67 | .name = "txx9aclc-generic", |
| 68 | .owner = THIS_MODULE, | 68 | .owner = THIS_MODULE, |
diff --git a/sound/sparc/amd7930.c b/sound/sparc/amd7930.c index ad7d4d7d9237..f036776380b5 100644 --- a/sound/sparc/amd7930.c +++ b/sound/sparc/amd7930.c | |||
| @@ -962,7 +962,7 @@ static int __devinit snd_amd7930_create(struct snd_card *card, | |||
| 962 | amd7930_idle(amd); | 962 | amd7930_idle(amd); |
| 963 | 963 | ||
| 964 | if (request_irq(irq, snd_amd7930_interrupt, | 964 | if (request_irq(irq, snd_amd7930_interrupt, |
| 965 | IRQF_DISABLED | IRQF_SHARED, "amd7930", amd)) { | 965 | IRQF_SHARED, "amd7930", amd)) { |
| 966 | snd_printk(KERN_ERR "amd7930-%d: Unable to grab IRQ %d\n", | 966 | snd_printk(KERN_ERR "amd7930-%d: Unable to grab IRQ %d\n", |
| 967 | dev, irq); | 967 | dev, irq); |
| 968 | snd_amd7930_free(amd); | 968 | snd_amd7930_free(amd); |
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 1e3ae3327dd3..07bcfe4d18a7 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include <linux/firmware.h> | 17 | #include <linux/firmware.h> |
| 18 | #include <linux/bitrev.h> | 18 | #include <linux/bitrev.h> |
| 19 | #include <linux/kernel.h> | ||
| 19 | 20 | ||
| 20 | #include "firmware.h" | 21 | #include "firmware.h" |
| 21 | #include "chip.h" | 22 | #include "chip.h" |
| @@ -59,21 +60,19 @@ struct ihex_record { | |||
| 59 | unsigned int txt_offset; /* current position in txt_data */ | 60 | unsigned int txt_offset; /* current position in txt_data */ |
| 60 | }; | 61 | }; |
| 61 | 62 | ||
| 62 | static u8 usb6fire_fw_ihex_nibble(const u8 n) | ||
| 63 | { | ||
| 64 | if (n >= '0' && n <= '9') | ||
| 65 | return n - '0'; | ||
| 66 | else if (n >= 'A' && n <= 'F') | ||
| 67 | return n - ('A' - 10); | ||
| 68 | else if (n >= 'a' && n <= 'f') | ||
| 69 | return n - ('a' - 10); | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc) | 63 | static u8 usb6fire_fw_ihex_hex(const u8 *data, u8 *crc) |
| 74 | { | 64 | { |
| 75 | u8 val = (usb6fire_fw_ihex_nibble(data[0]) << 4) | | 65 | u8 val = 0; |
| 76 | usb6fire_fw_ihex_nibble(data[1]); | 66 | int hval; |
| 67 | |||
| 68 | hval = hex_to_bin(data[0]); | ||
| 69 | if (hval >= 0) | ||
| 70 | val |= (hval << 4); | ||
| 71 | |||
| 72 | hval = hex_to_bin(data[1]); | ||
| 73 | if (hval >= 0) | ||
| 74 | val |= hval; | ||
| 75 | |||
| 77 | *crc += val; | 76 | *crc += val; |
| 78 | return val; | 77 | return val; |
| 79 | } | 78 | } |
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 8beb77563da2..3efc21c3d67c 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
| @@ -67,6 +67,7 @@ config SND_USB_CAIAQ | |||
| 67 | * Native Instruments Guitar Rig mobile | 67 | * Native Instruments Guitar Rig mobile |
| 68 | * Native Instruments Traktor Kontrol X1 | 68 | * Native Instruments Traktor Kontrol X1 |
| 69 | * Native Instruments Traktor Kontrol S4 | 69 | * Native Instruments Traktor Kontrol S4 |
| 70 | * Native Instruments Maschine Controller | ||
| 70 | 71 | ||
| 71 | To compile this driver as a module, choose M here: the module | 72 | To compile this driver as a module, choose M here: the module |
| 72 | will be called snd-usb-caiaq. | 73 | will be called snd-usb-caiaq. |
| @@ -85,6 +86,7 @@ config SND_USB_CAIAQ_INPUT | |||
| 85 | * Native Instruments Kore Controller 2 | 86 | * Native Instruments Kore Controller 2 |
| 86 | * Native Instruments Audio Kontrol 1 | 87 | * Native Instruments Audio Kontrol 1 |
| 87 | * Native Instruments Traktor Kontrol S4 | 88 | * Native Instruments Traktor Kontrol S4 |
| 89 | * Native Instruments Maschine Controller | ||
| 88 | 90 | ||
| 89 | config SND_USB_US122L | 91 | config SND_USB_US122L |
| 90 | tristate "Tascam US-122L USB driver" | 92 | tristate "Tascam US-122L USB driver" |
diff --git a/sound/usb/Makefile b/sound/usb/Makefile index cf9ed66445fa..ac256dc4c6be 100644 --- a/sound/usb/Makefile +++ b/sound/usb/Makefile | |||
| @@ -3,16 +3,16 @@ | |||
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | snd-usb-audio-objs := card.o \ | 5 | snd-usb-audio-objs := card.o \ |
| 6 | clock.o \ | ||
| 7 | endpoint.o \ | ||
| 8 | format.o \ | ||
| 9 | helper.o \ | ||
| 6 | mixer.o \ | 10 | mixer.o \ |
| 7 | mixer_quirks.o \ | 11 | mixer_quirks.o \ |
| 12 | pcm.o \ | ||
| 8 | proc.o \ | 13 | proc.o \ |
| 9 | quirks.o \ | 14 | quirks.o \ |
| 10 | format.o \ | 15 | stream.o |
| 11 | endpoint.o \ | ||
| 12 | urb.o \ | ||
| 13 | pcm.o \ | ||
| 14 | helper.o \ | ||
| 15 | clock.o | ||
| 16 | 16 | ||
| 17 | snd-usbmidi-lib-objs := midi.o | 17 | snd-usbmidi-lib-objs := midi.o |
| 18 | 18 | ||
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 45bc4a2dc6f0..3eb605bd9503 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
| @@ -50,7 +50,8 @@ MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," | |||
| 50 | "{Native Instruments, Session I/O}," | 50 | "{Native Instruments, Session I/O}," |
| 51 | "{Native Instruments, GuitarRig mobile}" | 51 | "{Native Instruments, GuitarRig mobile}" |
| 52 | "{Native Instruments, Traktor Kontrol X1}" | 52 | "{Native Instruments, Traktor Kontrol X1}" |
| 53 | "{Native Instruments, Traktor Kontrol S4}"); | 53 | "{Native Instruments, Traktor Kontrol S4}" |
| 54 | "{Native Instruments, Maschine Controller}"); | ||
| 54 | 55 | ||
| 55 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ | 56 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-max */ |
| 56 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ | 57 | static char* id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* Id for this card */ |
| @@ -146,6 +147,11 @@ static struct usb_device_id snd_usb_id_table[] = { | |||
| 146 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | 147 | .idVendor = USB_VID_NATIVEINSTRUMENTS, |
| 147 | .idProduct = USB_PID_TRAKTORAUDIO2 | 148 | .idProduct = USB_PID_TRAKTORAUDIO2 |
| 148 | }, | 149 | }, |
| 150 | { | ||
| 151 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
| 152 | .idVendor = USB_VID_NATIVEINSTRUMENTS, | ||
| 153 | .idProduct = USB_PID_MASCHINECONTROLLER | ||
| 154 | }, | ||
| 149 | { /* terminator */ } | 155 | { /* terminator */ } |
| 150 | }; | 156 | }; |
| 151 | 157 | ||
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h index 3f9c6339ae90..562b0bff9c41 100644 --- a/sound/usb/caiaq/device.h +++ b/sound/usb/caiaq/device.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 | 18 | #define USB_PID_TRAKTORKONTROLX1 0x2305 |
| 19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff | 19 | #define USB_PID_TRAKTORKONTROLS4 0xbaff |
| 20 | #define USB_PID_TRAKTORAUDIO2 0x041d | 20 | #define USB_PID_TRAKTORAUDIO2 0x041d |
| 21 | #define USB_PID_MASCHINECONTROLLER 0x0808 | ||
| 21 | 22 | ||
| 22 | #define EP1_BUFSIZE 64 | 23 | #define EP1_BUFSIZE 64 |
| 23 | #define EP4_BUFSIZE 512 | 24 | #define EP4_BUFSIZE 512 |
diff --git a/sound/usb/caiaq/input.c b/sound/usb/caiaq/input.c index a213813487bd..26a121b42c3c 100644 --- a/sound/usb/caiaq/input.c +++ b/sound/usb/caiaq/input.c | |||
| @@ -67,6 +67,61 @@ static unsigned short keycode_kore[] = { | |||
| 67 | KEY_BRL_DOT5 | 67 | KEY_BRL_DOT5 |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | #define MASCHINE_BUTTONS (42) | ||
| 71 | #define MASCHINE_BUTTON(X) ((X) + BTN_MISC) | ||
| 72 | #define MASCHINE_PADS (16) | ||
| 73 | #define MASCHINE_PAD(X) ((X) + ABS_PRESSURE) | ||
| 74 | |||
| 75 | static unsigned short keycode_maschine[] = { | ||
| 76 | MASCHINE_BUTTON(40), /* mute */ | ||
| 77 | MASCHINE_BUTTON(39), /* solo */ | ||
| 78 | MASCHINE_BUTTON(38), /* select */ | ||
| 79 | MASCHINE_BUTTON(37), /* duplicate */ | ||
| 80 | MASCHINE_BUTTON(36), /* navigate */ | ||
| 81 | MASCHINE_BUTTON(35), /* pad mode */ | ||
| 82 | MASCHINE_BUTTON(34), /* pattern */ | ||
| 83 | MASCHINE_BUTTON(33), /* scene */ | ||
| 84 | KEY_RESERVED, /* spacer */ | ||
| 85 | |||
| 86 | MASCHINE_BUTTON(30), /* rec */ | ||
| 87 | MASCHINE_BUTTON(31), /* erase */ | ||
| 88 | MASCHINE_BUTTON(32), /* shift */ | ||
| 89 | MASCHINE_BUTTON(28), /* grid */ | ||
| 90 | MASCHINE_BUTTON(27), /* > */ | ||
| 91 | MASCHINE_BUTTON(26), /* < */ | ||
| 92 | MASCHINE_BUTTON(25), /* restart */ | ||
| 93 | |||
| 94 | MASCHINE_BUTTON(21), /* E */ | ||
| 95 | MASCHINE_BUTTON(22), /* F */ | ||
| 96 | MASCHINE_BUTTON(23), /* G */ | ||
| 97 | MASCHINE_BUTTON(24), /* H */ | ||
| 98 | MASCHINE_BUTTON(20), /* D */ | ||
| 99 | MASCHINE_BUTTON(19), /* C */ | ||
| 100 | MASCHINE_BUTTON(18), /* B */ | ||
| 101 | MASCHINE_BUTTON(17), /* A */ | ||
| 102 | |||
| 103 | MASCHINE_BUTTON(0), /* control */ | ||
| 104 | MASCHINE_BUTTON(2), /* browse */ | ||
| 105 | MASCHINE_BUTTON(4), /* < */ | ||
| 106 | MASCHINE_BUTTON(6), /* snap */ | ||
| 107 | MASCHINE_BUTTON(7), /* autowrite */ | ||
| 108 | MASCHINE_BUTTON(5), /* > */ | ||
| 109 | MASCHINE_BUTTON(3), /* sampling */ | ||
| 110 | MASCHINE_BUTTON(1), /* step */ | ||
| 111 | |||
| 112 | MASCHINE_BUTTON(15), /* 8 softkeys */ | ||
| 113 | MASCHINE_BUTTON(14), | ||
| 114 | MASCHINE_BUTTON(13), | ||
| 115 | MASCHINE_BUTTON(12), | ||
| 116 | MASCHINE_BUTTON(11), | ||
| 117 | MASCHINE_BUTTON(10), | ||
| 118 | MASCHINE_BUTTON(9), | ||
| 119 | MASCHINE_BUTTON(8), | ||
| 120 | |||
| 121 | MASCHINE_BUTTON(16), /* note repeat */ | ||
| 122 | MASCHINE_BUTTON(29) /* play */ | ||
| 123 | }; | ||
| 124 | |||
| 70 | #define KONTROLX1_INPUTS (40) | 125 | #define KONTROLX1_INPUTS (40) |
| 71 | #define KONTROLS4_BUTTONS (12 * 8) | 126 | #define KONTROLS4_BUTTONS (12 * 8) |
| 72 | #define KONTROLS4_AXIS (46) | 127 | #define KONTROLS4_AXIS (46) |
| @@ -218,6 +273,29 @@ static void snd_caiaq_input_read_erp(struct snd_usb_caiaqdev *dev, | |||
| 218 | input_report_abs(input_dev, ABS_HAT3Y, i); | 273 | input_report_abs(input_dev, ABS_HAT3Y, i); |
| 219 | input_sync(input_dev); | 274 | input_sync(input_dev); |
| 220 | break; | 275 | break; |
| 276 | |||
| 277 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
| 278 | /* 4 under the left screen */ | ||
| 279 | input_report_abs(input_dev, ABS_HAT0X, decode_erp(buf[21], buf[20])); | ||
| 280 | input_report_abs(input_dev, ABS_HAT0Y, decode_erp(buf[15], buf[14])); | ||
| 281 | input_report_abs(input_dev, ABS_HAT1X, decode_erp(buf[9], buf[8])); | ||
| 282 | input_report_abs(input_dev, ABS_HAT1Y, decode_erp(buf[3], buf[2])); | ||
| 283 | |||
| 284 | /* 4 under the right screen */ | ||
| 285 | input_report_abs(input_dev, ABS_HAT2X, decode_erp(buf[19], buf[18])); | ||
| 286 | input_report_abs(input_dev, ABS_HAT2Y, decode_erp(buf[13], buf[12])); | ||
| 287 | input_report_abs(input_dev, ABS_HAT3X, decode_erp(buf[7], buf[6])); | ||
| 288 | input_report_abs(input_dev, ABS_HAT3Y, decode_erp(buf[1], buf[0])); | ||
| 289 | |||
| 290 | /* volume */ | ||
| 291 | input_report_abs(input_dev, ABS_RX, decode_erp(buf[17], buf[16])); | ||
| 292 | /* tempo */ | ||
| 293 | input_report_abs(input_dev, ABS_RY, decode_erp(buf[11], buf[10])); | ||
| 294 | /* swing */ | ||
| 295 | input_report_abs(input_dev, ABS_RZ, decode_erp(buf[5], buf[4])); | ||
| 296 | |||
| 297 | input_sync(input_dev); | ||
| 298 | break; | ||
| 221 | } | 299 | } |
| 222 | } | 300 | } |
| 223 | 301 | ||
| @@ -400,6 +478,25 @@ static void snd_usb_caiaq_tks4_dispatch(struct snd_usb_caiaqdev *dev, | |||
| 400 | input_sync(dev->input_dev); | 478 | input_sync(dev->input_dev); |
| 401 | } | 479 | } |
| 402 | 480 | ||
| 481 | #define MASCHINE_MSGBLOCK_SIZE 2 | ||
| 482 | |||
| 483 | static void snd_usb_caiaq_maschine_dispatch(struct snd_usb_caiaqdev *dev, | ||
| 484 | const unsigned char *buf, | ||
| 485 | unsigned int len) | ||
| 486 | { | ||
| 487 | unsigned int i, pad_id; | ||
| 488 | uint16_t pressure; | ||
| 489 | |||
| 490 | for (i = 0; i < MASCHINE_PADS; i++) { | ||
| 491 | pressure = be16_to_cpu(buf[i * 2] << 8 | buf[(i * 2) + 1]); | ||
| 492 | pad_id = pressure >> 12; | ||
| 493 | |||
| 494 | input_report_abs(dev->input_dev, MASCHINE_PAD(pad_id), pressure & 0xfff); | ||
| 495 | } | ||
| 496 | |||
| 497 | input_sync(dev->input_dev); | ||
| 498 | } | ||
| 499 | |||
| 403 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | 500 | static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) |
| 404 | { | 501 | { |
| 405 | struct snd_usb_caiaqdev *dev = urb->context; | 502 | struct snd_usb_caiaqdev *dev = urb->context; |
| @@ -425,6 +522,13 @@ static void snd_usb_caiaq_ep4_reply_dispatch(struct urb *urb) | |||
| 425 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 522 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
| 426 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); | 523 | snd_usb_caiaq_tks4_dispatch(dev, buf, urb->actual_length); |
| 427 | break; | 524 | break; |
| 525 | |||
| 526 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
| 527 | if (urb->actual_length < (MASCHINE_PADS * MASCHINE_MSGBLOCK_SIZE)) | ||
| 528 | goto requeue; | ||
| 529 | |||
| 530 | snd_usb_caiaq_maschine_dispatch(dev, buf, urb->actual_length); | ||
| 531 | break; | ||
| 428 | } | 532 | } |
| 429 | 533 | ||
| 430 | requeue: | 534 | requeue: |
| @@ -444,6 +548,7 @@ static int snd_usb_caiaq_input_open(struct input_dev *idev) | |||
| 444 | switch (dev->chip.usb_id) { | 548 | switch (dev->chip.usb_id) { |
| 445 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 549 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
| 446 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 550 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
| 551 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
| 447 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) | 552 | if (usb_submit_urb(dev->ep4_in_urb, GFP_KERNEL) != 0) |
| 448 | return -EIO; | 553 | return -EIO; |
| 449 | break; | 554 | break; |
| @@ -462,6 +567,7 @@ static void snd_usb_caiaq_input_close(struct input_dev *idev) | |||
| 462 | switch (dev->chip.usb_id) { | 567 | switch (dev->chip.usb_id) { |
| 463 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): | 568 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLX1): |
| 464 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): | 569 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_TRAKTORKONTROLS4): |
| 570 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
| 465 | usb_kill_urb(dev->ep4_in_urb); | 571 | usb_kill_urb(dev->ep4_in_urb); |
| 466 | break; | 572 | break; |
| 467 | } | 573 | } |
| @@ -652,6 +758,50 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
| 652 | 758 | ||
| 653 | break; | 759 | break; |
| 654 | 760 | ||
| 761 | case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_MASCHINECONTROLLER): | ||
| 762 | input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); | ||
| 763 | input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) | | ||
| 764 | BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) | | ||
| 765 | BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) | | ||
| 766 | BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) | | ||
| 767 | BIT_MASK(ABS_RX) | BIT_MASK(ABS_RY) | | ||
| 768 | BIT_MASK(ABS_RZ); | ||
| 769 | |||
| 770 | BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_maschine)); | ||
| 771 | memcpy(dev->keycode, keycode_maschine, sizeof(keycode_maschine)); | ||
| 772 | input->keycodemax = ARRAY_SIZE(keycode_maschine); | ||
| 773 | |||
| 774 | for (i = 0; i < MASCHINE_PADS; i++) { | ||
| 775 | input->absbit[0] |= MASCHINE_PAD(i); | ||
| 776 | input_set_abs_params(input, MASCHINE_PAD(i), 0, 0xfff, 5, 10); | ||
| 777 | } | ||
| 778 | |||
| 779 | input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10); | ||
| 780 | input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10); | ||
| 781 | input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10); | ||
| 782 | input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10); | ||
| 783 | input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10); | ||
| 784 | input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10); | ||
| 785 | input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10); | ||
| 786 | input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10); | ||
| 787 | input_set_abs_params(input, ABS_RX, 0, 999, 0, 10); | ||
| 788 | input_set_abs_params(input, ABS_RY, 0, 999, 0, 10); | ||
| 789 | input_set_abs_params(input, ABS_RZ, 0, 999, 0, 10); | ||
| 790 | |||
| 791 | dev->ep4_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 792 | if (!dev->ep4_in_urb) { | ||
| 793 | ret = -ENOMEM; | ||
| 794 | goto exit_free_idev; | ||
| 795 | } | ||
| 796 | |||
| 797 | usb_fill_bulk_urb(dev->ep4_in_urb, usb_dev, | ||
| 798 | usb_rcvbulkpipe(usb_dev, 0x4), | ||
| 799 | dev->ep4_in_buf, EP4_BUFSIZE, | ||
| 800 | snd_usb_caiaq_ep4_reply_dispatch, dev); | ||
| 801 | |||
| 802 | snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5); | ||
| 803 | break; | ||
| 804 | |||
| 655 | default: | 805 | default: |
| 656 | /* no input methods supported on this device */ | 806 | /* no input methods supported on this device */ |
| 657 | goto exit_free_idev; | 807 | goto exit_free_idev; |
| @@ -664,15 +814,17 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev) | |||
| 664 | for (i = 0; i < input->keycodemax; i++) | 814 | for (i = 0; i < input->keycodemax; i++) |
| 665 | __set_bit(dev->keycode[i], input->keybit); | 815 | __set_bit(dev->keycode[i], input->keybit); |
| 666 | 816 | ||
| 817 | dev->input_dev = input; | ||
| 818 | |||
| 667 | ret = input_register_device(input); | 819 | ret = input_register_device(input); |
| 668 | if (ret < 0) | 820 | if (ret < 0) |
| 669 | goto exit_free_idev; | 821 | goto exit_free_idev; |
| 670 | 822 | ||
| 671 | dev->input_dev = input; | ||
| 672 | return 0; | 823 | return 0; |
| 673 | 824 | ||
| 674 | exit_free_idev: | 825 | exit_free_idev: |
| 675 | input_free_device(input); | 826 | input_free_device(input); |
| 827 | dev->input_dev = NULL; | ||
| 676 | return ret; | 828 | return ret; |
| 677 | } | 829 | } |
| 678 | 830 | ||
| @@ -688,4 +840,3 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev) | |||
| 688 | input_unregister_device(dev->input_dev); | 840 | input_unregister_device(dev->input_dev); |
| 689 | dev->input_dev = NULL; | 841 | dev->input_dev = NULL; |
| 690 | } | 842 | } |
| 691 | |||
diff --git a/sound/usb/card.c b/sound/usb/card.c index 3068f043099a..05c1aae0b010 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
| @@ -65,9 +65,9 @@ | |||
| 65 | #include "helper.h" | 65 | #include "helper.h" |
| 66 | #include "debug.h" | 66 | #include "debug.h" |
| 67 | #include "pcm.h" | 67 | #include "pcm.h" |
| 68 | #include "urb.h" | ||
| 69 | #include "format.h" | 68 | #include "format.h" |
| 70 | #include "power.h" | 69 | #include "power.h" |
| 70 | #include "stream.h" | ||
| 71 | 71 | ||
| 72 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | 72 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); |
| 73 | MODULE_DESCRIPTION("USB Audio"); | 73 | MODULE_DESCRIPTION("USB Audio"); |
| @@ -185,7 +185,7 @@ static int snd_usb_create_stream(struct snd_usb_audio *chip, int ctrlif, int int | |||
| 185 | return -EINVAL; | 185 | return -EINVAL; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | if (! snd_usb_parse_audio_endpoints(chip, interface)) { | 188 | if (! snd_usb_parse_audio_interface(chip, interface)) { |
| 189 | usb_set_interface(dev, interface, 0); /* reset the current interface */ | 189 | usb_set_interface(dev, interface, 0); /* reset the current interface */ |
| 190 | usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); | 190 | usb_driver_claim_interface(&usb_audio_driver, iface, (void *)-1L); |
| 191 | return -EINVAL; | 191 | return -EINVAL; |
diff --git a/sound/usb/card.h b/sound/usb/card.h index ae4251d5abf7..a39edcc32a93 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
| @@ -94,6 +94,8 @@ struct snd_usb_substream { | |||
| 94 | spinlock_t lock; | 94 | spinlock_t lock; |
| 95 | 95 | ||
| 96 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ | 96 | struct snd_urb_ops ops; /* callbacks (must be filled at init) */ |
| 97 | int last_frame_number; /* stored frame number */ | ||
| 98 | int last_delay; /* stored delay */ | ||
| 97 | }; | 99 | }; |
| 98 | 100 | ||
| 99 | struct snd_usb_stream { | 101 | struct snd_usb_stream { |
diff --git a/sound/usb/clock.c b/sound/usb/clock.c index 075195e8661a..379baad3d5ad 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
| @@ -91,7 +91,7 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i | |||
| 91 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 91 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
| 92 | UAC2_CX_CLOCK_SELECTOR << 8, | 92 | UAC2_CX_CLOCK_SELECTOR << 8, |
| 93 | snd_usb_ctrl_intf(chip) | (selector_id << 8), | 93 | snd_usb_ctrl_intf(chip) | (selector_id << 8), |
| 94 | &buf, sizeof(buf), 1000); | 94 | &buf, sizeof(buf)); |
| 95 | 95 | ||
| 96 | if (ret < 0) | 96 | if (ret < 0) |
| 97 | return ret; | 97 | return ret; |
| @@ -118,7 +118,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | |||
| 118 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 118 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
| 119 | UAC2_CS_CONTROL_CLOCK_VALID << 8, | 119 | UAC2_CS_CONTROL_CLOCK_VALID << 8, |
| 120 | snd_usb_ctrl_intf(chip) | (source_id << 8), | 120 | snd_usb_ctrl_intf(chip) | (source_id << 8), |
| 121 | &data, sizeof(data), 1000); | 121 | &data, sizeof(data)); |
| 122 | 122 | ||
| 123 | if (err < 0) { | 123 | if (err < 0) { |
| 124 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", | 124 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", |
| @@ -222,7 +222,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
| 222 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 222 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
| 223 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 223 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
| 224 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | 224 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, |
| 225 | data, sizeof(data), 1000)) < 0) { | 225 | data, sizeof(data))) < 0) { |
| 226 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", | 226 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d to ep %#x\n", |
| 227 | dev->devnum, iface, fmt->altsetting, rate, ep); | 227 | dev->devnum, iface, fmt->altsetting, rate, ep); |
| 228 | return err; | 228 | return err; |
| @@ -231,7 +231,7 @@ static int set_sample_rate_v1(struct snd_usb_audio *chip, int iface, | |||
| 231 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, | 231 | if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_GET_CUR, |
| 232 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, | 232 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN, |
| 233 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, | 233 | UAC_EP_CS_ATTR_SAMPLE_RATE << 8, ep, |
| 234 | data, sizeof(data), 1000)) < 0) { | 234 | data, sizeof(data))) < 0) { |
| 235 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", | 235 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq at ep %#x\n", |
| 236 | dev->devnum, iface, fmt->altsetting, ep); | 236 | dev->devnum, iface, fmt->altsetting, ep); |
| 237 | return 0; /* some devices don't support reading */ | 237 | return 0; /* some devices don't support reading */ |
| @@ -273,7 +273,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
| 273 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | 273 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, |
| 274 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 274 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
| 275 | snd_usb_ctrl_intf(chip) | (clock << 8), | 275 | snd_usb_ctrl_intf(chip) | (clock << 8), |
| 276 | data, sizeof(data), 1000)) < 0) { | 276 | data, sizeof(data))) < 0) { |
| 277 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", | 277 | snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", |
| 278 | dev->devnum, iface, fmt->altsetting, rate); | 278 | dev->devnum, iface, fmt->altsetting, rate); |
| 279 | return err; | 279 | return err; |
| @@ -283,7 +283,7 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, | |||
| 283 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 283 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
| 284 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 284 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
| 285 | snd_usb_ctrl_intf(chip) | (clock << 8), | 285 | snd_usb_ctrl_intf(chip) | (clock << 8), |
| 286 | data, sizeof(data), 1000)) < 0) { | 286 | data, sizeof(data))) < 0) { |
| 287 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", | 287 | snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", |
| 288 | dev->devnum, iface, fmt->altsetting); | 288 | dev->devnum, iface, fmt->altsetting); |
| 289 | return err; | 289 | return err; |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 7d46e482375d..81c6edecd862 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
| @@ -15,436 +15,951 @@ | |||
| 15 | * | 15 | * |
| 16 | */ | 16 | */ |
| 17 | 17 | ||
| 18 | #include <linux/gfp.h> | ||
| 18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/usb.h> | 20 | #include <linux/usb.h> |
| 21 | #include <linux/usb/audio.h> | 21 | #include <linux/usb/audio.h> |
| 22 | #include <linux/usb/audio-v2.h> | ||
| 23 | 22 | ||
| 24 | #include <sound/core.h> | 23 | #include <sound/core.h> |
| 25 | #include <sound/pcm.h> | 24 | #include <sound/pcm.h> |
| 26 | 25 | ||
| 27 | #include "usbaudio.h" | 26 | #include "usbaudio.h" |
| 27 | #include "helper.h" | ||
| 28 | #include "card.h" | 28 | #include "card.h" |
| 29 | #include "proc.h" | ||
| 30 | #include "quirks.h" | ||
| 31 | #include "endpoint.h" | 29 | #include "endpoint.h" |
| 32 | #include "urb.h" | ||
| 33 | #include "pcm.h" | 30 | #include "pcm.h" |
| 34 | #include "helper.h" | ||
| 35 | #include "format.h" | ||
| 36 | #include "clock.h" | ||
| 37 | 31 | ||
| 38 | /* | 32 | /* |
| 39 | * free a substream | 33 | * convert a sampling rate into our full speed format (fs/1000 in Q16.16) |
| 34 | * this will overflow at approx 524 kHz | ||
| 40 | */ | 35 | */ |
| 41 | static void free_substream(struct snd_usb_substream *subs) | 36 | static inline unsigned get_usb_full_speed_rate(unsigned int rate) |
| 42 | { | 37 | { |
| 43 | struct list_head *p, *n; | 38 | return ((rate << 13) + 62) / 125; |
| 44 | |||
| 45 | if (!subs->num_formats) | ||
| 46 | return; /* not initialized */ | ||
| 47 | list_for_each_safe(p, n, &subs->fmt_list) { | ||
| 48 | struct audioformat *fp = list_entry(p, struct audioformat, list); | ||
| 49 | kfree(fp->rate_table); | ||
| 50 | kfree(fp); | ||
| 51 | } | ||
| 52 | kfree(subs->rate_list.list); | ||
| 53 | } | 39 | } |
| 54 | 40 | ||
| 41 | /* | ||
| 42 | * convert a sampling rate into USB high speed format (fs/8000 in Q16.16) | ||
| 43 | * this will overflow at approx 4 MHz | ||
| 44 | */ | ||
| 45 | static inline unsigned get_usb_high_speed_rate(unsigned int rate) | ||
| 46 | { | ||
| 47 | return ((rate << 10) + 62) / 125; | ||
| 48 | } | ||
| 55 | 49 | ||
| 56 | /* | 50 | /* |
| 57 | * free a usb stream instance | 51 | * unlink active urbs. |
| 58 | */ | 52 | */ |
| 59 | static void snd_usb_audio_stream_free(struct snd_usb_stream *stream) | 53 | static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep) |
| 60 | { | 54 | { |
| 61 | free_substream(&stream->substream[0]); | 55 | struct snd_usb_audio *chip = subs->stream->chip; |
| 62 | free_substream(&stream->substream[1]); | 56 | unsigned int i; |
| 63 | list_del(&stream->list); | 57 | int async; |
| 64 | kfree(stream); | 58 | |
| 59 | subs->running = 0; | ||
| 60 | |||
| 61 | if (!force && subs->stream->chip->shutdown) /* to be sure... */ | ||
| 62 | return -EBADFD; | ||
| 63 | |||
| 64 | async = !can_sleep && chip->async_unlink; | ||
| 65 | |||
| 66 | if (!async && in_interrupt()) | ||
| 67 | return 0; | ||
| 68 | |||
| 69 | for (i = 0; i < subs->nurbs; i++) { | ||
| 70 | if (test_bit(i, &subs->active_mask)) { | ||
| 71 | if (!test_and_set_bit(i, &subs->unlink_mask)) { | ||
| 72 | struct urb *u = subs->dataurb[i].urb; | ||
| 73 | if (async) | ||
| 74 | usb_unlink_urb(u); | ||
| 75 | else | ||
| 76 | usb_kill_urb(u); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | } | ||
| 80 | if (subs->syncpipe) { | ||
| 81 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 82 | if (test_bit(i+16, &subs->active_mask)) { | ||
| 83 | if (!test_and_set_bit(i+16, &subs->unlink_mask)) { | ||
| 84 | struct urb *u = subs->syncurb[i].urb; | ||
| 85 | if (async) | ||
| 86 | usb_unlink_urb(u); | ||
| 87 | else | ||
| 88 | usb_kill_urb(u); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | return 0; | ||
| 65 | } | 94 | } |
| 66 | 95 | ||
| 67 | static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) | 96 | |
| 97 | /* | ||
| 98 | * release a urb data | ||
| 99 | */ | ||
| 100 | static void release_urb_ctx(struct snd_urb_ctx *u) | ||
| 68 | { | 101 | { |
| 69 | struct snd_usb_stream *stream = pcm->private_data; | 102 | if (u->urb) { |
| 70 | if (stream) { | 103 | if (u->buffer_size) |
| 71 | stream->pcm = NULL; | 104 | usb_free_coherent(u->subs->dev, u->buffer_size, |
| 72 | snd_usb_audio_stream_free(stream); | 105 | u->urb->transfer_buffer, |
| 106 | u->urb->transfer_dma); | ||
| 107 | usb_free_urb(u->urb); | ||
| 108 | u->urb = NULL; | ||
| 73 | } | 109 | } |
| 74 | } | 110 | } |
| 75 | 111 | ||
| 112 | /* | ||
| 113 | * wait until all urbs are processed. | ||
| 114 | */ | ||
| 115 | static int wait_clear_urbs(struct snd_usb_substream *subs) | ||
| 116 | { | ||
| 117 | unsigned long end_time = jiffies + msecs_to_jiffies(1000); | ||
| 118 | unsigned int i; | ||
| 119 | int alive; | ||
| 120 | |||
| 121 | do { | ||
| 122 | alive = 0; | ||
| 123 | for (i = 0; i < subs->nurbs; i++) { | ||
| 124 | if (test_bit(i, &subs->active_mask)) | ||
| 125 | alive++; | ||
| 126 | } | ||
| 127 | if (subs->syncpipe) { | ||
| 128 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 129 | if (test_bit(i + 16, &subs->active_mask)) | ||
| 130 | alive++; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | if (! alive) | ||
| 134 | break; | ||
| 135 | schedule_timeout_uninterruptible(1); | ||
| 136 | } while (time_before(jiffies, end_time)); | ||
| 137 | if (alive) | ||
| 138 | snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); | ||
| 139 | return 0; | ||
| 140 | } | ||
| 76 | 141 | ||
| 77 | /* | 142 | /* |
| 78 | * add this endpoint to the chip instance. | 143 | * release a substream |
| 79 | * if a stream with the same endpoint already exists, append to it. | ||
| 80 | * if not, create a new pcm stream. | ||
| 81 | */ | 144 | */ |
| 82 | int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, int stream, struct audioformat *fp) | 145 | void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force) |
| 83 | { | 146 | { |
| 84 | struct list_head *p; | 147 | int i; |
| 85 | struct snd_usb_stream *as; | 148 | |
| 86 | struct snd_usb_substream *subs; | 149 | /* stop urbs (to be sure) */ |
| 87 | struct snd_pcm *pcm; | 150 | deactivate_urbs(subs, force, 1); |
| 88 | int err; | 151 | wait_clear_urbs(subs); |
| 152 | |||
| 153 | for (i = 0; i < MAX_URBS; i++) | ||
| 154 | release_urb_ctx(&subs->dataurb[i]); | ||
| 155 | for (i = 0; i < SYNC_URBS; i++) | ||
| 156 | release_urb_ctx(&subs->syncurb[i]); | ||
| 157 | usb_free_coherent(subs->dev, SYNC_URBS * 4, | ||
| 158 | subs->syncbuf, subs->sync_dma); | ||
| 159 | subs->syncbuf = NULL; | ||
| 160 | subs->nurbs = 0; | ||
| 161 | } | ||
| 89 | 162 | ||
| 90 | list_for_each(p, &chip->pcm_list) { | 163 | /* |
| 91 | as = list_entry(p, struct snd_usb_stream, list); | 164 | * complete callback from data urb |
| 92 | if (as->fmt_type != fp->fmt_type) | 165 | */ |
| 93 | continue; | 166 | static void snd_complete_urb(struct urb *urb) |
| 94 | subs = &as->substream[stream]; | 167 | { |
| 95 | if (!subs->endpoint) | 168 | struct snd_urb_ctx *ctx = urb->context; |
| 96 | continue; | 169 | struct snd_usb_substream *subs = ctx->subs; |
| 97 | if (subs->endpoint == fp->endpoint) { | 170 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; |
| 98 | list_add_tail(&fp->list, &subs->fmt_list); | 171 | int err = 0; |
| 99 | subs->num_formats++; | 172 | |
| 100 | subs->formats |= fp->formats; | 173 | if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) || |
| 101 | return 0; | 174 | !subs->running || /* can be stopped during retire callback */ |
| 175 | (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 || | ||
| 176 | (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | ||
| 177 | clear_bit(ctx->index, &subs->active_mask); | ||
| 178 | if (err < 0) { | ||
| 179 | snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err); | ||
| 180 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
| 102 | } | 181 | } |
| 103 | } | 182 | } |
| 104 | /* look for an empty stream */ | 183 | } |
| 105 | list_for_each(p, &chip->pcm_list) { | 184 | |
| 106 | as = list_entry(p, struct snd_usb_stream, list); | 185 | |
| 107 | if (as->fmt_type != fp->fmt_type) | 186 | /* |
| 108 | continue; | 187 | * complete callback from sync urb |
| 109 | subs = &as->substream[stream]; | 188 | */ |
| 110 | if (subs->endpoint) | 189 | static void snd_complete_sync_urb(struct urb *urb) |
| 111 | continue; | 190 | { |
| 112 | err = snd_pcm_new_stream(as->pcm, stream, 1); | 191 | struct snd_urb_ctx *ctx = urb->context; |
| 113 | if (err < 0) | 192 | struct snd_usb_substream *subs = ctx->subs; |
| 114 | return err; | 193 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; |
| 115 | snd_usb_init_substream(as, stream, fp); | 194 | int err = 0; |
| 116 | return 0; | 195 | |
| 196 | if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) || | ||
| 197 | !subs->running || /* can be stopped during retire callback */ | ||
| 198 | (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 || | ||
| 199 | (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | ||
| 200 | clear_bit(ctx->index + 16, &subs->active_mask); | ||
| 201 | if (err < 0) { | ||
| 202 | snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err); | ||
| 203 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
| 204 | } | ||
| 117 | } | 205 | } |
| 206 | } | ||
| 207 | |||
| 118 | 208 | ||
| 119 | /* create a new pcm */ | 209 | /* |
| 120 | as = kzalloc(sizeof(*as), GFP_KERNEL); | 210 | * initialize a substream for plaback/capture |
| 121 | if (!as) | 211 | */ |
| 122 | return -ENOMEM; | 212 | int snd_usb_init_substream_urbs(struct snd_usb_substream *subs, |
| 123 | as->pcm_index = chip->pcm_devs; | 213 | unsigned int period_bytes, |
| 124 | as->chip = chip; | 214 | unsigned int rate, |
| 125 | as->fmt_type = fp->fmt_type; | 215 | unsigned int frame_bits) |
| 126 | err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs, | 216 | { |
| 127 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0, | 217 | unsigned int maxsize, i; |
| 128 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1, | 218 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; |
| 129 | &pcm); | 219 | unsigned int urb_packs, total_packs, packs_per_ms; |
| 130 | if (err < 0) { | 220 | struct snd_usb_audio *chip = subs->stream->chip; |
| 131 | kfree(as); | 221 | |
| 132 | return err; | 222 | /* calculate the frequency in 16.16 format */ |
| 223 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | ||
| 224 | subs->freqn = get_usb_full_speed_rate(rate); | ||
| 225 | else | ||
| 226 | subs->freqn = get_usb_high_speed_rate(rate); | ||
| 227 | subs->freqm = subs->freqn; | ||
| 228 | subs->freqshift = INT_MIN; | ||
| 229 | /* calculate max. frequency */ | ||
| 230 | if (subs->maxpacksize) { | ||
| 231 | /* whatever fits into a max. size packet */ | ||
| 232 | maxsize = subs->maxpacksize; | ||
| 233 | subs->freqmax = (maxsize / (frame_bits >> 3)) | ||
| 234 | << (16 - subs->datainterval); | ||
| 235 | } else { | ||
| 236 | /* no max. packet size: just take 25% higher than nominal */ | ||
| 237 | subs->freqmax = subs->freqn + (subs->freqn >> 2); | ||
| 238 | maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) | ||
| 239 | >> (16 - subs->datainterval); | ||
| 133 | } | 240 | } |
| 134 | as->pcm = pcm; | 241 | subs->phase = 0; |
| 135 | pcm->private_data = as; | 242 | |
| 136 | pcm->private_free = snd_usb_audio_pcm_free; | 243 | if (subs->fill_max) |
| 137 | pcm->info_flags = 0; | 244 | subs->curpacksize = subs->maxpacksize; |
| 138 | if (chip->pcm_devs > 0) | ||
| 139 | sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs); | ||
| 140 | else | 245 | else |
| 141 | strcpy(pcm->name, "USB Audio"); | 246 | subs->curpacksize = maxsize; |
| 142 | 247 | ||
| 143 | snd_usb_init_substream(as, stream, fp); | 248 | if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) |
| 249 | packs_per_ms = 8 >> subs->datainterval; | ||
| 250 | else | ||
| 251 | packs_per_ms = 1; | ||
| 252 | |||
| 253 | if (is_playback) { | ||
| 254 | urb_packs = max(chip->nrpacks, 1); | ||
| 255 | urb_packs = min(urb_packs, (unsigned int)MAX_PACKS); | ||
| 256 | } else | ||
| 257 | urb_packs = 1; | ||
| 258 | urb_packs *= packs_per_ms; | ||
| 259 | if (subs->syncpipe) | ||
| 260 | urb_packs = min(urb_packs, 1U << subs->syncinterval); | ||
| 261 | |||
| 262 | /* decide how many packets to be used */ | ||
| 263 | if (is_playback) { | ||
| 264 | unsigned int minsize, maxpacks; | ||
| 265 | /* determine how small a packet can be */ | ||
| 266 | minsize = (subs->freqn >> (16 - subs->datainterval)) | ||
| 267 | * (frame_bits >> 3); | ||
| 268 | /* with sync from device, assume it can be 12% lower */ | ||
| 269 | if (subs->syncpipe) | ||
| 270 | minsize -= minsize >> 3; | ||
| 271 | minsize = max(minsize, 1u); | ||
| 272 | total_packs = (period_bytes + minsize - 1) / minsize; | ||
| 273 | /* we need at least two URBs for queueing */ | ||
| 274 | if (total_packs < 2) { | ||
| 275 | total_packs = 2; | ||
| 276 | } else { | ||
| 277 | /* and we don't want too long a queue either */ | ||
| 278 | maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); | ||
| 279 | total_packs = min(total_packs, maxpacks); | ||
| 280 | } | ||
| 281 | } else { | ||
| 282 | while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) | ||
| 283 | urb_packs >>= 1; | ||
| 284 | total_packs = MAX_URBS * urb_packs; | ||
| 285 | } | ||
| 286 | subs->nurbs = (total_packs + urb_packs - 1) / urb_packs; | ||
| 287 | if (subs->nurbs > MAX_URBS) { | ||
| 288 | /* too much... */ | ||
| 289 | subs->nurbs = MAX_URBS; | ||
| 290 | total_packs = MAX_URBS * urb_packs; | ||
| 291 | } else if (subs->nurbs < 2) { | ||
| 292 | /* too little - we need at least two packets | ||
| 293 | * to ensure contiguous playback/capture | ||
| 294 | */ | ||
| 295 | subs->nurbs = 2; | ||
| 296 | } | ||
| 144 | 297 | ||
| 145 | list_add(&as->list, &chip->pcm_list); | 298 | /* allocate and initialize data urbs */ |
| 146 | chip->pcm_devs++; | 299 | for (i = 0; i < subs->nurbs; i++) { |
| 300 | struct snd_urb_ctx *u = &subs->dataurb[i]; | ||
| 301 | u->index = i; | ||
| 302 | u->subs = subs; | ||
| 303 | u->packets = (i + 1) * total_packs / subs->nurbs | ||
| 304 | - i * total_packs / subs->nurbs; | ||
| 305 | u->buffer_size = maxsize * u->packets; | ||
| 306 | if (subs->fmt_type == UAC_FORMAT_TYPE_II) | ||
| 307 | u->packets++; /* for transfer delimiter */ | ||
| 308 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | ||
| 309 | if (!u->urb) | ||
| 310 | goto out_of_memory; | ||
| 311 | u->urb->transfer_buffer = | ||
| 312 | usb_alloc_coherent(subs->dev, u->buffer_size, | ||
| 313 | GFP_KERNEL, &u->urb->transfer_dma); | ||
| 314 | if (!u->urb->transfer_buffer) | ||
| 315 | goto out_of_memory; | ||
| 316 | u->urb->pipe = subs->datapipe; | ||
| 317 | u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | ||
| 318 | u->urb->interval = 1 << subs->datainterval; | ||
| 319 | u->urb->context = u; | ||
| 320 | u->urb->complete = snd_complete_urb; | ||
| 321 | } | ||
| 322 | |||
| 323 | if (subs->syncpipe) { | ||
| 324 | /* allocate and initialize sync urbs */ | ||
| 325 | subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4, | ||
| 326 | GFP_KERNEL, &subs->sync_dma); | ||
| 327 | if (!subs->syncbuf) | ||
| 328 | goto out_of_memory; | ||
| 329 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 330 | struct snd_urb_ctx *u = &subs->syncurb[i]; | ||
| 331 | u->index = i; | ||
| 332 | u->subs = subs; | ||
| 333 | u->packets = 1; | ||
| 334 | u->urb = usb_alloc_urb(1, GFP_KERNEL); | ||
| 335 | if (!u->urb) | ||
| 336 | goto out_of_memory; | ||
| 337 | u->urb->transfer_buffer = subs->syncbuf + i * 4; | ||
| 338 | u->urb->transfer_dma = subs->sync_dma + i * 4; | ||
| 339 | u->urb->transfer_buffer_length = 4; | ||
| 340 | u->urb->pipe = subs->syncpipe; | ||
| 341 | u->urb->transfer_flags = URB_ISO_ASAP | | ||
| 342 | URB_NO_TRANSFER_DMA_MAP; | ||
| 343 | u->urb->number_of_packets = 1; | ||
| 344 | u->urb->interval = 1 << subs->syncinterval; | ||
| 345 | u->urb->context = u; | ||
| 346 | u->urb->complete = snd_complete_sync_urb; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | return 0; | ||
| 147 | 350 | ||
| 148 | snd_usb_proc_pcm_format_add(as); | 351 | out_of_memory: |
| 352 | snd_usb_release_substream_urbs(subs, 0); | ||
| 353 | return -ENOMEM; | ||
| 354 | } | ||
| 149 | 355 | ||
| 356 | /* | ||
| 357 | * prepare urb for full speed capture sync pipe | ||
| 358 | * | ||
| 359 | * fill the length and offset of each urb descriptor. | ||
| 360 | * the fixed 10.14 frequency is passed through the pipe. | ||
| 361 | */ | ||
| 362 | static int prepare_capture_sync_urb(struct snd_usb_substream *subs, | ||
| 363 | struct snd_pcm_runtime *runtime, | ||
| 364 | struct urb *urb) | ||
| 365 | { | ||
| 366 | unsigned char *cp = urb->transfer_buffer; | ||
| 367 | struct snd_urb_ctx *ctx = urb->context; | ||
| 368 | |||
| 369 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 370 | urb->iso_frame_desc[0].length = 3; | ||
| 371 | urb->iso_frame_desc[0].offset = 0; | ||
| 372 | cp[0] = subs->freqn >> 2; | ||
| 373 | cp[1] = subs->freqn >> 10; | ||
| 374 | cp[2] = subs->freqn >> 18; | ||
| 150 | return 0; | 375 | return 0; |
| 151 | } | 376 | } |
| 152 | 377 | ||
| 153 | static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | 378 | /* |
| 154 | struct usb_host_interface *alts, | 379 | * prepare urb for high speed capture sync pipe |
| 155 | int protocol, int iface_no) | 380 | * |
| 381 | * fill the length and offset of each urb descriptor. | ||
| 382 | * the fixed 12.13 frequency is passed as 16.16 through the pipe. | ||
| 383 | */ | ||
| 384 | static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs, | ||
| 385 | struct snd_pcm_runtime *runtime, | ||
| 386 | struct urb *urb) | ||
| 156 | { | 387 | { |
| 157 | /* parsed with a v1 header here. that's ok as we only look at the | 388 | unsigned char *cp = urb->transfer_buffer; |
| 158 | * header first which is the same for both versions */ | 389 | struct snd_urb_ctx *ctx = urb->context; |
| 159 | struct uac_iso_endpoint_descriptor *csep; | 390 | |
| 160 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | 391 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ |
| 161 | int attributes = 0; | 392 | urb->iso_frame_desc[0].length = 4; |
| 162 | 393 | urb->iso_frame_desc[0].offset = 0; | |
| 163 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | 394 | cp[0] = subs->freqn; |
| 164 | 395 | cp[1] = subs->freqn >> 8; | |
| 165 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | 396 | cp[2] = subs->freqn >> 16; |
| 166 | if (!csep && altsd->bNumEndpoints >= 2) | 397 | cp[3] = subs->freqn >> 24; |
| 167 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | 398 | return 0; |
| 168 | 399 | } | |
| 169 | if (!csep || csep->bLength < 7 || | ||
| 170 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { | ||
| 171 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
| 172 | " class specific endpoint descriptor\n", | ||
| 173 | chip->dev->devnum, iface_no, | ||
| 174 | altsd->bAlternateSetting); | ||
| 175 | return 0; | ||
| 176 | } | ||
| 177 | 400 | ||
| 178 | if (protocol == UAC_VERSION_1) { | 401 | /* |
| 179 | attributes = csep->bmAttributes; | 402 | * process after capture sync complete |
| 180 | } else { | 403 | * - nothing to do |
| 181 | struct uac2_iso_endpoint_descriptor *csep2 = | 404 | */ |
| 182 | (struct uac2_iso_endpoint_descriptor *) csep; | 405 | static int retire_capture_sync_urb(struct snd_usb_substream *subs, |
| 406 | struct snd_pcm_runtime *runtime, | ||
| 407 | struct urb *urb) | ||
| 408 | { | ||
| 409 | return 0; | ||
| 410 | } | ||
| 183 | 411 | ||
| 184 | attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; | 412 | /* |
| 413 | * prepare urb for capture data pipe | ||
| 414 | * | ||
| 415 | * fill the offset and length of each descriptor. | ||
| 416 | * | ||
| 417 | * we use a temporary buffer to write the captured data. | ||
| 418 | * since the length of written data is determined by host, we cannot | ||
| 419 | * write onto the pcm buffer directly... the data is thus copied | ||
| 420 | * later at complete callback to the global buffer. | ||
| 421 | */ | ||
| 422 | static int prepare_capture_urb(struct snd_usb_substream *subs, | ||
| 423 | struct snd_pcm_runtime *runtime, | ||
| 424 | struct urb *urb) | ||
| 425 | { | ||
| 426 | int i, offs; | ||
| 427 | struct snd_urb_ctx *ctx = urb->context; | ||
| 428 | |||
| 429 | offs = 0; | ||
| 430 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 431 | for (i = 0; i < ctx->packets; i++) { | ||
| 432 | urb->iso_frame_desc[i].offset = offs; | ||
| 433 | urb->iso_frame_desc[i].length = subs->curpacksize; | ||
| 434 | offs += subs->curpacksize; | ||
| 435 | } | ||
| 436 | urb->transfer_buffer_length = offs; | ||
| 437 | urb->number_of_packets = ctx->packets; | ||
| 438 | return 0; | ||
| 439 | } | ||
| 185 | 440 | ||
| 186 | /* emulate the endpoint attributes of a v1 device */ | 441 | /* |
| 187 | if (csep2->bmControls & UAC2_CONTROL_PITCH) | 442 | * process after capture complete |
| 188 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | 443 | * |
| 444 | * copy the data from each desctiptor to the pcm buffer, and | ||
| 445 | * update the current position. | ||
| 446 | */ | ||
| 447 | static int retire_capture_urb(struct snd_usb_substream *subs, | ||
| 448 | struct snd_pcm_runtime *runtime, | ||
| 449 | struct urb *urb) | ||
| 450 | { | ||
| 451 | unsigned long flags; | ||
| 452 | unsigned char *cp; | ||
| 453 | int i; | ||
| 454 | unsigned int stride, frames, bytes, oldptr; | ||
| 455 | int period_elapsed = 0; | ||
| 456 | |||
| 457 | stride = runtime->frame_bits >> 3; | ||
| 458 | |||
| 459 | for (i = 0; i < urb->number_of_packets; i++) { | ||
| 460 | cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
| 461 | if (urb->iso_frame_desc[i].status) { | ||
| 462 | snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); | ||
| 463 | // continue; | ||
| 464 | } | ||
| 465 | bytes = urb->iso_frame_desc[i].actual_length; | ||
| 466 | frames = bytes / stride; | ||
| 467 | if (!subs->txfr_quirk) | ||
| 468 | bytes = frames * stride; | ||
| 469 | if (bytes % (runtime->sample_bits >> 3) != 0) { | ||
| 470 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
| 471 | int oldbytes = bytes; | ||
| 472 | #endif | ||
| 473 | bytes = frames * stride; | ||
| 474 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", | ||
| 475 | oldbytes, bytes); | ||
| 476 | } | ||
| 477 | /* update the current pointer */ | ||
| 478 | spin_lock_irqsave(&subs->lock, flags); | ||
| 479 | oldptr = subs->hwptr_done; | ||
| 480 | subs->hwptr_done += bytes; | ||
| 481 | if (subs->hwptr_done >= runtime->buffer_size * stride) | ||
| 482 | subs->hwptr_done -= runtime->buffer_size * stride; | ||
| 483 | frames = (bytes + (oldptr % stride)) / stride; | ||
| 484 | subs->transfer_done += frames; | ||
| 485 | if (subs->transfer_done >= runtime->period_size) { | ||
| 486 | subs->transfer_done -= runtime->period_size; | ||
| 487 | period_elapsed = 1; | ||
| 488 | } | ||
| 489 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 490 | /* copy a data chunk */ | ||
| 491 | if (oldptr + bytes > runtime->buffer_size * stride) { | ||
| 492 | unsigned int bytes1 = | ||
| 493 | runtime->buffer_size * stride - oldptr; | ||
| 494 | memcpy(runtime->dma_area + oldptr, cp, bytes1); | ||
| 495 | memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1); | ||
| 496 | } else { | ||
| 497 | memcpy(runtime->dma_area + oldptr, cp, bytes); | ||
| 498 | } | ||
| 189 | } | 499 | } |
| 500 | if (period_elapsed) | ||
| 501 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 502 | return 0; | ||
| 503 | } | ||
| 190 | 504 | ||
| 191 | return attributes; | 505 | /* |
| 506 | * Process after capture complete when paused. Nothing to do. | ||
| 507 | */ | ||
| 508 | static int retire_paused_capture_urb(struct snd_usb_substream *subs, | ||
| 509 | struct snd_pcm_runtime *runtime, | ||
| 510 | struct urb *urb) | ||
| 511 | { | ||
| 512 | return 0; | ||
| 192 | } | 513 | } |
| 193 | 514 | ||
| 194 | static struct uac2_input_terminal_descriptor * | 515 | |
| 195 | snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, | 516 | /* |
| 196 | int terminal_id) | 517 | * prepare urb for playback sync pipe |
| 518 | * | ||
| 519 | * set up the offset and length to receive the current frequency. | ||
| 520 | */ | ||
| 521 | static int prepare_playback_sync_urb(struct snd_usb_substream *subs, | ||
| 522 | struct snd_pcm_runtime *runtime, | ||
| 523 | struct urb *urb) | ||
| 197 | { | 524 | { |
| 198 | struct uac2_input_terminal_descriptor *term = NULL; | 525 | struct snd_urb_ctx *ctx = urb->context; |
| 526 | |||
| 527 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 528 | urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize); | ||
| 529 | urb->iso_frame_desc[0].offset = 0; | ||
| 530 | return 0; | ||
| 531 | } | ||
| 199 | 532 | ||
| 200 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | 533 | /* |
| 201 | ctrl_iface->extralen, | 534 | * process after playback sync complete |
| 202 | term, UAC_INPUT_TERMINAL))) { | 535 | * |
| 203 | if (term->bTerminalID == terminal_id) | 536 | * Full speed devices report feedback values in 10.14 format as samples per |
| 204 | return term; | 537 | * frame, high speed devices in 16.16 format as samples per microframe. |
| 538 | * Because the Audio Class 1 spec was written before USB 2.0, many high speed | ||
| 539 | * devices use a wrong interpretation, some others use an entirely different | ||
| 540 | * format. Therefore, we cannot predict what format any particular device uses | ||
| 541 | * and must detect it automatically. | ||
| 542 | */ | ||
| 543 | static int retire_playback_sync_urb(struct snd_usb_substream *subs, | ||
| 544 | struct snd_pcm_runtime *runtime, | ||
| 545 | struct urb *urb) | ||
| 546 | { | ||
| 547 | unsigned int f; | ||
| 548 | int shift; | ||
| 549 | unsigned long flags; | ||
| 550 | |||
| 551 | if (urb->iso_frame_desc[0].status != 0 || | ||
| 552 | urb->iso_frame_desc[0].actual_length < 3) | ||
| 553 | return 0; | ||
| 554 | |||
| 555 | f = le32_to_cpup(urb->transfer_buffer); | ||
| 556 | if (urb->iso_frame_desc[0].actual_length == 3) | ||
| 557 | f &= 0x00ffffff; | ||
| 558 | else | ||
| 559 | f &= 0x0fffffff; | ||
| 560 | if (f == 0) | ||
| 561 | return 0; | ||
| 562 | |||
| 563 | if (unlikely(subs->freqshift == INT_MIN)) { | ||
| 564 | /* | ||
| 565 | * The first time we see a feedback value, determine its format | ||
| 566 | * by shifting it left or right until it matches the nominal | ||
| 567 | * frequency value. This assumes that the feedback does not | ||
| 568 | * differ from the nominal value more than +50% or -25%. | ||
| 569 | */ | ||
| 570 | shift = 0; | ||
| 571 | while (f < subs->freqn - subs->freqn / 4) { | ||
| 572 | f <<= 1; | ||
| 573 | shift++; | ||
| 574 | } | ||
| 575 | while (f > subs->freqn + subs->freqn / 2) { | ||
| 576 | f >>= 1; | ||
| 577 | shift--; | ||
| 578 | } | ||
| 579 | subs->freqshift = shift; | ||
| 580 | } | ||
| 581 | else if (subs->freqshift >= 0) | ||
| 582 | f <<= subs->freqshift; | ||
| 583 | else | ||
| 584 | f >>= -subs->freqshift; | ||
| 585 | |||
| 586 | if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) { | ||
| 587 | /* | ||
| 588 | * If the frequency looks valid, set it. | ||
| 589 | * This value is referred to in prepare_playback_urb(). | ||
| 590 | */ | ||
| 591 | spin_lock_irqsave(&subs->lock, flags); | ||
| 592 | subs->freqm = f; | ||
| 593 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 594 | } else { | ||
| 595 | /* | ||
| 596 | * Out of range; maybe the shift value is wrong. | ||
| 597 | * Reset it so that we autodetect again the next time. | ||
| 598 | */ | ||
| 599 | subs->freqshift = INT_MIN; | ||
| 205 | } | 600 | } |
| 206 | 601 | ||
| 207 | return NULL; | 602 | return 0; |
| 208 | } | 603 | } |
| 209 | 604 | ||
| 210 | static struct uac2_output_terminal_descriptor * | 605 | /* determine the number of frames in the next packet */ |
| 211 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | 606 | static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) |
| 212 | int terminal_id) | ||
| 213 | { | 607 | { |
| 214 | struct uac2_output_terminal_descriptor *term = NULL; | 608 | if (subs->fill_max) |
| 215 | 609 | return subs->maxframesize; | |
| 216 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | 610 | else { |
| 217 | ctrl_iface->extralen, | 611 | subs->phase = (subs->phase & 0xffff) |
| 218 | term, UAC_OUTPUT_TERMINAL))) { | 612 | + (subs->freqm << subs->datainterval); |
| 219 | if (term->bTerminalID == terminal_id) | 613 | return min(subs->phase >> 16, subs->maxframesize); |
| 220 | return term; | ||
| 221 | } | 614 | } |
| 615 | } | ||
| 222 | 616 | ||
| 223 | return NULL; | 617 | /* |
| 618 | * Prepare urb for streaming before playback starts or when paused. | ||
| 619 | * | ||
| 620 | * We don't have any data, so we send silence. | ||
| 621 | */ | ||
| 622 | static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, | ||
| 623 | struct snd_pcm_runtime *runtime, | ||
| 624 | struct urb *urb) | ||
| 625 | { | ||
| 626 | unsigned int i, offs, counts; | ||
| 627 | struct snd_urb_ctx *ctx = urb->context; | ||
| 628 | int stride = runtime->frame_bits >> 3; | ||
| 629 | |||
| 630 | offs = 0; | ||
| 631 | urb->dev = ctx->subs->dev; | ||
| 632 | for (i = 0; i < ctx->packets; ++i) { | ||
| 633 | counts = snd_usb_audio_next_packet_size(subs); | ||
| 634 | urb->iso_frame_desc[i].offset = offs * stride; | ||
| 635 | urb->iso_frame_desc[i].length = counts * stride; | ||
| 636 | offs += counts; | ||
| 637 | } | ||
| 638 | urb->number_of_packets = ctx->packets; | ||
| 639 | urb->transfer_buffer_length = offs * stride; | ||
| 640 | memset(urb->transfer_buffer, | ||
| 641 | runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, | ||
| 642 | offs * stride); | ||
| 643 | return 0; | ||
| 224 | } | 644 | } |
| 225 | 645 | ||
| 226 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) | 646 | /* |
| 647 | * prepare urb for playback data pipe | ||
| 648 | * | ||
| 649 | * Since a URB can handle only a single linear buffer, we must use double | ||
| 650 | * buffering when the data to be transferred overflows the buffer boundary. | ||
| 651 | * To avoid inconsistencies when updating hwptr_done, we use double buffering | ||
| 652 | * for all URBs. | ||
| 653 | */ | ||
| 654 | static int prepare_playback_urb(struct snd_usb_substream *subs, | ||
| 655 | struct snd_pcm_runtime *runtime, | ||
| 656 | struct urb *urb) | ||
| 227 | { | 657 | { |
| 228 | struct usb_device *dev; | 658 | int i, stride; |
| 229 | struct usb_interface *iface; | 659 | unsigned int counts, frames, bytes; |
| 230 | struct usb_host_interface *alts; | 660 | unsigned long flags; |
| 231 | struct usb_interface_descriptor *altsd; | 661 | int period_elapsed = 0; |
| 232 | int i, altno, err, stream; | 662 | struct snd_urb_ctx *ctx = urb->context; |
| 233 | int format = 0, num_channels = 0; | 663 | |
| 234 | struct audioformat *fp = NULL; | 664 | stride = runtime->frame_bits >> 3; |
| 235 | int num, protocol, clock = 0; | 665 | |
| 236 | struct uac_format_type_i_continuous_descriptor *fmt; | 666 | frames = 0; |
| 667 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 668 | urb->number_of_packets = 0; | ||
| 669 | spin_lock_irqsave(&subs->lock, flags); | ||
| 670 | for (i = 0; i < ctx->packets; i++) { | ||
| 671 | counts = snd_usb_audio_next_packet_size(subs); | ||
| 672 | /* set up descriptor */ | ||
| 673 | urb->iso_frame_desc[i].offset = frames * stride; | ||
| 674 | urb->iso_frame_desc[i].length = counts * stride; | ||
| 675 | frames += counts; | ||
| 676 | urb->number_of_packets++; | ||
| 677 | subs->transfer_done += counts; | ||
| 678 | if (subs->transfer_done >= runtime->period_size) { | ||
| 679 | subs->transfer_done -= runtime->period_size; | ||
| 680 | period_elapsed = 1; | ||
| 681 | if (subs->fmt_type == UAC_FORMAT_TYPE_II) { | ||
| 682 | if (subs->transfer_done > 0) { | ||
| 683 | /* FIXME: fill-max mode is not | ||
| 684 | * supported yet */ | ||
| 685 | frames -= subs->transfer_done; | ||
| 686 | counts -= subs->transfer_done; | ||
| 687 | urb->iso_frame_desc[i].length = | ||
| 688 | counts * stride; | ||
| 689 | subs->transfer_done = 0; | ||
| 690 | } | ||
| 691 | i++; | ||
| 692 | if (i < ctx->packets) { | ||
| 693 | /* add a transfer delimiter */ | ||
| 694 | urb->iso_frame_desc[i].offset = | ||
| 695 | frames * stride; | ||
| 696 | urb->iso_frame_desc[i].length = 0; | ||
| 697 | urb->number_of_packets++; | ||
| 698 | } | ||
| 699 | break; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | if (period_elapsed) /* finish at the period boundary */ | ||
| 703 | break; | ||
| 704 | } | ||
| 705 | bytes = frames * stride; | ||
| 706 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { | ||
| 707 | /* err, the transferred area goes over buffer boundary. */ | ||
| 708 | unsigned int bytes1 = | ||
| 709 | runtime->buffer_size * stride - subs->hwptr_done; | ||
| 710 | memcpy(urb->transfer_buffer, | ||
| 711 | runtime->dma_area + subs->hwptr_done, bytes1); | ||
| 712 | memcpy(urb->transfer_buffer + bytes1, | ||
| 713 | runtime->dma_area, bytes - bytes1); | ||
| 714 | } else { | ||
| 715 | memcpy(urb->transfer_buffer, | ||
| 716 | runtime->dma_area + subs->hwptr_done, bytes); | ||
| 717 | } | ||
| 718 | subs->hwptr_done += bytes; | ||
| 719 | if (subs->hwptr_done >= runtime->buffer_size * stride) | ||
| 720 | subs->hwptr_done -= runtime->buffer_size * stride; | ||
| 721 | |||
| 722 | /* update delay with exact number of samples queued */ | ||
| 723 | runtime->delay = subs->last_delay; | ||
| 724 | runtime->delay += frames; | ||
| 725 | subs->last_delay = runtime->delay; | ||
| 726 | |||
| 727 | /* realign last_frame_number */ | ||
| 728 | subs->last_frame_number = usb_get_current_frame_number(subs->dev); | ||
| 729 | subs->last_frame_number &= 0xFF; /* keep 8 LSBs */ | ||
| 730 | |||
| 731 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 732 | urb->transfer_buffer_length = bytes; | ||
| 733 | if (period_elapsed) | ||
| 734 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 735 | return 0; | ||
| 736 | } | ||
| 237 | 737 | ||
| 238 | dev = chip->dev; | 738 | /* |
| 739 | * process after playback data complete | ||
| 740 | * - decrease the delay count again | ||
| 741 | */ | ||
| 742 | static int retire_playback_urb(struct snd_usb_substream *subs, | ||
| 743 | struct snd_pcm_runtime *runtime, | ||
| 744 | struct urb *urb) | ||
| 745 | { | ||
| 746 | unsigned long flags; | ||
| 747 | int stride = runtime->frame_bits >> 3; | ||
| 748 | int processed = urb->transfer_buffer_length / stride; | ||
| 749 | int est_delay; | ||
| 239 | 750 | ||
| 240 | /* parse the interface's altsettings */ | 751 | spin_lock_irqsave(&subs->lock, flags); |
| 241 | iface = usb_ifnum_to_if(dev, iface_no); | ||
| 242 | 752 | ||
| 243 | num = iface->num_altsetting; | 753 | est_delay = snd_usb_pcm_delay(subs, runtime->rate); |
| 754 | /* update delay with exact number of samples played */ | ||
| 755 | if (processed > subs->last_delay) | ||
| 756 | subs->last_delay = 0; | ||
| 757 | else | ||
| 758 | subs->last_delay -= processed; | ||
| 759 | runtime->delay = subs->last_delay; | ||
| 244 | 760 | ||
| 245 | /* | 761 | /* |
| 246 | * Dallas DS4201 workaround: It presents 5 altsettings, but the last | 762 | * Report when delay estimate is off by more than 2ms. |
| 247 | * one misses syncpipe, and does not produce any sound. | 763 | * The error should be lower than 2ms since the estimate relies |
| 764 | * on two reads of a counter updated every ms. | ||
| 248 | */ | 765 | */ |
| 249 | if (chip->usb_id == USB_ID(0x04fa, 0x4201)) | 766 | if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) |
| 250 | num = 4; | 767 | snd_printk(KERN_DEBUG "delay: estimated %d, actual %d\n", |
| 251 | 768 | est_delay, subs->last_delay); | |
| 252 | for (i = 0; i < num; i++) { | ||
| 253 | alts = &iface->altsetting[i]; | ||
| 254 | altsd = get_iface_desc(alts); | ||
| 255 | protocol = altsd->bInterfaceProtocol; | ||
| 256 | /* skip invalid one */ | ||
| 257 | if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && | ||
| 258 | altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || | ||
| 259 | (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING && | ||
| 260 | altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) || | ||
| 261 | altsd->bNumEndpoints < 1 || | ||
| 262 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) | ||
| 263 | continue; | ||
| 264 | /* must be isochronous */ | ||
| 265 | if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
| 266 | USB_ENDPOINT_XFER_ISOC) | ||
| 267 | continue; | ||
| 268 | /* check direction */ | ||
| 269 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | ||
| 270 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | ||
| 271 | altno = altsd->bAlternateSetting; | ||
| 272 | |||
| 273 | if (snd_usb_apply_interface_quirk(chip, iface_no, altno)) | ||
| 274 | continue; | ||
| 275 | |||
| 276 | /* get audio formats */ | ||
| 277 | switch (protocol) { | ||
| 278 | default: | ||
| 279 | snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n", | ||
| 280 | dev->devnum, iface_no, altno, protocol); | ||
| 281 | protocol = UAC_VERSION_1; | ||
| 282 | /* fall through */ | ||
| 283 | |||
| 284 | case UAC_VERSION_1: { | ||
| 285 | struct uac1_as_header_descriptor *as = | ||
| 286 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
| 287 | |||
| 288 | if (!as) { | ||
| 289 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
| 290 | dev->devnum, iface_no, altno); | ||
| 291 | continue; | ||
| 292 | } | ||
| 293 | 769 | ||
| 294 | if (as->bLength < sizeof(*as)) { | 770 | spin_unlock_irqrestore(&subs->lock, flags); |
| 295 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | 771 | return 0; |
| 296 | dev->devnum, iface_no, altno); | 772 | } |
| 297 | continue; | ||
| 298 | } | ||
| 299 | 773 | ||
| 300 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | 774 | static const char *usb_error_string(int err) |
| 301 | break; | 775 | { |
| 302 | } | 776 | switch (err) { |
| 777 | case -ENODEV: | ||
| 778 | return "no device"; | ||
| 779 | case -ENOENT: | ||
| 780 | return "endpoint not enabled"; | ||
| 781 | case -EPIPE: | ||
| 782 | return "endpoint stalled"; | ||
| 783 | case -ENOSPC: | ||
| 784 | return "not enough bandwidth"; | ||
| 785 | case -ESHUTDOWN: | ||
| 786 | return "device disabled"; | ||
| 787 | case -EHOSTUNREACH: | ||
| 788 | return "device suspended"; | ||
| 789 | case -EINVAL: | ||
| 790 | case -EAGAIN: | ||
| 791 | case -EFBIG: | ||
| 792 | case -EMSGSIZE: | ||
| 793 | return "internal error"; | ||
| 794 | default: | ||
| 795 | return "unknown error"; | ||
| 796 | } | ||
| 797 | } | ||
| 303 | 798 | ||
| 304 | case UAC_VERSION_2: { | 799 | /* |
| 305 | struct uac2_input_terminal_descriptor *input_term; | 800 | * set up and start data/sync urbs |
| 306 | struct uac2_output_terminal_descriptor *output_term; | 801 | */ |
| 307 | struct uac2_as_header_descriptor *as = | 802 | static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime) |
| 308 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | 803 | { |
| 804 | unsigned int i; | ||
| 805 | int err; | ||
| 309 | 806 | ||
| 310 | if (!as) { | 807 | if (subs->stream->chip->shutdown) |
| 311 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | 808 | return -EBADFD; |
| 312 | dev->devnum, iface_no, altno); | 809 | |
| 313 | continue; | 810 | for (i = 0; i < subs->nurbs; i++) { |
| 811 | if (snd_BUG_ON(!subs->dataurb[i].urb)) | ||
| 812 | return -EINVAL; | ||
| 813 | if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) { | ||
| 814 | snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i); | ||
| 815 | goto __error; | ||
| 816 | } | ||
| 817 | } | ||
| 818 | if (subs->syncpipe) { | ||
| 819 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 820 | if (snd_BUG_ON(!subs->syncurb[i].urb)) | ||
| 821 | return -EINVAL; | ||
| 822 | if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) { | ||
| 823 | snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i); | ||
| 824 | goto __error; | ||
| 314 | } | 825 | } |
| 826 | } | ||
| 827 | } | ||
| 315 | 828 | ||
| 316 | if (as->bLength < sizeof(*as)) { | 829 | subs->active_mask = 0; |
| 317 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | 830 | subs->unlink_mask = 0; |
| 318 | dev->devnum, iface_no, altno); | 831 | subs->running = 1; |
| 319 | continue; | 832 | for (i = 0; i < subs->nurbs; i++) { |
| 833 | err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC); | ||
| 834 | if (err < 0) { | ||
| 835 | snd_printk(KERN_ERR "cannot submit datapipe " | ||
| 836 | "for urb %d, error %d: %s\n", | ||
| 837 | i, err, usb_error_string(err)); | ||
| 838 | goto __error; | ||
| 839 | } | ||
| 840 | set_bit(i, &subs->active_mask); | ||
| 841 | } | ||
| 842 | if (subs->syncpipe) { | ||
| 843 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 844 | err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC); | ||
| 845 | if (err < 0) { | ||
| 846 | snd_printk(KERN_ERR "cannot submit syncpipe " | ||
| 847 | "for urb %d, error %d: %s\n", | ||
| 848 | i, err, usb_error_string(err)); | ||
| 849 | goto __error; | ||
| 320 | } | 850 | } |
| 851 | set_bit(i + 16, &subs->active_mask); | ||
| 852 | } | ||
| 853 | } | ||
| 854 | return 0; | ||
| 321 | 855 | ||
| 322 | num_channels = as->bNrChannels; | 856 | __error: |
| 323 | format = le32_to_cpu(as->bmFormats); | 857 | // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); |
| 858 | deactivate_urbs(subs, 0, 0); | ||
| 859 | return -EPIPE; | ||
| 860 | } | ||
| 324 | 861 | ||
| 325 | /* lookup the terminal associated to this interface | ||
| 326 | * to extract the clock */ | ||
| 327 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
| 328 | as->bTerminalLink); | ||
| 329 | if (input_term) { | ||
| 330 | clock = input_term->bCSourceID; | ||
| 331 | break; | ||
| 332 | } | ||
| 333 | 862 | ||
| 334 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | 863 | /* |
| 335 | as->bTerminalLink); | 864 | */ |
| 336 | if (output_term) { | 865 | static struct snd_urb_ops audio_urb_ops[2] = { |
| 337 | clock = output_term->bCSourceID; | 866 | { |
| 338 | break; | 867 | .prepare = prepare_nodata_playback_urb, |
| 339 | } | 868 | .retire = retire_playback_urb, |
| 869 | .prepare_sync = prepare_playback_sync_urb, | ||
| 870 | .retire_sync = retire_playback_sync_urb, | ||
| 871 | }, | ||
| 872 | { | ||
| 873 | .prepare = prepare_capture_urb, | ||
| 874 | .retire = retire_capture_urb, | ||
| 875 | .prepare_sync = prepare_capture_sync_urb, | ||
| 876 | .retire_sync = retire_capture_sync_urb, | ||
| 877 | }, | ||
| 878 | }; | ||
| 340 | 879 | ||
| 341 | snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", | 880 | /* |
| 342 | dev->devnum, iface_no, altno, as->bTerminalLink); | 881 | * initialize the substream instance. |
| 343 | continue; | 882 | */ |
| 344 | } | ||
| 345 | } | ||
| 346 | 883 | ||
| 347 | /* get format type */ | 884 | void snd_usb_init_substream(struct snd_usb_stream *as, |
| 348 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); | 885 | int stream, struct audioformat *fp) |
| 349 | if (!fmt) { | 886 | { |
| 350 | snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n", | 887 | struct snd_usb_substream *subs = &as->substream[stream]; |
| 351 | dev->devnum, iface_no, altno); | 888 | |
| 352 | continue; | 889 | INIT_LIST_HEAD(&subs->fmt_list); |
| 353 | } | 890 | spin_lock_init(&subs->lock); |
| 354 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | 891 | |
| 355 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { | 892 | subs->stream = as; |
| 356 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | 893 | subs->direction = stream; |
| 357 | dev->devnum, iface_no, altno); | 894 | subs->dev = as->chip->dev; |
| 358 | continue; | 895 | subs->txfr_quirk = as->chip->txfr_quirk; |
| 359 | } | 896 | subs->ops = audio_urb_ops[stream]; |
| 897 | if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH) | ||
| 898 | subs->ops.prepare_sync = prepare_capture_sync_urb_hs; | ||
| 899 | |||
| 900 | snd_usb_set_pcm_ops(as->pcm, stream); | ||
| 901 | |||
| 902 | list_add_tail(&fp->list, &subs->fmt_list); | ||
| 903 | subs->formats |= fp->formats; | ||
| 904 | subs->endpoint = fp->endpoint; | ||
| 905 | subs->num_formats++; | ||
| 906 | subs->fmt_type = fp->fmt_type; | ||
| 907 | } | ||
| 360 | 908 | ||
| 361 | /* | 909 | int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd) |
| 362 | * Blue Microphones workaround: The last altsetting is identical | 910 | { |
| 363 | * with the previous one, except for a larger packet size, but | 911 | struct snd_usb_substream *subs = substream->runtime->private_data; |
| 364 | * is actually a mislabeled two-channel setting; ignore it. | ||
| 365 | */ | ||
| 366 | if (fmt->bNrChannels == 1 && | ||
| 367 | fmt->bSubframeSize == 2 && | ||
| 368 | altno == 2 && num == 3 && | ||
| 369 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
| 370 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | ||
| 371 | protocol == UAC_VERSION_1 && | ||
| 372 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
| 373 | fp->maxpacksize * 2) | ||
| 374 | continue; | ||
| 375 | |||
| 376 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | ||
| 377 | if (! fp) { | ||
| 378 | snd_printk(KERN_ERR "cannot malloc\n"); | ||
| 379 | return -ENOMEM; | ||
| 380 | } | ||
| 381 | 912 | ||
| 382 | fp->iface = iface_no; | 913 | switch (cmd) { |
| 383 | fp->altsetting = altno; | 914 | case SNDRV_PCM_TRIGGER_START: |
| 384 | fp->altset_idx = i; | 915 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
| 385 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | 916 | subs->ops.prepare = prepare_playback_urb; |
| 386 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | 917 | return 0; |
| 387 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | 918 | case SNDRV_PCM_TRIGGER_STOP: |
| 388 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | 919 | return deactivate_urbs(subs, 0, 0); |
| 389 | /* num_channels is only set for v2 interfaces */ | 920 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 390 | fp->channels = num_channels; | 921 | subs->ops.prepare = prepare_nodata_playback_urb; |
| 391 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | 922 | return 0; |
| 392 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | 923 | } |
| 393 | * (fp->maxpacksize & 0x7ff); | ||
| 394 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); | ||
| 395 | fp->clock = clock; | ||
| 396 | |||
| 397 | /* some quirks for attributes here */ | ||
| 398 | |||
| 399 | switch (chip->usb_id) { | ||
| 400 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
| 401 | /* Optoplay sets the sample rate attribute although | ||
| 402 | * it seems not supporting it in fact. | ||
| 403 | */ | ||
| 404 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
| 405 | break; | ||
| 406 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
| 407 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
| 408 | /* doesn't set the sample rate attribute, but supports it */ | ||
| 409 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
| 410 | break; | ||
| 411 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
| 412 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
| 413 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
| 414 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
| 415 | an older model 77d:223) */ | ||
| 416 | /* | ||
| 417 | * plantronics headset and Griffin iMic have set adaptive-in | ||
| 418 | * although it's really not... | ||
| 419 | */ | ||
| 420 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | ||
| 421 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 422 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; | ||
| 423 | else | ||
| 424 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; | ||
| 425 | break; | ||
| 426 | } | ||
| 427 | 924 | ||
| 428 | /* ok, let's parse further... */ | 925 | return -EINVAL; |
| 429 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { | 926 | } |
| 430 | kfree(fp->rate_table); | ||
| 431 | kfree(fp); | ||
| 432 | fp = NULL; | ||
| 433 | continue; | ||
| 434 | } | ||
| 435 | 927 | ||
| 436 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); | 928 | int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd) |
| 437 | err = snd_usb_add_audio_endpoint(chip, stream, fp); | 929 | { |
| 438 | if (err < 0) { | 930 | struct snd_usb_substream *subs = substream->runtime->private_data; |
| 439 | kfree(fp->rate_table); | 931 | |
| 440 | kfree(fp); | 932 | switch (cmd) { |
| 441 | return err; | 933 | case SNDRV_PCM_TRIGGER_START: |
| 442 | } | 934 | subs->ops.retire = retire_capture_urb; |
| 443 | /* try to set the interface... */ | 935 | return start_urbs(subs, substream->runtime); |
| 444 | usb_set_interface(chip->dev, iface_no, altno); | 936 | case SNDRV_PCM_TRIGGER_STOP: |
| 445 | snd_usb_init_pitch(chip, iface_no, alts, fp); | 937 | return deactivate_urbs(subs, 0, 0); |
| 446 | snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max); | 938 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
| 939 | subs->ops.retire = retire_paused_capture_urb; | ||
| 940 | return 0; | ||
| 941 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 942 | subs->ops.retire = retire_capture_urb; | ||
| 943 | return 0; | ||
| 447 | } | 944 | } |
| 945 | |||
| 946 | return -EINVAL; | ||
| 947 | } | ||
| 948 | |||
| 949 | int snd_usb_substream_prepare(struct snd_usb_substream *subs, | ||
| 950 | struct snd_pcm_runtime *runtime) | ||
| 951 | { | ||
| 952 | /* clear urbs (to be sure) */ | ||
| 953 | deactivate_urbs(subs, 0, 1); | ||
| 954 | wait_clear_urbs(subs); | ||
| 955 | |||
| 956 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | ||
| 957 | * updates for all URBs would happen at the same time when starting */ | ||
| 958 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 959 | subs->ops.prepare = prepare_nodata_playback_urb; | ||
| 960 | return start_urbs(subs, runtime); | ||
| 961 | } | ||
| 962 | |||
| 448 | return 0; | 963 | return 0; |
| 449 | } | 964 | } |
| 450 | 965 | ||
diff --git a/sound/usb/endpoint.h b/sound/usb/endpoint.h index 64dd0db023b2..88eb63a636eb 100644 --- a/sound/usb/endpoint.h +++ b/sound/usb/endpoint.h | |||
| @@ -1,11 +1,21 @@ | |||
| 1 | #ifndef __USBAUDIO_ENDPOINT_H | 1 | #ifndef __USBAUDIO_ENDPOINT_H |
| 2 | #define __USBAUDIO_ENDPOINT_H | 2 | #define __USBAUDIO_ENDPOINT_H |
| 3 | 3 | ||
| 4 | int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, | 4 | void snd_usb_init_substream(struct snd_usb_stream *as, |
| 5 | int iface_no); | 5 | int stream, |
| 6 | struct audioformat *fp); | ||
| 6 | 7 | ||
| 7 | int snd_usb_add_audio_endpoint(struct snd_usb_audio *chip, | 8 | int snd_usb_init_substream_urbs(struct snd_usb_substream *subs, |
| 8 | int stream, | 9 | unsigned int period_bytes, |
| 9 | struct audioformat *fp); | 10 | unsigned int rate, |
| 11 | unsigned int frame_bits); | ||
| 12 | |||
| 13 | void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force); | ||
| 14 | |||
| 15 | int snd_usb_substream_prepare(struct snd_usb_substream *subs, | ||
| 16 | struct snd_pcm_runtime *runtime); | ||
| 17 | |||
| 18 | int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd); | ||
| 19 | int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd); | ||
| 10 | 20 | ||
| 11 | #endif /* __USBAUDIO_ENDPOINT_H */ | 21 | #endif /* __USBAUDIO_ENDPOINT_H */ |
diff --git a/sound/usb/format.c b/sound/usb/format.c index 8d042dce0d16..89421d176570 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
| @@ -286,7 +286,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
| 286 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 286 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
| 287 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 287 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
| 288 | snd_usb_ctrl_intf(chip) | (clock << 8), | 288 | snd_usb_ctrl_intf(chip) | (clock << 8), |
| 289 | tmp, sizeof(tmp), 1000); | 289 | tmp, sizeof(tmp)); |
| 290 | 290 | ||
| 291 | if (ret < 0) { | 291 | if (ret < 0) { |
| 292 | snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", | 292 | snd_printk(KERN_ERR "%s(): unable to retrieve number of sample rates (clock %d)\n", |
| @@ -307,7 +307,7 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, | |||
| 307 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 307 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
| 308 | UAC2_CS_CONTROL_SAM_FREQ << 8, | 308 | UAC2_CS_CONTROL_SAM_FREQ << 8, |
| 309 | snd_usb_ctrl_intf(chip) | (clock << 8), | 309 | snd_usb_ctrl_intf(chip) | (clock << 8), |
| 310 | data, data_size, 1000); | 310 | data, data_size); |
| 311 | 311 | ||
| 312 | if (ret < 0) { | 312 | if (ret < 0) { |
| 313 | snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", | 313 | snd_printk(KERN_ERR "%s(): unable to retrieve sample rate range (clock %d)\n", |
diff --git a/sound/usb/helper.c b/sound/usb/helper.c index f280c1903c25..9eed8f40b179 100644 --- a/sound/usb/helper.c +++ b/sound/usb/helper.c | |||
| @@ -81,7 +81,7 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype | |||
| 81 | */ | 81 | */ |
| 82 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, | 82 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, |
| 83 | __u8 requesttype, __u16 value, __u16 index, void *data, | 83 | __u8 requesttype, __u16 value, __u16 index, void *data, |
| 84 | __u16 size, int timeout) | 84 | __u16 size) |
| 85 | { | 85 | { |
| 86 | int err; | 86 | int err; |
| 87 | void *buf = NULL; | 87 | void *buf = NULL; |
| @@ -92,7 +92,7 @@ int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, __u8 request, | |||
| 92 | return -ENOMEM; | 92 | return -ENOMEM; |
| 93 | } | 93 | } |
| 94 | err = usb_control_msg(dev, pipe, request, requesttype, | 94 | err = usb_control_msg(dev, pipe, request, requesttype, |
| 95 | value, index, buf, size, timeout); | 95 | value, index, buf, size, 1000); |
| 96 | if (size > 0) { | 96 | if (size > 0) { |
| 97 | memcpy(data, buf, size); | 97 | memcpy(data, buf, size); |
| 98 | kfree(buf); | 98 | kfree(buf); |
diff --git a/sound/usb/helper.h b/sound/usb/helper.h index 09bd943c43bf..805c300dd004 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h | |||
| @@ -8,7 +8,7 @@ void *snd_usb_find_csint_desc(void *descstart, int desclen, void *after, u8 dsub | |||
| 8 | 8 | ||
| 9 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, | 9 | int snd_usb_ctl_msg(struct usb_device *dev, unsigned int pipe, |
| 10 | __u8 request, __u8 requesttype, __u16 value, __u16 index, | 10 | __u8 request, __u8 requesttype, __u16 value, __u16 index, |
| 11 | void *data, __u16 size, int timeout); | 11 | void *data, __u16 size); |
| 12 | 12 | ||
| 13 | unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, | 13 | unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, |
| 14 | struct usb_host_interface *alts); | 14 | struct usb_host_interface *alts); |
diff --git a/sound/usb/midi.c b/sound/usb/midi.c index f9289102886a..e21f026d9577 100644 --- a/sound/usb/midi.c +++ b/sound/usb/midi.c | |||
| @@ -816,6 +816,22 @@ static struct usb_protocol_ops snd_usbmidi_raw_ops = { | |||
| 816 | .output = snd_usbmidi_raw_output, | 816 | .output = snd_usbmidi_raw_output, |
| 817 | }; | 817 | }; |
| 818 | 818 | ||
| 819 | /* | ||
| 820 | * FTDI protocol: raw MIDI bytes, but input packets have two modem status bytes. | ||
| 821 | */ | ||
| 822 | |||
| 823 | static void snd_usbmidi_ftdi_input(struct snd_usb_midi_in_endpoint* ep, | ||
| 824 | uint8_t* buffer, int buffer_length) | ||
| 825 | { | ||
| 826 | if (buffer_length > 2) | ||
| 827 | snd_usbmidi_input_data(ep, 0, buffer + 2, buffer_length - 2); | ||
| 828 | } | ||
| 829 | |||
| 830 | static struct usb_protocol_ops snd_usbmidi_ftdi_ops = { | ||
| 831 | .input = snd_usbmidi_ftdi_input, | ||
| 832 | .output = snd_usbmidi_raw_output, | ||
| 833 | }; | ||
| 834 | |||
| 819 | static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, | 835 | static void snd_usbmidi_us122l_input(struct snd_usb_midi_in_endpoint *ep, |
| 820 | uint8_t *buffer, int buffer_length) | 836 | uint8_t *buffer, int buffer_length) |
| 821 | { | 837 | { |
| @@ -2163,6 +2179,17 @@ int snd_usbmidi_create(struct snd_card *card, | |||
| 2163 | /* endpoint 1 is input-only */ | 2179 | /* endpoint 1 is input-only */ |
| 2164 | endpoints[1].out_cables = 0; | 2180 | endpoints[1].out_cables = 0; |
| 2165 | break; | 2181 | break; |
| 2182 | case QUIRK_MIDI_FTDI: | ||
| 2183 | umidi->usb_protocol_ops = &snd_usbmidi_ftdi_ops; | ||
| 2184 | |||
| 2185 | /* set baud rate to 31250 (48 MHz / 16 / 96) */ | ||
| 2186 | err = usb_control_msg(umidi->dev, usb_sndctrlpipe(umidi->dev, 0), | ||
| 2187 | 3, 0x40, 0x60, 0, NULL, 0, 1000); | ||
| 2188 | if (err < 0) | ||
| 2189 | break; | ||
| 2190 | |||
| 2191 | err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); | ||
| 2192 | break; | ||
| 2166 | default: | 2193 | default: |
| 2167 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); | 2194 | snd_printd(KERN_ERR "invalid quirk type %d\n", quirk->type); |
| 2168 | err = -ENXIO; | 2195 | err = -ENXIO; |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index cdd19d7fe500..60f65ace7474 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c | |||
| @@ -296,7 +296,7 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v | |||
| 296 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, | 296 | if (snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), request, |
| 297 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 297 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
| 298 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), | 298 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
| 299 | buf, val_len, 100) >= val_len) { | 299 | buf, val_len) >= val_len) { |
| 300 | *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); | 300 | *value_ret = convert_signed_value(cval, snd_usb_combine_bytes(buf, val_len)); |
| 301 | snd_usb_autosuspend(cval->mixer->chip); | 301 | snd_usb_autosuspend(cval->mixer->chip); |
| 302 | return 0; | 302 | return 0; |
| @@ -333,7 +333,7 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v | |||
| 333 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, | 333 | ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), bRequest, |
| 334 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, | 334 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, |
| 335 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), | 335 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
| 336 | buf, size, 1000); | 336 | buf, size); |
| 337 | snd_usb_autosuspend(chip); | 337 | snd_usb_autosuspend(chip); |
| 338 | 338 | ||
| 339 | if (ret < 0) { | 339 | if (ret < 0) { |
| @@ -445,7 +445,7 @@ int snd_usb_mixer_set_ctl_value(struct usb_mixer_elem_info *cval, | |||
| 445 | usb_sndctrlpipe(chip->dev, 0), request, | 445 | usb_sndctrlpipe(chip->dev, 0), request, |
| 446 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, | 446 | USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, |
| 447 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), | 447 | validx, snd_usb_ctrl_intf(chip) | (cval->id << 8), |
| 448 | buf, val_len, 100) >= 0) { | 448 | buf, val_len) >= 0) { |
| 449 | snd_usb_autosuspend(chip); | 449 | snd_usb_autosuspend(chip); |
| 450 | return 0; | 450 | return 0; |
| 451 | } | 451 | } |
| @@ -881,8 +881,17 @@ static int mixer_ctl_feature_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
| 881 | uinfo->value.integer.min = 0; | 881 | uinfo->value.integer.min = 0; |
| 882 | uinfo->value.integer.max = 1; | 882 | uinfo->value.integer.max = 1; |
| 883 | } else { | 883 | } else { |
| 884 | if (! cval->initialized) | 884 | if (!cval->initialized) { |
| 885 | get_min_max(cval, 0); | 885 | get_min_max(cval, 0); |
| 886 | if (cval->initialized && cval->dBmin >= cval->dBmax) { | ||
| 887 | kcontrol->vd[0].access &= | ||
| 888 | ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
| 889 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK); | ||
| 890 | snd_ctl_notify(cval->mixer->chip->card, | ||
| 891 | SNDRV_CTL_EVENT_MASK_INFO, | ||
| 892 | &kcontrol->id); | ||
| 893 | } | ||
| 894 | } | ||
| 886 | uinfo->value.integer.min = 0; | 895 | uinfo->value.integer.min = 0; |
| 887 | uinfo->value.integer.max = | 896 | uinfo->value.integer.max = |
| 888 | (cval->max - cval->min + cval->res - 1) / cval->res; | 897 | (cval->max - cval->min + cval->res - 1) / cval->res; |
| @@ -1250,7 +1259,7 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void | |||
| 1250 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); | 1259 | build_feature_ctl(state, _ftr, 0, i, &iterm, unitid, 0); |
| 1251 | } | 1260 | } |
| 1252 | } else { /* UAC_VERSION_2 */ | 1261 | } else { /* UAC_VERSION_2 */ |
| 1253 | for (i = 0; i < 30/2; i++) { | 1262 | for (i = 0; i < ARRAY_SIZE(audio_feature_info); i++) { |
| 1254 | unsigned int ch_bits = 0; | 1263 | unsigned int ch_bits = 0; |
| 1255 | unsigned int ch_read_only = 0; | 1264 | unsigned int ch_read_only = 0; |
| 1256 | 1265 | ||
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 3d0f4873112b..ab125ee0b0f0 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
| @@ -190,18 +190,18 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
| 190 | err = snd_usb_ctl_msg(mixer->chip->dev, | 190 | err = snd_usb_ctl_msg(mixer->chip->dev, |
| 191 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 191 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
| 192 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 192 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
| 193 | !value, 0, NULL, 0, 100); | 193 | !value, 0, NULL, 0); |
| 194 | /* USB X-Fi S51 Pro */ | 194 | /* USB X-Fi S51 Pro */ |
| 195 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) | 195 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) |
| 196 | err = snd_usb_ctl_msg(mixer->chip->dev, | 196 | err = snd_usb_ctl_msg(mixer->chip->dev, |
| 197 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 197 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
| 198 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 198 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
| 199 | !value, 0, NULL, 0, 100); | 199 | !value, 0, NULL, 0); |
| 200 | else | 200 | else |
| 201 | err = snd_usb_ctl_msg(mixer->chip->dev, | 201 | err = snd_usb_ctl_msg(mixer->chip->dev, |
| 202 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 202 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
| 203 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 203 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
| 204 | value, index + 2, NULL, 0, 100); | 204 | value, index + 2, NULL, 0); |
| 205 | if (err < 0) | 205 | if (err < 0) |
| 206 | return err; | 206 | return err; |
| 207 | mixer->audigy2nx_leds[index] = value; | 207 | mixer->audigy2nx_leds[index] = value; |
| @@ -299,7 +299,7 @@ static void snd_audigy2nx_proc_read(struct snd_info_entry *entry, | |||
| 299 | usb_rcvctrlpipe(mixer->chip->dev, 0), | 299 | usb_rcvctrlpipe(mixer->chip->dev, 0), |
| 300 | UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | | 300 | UAC_GET_MEM, USB_DIR_IN | USB_TYPE_CLASS | |
| 301 | USB_RECIP_INTERFACE, 0, | 301 | USB_RECIP_INTERFACE, 0, |
| 302 | jacks[i].unitid << 8, buf, 3, 100); | 302 | jacks[i].unitid << 8, buf, 3); |
| 303 | if (err == 3 && (buf[0] == 3 || buf[0] == 6)) | 303 | if (err == 3 && (buf[0] == 3 || buf[0] == 6)) |
| 304 | snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); | 304 | snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]); |
| 305 | else | 305 | else |
| @@ -332,7 +332,7 @@ static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, | |||
| 332 | err = snd_usb_ctl_msg(mixer->chip->dev, | 332 | err = snd_usb_ctl_msg(mixer->chip->dev, |
| 333 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, | 333 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, |
| 334 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 334 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
| 335 | 50, 0, &new_status, 1, 100); | 335 | 50, 0, &new_status, 1); |
| 336 | if (err < 0) | 336 | if (err < 0) |
| 337 | return err; | 337 | return err; |
| 338 | mixer->xonar_u1_status = new_status; | 338 | mixer->xonar_u1_status = new_status; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index b8dcbf407bbb..0220b0f335b9 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
| @@ -28,12 +28,36 @@ | |||
| 28 | #include "card.h" | 28 | #include "card.h" |
| 29 | #include "quirks.h" | 29 | #include "quirks.h" |
| 30 | #include "debug.h" | 30 | #include "debug.h" |
| 31 | #include "urb.h" | 31 | #include "endpoint.h" |
| 32 | #include "helper.h" | 32 | #include "helper.h" |
| 33 | #include "pcm.h" | 33 | #include "pcm.h" |
| 34 | #include "clock.h" | 34 | #include "clock.h" |
| 35 | #include "power.h" | 35 | #include "power.h" |
| 36 | 36 | ||
| 37 | /* return the estimated delay based on USB frame counters */ | ||
| 38 | snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, | ||
| 39 | unsigned int rate) | ||
| 40 | { | ||
| 41 | int current_frame_number; | ||
| 42 | int frame_diff; | ||
| 43 | int est_delay; | ||
| 44 | |||
| 45 | current_frame_number = usb_get_current_frame_number(subs->dev); | ||
| 46 | /* | ||
| 47 | * HCD implementations use different widths, use lower 8 bits. | ||
| 48 | * The delay will be managed up to 256ms, which is more than | ||
| 49 | * enough | ||
| 50 | */ | ||
| 51 | frame_diff = (current_frame_number - subs->last_frame_number) & 0xff; | ||
| 52 | |||
| 53 | /* Approximation based on number of samples per USB frame (ms), | ||
| 54 | some truncation for 44.1 but the estimate is good enough */ | ||
| 55 | est_delay = subs->last_delay - (frame_diff * rate / 1000); | ||
| 56 | if (est_delay < 0) | ||
| 57 | est_delay = 0; | ||
| 58 | return est_delay; | ||
| 59 | } | ||
| 60 | |||
| 37 | /* | 61 | /* |
| 38 | * return the current pcm pointer. just based on the hwptr_done value. | 62 | * return the current pcm pointer. just based on the hwptr_done value. |
| 39 | */ | 63 | */ |
| @@ -45,6 +69,8 @@ static snd_pcm_uframes_t snd_usb_pcm_pointer(struct snd_pcm_substream *substream | |||
| 45 | subs = (struct snd_usb_substream *)substream->runtime->private_data; | 69 | subs = (struct snd_usb_substream *)substream->runtime->private_data; |
| 46 | spin_lock(&subs->lock); | 70 | spin_lock(&subs->lock); |
| 47 | hwptr_done = subs->hwptr_done; | 71 | hwptr_done = subs->hwptr_done; |
| 72 | substream->runtime->delay = snd_usb_pcm_delay(subs, | ||
| 73 | substream->runtime->rate); | ||
| 48 | spin_unlock(&subs->lock); | 74 | spin_unlock(&subs->lock); |
| 49 | return hwptr_done / (substream->runtime->frame_bits >> 3); | 75 | return hwptr_done / (substream->runtime->frame_bits >> 3); |
| 50 | } | 76 | } |
| @@ -126,7 +152,7 @@ static int init_pitch_v1(struct snd_usb_audio *chip, int iface, | |||
| 126 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, | 152 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR, |
| 127 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, | 153 | USB_TYPE_CLASS|USB_RECIP_ENDPOINT|USB_DIR_OUT, |
| 128 | UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, | 154 | UAC_EP_CS_ATTR_PITCH_CONTROL << 8, ep, |
| 129 | data, sizeof(data), 1000)) < 0) { | 155 | data, sizeof(data))) < 0) { |
| 130 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", | 156 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH\n", |
| 131 | dev->devnum, iface, ep); | 157 | dev->devnum, iface, ep); |
| 132 | return err; | 158 | return err; |
| @@ -150,7 +176,7 @@ static int init_pitch_v2(struct snd_usb_audio *chip, int iface, | |||
| 150 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, | 176 | if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, |
| 151 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 177 | USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
| 152 | UAC2_EP_CS_PITCH << 8, 0, | 178 | UAC2_EP_CS_PITCH << 8, 0, |
| 153 | data, sizeof(data), 1000)) < 0) { | 179 | data, sizeof(data))) < 0) { |
| 154 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", | 180 | snd_printk(KERN_ERR "%d:%d:%d: cannot set enable PITCH (v2)\n", |
| 155 | dev->devnum, iface, fmt->altsetting); | 181 | dev->devnum, iface, fmt->altsetting); |
| 156 | return err; | 182 | return err; |
| @@ -417,6 +443,8 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
| 417 | subs->hwptr_done = 0; | 443 | subs->hwptr_done = 0; |
| 418 | subs->transfer_done = 0; | 444 | subs->transfer_done = 0; |
| 419 | subs->phase = 0; | 445 | subs->phase = 0; |
| 446 | subs->last_delay = 0; | ||
| 447 | subs->last_frame_number = 0; | ||
| 420 | runtime->delay = 0; | 448 | runtime->delay = 0; |
| 421 | 449 | ||
| 422 | return snd_usb_substream_prepare(subs, runtime); | 450 | return snd_usb_substream_prepare(subs, runtime); |
diff --git a/sound/usb/pcm.h b/sound/usb/pcm.h index ed3e283f618d..df7a003682ad 100644 --- a/sound/usb/pcm.h +++ b/sound/usb/pcm.h | |||
| @@ -1,6 +1,9 @@ | |||
| 1 | #ifndef __USBAUDIO_PCM_H | 1 | #ifndef __USBAUDIO_PCM_H |
| 2 | #define __USBAUDIO_PCM_H | 2 | #define __USBAUDIO_PCM_H |
| 3 | 3 | ||
| 4 | snd_pcm_uframes_t snd_usb_pcm_delay(struct snd_usb_substream *subs, | ||
| 5 | unsigned int rate); | ||
| 6 | |||
| 4 | void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); | 7 | void snd_usb_set_pcm_ops(struct snd_pcm *pcm, int stream); |
| 5 | 8 | ||
| 6 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, | 9 | int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface, |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index a42e3ef3832d..b61945f3af9e 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
| @@ -39,6 +39,17 @@ | |||
| 39 | .idProduct = prod, \ | 39 | .idProduct = prod, \ |
| 40 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC | 40 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC |
| 41 | 41 | ||
| 42 | /* FTDI devices */ | ||
| 43 | { | ||
| 44 | USB_DEVICE(0x0403, 0xb8d8), | ||
| 45 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
| 46 | /* .vendor_name = "STARR LABS", */ | ||
| 47 | /* .product_name = "Starr Labs MIDI USB device", */ | ||
| 48 | .ifnum = 0, | ||
| 49 | .type = QUIRK_MIDI_FTDI | ||
| 50 | } | ||
| 51 | }, | ||
| 52 | |||
| 42 | /* Creative/Toshiba Multimedia Center SB-0500 */ | 53 | /* Creative/Toshiba Multimedia Center SB-0500 */ |
| 43 | { | 54 | { |
| 44 | USB_DEVICE(0x041e, 0x3048), | 55 | USB_DEVICE(0x041e, 0x3048), |
| @@ -1678,6 +1689,20 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
| 1678 | } | 1689 | } |
| 1679 | }, | 1690 | }, |
| 1680 | { | 1691 | { |
| 1692 | /* Added support for Roland UM-ONE which differs from UM-1 */ | ||
| 1693 | USB_DEVICE(0x0582, 0x012a), | ||
| 1694 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
| 1695 | /* .vendor_name = "ROLAND", */ | ||
| 1696 | /* .product_name = "UM-ONE", */ | ||
| 1697 | .ifnum = 0, | ||
| 1698 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
| 1699 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
| 1700 | .out_cables = 0x0001, | ||
| 1701 | .in_cables = 0x0003 | ||
| 1702 | } | ||
| 1703 | } | ||
| 1704 | }, | ||
| 1705 | { | ||
| 1681 | USB_DEVICE(0x0582, 0x011e), | 1706 | USB_DEVICE(0x0582, 0x011e), |
| 1682 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1707 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
| 1683 | /* .vendor_name = "BOSS", */ | 1708 | /* .vendor_name = "BOSS", */ |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 81e07d842581..2e5bc7344026 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include "endpoint.h" | 34 | #include "endpoint.h" |
| 35 | #include "pcm.h" | 35 | #include "pcm.h" |
| 36 | #include "clock.h" | 36 | #include "clock.h" |
| 37 | #include "stream.h" | ||
| 37 | 38 | ||
| 38 | /* | 39 | /* |
| 39 | * handle the quirks for the contained interfaces | 40 | * handle the quirks for the contained interfaces |
| @@ -106,7 +107,7 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip, | |||
| 106 | 107 | ||
| 107 | alts = &iface->altsetting[0]; | 108 | alts = &iface->altsetting[0]; |
| 108 | altsd = get_iface_desc(alts); | 109 | altsd = get_iface_desc(alts); |
| 109 | err = snd_usb_parse_audio_endpoints(chip, altsd->bInterfaceNumber); | 110 | err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber); |
| 110 | if (err < 0) { | 111 | if (err < 0) { |
| 111 | snd_printk(KERN_ERR "cannot setup if %d: error %d\n", | 112 | snd_printk(KERN_ERR "cannot setup if %d: error %d\n", |
| 112 | altsd->bInterfaceNumber, err); | 113 | altsd->bInterfaceNumber, err); |
| @@ -147,7 +148,7 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip, | |||
| 147 | 148 | ||
| 148 | stream = (fp->endpoint & USB_DIR_IN) | 149 | stream = (fp->endpoint & USB_DIR_IN) |
| 149 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 150 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
| 150 | err = snd_usb_add_audio_endpoint(chip, stream, fp); | 151 | err = snd_usb_add_audio_stream(chip, stream, fp); |
| 151 | if (err < 0) { | 152 | if (err < 0) { |
| 152 | kfree(fp); | 153 | kfree(fp); |
| 153 | kfree(rate_table); | 154 | kfree(rate_table); |
| @@ -254,7 +255,7 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip, | |||
| 254 | 255 | ||
| 255 | stream = (fp->endpoint & USB_DIR_IN) | 256 | stream = (fp->endpoint & USB_DIR_IN) |
| 256 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | 257 | ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; |
| 257 | err = snd_usb_add_audio_endpoint(chip, stream, fp); | 258 | err = snd_usb_add_audio_stream(chip, stream, fp); |
| 258 | if (err < 0) { | 259 | if (err < 0) { |
| 259 | kfree(fp); | 260 | kfree(fp); |
| 260 | return err; | 261 | return err; |
| @@ -306,6 +307,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip, | |||
| 306 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, | 307 | [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk, |
| 307 | [QUIRK_MIDI_CME] = create_any_midi_quirk, | 308 | [QUIRK_MIDI_CME] = create_any_midi_quirk, |
| 308 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, | 309 | [QUIRK_MIDI_AKAI] = create_any_midi_quirk, |
| 310 | [QUIRK_MIDI_FTDI] = create_any_midi_quirk, | ||
| 309 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, | 311 | [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, |
| 310 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, | 312 | [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, |
| 311 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, | 313 | [QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk, |
| @@ -338,7 +340,7 @@ static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interfac | |||
| 338 | snd_printdd("sending Extigy boot sequence...\n"); | 340 | snd_printdd("sending Extigy boot sequence...\n"); |
| 339 | /* Send message to force it to reconnect with full interface. */ | 341 | /* Send message to force it to reconnect with full interface. */ |
| 340 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0), | 342 | err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0), |
| 341 | 0x10, 0x43, 0x0001, 0x000a, NULL, 0, 1000); | 343 | 0x10, 0x43, 0x0001, 0x000a, NULL, 0); |
| 342 | if (err < 0) snd_printdd("error sending boot message: %d\n", err); | 344 | if (err < 0) snd_printdd("error sending boot message: %d\n", err); |
| 343 | err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, | 345 | err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, |
| 344 | &dev->descriptor, sizeof(dev->descriptor)); | 346 | &dev->descriptor, sizeof(dev->descriptor)); |
| @@ -359,11 +361,11 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev) | |||
| 359 | 361 | ||
| 360 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, | 362 | snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a, |
| 361 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 363 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
| 362 | 0, 0, &buf, 1, 1000); | 364 | 0, 0, &buf, 1); |
| 363 | if (buf == 0) { | 365 | if (buf == 0) { |
| 364 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, | 366 | snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29, |
| 365 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 367 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
| 366 | 1, 2000, NULL, 0, 1000); | 368 | 1, 2000, NULL, 0); |
| 367 | return -ENODEV; | 369 | return -ENODEV; |
| 368 | } | 370 | } |
| 369 | return 0; | 371 | return 0; |
| @@ -406,7 +408,7 @@ static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 valu | |||
| 406 | buf[3] = reg; | 408 | buf[3] = reg; |
| 407 | return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, | 409 | return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION, |
| 408 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, | 410 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT, |
| 409 | 0, 0, &buf, 4, 1000); | 411 | 0, 0, &buf, 4); |
| 410 | } | 412 | } |
| 411 | 413 | ||
| 412 | static int snd_usb_cm106_boot_quirk(struct usb_device *dev) | 414 | static int snd_usb_cm106_boot_quirk(struct usb_device *dev) |
diff --git a/sound/usb/stream.c b/sound/usb/stream.c new file mode 100644 index 000000000000..5ff8010b2d6f --- /dev/null +++ b/sound/usb/stream.c | |||
| @@ -0,0 +1,452 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 15 | */ | ||
| 16 | |||
| 17 | |||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/usb.h> | ||
| 21 | #include <linux/usb/audio.h> | ||
| 22 | #include <linux/usb/audio-v2.h> | ||
| 23 | |||
| 24 | #include <sound/core.h> | ||
| 25 | #include <sound/pcm.h> | ||
| 26 | |||
| 27 | #include "usbaudio.h" | ||
| 28 | #include "card.h" | ||
| 29 | #include "proc.h" | ||
| 30 | #include "quirks.h" | ||
| 31 | #include "endpoint.h" | ||
| 32 | #include "pcm.h" | ||
| 33 | #include "helper.h" | ||
| 34 | #include "format.h" | ||
| 35 | #include "clock.h" | ||
| 36 | #include "stream.h" | ||
| 37 | |||
| 38 | /* | ||
| 39 | * free a substream | ||
| 40 | */ | ||
| 41 | static void free_substream(struct snd_usb_substream *subs) | ||
| 42 | { | ||
| 43 | struct list_head *p, *n; | ||
| 44 | |||
| 45 | if (!subs->num_formats) | ||
| 46 | return; /* not initialized */ | ||
| 47 | list_for_each_safe(p, n, &subs->fmt_list) { | ||
| 48 | struct audioformat *fp = list_entry(p, struct audioformat, list); | ||
| 49 | kfree(fp->rate_table); | ||
| 50 | kfree(fp); | ||
| 51 | } | ||
| 52 | kfree(subs->rate_list.list); | ||
| 53 | } | ||
| 54 | |||
| 55 | |||
| 56 | /* | ||
| 57 | * free a usb stream instance | ||
| 58 | */ | ||
| 59 | static void snd_usb_audio_stream_free(struct snd_usb_stream *stream) | ||
| 60 | { | ||
| 61 | free_substream(&stream->substream[0]); | ||
| 62 | free_substream(&stream->substream[1]); | ||
| 63 | list_del(&stream->list); | ||
| 64 | kfree(stream); | ||
| 65 | } | ||
| 66 | |||
| 67 | static void snd_usb_audio_pcm_free(struct snd_pcm *pcm) | ||
| 68 | { | ||
| 69 | struct snd_usb_stream *stream = pcm->private_data; | ||
| 70 | if (stream) { | ||
| 71 | stream->pcm = NULL; | ||
| 72 | snd_usb_audio_stream_free(stream); | ||
| 73 | } | ||
| 74 | } | ||
| 75 | |||
| 76 | |||
| 77 | /* | ||
| 78 | * add this endpoint to the chip instance. | ||
| 79 | * if a stream with the same endpoint already exists, append to it. | ||
| 80 | * if not, create a new pcm stream. | ||
| 81 | */ | ||
| 82 | int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | ||
| 83 | int stream, | ||
| 84 | struct audioformat *fp) | ||
| 85 | { | ||
| 86 | struct list_head *p; | ||
| 87 | struct snd_usb_stream *as; | ||
| 88 | struct snd_usb_substream *subs; | ||
| 89 | struct snd_pcm *pcm; | ||
| 90 | int err; | ||
| 91 | |||
| 92 | list_for_each(p, &chip->pcm_list) { | ||
| 93 | as = list_entry(p, struct snd_usb_stream, list); | ||
| 94 | if (as->fmt_type != fp->fmt_type) | ||
| 95 | continue; | ||
| 96 | subs = &as->substream[stream]; | ||
| 97 | if (!subs->endpoint) | ||
| 98 | continue; | ||
| 99 | if (subs->endpoint == fp->endpoint) { | ||
| 100 | list_add_tail(&fp->list, &subs->fmt_list); | ||
| 101 | subs->num_formats++; | ||
| 102 | subs->formats |= fp->formats; | ||
| 103 | return 0; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | /* look for an empty stream */ | ||
| 107 | list_for_each(p, &chip->pcm_list) { | ||
| 108 | as = list_entry(p, struct snd_usb_stream, list); | ||
| 109 | if (as->fmt_type != fp->fmt_type) | ||
| 110 | continue; | ||
| 111 | subs = &as->substream[stream]; | ||
| 112 | if (subs->endpoint) | ||
| 113 | continue; | ||
| 114 | err = snd_pcm_new_stream(as->pcm, stream, 1); | ||
| 115 | if (err < 0) | ||
| 116 | return err; | ||
| 117 | snd_usb_init_substream(as, stream, fp); | ||
| 118 | return 0; | ||
| 119 | } | ||
| 120 | |||
| 121 | /* create a new pcm */ | ||
| 122 | as = kzalloc(sizeof(*as), GFP_KERNEL); | ||
| 123 | if (!as) | ||
| 124 | return -ENOMEM; | ||
| 125 | as->pcm_index = chip->pcm_devs; | ||
| 126 | as->chip = chip; | ||
| 127 | as->fmt_type = fp->fmt_type; | ||
| 128 | err = snd_pcm_new(chip->card, "USB Audio", chip->pcm_devs, | ||
| 129 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 1 : 0, | ||
| 130 | stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1, | ||
| 131 | &pcm); | ||
| 132 | if (err < 0) { | ||
| 133 | kfree(as); | ||
| 134 | return err; | ||
| 135 | } | ||
| 136 | as->pcm = pcm; | ||
| 137 | pcm->private_data = as; | ||
| 138 | pcm->private_free = snd_usb_audio_pcm_free; | ||
| 139 | pcm->info_flags = 0; | ||
| 140 | if (chip->pcm_devs > 0) | ||
| 141 | sprintf(pcm->name, "USB Audio #%d", chip->pcm_devs); | ||
| 142 | else | ||
| 143 | strcpy(pcm->name, "USB Audio"); | ||
| 144 | |||
| 145 | snd_usb_init_substream(as, stream, fp); | ||
| 146 | |||
| 147 | list_add(&as->list, &chip->pcm_list); | ||
| 148 | chip->pcm_devs++; | ||
| 149 | |||
| 150 | snd_usb_proc_pcm_format_add(as); | ||
| 151 | |||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | static int parse_uac_endpoint_attributes(struct snd_usb_audio *chip, | ||
| 156 | struct usb_host_interface *alts, | ||
| 157 | int protocol, int iface_no) | ||
| 158 | { | ||
| 159 | /* parsed with a v1 header here. that's ok as we only look at the | ||
| 160 | * header first which is the same for both versions */ | ||
| 161 | struct uac_iso_endpoint_descriptor *csep; | ||
| 162 | struct usb_interface_descriptor *altsd = get_iface_desc(alts); | ||
| 163 | int attributes = 0; | ||
| 164 | |||
| 165 | csep = snd_usb_find_desc(alts->endpoint[0].extra, alts->endpoint[0].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
| 166 | |||
| 167 | /* Creamware Noah has this descriptor after the 2nd endpoint */ | ||
| 168 | if (!csep && altsd->bNumEndpoints >= 2) | ||
| 169 | csep = snd_usb_find_desc(alts->endpoint[1].extra, alts->endpoint[1].extralen, NULL, USB_DT_CS_ENDPOINT); | ||
| 170 | |||
| 171 | if (!csep || csep->bLength < 7 || | ||
| 172 | csep->bDescriptorSubtype != UAC_EP_GENERAL) { | ||
| 173 | snd_printk(KERN_WARNING "%d:%u:%d : no or invalid" | ||
| 174 | " class specific endpoint descriptor\n", | ||
| 175 | chip->dev->devnum, iface_no, | ||
| 176 | altsd->bAlternateSetting); | ||
| 177 | return 0; | ||
| 178 | } | ||
| 179 | |||
| 180 | if (protocol == UAC_VERSION_1) { | ||
| 181 | attributes = csep->bmAttributes; | ||
| 182 | } else { | ||
| 183 | struct uac2_iso_endpoint_descriptor *csep2 = | ||
| 184 | (struct uac2_iso_endpoint_descriptor *) csep; | ||
| 185 | |||
| 186 | attributes = csep->bmAttributes & UAC_EP_CS_ATTR_FILL_MAX; | ||
| 187 | |||
| 188 | /* emulate the endpoint attributes of a v1 device */ | ||
| 189 | if (csep2->bmControls & UAC2_CONTROL_PITCH) | ||
| 190 | attributes |= UAC_EP_CS_ATTR_PITCH_CONTROL; | ||
| 191 | } | ||
| 192 | |||
| 193 | return attributes; | ||
| 194 | } | ||
| 195 | |||
| 196 | static struct uac2_input_terminal_descriptor * | ||
| 197 | snd_usb_find_input_terminal_descriptor(struct usb_host_interface *ctrl_iface, | ||
| 198 | int terminal_id) | ||
| 199 | { | ||
| 200 | struct uac2_input_terminal_descriptor *term = NULL; | ||
| 201 | |||
| 202 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
| 203 | ctrl_iface->extralen, | ||
| 204 | term, UAC_INPUT_TERMINAL))) { | ||
| 205 | if (term->bTerminalID == terminal_id) | ||
| 206 | return term; | ||
| 207 | } | ||
| 208 | |||
| 209 | return NULL; | ||
| 210 | } | ||
| 211 | |||
| 212 | static struct uac2_output_terminal_descriptor * | ||
| 213 | snd_usb_find_output_terminal_descriptor(struct usb_host_interface *ctrl_iface, | ||
| 214 | int terminal_id) | ||
| 215 | { | ||
| 216 | struct uac2_output_terminal_descriptor *term = NULL; | ||
| 217 | |||
| 218 | while ((term = snd_usb_find_csint_desc(ctrl_iface->extra, | ||
| 219 | ctrl_iface->extralen, | ||
| 220 | term, UAC_OUTPUT_TERMINAL))) { | ||
| 221 | if (term->bTerminalID == terminal_id) | ||
| 222 | return term; | ||
| 223 | } | ||
| 224 | |||
| 225 | return NULL; | ||
| 226 | } | ||
| 227 | |||
| 228 | int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no) | ||
| 229 | { | ||
| 230 | struct usb_device *dev; | ||
| 231 | struct usb_interface *iface; | ||
| 232 | struct usb_host_interface *alts; | ||
| 233 | struct usb_interface_descriptor *altsd; | ||
| 234 | int i, altno, err, stream; | ||
| 235 | int format = 0, num_channels = 0; | ||
| 236 | struct audioformat *fp = NULL; | ||
| 237 | int num, protocol, clock = 0; | ||
| 238 | struct uac_format_type_i_continuous_descriptor *fmt; | ||
| 239 | |||
| 240 | dev = chip->dev; | ||
| 241 | |||
| 242 | /* parse the interface's altsettings */ | ||
| 243 | iface = usb_ifnum_to_if(dev, iface_no); | ||
| 244 | |||
| 245 | num = iface->num_altsetting; | ||
| 246 | |||
| 247 | /* | ||
| 248 | * Dallas DS4201 workaround: It presents 5 altsettings, but the last | ||
| 249 | * one misses syncpipe, and does not produce any sound. | ||
| 250 | */ | ||
| 251 | if (chip->usb_id == USB_ID(0x04fa, 0x4201)) | ||
| 252 | num = 4; | ||
| 253 | |||
| 254 | for (i = 0; i < num; i++) { | ||
| 255 | alts = &iface->altsetting[i]; | ||
| 256 | altsd = get_iface_desc(alts); | ||
| 257 | protocol = altsd->bInterfaceProtocol; | ||
| 258 | /* skip invalid one */ | ||
| 259 | if ((altsd->bInterfaceClass != USB_CLASS_AUDIO && | ||
| 260 | altsd->bInterfaceClass != USB_CLASS_VENDOR_SPEC) || | ||
| 261 | (altsd->bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING && | ||
| 262 | altsd->bInterfaceSubClass != USB_SUBCLASS_VENDOR_SPEC) || | ||
| 263 | altsd->bNumEndpoints < 1 || | ||
| 264 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == 0) | ||
| 265 | continue; | ||
| 266 | /* must be isochronous */ | ||
| 267 | if ((get_endpoint(alts, 0)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
| 268 | USB_ENDPOINT_XFER_ISOC) | ||
| 269 | continue; | ||
| 270 | /* check direction */ | ||
| 271 | stream = (get_endpoint(alts, 0)->bEndpointAddress & USB_DIR_IN) ? | ||
| 272 | SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; | ||
| 273 | altno = altsd->bAlternateSetting; | ||
| 274 | |||
| 275 | if (snd_usb_apply_interface_quirk(chip, iface_no, altno)) | ||
| 276 | continue; | ||
| 277 | |||
| 278 | /* get audio formats */ | ||
| 279 | switch (protocol) { | ||
| 280 | default: | ||
| 281 | snd_printdd(KERN_WARNING "%d:%u:%d: unknown interface protocol %#02x, assuming v1\n", | ||
| 282 | dev->devnum, iface_no, altno, protocol); | ||
| 283 | protocol = UAC_VERSION_1; | ||
| 284 | /* fall through */ | ||
| 285 | |||
| 286 | case UAC_VERSION_1: { | ||
| 287 | struct uac1_as_header_descriptor *as = | ||
| 288 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
| 289 | |||
| 290 | if (!as) { | ||
| 291 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
| 292 | dev->devnum, iface_no, altno); | ||
| 293 | continue; | ||
| 294 | } | ||
| 295 | |||
| 296 | if (as->bLength < sizeof(*as)) { | ||
| 297 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
| 298 | dev->devnum, iface_no, altno); | ||
| 299 | continue; | ||
| 300 | } | ||
| 301 | |||
| 302 | format = le16_to_cpu(as->wFormatTag); /* remember the format value */ | ||
| 303 | break; | ||
| 304 | } | ||
| 305 | |||
| 306 | case UAC_VERSION_2: { | ||
| 307 | struct uac2_input_terminal_descriptor *input_term; | ||
| 308 | struct uac2_output_terminal_descriptor *output_term; | ||
| 309 | struct uac2_as_header_descriptor *as = | ||
| 310 | snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_AS_GENERAL); | ||
| 311 | |||
| 312 | if (!as) { | ||
| 313 | snd_printk(KERN_ERR "%d:%u:%d : UAC_AS_GENERAL descriptor not found\n", | ||
| 314 | dev->devnum, iface_no, altno); | ||
| 315 | continue; | ||
| 316 | } | ||
| 317 | |||
| 318 | if (as->bLength < sizeof(*as)) { | ||
| 319 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_AS_GENERAL desc\n", | ||
| 320 | dev->devnum, iface_no, altno); | ||
| 321 | continue; | ||
| 322 | } | ||
| 323 | |||
| 324 | num_channels = as->bNrChannels; | ||
| 325 | format = le32_to_cpu(as->bmFormats); | ||
| 326 | |||
| 327 | /* lookup the terminal associated to this interface | ||
| 328 | * to extract the clock */ | ||
| 329 | input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf, | ||
| 330 | as->bTerminalLink); | ||
| 331 | if (input_term) { | ||
| 332 | clock = input_term->bCSourceID; | ||
| 333 | break; | ||
| 334 | } | ||
| 335 | |||
| 336 | output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf, | ||
| 337 | as->bTerminalLink); | ||
| 338 | if (output_term) { | ||
| 339 | clock = output_term->bCSourceID; | ||
| 340 | break; | ||
| 341 | } | ||
| 342 | |||
| 343 | snd_printk(KERN_ERR "%d:%u:%d : bogus bTerminalLink %d\n", | ||
| 344 | dev->devnum, iface_no, altno, as->bTerminalLink); | ||
| 345 | continue; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | /* get format type */ | ||
| 350 | fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL, UAC_FORMAT_TYPE); | ||
| 351 | if (!fmt) { | ||
| 352 | snd_printk(KERN_ERR "%d:%u:%d : no UAC_FORMAT_TYPE desc\n", | ||
| 353 | dev->devnum, iface_no, altno); | ||
| 354 | continue; | ||
| 355 | } | ||
| 356 | if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8)) || | ||
| 357 | ((protocol == UAC_VERSION_2) && (fmt->bLength < 6))) { | ||
| 358 | snd_printk(KERN_ERR "%d:%u:%d : invalid UAC_FORMAT_TYPE desc\n", | ||
| 359 | dev->devnum, iface_no, altno); | ||
| 360 | continue; | ||
| 361 | } | ||
| 362 | |||
| 363 | /* | ||
| 364 | * Blue Microphones workaround: The last altsetting is identical | ||
| 365 | * with the previous one, except for a larger packet size, but | ||
| 366 | * is actually a mislabeled two-channel setting; ignore it. | ||
| 367 | */ | ||
| 368 | if (fmt->bNrChannels == 1 && | ||
| 369 | fmt->bSubframeSize == 2 && | ||
| 370 | altno == 2 && num == 3 && | ||
| 371 | fp && fp->altsetting == 1 && fp->channels == 1 && | ||
| 372 | fp->formats == SNDRV_PCM_FMTBIT_S16_LE && | ||
| 373 | protocol == UAC_VERSION_1 && | ||
| 374 | le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) == | ||
| 375 | fp->maxpacksize * 2) | ||
| 376 | continue; | ||
| 377 | |||
| 378 | fp = kzalloc(sizeof(*fp), GFP_KERNEL); | ||
| 379 | if (! fp) { | ||
| 380 | snd_printk(KERN_ERR "cannot malloc\n"); | ||
| 381 | return -ENOMEM; | ||
| 382 | } | ||
| 383 | |||
| 384 | fp->iface = iface_no; | ||
| 385 | fp->altsetting = altno; | ||
| 386 | fp->altset_idx = i; | ||
| 387 | fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress; | ||
| 388 | fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; | ||
| 389 | fp->datainterval = snd_usb_parse_datainterval(chip, alts); | ||
| 390 | fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); | ||
| 391 | /* num_channels is only set for v2 interfaces */ | ||
| 392 | fp->channels = num_channels; | ||
| 393 | if (snd_usb_get_speed(dev) == USB_SPEED_HIGH) | ||
| 394 | fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1) | ||
| 395 | * (fp->maxpacksize & 0x7ff); | ||
| 396 | fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); | ||
| 397 | fp->clock = clock; | ||
| 398 | |||
| 399 | /* some quirks for attributes here */ | ||
| 400 | |||
| 401 | switch (chip->usb_id) { | ||
| 402 | case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ | ||
| 403 | /* Optoplay sets the sample rate attribute although | ||
| 404 | * it seems not supporting it in fact. | ||
| 405 | */ | ||
| 406 | fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
| 407 | break; | ||
| 408 | case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ | ||
| 409 | case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ | ||
| 410 | /* doesn't set the sample rate attribute, but supports it */ | ||
| 411 | fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; | ||
| 412 | break; | ||
| 413 | case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ | ||
| 414 | case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ | ||
| 415 | case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ | ||
| 416 | case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is | ||
| 417 | an older model 77d:223) */ | ||
| 418 | /* | ||
| 419 | * plantronics headset and Griffin iMic have set adaptive-in | ||
| 420 | * although it's really not... | ||
| 421 | */ | ||
| 422 | fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; | ||
| 423 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
| 424 | fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; | ||
| 425 | else | ||
| 426 | fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; | ||
| 427 | break; | ||
| 428 | } | ||
| 429 | |||
| 430 | /* ok, let's parse further... */ | ||
| 431 | if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { | ||
| 432 | kfree(fp->rate_table); | ||
| 433 | kfree(fp); | ||
| 434 | fp = NULL; | ||
| 435 | continue; | ||
| 436 | } | ||
| 437 | |||
| 438 | snd_printdd(KERN_INFO "%d:%u:%d: add audio endpoint %#x\n", dev->devnum, iface_no, altno, fp->endpoint); | ||
| 439 | err = snd_usb_add_audio_stream(chip, stream, fp); | ||
| 440 | if (err < 0) { | ||
| 441 | kfree(fp->rate_table); | ||
| 442 | kfree(fp); | ||
| 443 | return err; | ||
| 444 | } | ||
| 445 | /* try to set the interface... */ | ||
| 446 | usb_set_interface(chip->dev, iface_no, altno); | ||
| 447 | snd_usb_init_pitch(chip, iface_no, alts, fp); | ||
| 448 | snd_usb_init_sample_rate(chip, iface_no, alts, fp, fp->rate_max); | ||
| 449 | } | ||
| 450 | return 0; | ||
| 451 | } | ||
| 452 | |||
diff --git a/sound/usb/stream.h b/sound/usb/stream.h new file mode 100644 index 000000000000..c97f679fc84f --- /dev/null +++ b/sound/usb/stream.h | |||
| @@ -0,0 +1,12 @@ | |||
| 1 | #ifndef __USBAUDIO_STREAM_H | ||
| 2 | #define __USBAUDIO_STREAM_H | ||
| 3 | |||
| 4 | int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, | ||
| 5 | int iface_no); | ||
| 6 | |||
| 7 | int snd_usb_add_audio_stream(struct snd_usb_audio *chip, | ||
| 8 | int stream, | ||
| 9 | struct audioformat *fp); | ||
| 10 | |||
| 11 | #endif /* __USBAUDIO_STREAM_H */ | ||
| 12 | |||
diff --git a/sound/usb/urb.c b/sound/usb/urb.c deleted file mode 100644 index e184349aee83..000000000000 --- a/sound/usb/urb.c +++ /dev/null | |||
| @@ -1,941 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * This program is free software; you can redistribute it and/or modify | ||
| 3 | * it under the terms of the GNU General Public License as published by | ||
| 4 | * the Free Software Foundation; either version 2 of the License, or | ||
| 5 | * (at your option) any later version. | ||
| 6 | * | ||
| 7 | * This program is distributed in the hope that it will be useful, | ||
| 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 10 | * GNU General Public License for more details. | ||
| 11 | * | ||
| 12 | * You should have received a copy of the GNU General Public License | ||
| 13 | * along with this program; if not, write to the Free Software | ||
| 14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 15 | * | ||
| 16 | */ | ||
| 17 | |||
| 18 | #include <linux/gfp.h> | ||
| 19 | #include <linux/init.h> | ||
| 20 | #include <linux/usb.h> | ||
| 21 | #include <linux/usb/audio.h> | ||
| 22 | |||
| 23 | #include <sound/core.h> | ||
| 24 | #include <sound/pcm.h> | ||
| 25 | |||
| 26 | #include "usbaudio.h" | ||
| 27 | #include "helper.h" | ||
| 28 | #include "card.h" | ||
| 29 | #include "urb.h" | ||
| 30 | #include "pcm.h" | ||
| 31 | |||
| 32 | /* | ||
| 33 | * convert a sampling rate into our full speed format (fs/1000 in Q16.16) | ||
| 34 | * this will overflow at approx 524 kHz | ||
| 35 | */ | ||
| 36 | static inline unsigned get_usb_full_speed_rate(unsigned int rate) | ||
| 37 | { | ||
| 38 | return ((rate << 13) + 62) / 125; | ||
| 39 | } | ||
| 40 | |||
| 41 | /* | ||
| 42 | * convert a sampling rate into USB high speed format (fs/8000 in Q16.16) | ||
| 43 | * this will overflow at approx 4 MHz | ||
| 44 | */ | ||
| 45 | static inline unsigned get_usb_high_speed_rate(unsigned int rate) | ||
| 46 | { | ||
| 47 | return ((rate << 10) + 62) / 125; | ||
| 48 | } | ||
| 49 | |||
| 50 | /* | ||
| 51 | * unlink active urbs. | ||
| 52 | */ | ||
| 53 | static int deactivate_urbs(struct snd_usb_substream *subs, int force, int can_sleep) | ||
| 54 | { | ||
| 55 | struct snd_usb_audio *chip = subs->stream->chip; | ||
| 56 | unsigned int i; | ||
| 57 | int async; | ||
| 58 | |||
| 59 | subs->running = 0; | ||
| 60 | |||
| 61 | if (!force && subs->stream->chip->shutdown) /* to be sure... */ | ||
| 62 | return -EBADFD; | ||
| 63 | |||
| 64 | async = !can_sleep && chip->async_unlink; | ||
| 65 | |||
| 66 | if (!async && in_interrupt()) | ||
| 67 | return 0; | ||
| 68 | |||
| 69 | for (i = 0; i < subs->nurbs; i++) { | ||
| 70 | if (test_bit(i, &subs->active_mask)) { | ||
| 71 | if (!test_and_set_bit(i, &subs->unlink_mask)) { | ||
| 72 | struct urb *u = subs->dataurb[i].urb; | ||
| 73 | if (async) | ||
| 74 | usb_unlink_urb(u); | ||
| 75 | else | ||
| 76 | usb_kill_urb(u); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | } | ||
| 80 | if (subs->syncpipe) { | ||
| 81 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 82 | if (test_bit(i+16, &subs->active_mask)) { | ||
| 83 | if (!test_and_set_bit(i+16, &subs->unlink_mask)) { | ||
| 84 | struct urb *u = subs->syncurb[i].urb; | ||
| 85 | if (async) | ||
| 86 | usb_unlink_urb(u); | ||
| 87 | else | ||
| 88 | usb_kill_urb(u); | ||
| 89 | } | ||
| 90 | } | ||
| 91 | } | ||
| 92 | } | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | |||
| 97 | /* | ||
| 98 | * release a urb data | ||
| 99 | */ | ||
| 100 | static void release_urb_ctx(struct snd_urb_ctx *u) | ||
| 101 | { | ||
| 102 | if (u->urb) { | ||
| 103 | if (u->buffer_size) | ||
| 104 | usb_free_coherent(u->subs->dev, u->buffer_size, | ||
| 105 | u->urb->transfer_buffer, | ||
| 106 | u->urb->transfer_dma); | ||
| 107 | usb_free_urb(u->urb); | ||
| 108 | u->urb = NULL; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | /* | ||
| 113 | * wait until all urbs are processed. | ||
| 114 | */ | ||
| 115 | static int wait_clear_urbs(struct snd_usb_substream *subs) | ||
| 116 | { | ||
| 117 | unsigned long end_time = jiffies + msecs_to_jiffies(1000); | ||
| 118 | unsigned int i; | ||
| 119 | int alive; | ||
| 120 | |||
| 121 | do { | ||
| 122 | alive = 0; | ||
| 123 | for (i = 0; i < subs->nurbs; i++) { | ||
| 124 | if (test_bit(i, &subs->active_mask)) | ||
| 125 | alive++; | ||
| 126 | } | ||
| 127 | if (subs->syncpipe) { | ||
| 128 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 129 | if (test_bit(i + 16, &subs->active_mask)) | ||
| 130 | alive++; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | if (! alive) | ||
| 134 | break; | ||
| 135 | schedule_timeout_uninterruptible(1); | ||
| 136 | } while (time_before(jiffies, end_time)); | ||
| 137 | if (alive) | ||
| 138 | snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive); | ||
| 139 | return 0; | ||
| 140 | } | ||
| 141 | |||
| 142 | /* | ||
| 143 | * release a substream | ||
| 144 | */ | ||
| 145 | void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force) | ||
| 146 | { | ||
| 147 | int i; | ||
| 148 | |||
| 149 | /* stop urbs (to be sure) */ | ||
| 150 | deactivate_urbs(subs, force, 1); | ||
| 151 | wait_clear_urbs(subs); | ||
| 152 | |||
| 153 | for (i = 0; i < MAX_URBS; i++) | ||
| 154 | release_urb_ctx(&subs->dataurb[i]); | ||
| 155 | for (i = 0; i < SYNC_URBS; i++) | ||
| 156 | release_urb_ctx(&subs->syncurb[i]); | ||
| 157 | usb_free_coherent(subs->dev, SYNC_URBS * 4, | ||
| 158 | subs->syncbuf, subs->sync_dma); | ||
| 159 | subs->syncbuf = NULL; | ||
| 160 | subs->nurbs = 0; | ||
| 161 | } | ||
| 162 | |||
| 163 | /* | ||
| 164 | * complete callback from data urb | ||
| 165 | */ | ||
| 166 | static void snd_complete_urb(struct urb *urb) | ||
| 167 | { | ||
| 168 | struct snd_urb_ctx *ctx = urb->context; | ||
| 169 | struct snd_usb_substream *subs = ctx->subs; | ||
| 170 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; | ||
| 171 | int err = 0; | ||
| 172 | |||
| 173 | if ((subs->running && subs->ops.retire(subs, substream->runtime, urb)) || | ||
| 174 | !subs->running || /* can be stopped during retire callback */ | ||
| 175 | (err = subs->ops.prepare(subs, substream->runtime, urb)) < 0 || | ||
| 176 | (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | ||
| 177 | clear_bit(ctx->index, &subs->active_mask); | ||
| 178 | if (err < 0) { | ||
| 179 | snd_printd(KERN_ERR "cannot submit urb (err = %d)\n", err); | ||
| 180 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | } | ||
| 184 | |||
| 185 | |||
| 186 | /* | ||
| 187 | * complete callback from sync urb | ||
| 188 | */ | ||
| 189 | static void snd_complete_sync_urb(struct urb *urb) | ||
| 190 | { | ||
| 191 | struct snd_urb_ctx *ctx = urb->context; | ||
| 192 | struct snd_usb_substream *subs = ctx->subs; | ||
| 193 | struct snd_pcm_substream *substream = ctx->subs->pcm_substream; | ||
| 194 | int err = 0; | ||
| 195 | |||
| 196 | if ((subs->running && subs->ops.retire_sync(subs, substream->runtime, urb)) || | ||
| 197 | !subs->running || /* can be stopped during retire callback */ | ||
| 198 | (err = subs->ops.prepare_sync(subs, substream->runtime, urb)) < 0 || | ||
| 199 | (err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { | ||
| 200 | clear_bit(ctx->index + 16, &subs->active_mask); | ||
| 201 | if (err < 0) { | ||
| 202 | snd_printd(KERN_ERR "cannot submit sync urb (err = %d)\n", err); | ||
| 203 | snd_pcm_stop(substream, SNDRV_PCM_STATE_XRUN); | ||
| 204 | } | ||
| 205 | } | ||
| 206 | } | ||
| 207 | |||
| 208 | |||
| 209 | /* | ||
| 210 | * initialize a substream for plaback/capture | ||
| 211 | */ | ||
| 212 | int snd_usb_init_substream_urbs(struct snd_usb_substream *subs, | ||
| 213 | unsigned int period_bytes, | ||
| 214 | unsigned int rate, | ||
| 215 | unsigned int frame_bits) | ||
| 216 | { | ||
| 217 | unsigned int maxsize, i; | ||
| 218 | int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; | ||
| 219 | unsigned int urb_packs, total_packs, packs_per_ms; | ||
| 220 | struct snd_usb_audio *chip = subs->stream->chip; | ||
| 221 | |||
| 222 | /* calculate the frequency in 16.16 format */ | ||
| 223 | if (snd_usb_get_speed(subs->dev) == USB_SPEED_FULL) | ||
| 224 | subs->freqn = get_usb_full_speed_rate(rate); | ||
| 225 | else | ||
| 226 | subs->freqn = get_usb_high_speed_rate(rate); | ||
| 227 | subs->freqm = subs->freqn; | ||
| 228 | subs->freqshift = INT_MIN; | ||
| 229 | /* calculate max. frequency */ | ||
| 230 | if (subs->maxpacksize) { | ||
| 231 | /* whatever fits into a max. size packet */ | ||
| 232 | maxsize = subs->maxpacksize; | ||
| 233 | subs->freqmax = (maxsize / (frame_bits >> 3)) | ||
| 234 | << (16 - subs->datainterval); | ||
| 235 | } else { | ||
| 236 | /* no max. packet size: just take 25% higher than nominal */ | ||
| 237 | subs->freqmax = subs->freqn + (subs->freqn >> 2); | ||
| 238 | maxsize = ((subs->freqmax + 0xffff) * (frame_bits >> 3)) | ||
| 239 | >> (16 - subs->datainterval); | ||
| 240 | } | ||
| 241 | subs->phase = 0; | ||
| 242 | |||
| 243 | if (subs->fill_max) | ||
| 244 | subs->curpacksize = subs->maxpacksize; | ||
| 245 | else | ||
| 246 | subs->curpacksize = maxsize; | ||
| 247 | |||
| 248 | if (snd_usb_get_speed(subs->dev) != USB_SPEED_FULL) | ||
| 249 | packs_per_ms = 8 >> subs->datainterval; | ||
| 250 | else | ||
| 251 | packs_per_ms = 1; | ||
| 252 | |||
| 253 | if (is_playback) { | ||
| 254 | urb_packs = max(chip->nrpacks, 1); | ||
| 255 | urb_packs = min(urb_packs, (unsigned int)MAX_PACKS); | ||
| 256 | } else | ||
| 257 | urb_packs = 1; | ||
| 258 | urb_packs *= packs_per_ms; | ||
| 259 | if (subs->syncpipe) | ||
| 260 | urb_packs = min(urb_packs, 1U << subs->syncinterval); | ||
| 261 | |||
| 262 | /* decide how many packets to be used */ | ||
| 263 | if (is_playback) { | ||
| 264 | unsigned int minsize, maxpacks; | ||
| 265 | /* determine how small a packet can be */ | ||
| 266 | minsize = (subs->freqn >> (16 - subs->datainterval)) | ||
| 267 | * (frame_bits >> 3); | ||
| 268 | /* with sync from device, assume it can be 12% lower */ | ||
| 269 | if (subs->syncpipe) | ||
| 270 | minsize -= minsize >> 3; | ||
| 271 | minsize = max(minsize, 1u); | ||
| 272 | total_packs = (period_bytes + minsize - 1) / minsize; | ||
| 273 | /* we need at least two URBs for queueing */ | ||
| 274 | if (total_packs < 2) { | ||
| 275 | total_packs = 2; | ||
| 276 | } else { | ||
| 277 | /* and we don't want too long a queue either */ | ||
| 278 | maxpacks = max(MAX_QUEUE * packs_per_ms, urb_packs * 2); | ||
| 279 | total_packs = min(total_packs, maxpacks); | ||
| 280 | } | ||
| 281 | } else { | ||
| 282 | while (urb_packs > 1 && urb_packs * maxsize >= period_bytes) | ||
| 283 | urb_packs >>= 1; | ||
| 284 | total_packs = MAX_URBS * urb_packs; | ||
| 285 | } | ||
| 286 | subs->nurbs = (total_packs + urb_packs - 1) / urb_packs; | ||
| 287 | if (subs->nurbs > MAX_URBS) { | ||
| 288 | /* too much... */ | ||
| 289 | subs->nurbs = MAX_URBS; | ||
| 290 | total_packs = MAX_URBS * urb_packs; | ||
| 291 | } else if (subs->nurbs < 2) { | ||
| 292 | /* too little - we need at least two packets | ||
| 293 | * to ensure contiguous playback/capture | ||
| 294 | */ | ||
| 295 | subs->nurbs = 2; | ||
| 296 | } | ||
| 297 | |||
| 298 | /* allocate and initialize data urbs */ | ||
| 299 | for (i = 0; i < subs->nurbs; i++) { | ||
| 300 | struct snd_urb_ctx *u = &subs->dataurb[i]; | ||
| 301 | u->index = i; | ||
| 302 | u->subs = subs; | ||
| 303 | u->packets = (i + 1) * total_packs / subs->nurbs | ||
| 304 | - i * total_packs / subs->nurbs; | ||
| 305 | u->buffer_size = maxsize * u->packets; | ||
| 306 | if (subs->fmt_type == UAC_FORMAT_TYPE_II) | ||
| 307 | u->packets++; /* for transfer delimiter */ | ||
| 308 | u->urb = usb_alloc_urb(u->packets, GFP_KERNEL); | ||
| 309 | if (!u->urb) | ||
| 310 | goto out_of_memory; | ||
| 311 | u->urb->transfer_buffer = | ||
| 312 | usb_alloc_coherent(subs->dev, u->buffer_size, | ||
| 313 | GFP_KERNEL, &u->urb->transfer_dma); | ||
| 314 | if (!u->urb->transfer_buffer) | ||
| 315 | goto out_of_memory; | ||
| 316 | u->urb->pipe = subs->datapipe; | ||
| 317 | u->urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | ||
| 318 | u->urb->interval = 1 << subs->datainterval; | ||
| 319 | u->urb->context = u; | ||
| 320 | u->urb->complete = snd_complete_urb; | ||
| 321 | } | ||
| 322 | |||
| 323 | if (subs->syncpipe) { | ||
| 324 | /* allocate and initialize sync urbs */ | ||
| 325 | subs->syncbuf = usb_alloc_coherent(subs->dev, SYNC_URBS * 4, | ||
| 326 | GFP_KERNEL, &subs->sync_dma); | ||
| 327 | if (!subs->syncbuf) | ||
| 328 | goto out_of_memory; | ||
| 329 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 330 | struct snd_urb_ctx *u = &subs->syncurb[i]; | ||
| 331 | u->index = i; | ||
| 332 | u->subs = subs; | ||
| 333 | u->packets = 1; | ||
| 334 | u->urb = usb_alloc_urb(1, GFP_KERNEL); | ||
| 335 | if (!u->urb) | ||
| 336 | goto out_of_memory; | ||
| 337 | u->urb->transfer_buffer = subs->syncbuf + i * 4; | ||
| 338 | u->urb->transfer_dma = subs->sync_dma + i * 4; | ||
| 339 | u->urb->transfer_buffer_length = 4; | ||
| 340 | u->urb->pipe = subs->syncpipe; | ||
| 341 | u->urb->transfer_flags = URB_ISO_ASAP | | ||
| 342 | URB_NO_TRANSFER_DMA_MAP; | ||
| 343 | u->urb->number_of_packets = 1; | ||
| 344 | u->urb->interval = 1 << subs->syncinterval; | ||
| 345 | u->urb->context = u; | ||
| 346 | u->urb->complete = snd_complete_sync_urb; | ||
| 347 | } | ||
| 348 | } | ||
| 349 | return 0; | ||
| 350 | |||
| 351 | out_of_memory: | ||
| 352 | snd_usb_release_substream_urbs(subs, 0); | ||
| 353 | return -ENOMEM; | ||
| 354 | } | ||
| 355 | |||
| 356 | /* | ||
| 357 | * prepare urb for full speed capture sync pipe | ||
| 358 | * | ||
| 359 | * fill the length and offset of each urb descriptor. | ||
| 360 | * the fixed 10.14 frequency is passed through the pipe. | ||
| 361 | */ | ||
| 362 | static int prepare_capture_sync_urb(struct snd_usb_substream *subs, | ||
| 363 | struct snd_pcm_runtime *runtime, | ||
| 364 | struct urb *urb) | ||
| 365 | { | ||
| 366 | unsigned char *cp = urb->transfer_buffer; | ||
| 367 | struct snd_urb_ctx *ctx = urb->context; | ||
| 368 | |||
| 369 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 370 | urb->iso_frame_desc[0].length = 3; | ||
| 371 | urb->iso_frame_desc[0].offset = 0; | ||
| 372 | cp[0] = subs->freqn >> 2; | ||
| 373 | cp[1] = subs->freqn >> 10; | ||
| 374 | cp[2] = subs->freqn >> 18; | ||
| 375 | return 0; | ||
| 376 | } | ||
| 377 | |||
| 378 | /* | ||
| 379 | * prepare urb for high speed capture sync pipe | ||
| 380 | * | ||
| 381 | * fill the length and offset of each urb descriptor. | ||
| 382 | * the fixed 12.13 frequency is passed as 16.16 through the pipe. | ||
| 383 | */ | ||
| 384 | static int prepare_capture_sync_urb_hs(struct snd_usb_substream *subs, | ||
| 385 | struct snd_pcm_runtime *runtime, | ||
| 386 | struct urb *urb) | ||
| 387 | { | ||
| 388 | unsigned char *cp = urb->transfer_buffer; | ||
| 389 | struct snd_urb_ctx *ctx = urb->context; | ||
| 390 | |||
| 391 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 392 | urb->iso_frame_desc[0].length = 4; | ||
| 393 | urb->iso_frame_desc[0].offset = 0; | ||
| 394 | cp[0] = subs->freqn; | ||
| 395 | cp[1] = subs->freqn >> 8; | ||
| 396 | cp[2] = subs->freqn >> 16; | ||
| 397 | cp[3] = subs->freqn >> 24; | ||
| 398 | return 0; | ||
| 399 | } | ||
| 400 | |||
| 401 | /* | ||
| 402 | * process after capture sync complete | ||
| 403 | * - nothing to do | ||
| 404 | */ | ||
| 405 | static int retire_capture_sync_urb(struct snd_usb_substream *subs, | ||
| 406 | struct snd_pcm_runtime *runtime, | ||
| 407 | struct urb *urb) | ||
| 408 | { | ||
| 409 | return 0; | ||
| 410 | } | ||
| 411 | |||
| 412 | /* | ||
| 413 | * prepare urb for capture data pipe | ||
| 414 | * | ||
| 415 | * fill the offset and length of each descriptor. | ||
| 416 | * | ||
| 417 | * we use a temporary buffer to write the captured data. | ||
| 418 | * since the length of written data is determined by host, we cannot | ||
| 419 | * write onto the pcm buffer directly... the data is thus copied | ||
| 420 | * later at complete callback to the global buffer. | ||
| 421 | */ | ||
| 422 | static int prepare_capture_urb(struct snd_usb_substream *subs, | ||
| 423 | struct snd_pcm_runtime *runtime, | ||
| 424 | struct urb *urb) | ||
| 425 | { | ||
| 426 | int i, offs; | ||
| 427 | struct snd_urb_ctx *ctx = urb->context; | ||
| 428 | |||
| 429 | offs = 0; | ||
| 430 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 431 | for (i = 0; i < ctx->packets; i++) { | ||
| 432 | urb->iso_frame_desc[i].offset = offs; | ||
| 433 | urb->iso_frame_desc[i].length = subs->curpacksize; | ||
| 434 | offs += subs->curpacksize; | ||
| 435 | } | ||
| 436 | urb->transfer_buffer_length = offs; | ||
| 437 | urb->number_of_packets = ctx->packets; | ||
| 438 | return 0; | ||
| 439 | } | ||
| 440 | |||
| 441 | /* | ||
| 442 | * process after capture complete | ||
| 443 | * | ||
| 444 | * copy the data from each desctiptor to the pcm buffer, and | ||
| 445 | * update the current position. | ||
| 446 | */ | ||
| 447 | static int retire_capture_urb(struct snd_usb_substream *subs, | ||
| 448 | struct snd_pcm_runtime *runtime, | ||
| 449 | struct urb *urb) | ||
| 450 | { | ||
| 451 | unsigned long flags; | ||
| 452 | unsigned char *cp; | ||
| 453 | int i; | ||
| 454 | unsigned int stride, frames, bytes, oldptr; | ||
| 455 | int period_elapsed = 0; | ||
| 456 | |||
| 457 | stride = runtime->frame_bits >> 3; | ||
| 458 | |||
| 459 | for (i = 0; i < urb->number_of_packets; i++) { | ||
| 460 | cp = (unsigned char *)urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
| 461 | if (urb->iso_frame_desc[i].status) { | ||
| 462 | snd_printd(KERN_ERR "frame %d active: %d\n", i, urb->iso_frame_desc[i].status); | ||
| 463 | // continue; | ||
| 464 | } | ||
| 465 | bytes = urb->iso_frame_desc[i].actual_length; | ||
| 466 | frames = bytes / stride; | ||
| 467 | if (!subs->txfr_quirk) | ||
| 468 | bytes = frames * stride; | ||
| 469 | if (bytes % (runtime->sample_bits >> 3) != 0) { | ||
| 470 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
| 471 | int oldbytes = bytes; | ||
| 472 | #endif | ||
| 473 | bytes = frames * stride; | ||
| 474 | snd_printdd(KERN_ERR "Corrected urb data len. %d->%d\n", | ||
| 475 | oldbytes, bytes); | ||
| 476 | } | ||
| 477 | /* update the current pointer */ | ||
| 478 | spin_lock_irqsave(&subs->lock, flags); | ||
| 479 | oldptr = subs->hwptr_done; | ||
| 480 | subs->hwptr_done += bytes; | ||
| 481 | if (subs->hwptr_done >= runtime->buffer_size * stride) | ||
| 482 | subs->hwptr_done -= runtime->buffer_size * stride; | ||
| 483 | frames = (bytes + (oldptr % stride)) / stride; | ||
| 484 | subs->transfer_done += frames; | ||
| 485 | if (subs->transfer_done >= runtime->period_size) { | ||
| 486 | subs->transfer_done -= runtime->period_size; | ||
| 487 | period_elapsed = 1; | ||
| 488 | } | ||
| 489 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 490 | /* copy a data chunk */ | ||
| 491 | if (oldptr + bytes > runtime->buffer_size * stride) { | ||
| 492 | unsigned int bytes1 = | ||
| 493 | runtime->buffer_size * stride - oldptr; | ||
| 494 | memcpy(runtime->dma_area + oldptr, cp, bytes1); | ||
| 495 | memcpy(runtime->dma_area, cp + bytes1, bytes - bytes1); | ||
| 496 | } else { | ||
| 497 | memcpy(runtime->dma_area + oldptr, cp, bytes); | ||
| 498 | } | ||
| 499 | } | ||
| 500 | if (period_elapsed) | ||
| 501 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 502 | return 0; | ||
| 503 | } | ||
| 504 | |||
| 505 | /* | ||
| 506 | * Process after capture complete when paused. Nothing to do. | ||
| 507 | */ | ||
| 508 | static int retire_paused_capture_urb(struct snd_usb_substream *subs, | ||
| 509 | struct snd_pcm_runtime *runtime, | ||
| 510 | struct urb *urb) | ||
| 511 | { | ||
| 512 | return 0; | ||
| 513 | } | ||
| 514 | |||
| 515 | |||
| 516 | /* | ||
| 517 | * prepare urb for playback sync pipe | ||
| 518 | * | ||
| 519 | * set up the offset and length to receive the current frequency. | ||
| 520 | */ | ||
| 521 | static int prepare_playback_sync_urb(struct snd_usb_substream *subs, | ||
| 522 | struct snd_pcm_runtime *runtime, | ||
| 523 | struct urb *urb) | ||
| 524 | { | ||
| 525 | struct snd_urb_ctx *ctx = urb->context; | ||
| 526 | |||
| 527 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 528 | urb->iso_frame_desc[0].length = min(4u, ctx->subs->syncmaxsize); | ||
| 529 | urb->iso_frame_desc[0].offset = 0; | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | |||
| 533 | /* | ||
| 534 | * process after playback sync complete | ||
| 535 | * | ||
| 536 | * Full speed devices report feedback values in 10.14 format as samples per | ||
| 537 | * frame, high speed devices in 16.16 format as samples per microframe. | ||
| 538 | * Because the Audio Class 1 spec was written before USB 2.0, many high speed | ||
| 539 | * devices use a wrong interpretation, some others use an entirely different | ||
| 540 | * format. Therefore, we cannot predict what format any particular device uses | ||
| 541 | * and must detect it automatically. | ||
| 542 | */ | ||
| 543 | static int retire_playback_sync_urb(struct snd_usb_substream *subs, | ||
| 544 | struct snd_pcm_runtime *runtime, | ||
| 545 | struct urb *urb) | ||
| 546 | { | ||
| 547 | unsigned int f; | ||
| 548 | int shift; | ||
| 549 | unsigned long flags; | ||
| 550 | |||
| 551 | if (urb->iso_frame_desc[0].status != 0 || | ||
| 552 | urb->iso_frame_desc[0].actual_length < 3) | ||
| 553 | return 0; | ||
| 554 | |||
| 555 | f = le32_to_cpup(urb->transfer_buffer); | ||
| 556 | if (urb->iso_frame_desc[0].actual_length == 3) | ||
| 557 | f &= 0x00ffffff; | ||
| 558 | else | ||
| 559 | f &= 0x0fffffff; | ||
| 560 | if (f == 0) | ||
| 561 | return 0; | ||
| 562 | |||
| 563 | if (unlikely(subs->freqshift == INT_MIN)) { | ||
| 564 | /* | ||
| 565 | * The first time we see a feedback value, determine its format | ||
| 566 | * by shifting it left or right until it matches the nominal | ||
| 567 | * frequency value. This assumes that the feedback does not | ||
| 568 | * differ from the nominal value more than +50% or -25%. | ||
| 569 | */ | ||
| 570 | shift = 0; | ||
| 571 | while (f < subs->freqn - subs->freqn / 4) { | ||
| 572 | f <<= 1; | ||
| 573 | shift++; | ||
| 574 | } | ||
| 575 | while (f > subs->freqn + subs->freqn / 2) { | ||
| 576 | f >>= 1; | ||
| 577 | shift--; | ||
| 578 | } | ||
| 579 | subs->freqshift = shift; | ||
| 580 | } | ||
| 581 | else if (subs->freqshift >= 0) | ||
| 582 | f <<= subs->freqshift; | ||
| 583 | else | ||
| 584 | f >>= -subs->freqshift; | ||
| 585 | |||
| 586 | if (likely(f >= subs->freqn - subs->freqn / 8 && f <= subs->freqmax)) { | ||
| 587 | /* | ||
| 588 | * If the frequency looks valid, set it. | ||
| 589 | * This value is referred to in prepare_playback_urb(). | ||
| 590 | */ | ||
| 591 | spin_lock_irqsave(&subs->lock, flags); | ||
| 592 | subs->freqm = f; | ||
| 593 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 594 | } else { | ||
| 595 | /* | ||
| 596 | * Out of range; maybe the shift value is wrong. | ||
| 597 | * Reset it so that we autodetect again the next time. | ||
| 598 | */ | ||
| 599 | subs->freqshift = INT_MIN; | ||
| 600 | } | ||
| 601 | |||
| 602 | return 0; | ||
| 603 | } | ||
| 604 | |||
| 605 | /* determine the number of frames in the next packet */ | ||
| 606 | static int snd_usb_audio_next_packet_size(struct snd_usb_substream *subs) | ||
| 607 | { | ||
| 608 | if (subs->fill_max) | ||
| 609 | return subs->maxframesize; | ||
| 610 | else { | ||
| 611 | subs->phase = (subs->phase & 0xffff) | ||
| 612 | + (subs->freqm << subs->datainterval); | ||
| 613 | return min(subs->phase >> 16, subs->maxframesize); | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | /* | ||
| 618 | * Prepare urb for streaming before playback starts or when paused. | ||
| 619 | * | ||
| 620 | * We don't have any data, so we send silence. | ||
| 621 | */ | ||
| 622 | static int prepare_nodata_playback_urb(struct snd_usb_substream *subs, | ||
| 623 | struct snd_pcm_runtime *runtime, | ||
| 624 | struct urb *urb) | ||
| 625 | { | ||
| 626 | unsigned int i, offs, counts; | ||
| 627 | struct snd_urb_ctx *ctx = urb->context; | ||
| 628 | int stride = runtime->frame_bits >> 3; | ||
| 629 | |||
| 630 | offs = 0; | ||
| 631 | urb->dev = ctx->subs->dev; | ||
| 632 | for (i = 0; i < ctx->packets; ++i) { | ||
| 633 | counts = snd_usb_audio_next_packet_size(subs); | ||
| 634 | urb->iso_frame_desc[i].offset = offs * stride; | ||
| 635 | urb->iso_frame_desc[i].length = counts * stride; | ||
| 636 | offs += counts; | ||
| 637 | } | ||
| 638 | urb->number_of_packets = ctx->packets; | ||
| 639 | urb->transfer_buffer_length = offs * stride; | ||
| 640 | memset(urb->transfer_buffer, | ||
| 641 | runtime->format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0, | ||
| 642 | offs * stride); | ||
| 643 | return 0; | ||
| 644 | } | ||
| 645 | |||
| 646 | /* | ||
| 647 | * prepare urb for playback data pipe | ||
| 648 | * | ||
| 649 | * Since a URB can handle only a single linear buffer, we must use double | ||
| 650 | * buffering when the data to be transferred overflows the buffer boundary. | ||
| 651 | * To avoid inconsistencies when updating hwptr_done, we use double buffering | ||
| 652 | * for all URBs. | ||
| 653 | */ | ||
| 654 | static int prepare_playback_urb(struct snd_usb_substream *subs, | ||
| 655 | struct snd_pcm_runtime *runtime, | ||
| 656 | struct urb *urb) | ||
| 657 | { | ||
| 658 | int i, stride; | ||
| 659 | unsigned int counts, frames, bytes; | ||
| 660 | unsigned long flags; | ||
| 661 | int period_elapsed = 0; | ||
| 662 | struct snd_urb_ctx *ctx = urb->context; | ||
| 663 | |||
| 664 | stride = runtime->frame_bits >> 3; | ||
| 665 | |||
| 666 | frames = 0; | ||
| 667 | urb->dev = ctx->subs->dev; /* we need to set this at each time */ | ||
| 668 | urb->number_of_packets = 0; | ||
| 669 | spin_lock_irqsave(&subs->lock, flags); | ||
| 670 | for (i = 0; i < ctx->packets; i++) { | ||
| 671 | counts = snd_usb_audio_next_packet_size(subs); | ||
| 672 | /* set up descriptor */ | ||
| 673 | urb->iso_frame_desc[i].offset = frames * stride; | ||
| 674 | urb->iso_frame_desc[i].length = counts * stride; | ||
| 675 | frames += counts; | ||
| 676 | urb->number_of_packets++; | ||
| 677 | subs->transfer_done += counts; | ||
| 678 | if (subs->transfer_done >= runtime->period_size) { | ||
| 679 | subs->transfer_done -= runtime->period_size; | ||
| 680 | period_elapsed = 1; | ||
| 681 | if (subs->fmt_type == UAC_FORMAT_TYPE_II) { | ||
| 682 | if (subs->transfer_done > 0) { | ||
| 683 | /* FIXME: fill-max mode is not | ||
| 684 | * supported yet */ | ||
| 685 | frames -= subs->transfer_done; | ||
| 686 | counts -= subs->transfer_done; | ||
| 687 | urb->iso_frame_desc[i].length = | ||
| 688 | counts * stride; | ||
| 689 | subs->transfer_done = 0; | ||
| 690 | } | ||
| 691 | i++; | ||
| 692 | if (i < ctx->packets) { | ||
| 693 | /* add a transfer delimiter */ | ||
| 694 | urb->iso_frame_desc[i].offset = | ||
| 695 | frames * stride; | ||
| 696 | urb->iso_frame_desc[i].length = 0; | ||
| 697 | urb->number_of_packets++; | ||
| 698 | } | ||
| 699 | break; | ||
| 700 | } | ||
| 701 | } | ||
| 702 | if (period_elapsed) /* finish at the period boundary */ | ||
| 703 | break; | ||
| 704 | } | ||
| 705 | bytes = frames * stride; | ||
| 706 | if (subs->hwptr_done + bytes > runtime->buffer_size * stride) { | ||
| 707 | /* err, the transferred area goes over buffer boundary. */ | ||
| 708 | unsigned int bytes1 = | ||
| 709 | runtime->buffer_size * stride - subs->hwptr_done; | ||
| 710 | memcpy(urb->transfer_buffer, | ||
| 711 | runtime->dma_area + subs->hwptr_done, bytes1); | ||
| 712 | memcpy(urb->transfer_buffer + bytes1, | ||
| 713 | runtime->dma_area, bytes - bytes1); | ||
| 714 | } else { | ||
| 715 | memcpy(urb->transfer_buffer, | ||
| 716 | runtime->dma_area + subs->hwptr_done, bytes); | ||
| 717 | } | ||
| 718 | subs->hwptr_done += bytes; | ||
| 719 | if (subs->hwptr_done >= runtime->buffer_size * stride) | ||
| 720 | subs->hwptr_done -= runtime->buffer_size * stride; | ||
| 721 | runtime->delay += frames; | ||
| 722 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 723 | urb->transfer_buffer_length = bytes; | ||
| 724 | if (period_elapsed) | ||
| 725 | snd_pcm_period_elapsed(subs->pcm_substream); | ||
| 726 | return 0; | ||
| 727 | } | ||
| 728 | |||
| 729 | /* | ||
| 730 | * process after playback data complete | ||
| 731 | * - decrease the delay count again | ||
| 732 | */ | ||
| 733 | static int retire_playback_urb(struct snd_usb_substream *subs, | ||
| 734 | struct snd_pcm_runtime *runtime, | ||
| 735 | struct urb *urb) | ||
| 736 | { | ||
| 737 | unsigned long flags; | ||
| 738 | int stride = runtime->frame_bits >> 3; | ||
| 739 | int processed = urb->transfer_buffer_length / stride; | ||
| 740 | |||
| 741 | spin_lock_irqsave(&subs->lock, flags); | ||
| 742 | if (processed > runtime->delay) | ||
| 743 | runtime->delay = 0; | ||
| 744 | else | ||
| 745 | runtime->delay -= processed; | ||
| 746 | spin_unlock_irqrestore(&subs->lock, flags); | ||
| 747 | return 0; | ||
| 748 | } | ||
| 749 | |||
| 750 | static const char *usb_error_string(int err) | ||
| 751 | { | ||
| 752 | switch (err) { | ||
| 753 | case -ENODEV: | ||
| 754 | return "no device"; | ||
| 755 | case -ENOENT: | ||
| 756 | return "endpoint not enabled"; | ||
| 757 | case -EPIPE: | ||
| 758 | return "endpoint stalled"; | ||
| 759 | case -ENOSPC: | ||
| 760 | return "not enough bandwidth"; | ||
| 761 | case -ESHUTDOWN: | ||
| 762 | return "device disabled"; | ||
| 763 | case -EHOSTUNREACH: | ||
| 764 | return "device suspended"; | ||
| 765 | case -EINVAL: | ||
| 766 | case -EAGAIN: | ||
| 767 | case -EFBIG: | ||
| 768 | case -EMSGSIZE: | ||
| 769 | return "internal error"; | ||
| 770 | default: | ||
| 771 | return "unknown error"; | ||
| 772 | } | ||
| 773 | } | ||
| 774 | |||
| 775 | /* | ||
| 776 | * set up and start data/sync urbs | ||
| 777 | */ | ||
| 778 | static int start_urbs(struct snd_usb_substream *subs, struct snd_pcm_runtime *runtime) | ||
| 779 | { | ||
| 780 | unsigned int i; | ||
| 781 | int err; | ||
| 782 | |||
| 783 | if (subs->stream->chip->shutdown) | ||
| 784 | return -EBADFD; | ||
| 785 | |||
| 786 | for (i = 0; i < subs->nurbs; i++) { | ||
| 787 | if (snd_BUG_ON(!subs->dataurb[i].urb)) | ||
| 788 | return -EINVAL; | ||
| 789 | if (subs->ops.prepare(subs, runtime, subs->dataurb[i].urb) < 0) { | ||
| 790 | snd_printk(KERN_ERR "cannot prepare datapipe for urb %d\n", i); | ||
| 791 | goto __error; | ||
| 792 | } | ||
| 793 | } | ||
| 794 | if (subs->syncpipe) { | ||
| 795 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 796 | if (snd_BUG_ON(!subs->syncurb[i].urb)) | ||
| 797 | return -EINVAL; | ||
| 798 | if (subs->ops.prepare_sync(subs, runtime, subs->syncurb[i].urb) < 0) { | ||
| 799 | snd_printk(KERN_ERR "cannot prepare syncpipe for urb %d\n", i); | ||
| 800 | goto __error; | ||
| 801 | } | ||
| 802 | } | ||
| 803 | } | ||
| 804 | |||
| 805 | subs->active_mask = 0; | ||
| 806 | subs->unlink_mask = 0; | ||
| 807 | subs->running = 1; | ||
| 808 | for (i = 0; i < subs->nurbs; i++) { | ||
| 809 | err = usb_submit_urb(subs->dataurb[i].urb, GFP_ATOMIC); | ||
| 810 | if (err < 0) { | ||
| 811 | snd_printk(KERN_ERR "cannot submit datapipe " | ||
| 812 | "for urb %d, error %d: %s\n", | ||
| 813 | i, err, usb_error_string(err)); | ||
| 814 | goto __error; | ||
| 815 | } | ||
| 816 | set_bit(i, &subs->active_mask); | ||
| 817 | } | ||
| 818 | if (subs->syncpipe) { | ||
| 819 | for (i = 0; i < SYNC_URBS; i++) { | ||
| 820 | err = usb_submit_urb(subs->syncurb[i].urb, GFP_ATOMIC); | ||
| 821 | if (err < 0) { | ||
| 822 | snd_printk(KERN_ERR "cannot submit syncpipe " | ||
| 823 | "for urb %d, error %d: %s\n", | ||
| 824 | i, err, usb_error_string(err)); | ||
| 825 | goto __error; | ||
| 826 | } | ||
| 827 | set_bit(i + 16, &subs->active_mask); | ||
| 828 | } | ||
| 829 | } | ||
| 830 | return 0; | ||
| 831 | |||
| 832 | __error: | ||
| 833 | // snd_pcm_stop(subs->pcm_substream, SNDRV_PCM_STATE_XRUN); | ||
| 834 | deactivate_urbs(subs, 0, 0); | ||
| 835 | return -EPIPE; | ||
| 836 | } | ||
| 837 | |||
| 838 | |||
| 839 | /* | ||
| 840 | */ | ||
| 841 | static struct snd_urb_ops audio_urb_ops[2] = { | ||
| 842 | { | ||
| 843 | .prepare = prepare_nodata_playback_urb, | ||
| 844 | .retire = retire_playback_urb, | ||
| 845 | .prepare_sync = prepare_playback_sync_urb, | ||
| 846 | .retire_sync = retire_playback_sync_urb, | ||
| 847 | }, | ||
| 848 | { | ||
| 849 | .prepare = prepare_capture_urb, | ||
| 850 | .retire = retire_capture_urb, | ||
| 851 | .prepare_sync = prepare_capture_sync_urb, | ||
| 852 | .retire_sync = retire_capture_sync_urb, | ||
| 853 | }, | ||
| 854 | }; | ||
| 855 | |||
| 856 | /* | ||
| 857 | * initialize the substream instance. | ||
| 858 | */ | ||
| 859 | |||
| 860 | void snd_usb_init_substream(struct snd_usb_stream *as, | ||
| 861 | int stream, struct audioformat *fp) | ||
| 862 | { | ||
| 863 | struct snd_usb_substream *subs = &as->substream[stream]; | ||
| 864 | |||
| 865 | INIT_LIST_HEAD(&subs->fmt_list); | ||
| 866 | spin_lock_init(&subs->lock); | ||
| 867 | |||
| 868 | subs->stream = as; | ||
| 869 | subs->direction = stream; | ||
| 870 | subs->dev = as->chip->dev; | ||
| 871 | subs->txfr_quirk = as->chip->txfr_quirk; | ||
| 872 | subs->ops = audio_urb_ops[stream]; | ||
| 873 | if (snd_usb_get_speed(subs->dev) >= USB_SPEED_HIGH) | ||
| 874 | subs->ops.prepare_sync = prepare_capture_sync_urb_hs; | ||
| 875 | |||
| 876 | snd_usb_set_pcm_ops(as->pcm, stream); | ||
| 877 | |||
| 878 | list_add_tail(&fp->list, &subs->fmt_list); | ||
| 879 | subs->formats |= fp->formats; | ||
| 880 | subs->endpoint = fp->endpoint; | ||
| 881 | subs->num_formats++; | ||
| 882 | subs->fmt_type = fp->fmt_type; | ||
| 883 | } | ||
| 884 | |||
| 885 | int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd) | ||
| 886 | { | ||
| 887 | struct snd_usb_substream *subs = substream->runtime->private_data; | ||
| 888 | |||
| 889 | switch (cmd) { | ||
| 890 | case SNDRV_PCM_TRIGGER_START: | ||
| 891 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 892 | subs->ops.prepare = prepare_playback_urb; | ||
| 893 | return 0; | ||
| 894 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 895 | return deactivate_urbs(subs, 0, 0); | ||
| 896 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 897 | subs->ops.prepare = prepare_nodata_playback_urb; | ||
| 898 | return 0; | ||
| 899 | } | ||
| 900 | |||
| 901 | return -EINVAL; | ||
| 902 | } | ||
| 903 | |||
| 904 | int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd) | ||
| 905 | { | ||
| 906 | struct snd_usb_substream *subs = substream->runtime->private_data; | ||
| 907 | |||
| 908 | switch (cmd) { | ||
| 909 | case SNDRV_PCM_TRIGGER_START: | ||
| 910 | subs->ops.retire = retire_capture_urb; | ||
| 911 | return start_urbs(subs, substream->runtime); | ||
| 912 | case SNDRV_PCM_TRIGGER_STOP: | ||
| 913 | return deactivate_urbs(subs, 0, 0); | ||
| 914 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
| 915 | subs->ops.retire = retire_paused_capture_urb; | ||
| 916 | return 0; | ||
| 917 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
| 918 | subs->ops.retire = retire_capture_urb; | ||
| 919 | return 0; | ||
| 920 | } | ||
| 921 | |||
| 922 | return -EINVAL; | ||
| 923 | } | ||
| 924 | |||
| 925 | int snd_usb_substream_prepare(struct snd_usb_substream *subs, | ||
| 926 | struct snd_pcm_runtime *runtime) | ||
| 927 | { | ||
| 928 | /* clear urbs (to be sure) */ | ||
| 929 | deactivate_urbs(subs, 0, 1); | ||
| 930 | wait_clear_urbs(subs); | ||
| 931 | |||
| 932 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | ||
| 933 | * updates for all URBs would happen at the same time when starting */ | ||
| 934 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) { | ||
| 935 | subs->ops.prepare = prepare_nodata_playback_urb; | ||
| 936 | return start_urbs(subs, runtime); | ||
| 937 | } | ||
| 938 | |||
| 939 | return 0; | ||
| 940 | } | ||
| 941 | |||
diff --git a/sound/usb/urb.h b/sound/usb/urb.h deleted file mode 100644 index 888da38079cf..000000000000 --- a/sound/usb/urb.h +++ /dev/null | |||
| @@ -1,21 +0,0 @@ | |||
| 1 | #ifndef __USBAUDIO_URB_H | ||
| 2 | #define __USBAUDIO_URB_H | ||
| 3 | |||
| 4 | void snd_usb_init_substream(struct snd_usb_stream *as, | ||
| 5 | int stream, | ||
| 6 | struct audioformat *fp); | ||
| 7 | |||
| 8 | int snd_usb_init_substream_urbs(struct snd_usb_substream *subs, | ||
| 9 | unsigned int period_bytes, | ||
| 10 | unsigned int rate, | ||
| 11 | unsigned int frame_bits); | ||
| 12 | |||
| 13 | void snd_usb_release_substream_urbs(struct snd_usb_substream *subs, int force); | ||
| 14 | |||
| 15 | int snd_usb_substream_prepare(struct snd_usb_substream *subs, | ||
| 16 | struct snd_pcm_runtime *runtime); | ||
| 17 | |||
| 18 | int snd_usb_substream_playback_trigger(struct snd_pcm_substream *substream, int cmd); | ||
| 19 | int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream, int cmd); | ||
| 20 | |||
| 21 | #endif /* __USBAUDIO_URB_H */ | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 1e79986b5777..3e2b03577936 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
| @@ -80,6 +80,7 @@ enum quirk_type { | |||
| 80 | QUIRK_MIDI_CME, | 80 | QUIRK_MIDI_CME, |
| 81 | QUIRK_MIDI_AKAI, | 81 | QUIRK_MIDI_AKAI, |
| 82 | QUIRK_MIDI_US122L, | 82 | QUIRK_MIDI_US122L, |
| 83 | QUIRK_MIDI_FTDI, | ||
| 83 | QUIRK_AUDIO_STANDARD_INTERFACE, | 84 | QUIRK_AUDIO_STANDARD_INTERFACE, |
| 84 | QUIRK_AUDIO_FIXED_ENDPOINT, | 85 | QUIRK_AUDIO_FIXED_ENDPOINT, |
| 85 | QUIRK_AUDIO_EDIROL_UAXX, | 86 | QUIRK_AUDIO_EDIROL_UAXX, |
