[PATCH 1/2] ALSA: hda/ca0132 - Add 8051 PLL write helper functions.

2020-12-11 Thread Connor McAdams
Add helper functions for the 8051 PLL PMU write verbs.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 130 ++-
 1 file changed, 50 insertions(+), 80 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index e9019e840a4d..9b6b7601a881 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1949,6 +1949,14 @@ static unsigned int chipio_8051_get_data(struct 
hda_codec *codec)
   VENDOR_CHIPIO_8051_DATA_READ, 0);
 }
 
+/* PLL_PMU writes share the lower address register of the 8051 exram writes. */
+static void chipio_8051_set_data_pll(struct hda_codec *codec, unsigned int 
data)
+{
+   /* 8-bits of data. */
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, data & 0xff);
+}
+
 static void chipio_8051_write_exram(struct hda_codec *codec,
unsigned int addr, unsigned int data)
 {
@@ -1977,6 +1985,26 @@ static void chipio_8051_read_exram(struct hda_codec 
*codec,
*data = chipio_8051_get_data(codec);
 }
 
+static void chipio_8051_write_pll_pmu(struct hda_codec *codec,
+   unsigned int addr, unsigned int data)
+{
+   struct ca0132_spec *spec = codec->spec;
+
+   mutex_lock(>chipio_mutex);
+
+   chipio_8051_set_address(codec, addr & 0xff);
+   chipio_8051_set_data_pll(codec, data);
+
+   mutex_unlock(>chipio_mutex);
+}
+
+static void chipio_8051_write_pll_pmu_no_mutex(struct hda_codec *codec,
+   unsigned int addr, unsigned int data)
+{
+   chipio_8051_set_address(codec, addr & 0xff);
+   chipio_8051_set_data_pll(codec, data);
+}
+
 /*
  * Enable clocks.
  */
@@ -1985,18 +2013,11 @@ static void chipio_enable_clocks(struct hda_codec 
*codec)
struct ca0132_spec *spec = codec->spec;
 
mutex_lock(>chipio_mutex);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xff);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 5);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0x0b);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 6);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xff);
+
+   chipio_8051_write_pll_pmu_no_mutex(codec, 0x00, 0xff);
+   chipio_8051_write_pll_pmu_no_mutex(codec, 0x05, 0x0b);
+   chipio_8051_write_pll_pmu_no_mutex(codec, 0x06, 0xff);
+
mutex_unlock(>chipio_mutex);
 }
 
@@ -7904,10 +7925,7 @@ static void ae5_post_dsp_register_set(struct hda_codec 
*codec)
struct ca0132_spec *spec = codec->spec;
 
chipio_8051_write_direct(codec, 0x93, 0x10);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x44);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
+   chipio_8051_write_pll_pmu(codec, 0x44, 0xc2);
 
writeb(0xff, spec->mem_base + 0x304);
writeb(0xff, spec->mem_base + 0x304);
@@ -7949,30 +7967,11 @@ static void ae5_post_dsp_param_setup(struct hda_codec 
*codec)
 
 static void ae5_post_dsp_pll_setup(struct hda_codec *codec)
 {
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x41);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc8);
-
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x45);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xcc);
-
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x40);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xcb);
-
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
-
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x51);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_PLL_PMU_WRITE, 0x8d);
+   chipio_8051_write_pll_pmu(codec, 0x41, 0xc8);
+   chipio_8051_write_pll_pmu(codec, 0x45, 0xcc);
+   chip

[PATCH 2/2] ALSA: hda/ca0132 - Add ZxR surround DAC setup.

2020-12-11 Thread Connor McAdams
Add pre-dsp download initialization for the DAC's used in the surround
sound configuration. Fixes issues of no audio on surround channels.

Fixes: 2e492b8ee5da8 ("ALSA: hda/ca0132 - Add ZxR init commands")
Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 40 
 1 file changed, 40 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9b6b7601a881..7e62aed172a9 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -9186,6 +9186,44 @@ static void r3di_pre_dsp_setup(struct hda_codec *codec)
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x04);
 }
 
+/*
+ * The ZxR seems to use alternative DAC's for the surround channels, which
+ * require PLL PMU setup for the clock rate, I'm guessing. Without setting
+ * this up, we get no audio out of the surround jacks.
+ */
+static void zxr_pre_dsp_setup(struct hda_codec *codec)
+{
+   static const unsigned int addr[] = { 0x43, 0x40, 0x41, 0x42, 0x45 };
+   static const unsigned int data[] = { 0x08, 0x0c, 0x0b, 0x07, 0x0d };
+   unsigned int i;
+
+   chipio_write(codec, 0x189000, 0x0001f100);
+   msleep(50);
+   chipio_write(codec, 0x18900c, 0x0001f100);
+   msleep(50);
+
+   /*
+* This writes a RET instruction at the entry point of the function at
+* 0xfa92 in exram. This function seems to have something to do with
+* ASI. Might be some way to prevent the card from reconfiguring the
+* ASI stuff itself.
+*/
+   chipio_8051_write_exram(codec, 0xfa92, 0x22);
+
+   chipio_8051_write_pll_pmu(codec, 0x51, 0x98);
+
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x82);
+   chipio_set_control_param(codec, CONTROL_PARAM_ASI, 3);
+
+   chipio_write(codec, 0x18902c, 0x);
+   msleep(50);
+   chipio_write(codec, 0x18902c, 0x0003);
+   msleep(50);
+
+   for (i = 0; i < ARRAY_SIZE(addr); i++)
+   chipio_8051_write_pll_pmu(codec, addr[i], data[i]);
+}
+
 /*
  * These are sent before the DSP is downloaded. Not sure
  * what they do, or if they're necessary. Could possibly
@@ -9447,8 +9485,10 @@ static void ca0132_alt_init(struct hda_codec *codec)
ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
break;
case QUIRK_ZXR:
+   chipio_8051_write_pll_pmu(codec, 0x49, 0x88);
snd_hda_sequence_write(codec, spec->chip_init_verbs);
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
+   zxr_pre_dsp_setup(codec);
break;
default:
break;
-- 
2.25.1



[PATCH v3 2/2] ALSA: hda/ca0132 - Change Input Source enum strings.

2020-12-10 Thread Connor McAdams
Change the Input Source enumerated control's strings to make it play
nice with pulseaudio.

Fixes: 7cb9d94c05de9 ("ALSA: hda/ca0132: add alt_select_in/out for R3Di + SBZ")
Cc: 
Signed-off-by: Connor McAdams 
Link: https://lore.kernel.org/r/20201208195223.424753-2-conmanx...@gmail.com
Signed-off-by: Takashi Iwai 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index e96db73c32f5..793dc5d501a5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -95,7 +95,7 @@ enum {
 };
 
 /* Strings for Input Source Enum Control */
-static const char *const in_src_str[3] = {"Rear Mic", "Line", "Front Mic" };
+static const char *const in_src_str[3] = { "Microphone", "Line In", "Front 
Microphone" };
 #define IN_SRC_NUM_OF_INPUTS 3
 enum {
REAR_MIC,
-- 
2.25.1



[PATCH v3 1/2] ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg.

2020-12-10 Thread Connor McAdams
The Windows driver sets the pincfg for the AE-5's rear-headphone to
report as a microphone. This causes issues with Pulseaudio mistakenly
believing there is no headphone plugged in. In Linux, we should instead
set it to be a headphone.

Fixes: a6b0961b39896 ("ALSA: hda/ca0132 - fix AE-5 pincfg")
Cc: 
Signed-off-by: Connor McAdams 
Link: https://lore.kernel.org/r/20201208195223.424753-1-conmanx...@gmail.com
Signed-off-by: Takashi Iwai 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4fbec4258f58..e96db73c32f5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1223,7 +1223,7 @@ static const struct hda_pintbl ae5_pincfgs[] = {
{ 0x0e, 0x01c510f0 }, /* SPDIF In */
{ 0x0f, 0x01017114 }, /* Port A -- Rear L/R. */
{ 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */
-   { 0x11, 0x01a170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
+   { 0x11, 0x012170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
{ 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */
{ 0x13, 0x908700f0 }, /* What U Hear In*/
{ 0x18, 0x50d000f0 }, /* N/A */
-- 
2.25.1



Re: [PATCH v2 3/3] ALSA: hda/ca0132 - Unmute surround when speaker output is selected.

2020-12-10 Thread Connor McAdams
Will do. Sorry about that.

On Thu, Dec 10, 2020 at 12:22 PM Takashi Iwai  wrote:
>
> On Thu, 10 Dec 2020 18:16:00 +0100,
> Connor McAdams wrote:
> >
> > Woops, sent previous email on the first version of this patch.
> >
> > This patch is a mistake. Not sure why I did this.
>
> OK, then could you resubmit v3?  Now I reverted the v2 patches.
>
>
> Takashi


Re: [PATCH v2 3/3] ALSA: hda/ca0132 - Unmute surround when speaker output is selected.

2020-12-10 Thread Connor McAdams
Woops, sent previous email on the first version of this patch.

This patch is a mistake. Not sure why I did this.

On Tue, Dec 8, 2020 at 2:52 PM Connor McAdams  wrote:
>
> Make sure GPIO pin for surround channel mute is set to 0 when speaker
> output is selected.
>
> Fixes: def3f0a5c7007 ("ALSA: hda/ca0132 - Add quirk output selection 
> structures.")
> Cc: 
> Signed-off-by: Connor McAdams 
> ---
>  sound/pci/hda/patch_ca0132.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
> index 793dc5d501a5..6d647d461eab 100644
> --- a/sound/pci/hda/patch_ca0132.c
> +++ b/sound/pci/hda/patch_ca0132.c
> @@ -1390,7 +1390,7 @@ static const struct ca0132_alt_out_set_quirk_data 
> quirk_out_set_data[] = {
>   .has_hda_gpio = false,
>   .mmio_gpio_count  = 3,
>   .mmio_gpio_pin= { 2, 3, 5 },
> - .mmio_gpio_set= { 1, 1, 0 },
> + .mmio_gpio_set= { 1, 0, 0 },
>   .scp_cmds_count   = 0,
>   .has_chipio_write = false,
> },
> --
> 2.25.1
>


Re: [PATCH 3/3] ALSA: hda/ca0132 - Unmute surround when speaker output is selected.

2020-12-10 Thread Connor McAdams
Apologies, this patch seems to be a mistake.

I don't know why I thought this was the case.

On Mon, Dec 7, 2020 at 3:46 AM Connor McAdams  wrote:
>
> Make sure GPIO pin for surround channel mute is set to 0 when speaker
> output is selected.
>
> Signed-off-by: Connor McAdams 
> ---
>  sound/pci/hda/patch_ca0132.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
> index 793dc5d501a5..6d647d461eab 100644
> --- a/sound/pci/hda/patch_ca0132.c
> +++ b/sound/pci/hda/patch_ca0132.c
> @@ -1390,7 +1390,7 @@ static const struct ca0132_alt_out_set_quirk_data 
> quirk_out_set_data[] = {
>   .has_hda_gpio = false,
>   .mmio_gpio_count  = 3,
>   .mmio_gpio_pin= { 2, 3, 5 },
> - .mmio_gpio_set= { 1, 1, 0 },
> + .mmio_gpio_set= { 1, 0, 0 },
>   .scp_cmds_count   = 0,
>   .has_chipio_write = false,
> },
> --
> 2.25.1
>


[PATCH v2 5/5] ALSA: hda/ca0132 - Remove now unnecessary DSP setup functions.

2020-12-10 Thread Connor McAdams
Now that the DSP's audio configuration is understood, remove previous
hacky methods of trying to properly configure it.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 105 ---
 1 file changed, 105 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 8884ad0910cd..df8bee4eef26 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -2426,13 +2426,6 @@ static int dspio_set_uint_param(struct hda_codec *codec, 
int mod_id,
sizeof(unsigned int));
 }
 
-static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id,
-   int req, const unsigned int data)
-{
-   return dspio_set_param(codec, mod_id, 0x00, req, ,
-   sizeof(unsigned int));
-}
-
 /*
  * Allocate a DSP DMA channel via an SCP message
  */
@@ -7780,24 +7773,6 @@ static void ca0132_alt_init_speaker_tuning(struct 
hda_codec *codec)
SPEAKER_TUNING_FRONT_LEFT_DELAY + i, values[i]);
 }
 
-/*
- * Creates a dummy stream to bind the output to. This seems to have to be done
- * after changing the main outputs source and destination streams.
- */
-static void ca0132_alt_create_dummy_stream(struct hda_codec *codec)
-{
-   struct ca0132_spec *spec = codec->spec;
-   unsigned int stream_format;
-
-   stream_format = snd_hdac_calc_stream_format(48000, 2,
-   SNDRV_PCM_FORMAT_S32_LE, 32, 0);
-
-   snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id,
-   0, stream_format);
-
-   snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
-}
-
 /*
  * Initialize mic for non-chromebook ca0132 implementations.
  */
@@ -7839,9 +7814,6 @@ static void sbz_connect_streams(struct hda_codec *codec)
 
codec_dbg(codec, "Connect Streams entered, mutex locked and loaded.\n");
 
-   chipio_set_stream_channels(codec, 0x0C, 6);
-   chipio_set_stream_control(codec, 0x0C, 1);
-
/* This value is 0x43 for 96khz, and 0x83 for 192khz. */
chipio_write_no_mutex(codec, 0x18a020, 0x0043);
 
@@ -7889,9 +7861,6 @@ static void sbz_chipio_startup_data(struct hda_codec 
*codec)
break;
}
 
-   chipio_set_stream_channels(codec, 0x0c, 6);
-   chipio_set_stream_control(codec, 0x0c, 1);
-
if (dsp_out_remap_data)
chipio_remap_stream(codec, dsp_out_remap_data);
 
@@ -7899,57 +7868,6 @@ static void sbz_chipio_startup_data(struct hda_codec 
*codec)
mutex_unlock(>chipio_mutex);
 }
 
-/*
- * Custom DSP SCP commands where the src value is 0x00 instead of 0x20. This is
- * done after the DSP is loaded.
- */
-static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
-{
-   struct ca0132_spec *spec = codec->spec;
-   unsigned int tmp, i;
-
-   /*
-* Gotta run these twice, or else mic works inconsistently. Not clear
-* why this is, but multiple tests have confirmed it.
-*/
-   for (i = 0; i < 2; i++) {
-   switch (ca0132_quirk(spec)) {
-   case QUIRK_SBZ:
-   case QUIRK_AE5:
-   case QUIRK_AE7:
-   tmp = 0x0003;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
-   case QUIRK_R3D:
-   case QUIRK_R3DI:
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
-   default:
-   break;
-   }
-   msleep(100);
-   }
-}
-
 static void ca0132_alt_dsp_initial_mic_setup(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;

[PATCH v2 1/5] ALSA: hda/ca0132 - Reset codec upon initialization.

2020-12-10 Thread Connor McAdams
Reset the codec upon initialization to clear out anything that may have
been setup on a previous boot into Windows, or in case of an improper
shutdown.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 6d647d461eab..7ce4a966b733 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8642,6 +8642,22 @@ static void ca0132_init_chip(struct hda_codec *codec)
 
mutex_init(>chipio_mutex);
 
+   /*
+* The Windows driver always does this upon startup, which seems to
+* clear out any previous configuration. This should help issues where
+* a boot into Windows prior to a boot into Linux breaks things. Also,
+* Windows always sends the reset twice.
+*/
+   if (ca0132_use_alt_functions(spec)) {
+   chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
+   chipio_write_no_mutex(codec, 0x18b0a4, 0x00c2);
+
+   snd_hda_codec_write(codec, codec->core.afg, 0,
+   AC_VERB_SET_CODEC_RESET, 0);
+   snd_hda_codec_write(codec, codec->core.afg, 0,
+   AC_VERB_SET_CODEC_RESET, 0);
+   }
+
spec->cur_out_type = SPEAKER_OUT;
if (!ca0132_use_alt_functions(spec))
spec->cur_mic_type = DIGITAL_MIC;
@@ -9262,11 +9278,6 @@ static void ae5_register_set(struct hda_codec *codec)
 
if (ca0132_quirk(spec) == QUIRK_AE5)
ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
-
-   chipio_write(codec, 0x18b0a4, 0x00c2);
-
-   snd_hda_codec_write(codec, 0x01, 0, 0x7ff, 0x00);
-   snd_hda_codec_write(codec, 0x01, 0, 0x7ff, 0x00);
 }
 
 /*
-- 
2.25.1



[PATCH v2 4/5] ALSA: hda/ca0132 - Ensure DSP is properly setup post-firmware download.

2020-12-10 Thread Connor McAdams
Make sure that the DSP has no DMA channels allocated once the firmware
is downloaded, and that the default audio streams in use by the DSP are
setup in the correct order.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 119 +++
 1 file changed, 119 insertions(+)

v2 changes:
-Remove conditional mutex.

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index f84815cc8d2f..8884ad0910cd 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1863,6 +1863,18 @@ static void chipio_set_stream_control(struct hda_codec 
*codec,
CONTROL_PARAM_STREAM_CONTROL, enable);
 }
 
+/*
+ * Get ChipIO audio stream's status.
+ */
+static void chipio_get_stream_control(struct hda_codec *codec,
+   int streamid, unsigned int *enable)
+{
+   chipio_set_control_param_no_mutex(codec,
+   CONTROL_PARAM_STREAM_ID, streamid);
+   *enable = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
+  VENDOR_CHIPIO_PARAM_GET,
+  CONTROL_PARAM_STREAM_CONTROL);
+}
 
 /*
  * Set sampling rate of the connection point. NO MUTEX.
@@ -7513,6 +7525,109 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
}
 }
 
+
+/* If there is an active channel for some reason, find it and free it. */
+static void ca0132_alt_free_active_dma_channels(struct hda_codec *codec)
+{
+   unsigned int i, tmp;
+   int status;
+
+   /* Read active DSPDMAC channel register. */
+   status = chipio_read(codec, DSPDMAC_CHNLSTART_MODULE_OFFSET, );
+   if (status >= 0) {
+   /* AND against 0xfff to get the active channel bits. */
+   tmp = tmp & 0xfff;
+
+   /* If there are no active channels, nothing to free. */
+   if (!tmp)
+   return;
+   } else {
+   codec_dbg(codec, "%s: Failed to read active DSP DMA channel 
register.\n",
+   __func__);
+   return;
+   }
+
+   /*
+* Check each DSP DMA channel for activity, and if the channel is
+* active, free it.
+*/
+   for (i = 0; i < DSPDMAC_DMA_CFG_CHANNEL_COUNT; i++) {
+   if (dsp_is_dma_active(codec, i)) {
+   status = dspio_free_dma_chan(codec, i);
+   if (status < 0)
+   codec_dbg(codec, "%s: Failed to free active DSP 
DMA channel %d.\n",
+   __func__, i);
+   }
+   }
+}
+
+/*
+ * In the case of CT_EXTENSIONS_ENABLE being set to 1, and the DSP being in
+ * use, audio is no longer routed directly to the DAC/ADC from the HDA stream.
+ * Instead, audio is now routed through the DSP's DMA controllers, which
+ * the DSP is tasked with setting up itself. Through debugging, it seems the
+ * cause of most of the no-audio on startup issues were due to improperly
+ * configured DSP DMA channels.
+ *
+ * Normally, the DSP configures these the first time an HDA audio stream is
+ * started post DSP firmware download. That is why creating a 'dummy' stream
+ * worked in fixing the audio in some cases. This works most of the time, but
+ * sometimes if a stream is started/stopped before the DSP can setup the DMA
+ * configuration registers, it ends up in a broken state. Issues can also
+ * arise if streams are started in an unusual order, i.e the audio output dma
+ * channel being sandwiched between the mic1 and mic2 dma channels.
+ *
+ * The solution to this is to make sure that the DSP has no DMA channels
+ * in use post DSP firmware download, and then to manually start each default
+ * DSP stream that uses the DMA channels. These are 0x0c, the audio output
+ * stream, 0x03, analog mic 1, and 0x04, analog mic 2.
+ */
+static void ca0132_alt_start_dsp_audio_streams(struct hda_codec *codec)
+{
+   const unsigned int dsp_dma_stream_ids[] = { 0x0c, 0x03, 0x04 };
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int i, tmp;
+
+   /*
+* Check if any of the default streams are active, and if they are,
+* stop them.
+*/
+   mutex_lock(>chipio_mutex);
+
+   for (i = 0; i < ARRAY_SIZE(dsp_dma_stream_ids); i++) {
+   chipio_get_stream_control(codec, dsp_dma_stream_ids[i], );
+
+   if (tmp) {
+   chipio_set_stream_control(codec,
+   dsp_dma_stream_ids[i], 0);
+   }
+   }
+
+   mutex_unlock(>chipio_mutex);
+
+   /*
+* If all DSP streams are inactive, there should be no active DSP DMA
+* channels. Check and make sure this is the case, and if it isn't,
+* free any active channels.
+*/
+   ca0132_alt_free_active_dma_channels(codec);
+
+   mutex_lock(>chipio_m

[PATCH v2 2/5] ALSA: hda/ca0132 - Add stream port remapping function.

2020-12-10 Thread Connor McAdams
Add function for remapping a ChipIO stream's ports. Also include some
documentation as to how this works.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 208 ++-
 1 file changed, 156 insertions(+), 52 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 7ce4a966b733..8d2f12f2ce3f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -788,6 +788,40 @@ static const struct ae5_filter_set ae5_filter_presets[] = {
}
 };
 
+/*
+ * Data structures for storing audio router remapping data. These are used to
+ * remap a currently active streams ports.
+ */
+struct chipio_stream_remap_data {
+   unsigned int stream_id;
+   unsigned int count;
+
+   unsigned int offset[16];
+   unsigned int value[16];
+};
+
+static const struct chipio_stream_remap_data stream_remap_data[] = {
+   { .stream_id = 0x14,
+ .count = 0x04,
+ .offset= { 0x00, 0x04, 0x08, 0x0c },
+ .value = { 0x0001f8c0, 0x0001f9c1, 0x0001fac6, 0x0001fbc7 },
+   },
+   { .stream_id = 0x0c,
+ .count = 0x0c,
+ .offset= { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
+0x20, 0x24, 0x28, 0x2c },
+ .value = { 0x0001e0c0, 0x0001e1c1, 0x0001e4c2, 0x0001e5c3,
+0x0001e2c4, 0x0001e3c5, 0x0001e8c6, 0x0001e9c7,
+0x0001ecc8, 0x0001edc9, 0x0001eaca, 0x0001ebcb },
+   },
+   { .stream_id = 0x0c,
+ .count = 0x08,
+ .offset= { 0x08, 0x0c, 0x10, 0x14, 0x20, 0x24, 0x28, 0x2c },
+ .value = { 0x000140c2, 0x000141c3, 0x000150c4, 0x000151c5,
+0x000142c8, 0x000143c9, 0x000152ca, 0x000153cb },
+   }
+};
+
 enum hda_cmd_vendor_io {
/* for DspIO node */
VENDOR_DSPIO_SCP_WRITE_DATA_LOW  = 0x000,
@@ -7423,6 +7457,104 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
}
 }
 
+/*
+ * The region of ChipIO memory from 0x19-0x1903fc is a sort of 'audio
+ * router', where each entry represents a 48khz audio channel, with a format
+ * of an 8-bit destination, an 8-bit source, and an unknown 2-bit number
+ * value. The 2-bit number value is seemingly 0 if inactive, 1 if active,
+ * and 3 if it's using Sample Rate Converter ports.
+ * An example is:
+ * 0x0001f8c0
+ * In this case, f8 is the destination, and c0 is the source. The number value
+ * is 1.
+ * This region of memory is normally managed internally by the 8051, where
+ * the region of exram memory from 0x1477-0x1575 has each byte represent an
+ * entry within the 0x19 range, and when a range of entries is in use, the
+ * ending value is overwritten with 0xff.
+ * 0x1578 in exram is a table of 0x25 entries, corresponding to the ChipIO
+ * streamID's, where each entry is a starting 0x19 port offset.
+ * 0x159d in exram is the same as 0x1578, except it contains the ending port
+ * offset for the corresponding streamID.
+ *
+ * On certain cards, such as the SBZ/ZxR/AE7, these are originally setup by
+ * the 8051, then manually overwritten to remap the ports to work with the
+ * new DACs.
+ *
+ * Currently known portID's:
+ * 0x00-0x1f: HDA audio stream input/output ports.
+ * 0x80-0xbf: Sample rate converter input/outputs. Only valid ports seem to
+ *have the lower-nibble set to 0x1, 0x2, and 0x9.
+ * 0xc0-0xdf: DSP DMA input/output ports. Dynamically assigned.
+ * 0xe0-0xff: DAC/ADC audio input/output ports.
+ *
+ * Currently known streamID's:
+ * 0x03: Mic1 ADC to DSP.
+ * 0x04: Mic2 ADC to DSP.
+ * 0x05: HDA node 0x02 audio stream to DSP.
+ * 0x0f: DSP Mic exit to HDA node 0x07.
+ * 0x0c: DSP processed audio to DACs.
+ * 0x14: DAC0, front L/R.
+ *
+ * It is possible to route the HDA audio streams directly to the DAC and
+ * bypass the DSP entirely, with the only downside being that since the DSP
+ * does volume control, the only volume control you'll get is through PCM on
+ * the PC side, in the same way volume is handled for optical out. This may be
+ * useful for debugging.
+ */
+static void chipio_remap_stream(struct hda_codec *codec,
+   const struct chipio_stream_remap_data *remap_data)
+{
+   unsigned int i, stream_offset, tmp;
+
+   /* Get the starting port for the stream to be remapped. */
+   tmp = 0x1578 + remap_data->stream_id;
+   for (i = 0; i < 2; i++) {
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW + i,
+   ((tmp >> (i * 8)) & 0xff));
+   }
+
+   stream_offset = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
+  VENDOR_CHIPIO_8051_DATA_READ, 0);
+
+   /*
+* Check if the stream's port value is 0xff, because the 8051 may not
+* have gotten around to setting up the stream yet.

[PATCH v2 0/5] ALSA: hda/ca0132 - Fix no-audio issues and add documentation.

2020-12-10 Thread Connor McAdams
This patch series attempts to fix the no audio at startup issues that
have been occurring for some users, using information gained through
reverse engineering the ca0132's onboard 8051 processor.

The issue of no audio on startup seemed to be caused by two separate
problems: not resetting the codec upon initialization, and not making
sure the DSP allocates it's DMA channels correctly.

Tested and working on all cards, except for the AE-7. The AE-7 shouldn't
have any issues, however, I don't have one on hand to test.

Connor McAdams (5):
  ALSA: hda/ca0132 - Reset codec upon initialization.
  ALSA: hda/ca0132 - Add stream port remapping function.
  ALSA: hda/ca0132 - Add 8051 exram helper functions.
  ALSA: hda/ca0132 - Ensure DSP is properly setup post-firmware
download.
  ALSA: hda/ca0132 - Remove now unnecessary DSP setup functions.

 sound/pci/hda/patch_ca0132.c | 558 ++-
 1 file changed, 354 insertions(+), 204 deletions(-)

v2 changes:
-Remove conditional mutexes from patches 3 and 4.

-- 
2.25.1



[PATCH v2 3/5] ALSA: hda/ca0132 - Add 8051 exram helper functions.

2020-12-10 Thread Connor McAdams
Add functions for both reading and writing to the 8051's exram. Also,
add a little bit of documentation on how the addresses are segmented.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 137 ---
 1 file changed, 79 insertions(+), 58 deletions(-)

v2 changes:
-Remove conditional mutex.

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 8d2f12f2ce3f..f84815cc8d2f 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1901,6 +1901,70 @@ static void chipio_8051_write_direct(struct hda_codec 
*codec,
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, verb, addr);
 }
 
+/*
+ * Writes to the 8051's exram, which has 16-bits of address space.
+ * Data at addresses 0x2000-0x7fff is mirrored to 0x8000-0xdfff.
+ * Data at 0x8000-0xdfff can also be used as program memory for the 8051 by
+ * setting the pmem bank selection SFR.
+ * 0xe000-0x is always mapped as program memory, with only 0xf000-0x
+ * being writable.
+ */
+static void chipio_8051_set_address(struct hda_codec *codec, unsigned int addr)
+{
+   unsigned int tmp;
+
+   /* Lower 8-bits. */
+   tmp = addr & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, tmp);
+
+   /* Upper 8-bits. */
+   tmp = (addr >> 8) & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_HIGH, tmp);
+}
+
+static void chipio_8051_set_data(struct hda_codec *codec, unsigned int data)
+{
+   /* 8-bits of data. */
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_DATA_WRITE, data & 0xff);
+}
+
+static unsigned int chipio_8051_get_data(struct hda_codec *codec)
+{
+   return snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
+  VENDOR_CHIPIO_8051_DATA_READ, 0);
+}
+
+static void chipio_8051_write_exram(struct hda_codec *codec,
+   unsigned int addr, unsigned int data)
+{
+   struct ca0132_spec *spec = codec->spec;
+
+   mutex_lock(>chipio_mutex);
+
+   chipio_8051_set_address(codec, addr);
+   chipio_8051_set_data(codec, data);
+
+   mutex_unlock(>chipio_mutex);
+}
+
+static void chipio_8051_write_exram_no_mutex(struct hda_codec *codec,
+   unsigned int addr, unsigned int data)
+{
+   chipio_8051_set_address(codec, addr);
+   chipio_8051_set_data(codec, data);
+}
+
+/* Readback data from the 8051's exram. No mutex. */
+static void chipio_8051_read_exram(struct hda_codec *codec,
+   unsigned int addr, unsigned int *data)
+{
+   chipio_8051_set_address(codec, addr);
+   *data = chipio_8051_get_data(codec);
+}
+
 /*
  * Enable clocks.
  */
@@ -7422,18 +7486,10 @@ static void ca0132_init_analog_mic2(struct hda_codec 
*codec)
struct ca0132_spec *spec = codec->spec;
 
mutex_lock(>chipio_mutex);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x2D);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
+
+   chipio_8051_write_exram_no_mutex(codec, 0x1920, 0x00);
+   chipio_8051_write_exram_no_mutex(codec, 0x192d, 0x00);
+
mutex_unlock(>chipio_mutex);
 }
 
@@ -7504,18 +7560,11 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
 static void chipio_remap_stream(struct hda_codec *codec,
const struct chipio_stream_remap_data *remap_data)
 {
-   unsigned int i, stream_offset, tmp;
+   unsigned int i, stream_offset;
 
/* Get the starting port for the stream to be remapped. */
-   tmp = 0x1578 + remap_data->stream_id;
-   for (i = 0; i < 2; i++) {
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW + i,
-   ((tmp >> (i * 8)) & 0xff));
-   }
-
-   stream_offset = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
-  VENDOR_CHIPIO_8051_DATA_READ, 0);
+   chipio_8051_read_exram(codec, 0x1578 + remap_data->stream_id,
+   _offset);
 
/*
 * Check if the stream's port value is 0xff, because the 8051 may not
@@ -7526,9 +7575,8 @@ 

[PATCH 4/5] ALSA: hda/ca0132 - Ensure DSP is properly setup post-firmware download.

2020-12-08 Thread Connor McAdams
Make sure that the DSP has no DMA channels allocated once the firmware
is downloaded, and that the default audio streams in use by the DSP are
setup in the correct order.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 127 +++
 1 file changed, 127 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index cb725586d38b..12fee1146fc2 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1863,6 +1863,27 @@ static void chipio_set_stream_control(struct hda_codec 
*codec,
CONTROL_PARAM_STREAM_CONTROL, enable);
 }
 
+/*
+ * Get ChipIO audio stream's status.
+ */
+static void chipio_get_stream_control(struct hda_codec *codec,
+   int streamid, unsigned int *enable,
+   bool use_mutex)
+{
+   struct ca0132_spec *spec = codec->spec;
+
+   if (use_mutex)
+   mutex_lock(>chipio_mutex);
+
+   chipio_set_control_param_no_mutex(codec,
+   CONTROL_PARAM_STREAM_ID, streamid);
+   *enable = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
+  VENDOR_CHIPIO_PARAM_GET,
+  CONTROL_PARAM_STREAM_CONTROL);
+
+   if (use_mutex)
+   mutex_unlock(>chipio_mutex);
+}
 
 /*
  * Set sampling rate of the connection point. NO MUTEX.
@@ -7514,6 +7535,108 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
}
 }
 
+
+/* If there is an active channel for some reason, find it and free it. */
+static void ca0132_alt_free_active_dma_channels(struct hda_codec *codec)
+{
+   unsigned int i, tmp;
+   int status;
+
+   /* Read active DSPDMAC channel register. */
+   status = chipio_read(codec, DSPDMAC_CHNLSTART_MODULE_OFFSET, );
+   if (status >= 0) {
+   /* AND against 0xfff to get the active channel bits. */
+   tmp = tmp & 0xfff;
+
+   /* If there are no active channels, nothing to free. */
+   if (!tmp)
+   return;
+   } else {
+   codec_dbg(codec, "%s: Failed to read active DSP DMA channel 
register.\n",
+   __func__);
+   return;
+   }
+
+   /*
+* Check each DSP DMA channel for activity, and if the channel is
+* active, free it.
+*/
+   for (i = 0; i < DSPDMAC_DMA_CFG_CHANNEL_COUNT; i++) {
+   if (dsp_is_dma_active(codec, i)) {
+   status = dspio_free_dma_chan(codec, i);
+   if (status < 0)
+   codec_dbg(codec, "%s: Failed to free active DSP 
DMA channel %d.\n",
+   __func__, i);
+   }
+   }
+}
+
+/*
+ * In the case of CT_EXTENSIONS_ENABLE being set to 1, and the DSP being in
+ * use, audio is no longer routed directly to the DAC/ADC from the HDA stream.
+ * Instead, audio is now routed through the DSP's DMA controllers, which
+ * the DSP is tasked with setting up itself. Through debugging, it seems the
+ * cause of most of the no-audio on startup issues were due to improperly
+ * configured DSP DMA channels.
+ *
+ * Normally, the DSP configures these the first time an HDA audio stream is
+ * started post DSP firmware download. That is why creating a 'dummy' stream
+ * worked in fixing the audio in some cases. This works most of the time, but
+ * sometimes if a stream is started/stopped before the DSP can setup the DMA
+ * configuration registers, it ends up in a broken state. Issues can also
+ * arise if streams are started in an unusual order, i.e the audio output dma
+ * channel being sandwiched between the mic1 and mic2 dma channels.
+ *
+ * The solution to this is to make sure that the DSP has no DMA channels
+ * in use post DSP firmware download, and then to manually start each default
+ * DSP stream that uses the DMA channels. These are 0x0c, the audio output
+ * stream, 0x03, analog mic 1, and 0x04, analog mic 2.
+ */
+static void ca0132_alt_start_dsp_audio_streams(struct hda_codec *codec)
+{
+   const unsigned int dsp_dma_stream_ids[] = { 0x0c, 0x03, 0x04 };
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int i, tmp;
+
+   /*
+* Check if any of the default streams are active, and if they are,
+* stop them.
+*/
+   for (i = 0; i < ARRAY_SIZE(dsp_dma_stream_ids); i++) {
+   chipio_get_stream_control(codec, dsp_dma_stream_ids[i], ,
+   true);
+
+   if (tmp) {
+   mutex_lock(>chipio_mutex);
+   chipio_set_stream_control(codec,
+   dsp_dma_stream_ids[i], 0);
+   mutex_unlock(>chipio_mutex);
+   }
+   }
+
+   /*
+* If all DSP s

[PATCH 1/5] ALSA: hda/ca0132 - Reset codec upon initialization.

2020-12-08 Thread Connor McAdams
Reset the codec upon initialization to clear out anything that may have
been setup on a previous boot into Windows, or in case of an improper
shutdown.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 21 -
 1 file changed, 16 insertions(+), 5 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4fbec4258f58..05945f021e74 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8642,6 +8642,22 @@ static void ca0132_init_chip(struct hda_codec *codec)
 
mutex_init(>chipio_mutex);
 
+   /*
+* The Windows driver always does this upon startup, which seems to
+* clear out any previous configuration. This should help issues where
+* a boot into Windows prior to a boot into Linux breaks things. Also,
+* Windows always sends the reset twice.
+*/
+   if (ca0132_use_alt_functions(spec)) {
+   chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
+   chipio_write_no_mutex(codec, 0x18b0a4, 0x00c2);
+
+   snd_hda_codec_write(codec, codec->core.afg, 0,
+   AC_VERB_SET_CODEC_RESET, 0);
+   snd_hda_codec_write(codec, codec->core.afg, 0,
+   AC_VERB_SET_CODEC_RESET, 0);
+   }
+
spec->cur_out_type = SPEAKER_OUT;
if (!ca0132_use_alt_functions(spec))
spec->cur_mic_type = DIGITAL_MIC;
@@ -9262,11 +9278,6 @@ static void ae5_register_set(struct hda_codec *codec)
 
if (ca0132_quirk(spec) == QUIRK_AE5)
ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
-
-   chipio_write(codec, 0x18b0a4, 0x00c2);
-
-   snd_hda_codec_write(codec, 0x01, 0, 0x7ff, 0x00);
-   snd_hda_codec_write(codec, 0x01, 0, 0x7ff, 0x00);
 }
 
 /*
-- 
2.25.1



[PATCH 5/5] ALSA: hda/ca0132 - Remove now unnecessary DSP setup functions.

2020-12-08 Thread Connor McAdams
Now that the DSP's audio configuration is understood, remove previous
hacky methods of trying to properly configure it.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 105 ---
 1 file changed, 105 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 12fee1146fc2..b7d36c9b28b5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -2436,13 +2436,6 @@ static int dspio_set_uint_param(struct hda_codec *codec, 
int mod_id,
sizeof(unsigned int));
 }
 
-static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id,
-   int req, const unsigned int data)
-{
-   return dspio_set_param(codec, mod_id, 0x00, req, ,
-   sizeof(unsigned int));
-}
-
 /*
  * Allocate a DSP DMA channel via an SCP message
  */
@@ -7789,24 +7782,6 @@ static void ca0132_alt_init_speaker_tuning(struct 
hda_codec *codec)
SPEAKER_TUNING_FRONT_LEFT_DELAY + i, values[i]);
 }
 
-/*
- * Creates a dummy stream to bind the output to. This seems to have to be done
- * after changing the main outputs source and destination streams.
- */
-static void ca0132_alt_create_dummy_stream(struct hda_codec *codec)
-{
-   struct ca0132_spec *spec = codec->spec;
-   unsigned int stream_format;
-
-   stream_format = snd_hdac_calc_stream_format(48000, 2,
-   SNDRV_PCM_FORMAT_S32_LE, 32, 0);
-
-   snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id,
-   0, stream_format);
-
-   snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
-}
-
 /*
  * Initialize mic for non-chromebook ca0132 implementations.
  */
@@ -7848,9 +7823,6 @@ static void sbz_connect_streams(struct hda_codec *codec)
 
codec_dbg(codec, "Connect Streams entered, mutex locked and loaded.\n");
 
-   chipio_set_stream_channels(codec, 0x0C, 6);
-   chipio_set_stream_control(codec, 0x0C, 1);
-
/* This value is 0x43 for 96khz, and 0x83 for 192khz. */
chipio_write_no_mutex(codec, 0x18a020, 0x0043);
 
@@ -7898,9 +7870,6 @@ static void sbz_chipio_startup_data(struct hda_codec 
*codec)
break;
}
 
-   chipio_set_stream_channels(codec, 0x0c, 6);
-   chipio_set_stream_control(codec, 0x0c, 1);
-
if (dsp_out_remap_data)
chipio_remap_stream(codec, dsp_out_remap_data);
 
@@ -7908,57 +7877,6 @@ static void sbz_chipio_startup_data(struct hda_codec 
*codec)
mutex_unlock(>chipio_mutex);
 }
 
-/*
- * Custom DSP SCP commands where the src value is 0x00 instead of 0x20. This is
- * done after the DSP is loaded.
- */
-static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
-{
-   struct ca0132_spec *spec = codec->spec;
-   unsigned int tmp, i;
-
-   /*
-* Gotta run these twice, or else mic works inconsistently. Not clear
-* why this is, but multiple tests have confirmed it.
-*/
-   for (i = 0; i < 2; i++) {
-   switch (ca0132_quirk(spec)) {
-   case QUIRK_SBZ:
-   case QUIRK_AE5:
-   case QUIRK_AE7:
-   tmp = 0x0003;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
-   case QUIRK_R3D:
-   case QUIRK_R3DI:
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
-   default:
-   break;
-   }
-   msleep(100);
-   }
-}
-
 static void ca0132_alt_dsp_initial_mic_setup(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;

[PATCH 2/5] ALSA: hda/ca0132 - Add stream port remapping function.

2020-12-08 Thread Connor McAdams
Add function for remapping a ChipIO stream's ports. Also include some
documentation as to how this works.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 208 ++-
 1 file changed, 156 insertions(+), 52 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 05945f021e74..650a7e2bd311 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -788,6 +788,40 @@ static const struct ae5_filter_set ae5_filter_presets[] = {
}
 };
 
+/*
+ * Data structures for storing audio router remapping data. These are used to
+ * remap a currently active streams ports.
+ */
+struct chipio_stream_remap_data {
+   unsigned int stream_id;
+   unsigned int count;
+
+   unsigned int offset[16];
+   unsigned int value[16];
+};
+
+static const struct chipio_stream_remap_data stream_remap_data[] = {
+   { .stream_id = 0x14,
+ .count = 0x04,
+ .offset= { 0x00, 0x04, 0x08, 0x0c },
+ .value = { 0x0001f8c0, 0x0001f9c1, 0x0001fac6, 0x0001fbc7 },
+   },
+   { .stream_id = 0x0c,
+ .count = 0x0c,
+ .offset= { 0x00, 0x04, 0x08, 0x0c, 0x10, 0x14, 0x18, 0x1c,
+0x20, 0x24, 0x28, 0x2c },
+ .value = { 0x0001e0c0, 0x0001e1c1, 0x0001e4c2, 0x0001e5c3,
+0x0001e2c4, 0x0001e3c5, 0x0001e8c6, 0x0001e9c7,
+0x0001ecc8, 0x0001edc9, 0x0001eaca, 0x0001ebcb },
+   },
+   { .stream_id = 0x0c,
+ .count = 0x08,
+ .offset= { 0x08, 0x0c, 0x10, 0x14, 0x20, 0x24, 0x28, 0x2c },
+ .value = { 0x000140c2, 0x000141c3, 0x000150c4, 0x000151c5,
+0x000142c8, 0x000143c9, 0x000152ca, 0x000153cb },
+   }
+};
+
 enum hda_cmd_vendor_io {
/* for DspIO node */
VENDOR_DSPIO_SCP_WRITE_DATA_LOW  = 0x000,
@@ -7423,6 +7457,104 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
}
 }
 
+/*
+ * The region of ChipIO memory from 0x19-0x1903fc is a sort of 'audio
+ * router', where each entry represents a 48khz audio channel, with a format
+ * of an 8-bit destination, an 8-bit source, and an unknown 2-bit number
+ * value. The 2-bit number value is seemingly 0 if inactive, 1 if active,
+ * and 3 if it's using Sample Rate Converter ports.
+ * An example is:
+ * 0x0001f8c0
+ * In this case, f8 is the destination, and c0 is the source. The number value
+ * is 1.
+ * This region of memory is normally managed internally by the 8051, where
+ * the region of exram memory from 0x1477-0x1575 has each byte represent an
+ * entry within the 0x19 range, and when a range of entries is in use, the
+ * ending value is overwritten with 0xff.
+ * 0x1578 in exram is a table of 0x25 entries, corresponding to the ChipIO
+ * streamID's, where each entry is a starting 0x19 port offset.
+ * 0x159d in exram is the same as 0x1578, except it contains the ending port
+ * offset for the corresponding streamID.
+ *
+ * On certain cards, such as the SBZ/ZxR/AE7, these are originally setup by
+ * the 8051, then manually overwritten to remap the ports to work with the
+ * new DACs.
+ *
+ * Currently known portID's:
+ * 0x00-0x1f: HDA audio stream input/output ports.
+ * 0x80-0xbf: Sample rate converter input/outputs. Only valid ports seem to
+ *have the lower-nibble set to 0x1, 0x2, and 0x9.
+ * 0xc0-0xdf: DSP DMA input/output ports. Dynamically assigned.
+ * 0xe0-0xff: DAC/ADC audio input/output ports.
+ *
+ * Currently known streamID's:
+ * 0x03: Mic1 ADC to DSP.
+ * 0x04: Mic2 ADC to DSP.
+ * 0x05: HDA node 0x02 audio stream to DSP.
+ * 0x0f: DSP Mic exit to HDA node 0x07.
+ * 0x0c: DSP processed audio to DACs.
+ * 0x14: DAC0, front L/R.
+ *
+ * It is possible to route the HDA audio streams directly to the DAC and
+ * bypass the DSP entirely, with the only downside being that since the DSP
+ * does volume control, the only volume control you'll get is through PCM on
+ * the PC side, in the same way volume is handled for optical out. This may be
+ * useful for debugging.
+ */
+static void chipio_remap_stream(struct hda_codec *codec,
+   const struct chipio_stream_remap_data *remap_data)
+{
+   unsigned int i, stream_offset, tmp;
+
+   /* Get the starting port for the stream to be remapped. */
+   tmp = 0x1578 + remap_data->stream_id;
+   for (i = 0; i < 2; i++) {
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW + i,
+   ((tmp >> (i * 8)) & 0xff));
+   }
+
+   stream_offset = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
+  VENDOR_CHIPIO_8051_DATA_READ, 0);
+
+   /*
+* Check if the stream's port value is 0xff, because the 8051 may not
+* have gotten around to setting up the stream yet.

[PATCH 3/5] ALSA: hda/ca0132 - Add 8051 exram helper functions.

2020-12-08 Thread Connor McAdams
Add functions for both reading and writing to the 8051's exram. Also,
add a little bit of documentation on how the addresses are segmented.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 138 ---
 1 file changed, 80 insertions(+), 58 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 650a7e2bd311..cb725586d38b 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1901,6 +1901,71 @@ static void chipio_8051_write_direct(struct hda_codec 
*codec,
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, verb, addr);
 }
 
+/*
+ * Writes to the 8051's exram, which has 16-bits of address space.
+ * Data at addresses 0x2000-0x7fff is mirrored to 0x8000-0xdfff.
+ * Data at 0x8000-0xdfff can also be used as program memory for the 8051 by
+ * setting the pmem bank selection SFR.
+ * 0xe000-0x is always mapped as program memory, with only 0xf000-0x
+ * being writable.
+ */
+static void chipio_8051_write_exram(struct hda_codec *codec,
+   unsigned int addr, unsigned int data, bool use_mutex)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp;
+
+   if (use_mutex)
+   mutex_lock(>chipio_mutex);
+
+   /* Lower 8-bits. */
+   tmp = addr & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, tmp);
+
+   /* Upper 8-bits. */
+   tmp = (addr >> 8) & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_HIGH, tmp);
+
+   /* 8-bits of data. */
+   tmp = data & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_DATA_WRITE, tmp);
+
+   if (use_mutex)
+   mutex_unlock(>chipio_mutex);
+}
+
+/* Readback data from the 8051's exram. */
+static void chipio_8051_read_exram(struct hda_codec *codec,
+   unsigned int addr, unsigned int *data, bool use_mutex)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp;
+
+   if (use_mutex)
+   mutex_lock(>chipio_mutex);
+
+   /* Lower 8-bits. */
+   tmp = addr & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, tmp);
+
+   /* Upper 8-bits. */
+   tmp = (addr >> 8) & 0xff;
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_HIGH, tmp);
+
+   /* 8-bits of data. */
+   *data = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
+  VENDOR_CHIPIO_8051_DATA_READ,
+  0);
+
+   if (use_mutex)
+   mutex_unlock(>chipio_mutex);
+}
+
 /*
  * Enable clocks.
  */
@@ -7422,18 +7487,10 @@ static void ca0132_init_analog_mic2(struct hda_codec 
*codec)
struct ca0132_spec *spec = codec->spec;
 
mutex_lock(>chipio_mutex);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x2D);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
+
+   chipio_8051_write_exram(codec, 0x1920, 0x00, false);
+   chipio_8051_write_exram(codec, 0x192d, 0x00, false);
+
mutex_unlock(>chipio_mutex);
 }
 
@@ -7504,18 +7561,11 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
 static void chipio_remap_stream(struct hda_codec *codec,
const struct chipio_stream_remap_data *remap_data)
 {
-   unsigned int i, stream_offset, tmp;
+   unsigned int i, stream_offset;
 
/* Get the starting port for the stream to be remapped. */
-   tmp = 0x1578 + remap_data->stream_id;
-   for (i = 0; i < 2; i++) {
-   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
-   VENDOR_CHIPIO_8051_ADDRESS_LOW + i,
-   ((tmp >> (i * 8)) & 0xff));
-   }
-
-   stream_offset = snd_hda_codec_read(codec, WIDGET_CHIP_CTRL, 0,
-  VENDOR_CHIPIO_8051_DATA_READ, 0);
+   chipio_8051_read_exram(codec, 0x1578 + remap_data->stream_id,
+   _offset, false);
 
/*
 * Check if the stre

[PATCH 0/5] ALSA: hda/ca0132 - Fix no-audio issues and add documentation.

2020-12-08 Thread Connor McAdams
This patch series attempts to fix the no audio at startup issues that
have been occurring for some users, using information gained through
reverse engineering the ca0132's onboard 8051 processor.

The issue of no audio on startup seemed to be caused by two separate
problems: not resetting the codec upon initialization, and not making
sure the DSP allocates it's DMA channels correctly.

Tested and working on all cards, except for the AE-7. The AE-7 shouldn't
have any issues, however, I don't have one on hand to test.

As an aside, I'm not sure how to classify which commits this necessarily
'fixes', as it's covering multiple areas. Please let me know if this is
necessary.

Connor McAdams (5):
  ALSA: hda/ca0132 - Reset codec upon initialization.
  ALSA: hda/ca0132 - Add stream port remapping function.
  ALSA: hda/ca0132 - Add 8051 exram helper functions.
  ALSA: hda/ca0132 - Ensure DSP is properly setup post-firmware
download.
  ALSA: hda/ca0132 - Remove now unnecessary DSP setup functions.

 sound/pci/hda/patch_ca0132.c | 567 ++-
 1 file changed, 363 insertions(+), 204 deletions(-)

-- 
2.25.1



[PATCH v2 1/3] ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg.

2020-12-08 Thread Connor McAdams
The Windows driver sets the pincfg for the AE-5's rear-headphone to
report as a microphone. This causes issues with Pulseaudio mistakenly
believing there is no headphone plugged in. In Linux, we should instead
set it to be a headphone.

Fixes: a6b0961b39896 ("ALSA: hda/ca0132 - fix AE-5 pincfg")
Cc: 
Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

v2 changes:
- Add fixes references to previous commits that these patches now fix.

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4fbec4258f58..e96db73c32f5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1223,7 +1223,7 @@ static const struct hda_pintbl ae5_pincfgs[] = {
{ 0x0e, 0x01c510f0 }, /* SPDIF In */
{ 0x0f, 0x01017114 }, /* Port A -- Rear L/R. */
{ 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */
-   { 0x11, 0x01a170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
+   { 0x11, 0x012170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
{ 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */
{ 0x13, 0x908700f0 }, /* What U Hear In*/
{ 0x18, 0x50d000f0 }, /* N/A */
-- 
2.25.1



[PATCH v2 2/3] ALSA: hda/ca0132 - Change Input Source enum strings.

2020-12-08 Thread Connor McAdams
Change the Input Source enumerated control's strings to make it play
nice with pulseaudio.

Fixes: 7cb9d94c05de9 ("ALSA: hda/ca0132: add alt_select_in/out for R3Di + SBZ") 
Cc: 
Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index e96db73c32f5..793dc5d501a5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -95,7 +95,7 @@ enum {
 };
 
 /* Strings for Input Source Enum Control */
-static const char *const in_src_str[3] = {"Rear Mic", "Line", "Front Mic" };
+static const char *const in_src_str[3] = { "Microphone", "Line In", "Front 
Microphone" };
 #define IN_SRC_NUM_OF_INPUTS 3
 enum {
REAR_MIC,
-- 
2.25.1



[PATCH v2 3/3] ALSA: hda/ca0132 - Unmute surround when speaker output is selected.

2020-12-08 Thread Connor McAdams
Make sure GPIO pin for surround channel mute is set to 0 when speaker
output is selected.

Fixes: def3f0a5c7007 ("ALSA: hda/ca0132 - Add quirk output selection 
structures.")
Cc: 
Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 793dc5d501a5..6d647d461eab 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1390,7 +1390,7 @@ static const struct ca0132_alt_out_set_quirk_data 
quirk_out_set_data[] = {
  .has_hda_gpio = false,
  .mmio_gpio_count  = 3,
  .mmio_gpio_pin= { 2, 3, 5 },
- .mmio_gpio_set= { 1, 1, 0 },
+ .mmio_gpio_set= { 1, 0, 0 },
  .scp_cmds_count   = 0,
  .has_chipio_write = false,
},
-- 
2.25.1



Re: [PATCH 1/3] ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg.

2020-12-07 Thread Connor McAdams
Will do, thanks for the info.

On Mon, Dec 7, 2020 at 3:58 AM Takashi Iwai  wrote:
>
> On Mon, 07 Dec 2020 09:46:13 +0100,
> Connor McAdams wrote:
> >
> > The Windows driver sets the pincfg for the AE-5's rear-headphone to
> > report as a microphone. This causes issues with Pulseaudio mistakenly
> > believing there is no headphone plugged in. In Linux, we should instead
> > set it to be a headphone.
> >
> > Signed-off-by: Connor McAdams 
>
> Those patches are relevant with your previous patches, right?
> If it's a fix for a specific commit, it'd be appreciated to have a
> "Fixes:" tag with the commit id and "Cc:" tag to stable in the patch.
>
>
> thanks,
>
> Takashi


[PATCH 3/3] ALSA: hda/ca0132 - Unmute surround when speaker output is selected.

2020-12-07 Thread Connor McAdams
Make sure GPIO pin for surround channel mute is set to 0 when speaker
output is selected.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 793dc5d501a5..6d647d461eab 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1390,7 +1390,7 @@ static const struct ca0132_alt_out_set_quirk_data 
quirk_out_set_data[] = {
  .has_hda_gpio = false,
  .mmio_gpio_count  = 3,
  .mmio_gpio_pin= { 2, 3, 5 },
- .mmio_gpio_set= { 1, 1, 0 },
+ .mmio_gpio_set= { 1, 0, 0 },
  .scp_cmds_count   = 0,
  .has_chipio_write = false,
},
-- 
2.25.1



[PATCH 2/3] ALSA: hda/ca0132 - Change Input Source enum strings.

2020-12-07 Thread Connor McAdams
Change the Input Source enumerated control's strings to make it play
nice with pulseaudio.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index e96db73c32f5..793dc5d501a5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -95,7 +95,7 @@ enum {
 };
 
 /* Strings for Input Source Enum Control */
-static const char *const in_src_str[3] = {"Rear Mic", "Line", "Front Mic" };
+static const char *const in_src_str[3] = { "Microphone", "Line In", "Front 
Microphone" };
 #define IN_SRC_NUM_OF_INPUTS 3
 enum {
REAR_MIC,
-- 
2.25.1



[PATCH 1/3] ALSA: hda/ca0132 - Fix AE-5 rear headphone pincfg.

2020-12-07 Thread Connor McAdams
The Windows driver sets the pincfg for the AE-5's rear-headphone to
report as a microphone. This causes issues with Pulseaudio mistakenly
believing there is no headphone plugged in. In Linux, we should instead
set it to be a headphone.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4fbec4258f58..e96db73c32f5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1223,7 +1223,7 @@ static const struct hda_pintbl ae5_pincfgs[] = {
{ 0x0e, 0x01c510f0 }, /* SPDIF In */
{ 0x0f, 0x01017114 }, /* Port A -- Rear L/R. */
{ 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */
-   { 0x11, 0x01a170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
+   { 0x11, 0x012170ff }, /* Port B -- LineMicIn2 / Rear Headphone */
{ 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */
{ 0x13, 0x908700f0 }, /* What U Hear In*/
{ 0x18, 0x50d000f0 }, /* N/A */
-- 
2.25.1



[PATCH v2 03/20] ALSA: hda/ca0132 - Add surround channel config control.

2020-08-25 Thread Connor McAdams
Add a surround channel configuration enumeration control. Setting up
different channel configurations allows the DSP to upmix stereo audio
into multi-channel audio, and allows for redirection of bass to a
subwoofer.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 110 ++-
 1 file changed, 108 insertions(+), 2 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 2e664aeee1c4..1a5fb30b69ab 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -38,6 +38,8 @@
 #define FLOAT_ONE  0x3f80
 #define FLOAT_TWO  0x4000
 #define FLOAT_THREE 0x4040
+#define FLOAT_FIVE 0x40a0
+#define FLOAT_SIX   0x40c0
 #define FLOAT_EIGHT 0x4100
 #define FLOAT_MINUS_5  0xc0a0
 
@@ -143,7 +145,8 @@ enum {
MIC_BOOST_ENUM,
AE5_HEADPHONE_GAIN_ENUM,
AE5_SOUND_FILTER_ENUM,
-   ZXR_HEADPHONE_GAIN
+   ZXR_HEADPHONE_GAIN,
+   SPEAKER_CHANNEL_CFG_ENUM,
 #define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
 };
 
@@ -686,6 +689,39 @@ static const struct ca0132_alt_out_set alt_out_presets[] = 
{
}
 };
 
+/* Surround output channel count configuration structures. */
+#define SPEAKER_CHANNEL_CFG_COUNT 5
+enum {
+   SPEAKER_CHANNELS_2_0,
+   SPEAKER_CHANNELS_2_1,
+   SPEAKER_CHANNELS_4_0,
+   SPEAKER_CHANNELS_4_1,
+   SPEAKER_CHANNELS_5_1,
+};
+
+struct ca0132_alt_speaker_channel_cfg {
+   char *name;
+   unsigned int val;
+};
+
+static const struct ca0132_alt_speaker_channel_cfg speaker_channel_cfgs[] = {
+   { .name = "2.0",
+ .val = FLOAT_ONE
+   },
+   { .name = "2.1",
+ .val = FLOAT_TWO
+   },
+   { .name = "4.0",
+ .val = FLOAT_FIVE
+   },
+   { .name = "4.1",
+ .val = FLOAT_SIX
+   },
+   { .name = "5.1",
+ .val = FLOAT_EIGHT
+   }
+};
+
 /*
  * DSP volume setting structs. Req 1 is left volume, req 2 is right volume,
  * and I don't know what the third req is, but it's always zero. I assume it's
@@ -1063,6 +1099,7 @@ struct ca0132_spec {
/* ca0132_alt control related values */
unsigned char in_enum_val;
unsigned char out_enum_val;
+   unsigned char channel_cfg_val;
unsigned char mic_boost_enum_val;
unsigned char smart_volume_setting;
long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
@@ -4476,7 +4513,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
snd_hda_set_pin_ctl(codec, spec->out_pins[3],
pin_ctl | PIN_OUT);
 
-   dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_EIGHT);
+   tmp = speaker_channel_cfgs[spec->channel_cfg_val].val;
+   dspio_set_uint_param(codec, 0x80, 0x04, tmp);
break;
}
/*
@@ -5582,6 +5620,54 @@ static int ca0132_alt_output_select_put(struct 
snd_kcontrol *kcontrol,
return 1;
 }
 
+/* Select surround output type: 2.1, 4.0, 4.1, or 5.1. */
+static int ca0132_alt_speaker_channel_cfg_get_info(struct snd_kcontrol 
*kcontrol,
+struct snd_ctl_elem_info *uinfo)
+{
+   unsigned int items = SPEAKER_CHANNEL_CFG_COUNT;
+
+   uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+   uinfo->count = 1;
+   uinfo->value.enumerated.items = items;
+   if (uinfo->value.enumerated.item >= items)
+   uinfo->value.enumerated.item = items - 1;
+   strcpy(uinfo->value.enumerated.name,
+   
speaker_channel_cfgs[uinfo->value.enumerated.item].name);
+   return 0;
+}
+
+static int ca0132_alt_speaker_channel_cfg_get(struct snd_kcontrol *kcontrol,
+   struct snd_ctl_elem_value *ucontrol)
+{
+   struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+   struct ca0132_spec *spec = codec->spec;
+
+   ucontrol->value.enumerated.item[0] = spec->channel_cfg_val;
+   return 0;
+}
+
+static int ca0132_alt_speaker_channel_cfg_put(struct snd_kcontrol *kcontrol,
+   struct snd_ctl_elem_value *ucontrol)
+{
+   struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+   struct ca0132_spec *spec = codec->spec;
+   int sel = ucontrol->value.enumerated.item[0];
+   unsigned int items = SPEAKER_CHANNEL_CFG_COUNT;
+
+   if (sel >= items)
+   return 0;
+
+   codec_dbg(codec, "ca0132_alt_speaker_channels: sel=%d, channels=%s\n",
+   sel, speaker_channel_cfgs[sel].name);
+
+   spec->channel_cfg_val = sel;
+
+   if (spec->out_enum_val == SURROUND_OUT)
+   ca0132_alt_select_out(codec);
+
+   return 1;
+}
+
 /*
  * Smart Volume output setting control. Three different settings, Normal,
  * which takes the value from the smart volume 

[PATCH v2 08/20] ALSA: hda/ca0132 - Add quirk output selection structures.

2020-08-25 Thread Connor McAdams
Add structures containing the changes that need to happen on output
selection for each quirk. This should streamline the addition of new
quirks.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 336 +--
 1 file changed, 241 insertions(+), 95 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 39e333866be3..ab84ea397552 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1256,6 +1256,164 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
{}
 };
 
+/* Output selection quirk info structures. */
+#define MAX_QUIRK_MMIO_GPIO_SET_VALS 3
+#define MAX_QUIRK_SCP_SET_VALS 2
+struct ca0132_alt_out_set_info {
+   unsigned int dac2port; /* ParamID 0x0d value. */
+
+   bool has_hda_gpio;
+   char hda_gpio_pin;
+   char hda_gpio_set;
+
+   unsigned int mmio_gpio_count;
+   char mmio_gpio_pin[MAX_QUIRK_MMIO_GPIO_SET_VALS];
+   char mmio_gpio_set[MAX_QUIRK_MMIO_GPIO_SET_VALS];
+
+   unsigned int scp_cmds_count;
+   unsigned int scp_cmd_mid[MAX_QUIRK_SCP_SET_VALS];
+   unsigned int scp_cmd_req[MAX_QUIRK_SCP_SET_VALS];
+   unsigned int scp_cmd_val[MAX_QUIRK_SCP_SET_VALS];
+
+   bool has_chipio_write;
+   unsigned int chipio_write_addr;
+   unsigned int chipio_write_data;
+};
+
+struct ca0132_alt_out_set_quirk_data {
+   int quirk_id;
+
+   bool has_headphone_gain;
+   bool is_ae_series;
+
+   struct ca0132_alt_out_set_info out_set_info[NUM_OF_OUTPUTS];
+};
+
+static const struct ca0132_alt_out_set_quirk_data quirk_out_set_data[] = {
+   { .quirk_id = QUIRK_R3DI,
+ .has_headphone_gain = false,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x24,
+ .has_hda_gpio = true,
+ .hda_gpio_pin = 2,
+ .hda_gpio_set = 1,
+ .mmio_gpio_count  = 0,
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   },
+   /* Headphones. */
+   { .dac2port = 0x21,
+ .has_hda_gpio = true,
+ .hda_gpio_pin = 2,
+ .hda_gpio_set = 0,
+ .mmio_gpio_count  = 0,
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   } },
+   },
+   { .quirk_id = QUIRK_R3D,
+ .has_headphone_gain = false,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x24,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 1,
+ .mmio_gpio_pin= { 1 },
+ .mmio_gpio_set= { 1 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   },
+   /* Headphones. */
+   { .dac2port = 0x21,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 1,
+ .mmio_gpio_pin= { 1 },
+ .mmio_gpio_set= { 0 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   } },
+   },
+   { .quirk_id = QUIRK_SBZ,
+ .has_headphone_gain = false,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x18,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 7, 4, 1 },
+ .mmio_gpio_set= { 0, 1, 1 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false, },
+   /* Headphones. */
+   { .dac2port = 0x12,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 7, 4, 1 },
+ .mmio_gpio_set= { 1, 1, 0 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   } },
+   },
+   { .quirk_id = QUIRK_ZXR,
+ .has_headphone_gain = true,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x24,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 2, 3, 5 },
+ .mmio_gpio_set= { 1, 1, 0 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   },
+   /* Headphones. */
+   { .dac2port = 0x21,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 2, 3, 5 },
+ .mmio_gpio_set

[PATCH v2 13/20] ALSA: hda/ca0132 - Add ca0132_mmio_init data for SoundBlaster AE-7.

2020-08-25 Thread Connor McAdams
Modify the AE-5 ca0132_mmio_init function to add AE-7 specific writes.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index bd5d4f0bd6f5..10aaa4806946 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8748,8 +8748,26 @@ static void ca0132_mmio_init_ae5(struct hda_codec *codec)
data = ca0113_mmio_init_data_ae5;
count = ARRAY_SIZE(ca0113_mmio_init_data_ae5);
 
-   for (i = 0; i < count; i++)
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   writel(0x0680, spec->mem_base + 0x1c);
+   writel(0x00880680, spec->mem_base + 0x1c);
+   }
+
+   for (i = 0; i < count; i++) {
+   /*
+* AE-7 shares all writes with the AE-5, except that it writes
+* a different value to 0x20c.
+*/
+   if (i == 21 && ca0132_quirk(spec) == QUIRK_AE7) {
+   writel(0x0081, spec->mem_base + addr[i]);
+   continue;
+   }
+
writel(data[i], spec->mem_base + addr[i]);
+   }
+
+   if (ca0132_quirk(spec) == QUIRK_AE5)
+   writel(0x00880680, spec->mem_base + 0x1c);
 }
 
 static void ca0132_mmio_init(struct hda_codec *codec)
-- 
2.20.1



[PATCH v2 14/20] ALSA: hda/ca0132 - Add pre-init function for SoundBlaster AE-7.

2020-08-25 Thread Connor McAdams
Add pre DSP initialization function for the AE-7.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 70 
 1 file changed, 55 insertions(+), 15 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 10aaa4806946..cd46112c827e 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8786,6 +8786,16 @@ static void ca0132_mmio_init(struct hda_codec *codec)
}
 }
 
+static const unsigned int ca0132_ae5_register_set_addresses[] = {
+   0x304, 0x304, 0x304, 0x304, 0x100, 0x304, 0x100, 0x304, 0x100, 0x304,
+   0x100, 0x304, 0x86c, 0x800, 0x86c, 0x800, 0x804
+};
+
+static const unsigned char ca0132_ae5_register_set_data[] = {
+   0x0f, 0x0e, 0x1f, 0x0c, 0x3f, 0x08, 0x7f, 0x00, 0xff, 0x00, 0x6b,
+   0x01, 0x6b, 0x57
+};
+
 /*
  * This function writes to some SFR's, does some region2 writes, and then
  * eventually resets the codec with the 0x7ff verb. Not quite sure why it does
@@ -8794,6 +8804,18 @@ static void ca0132_mmio_init(struct hda_codec *codec)
 static void ae5_register_set(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   unsigned int count = ARRAY_SIZE(ca0132_ae5_register_set_addresses);
+   const unsigned int *addr = ca0132_ae5_register_set_addresses;
+   const unsigned char *data = ca0132_ae5_register_set_data;
+   unsigned int i, cur_addr;
+   unsigned char tmp[3];
+
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x41);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc8);
+   }
 
chipio_8051_write_direct(codec, 0x93, 0x10);
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
@@ -8801,25 +8823,43 @@ static void ae5_register_set(struct hda_codec *codec)
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
 
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0e, spec->mem_base + 0x100);
-   writeb(0x1f, spec->mem_base + 0x304);
-   writeb(0x0c, spec->mem_base + 0x100);
-   writeb(0x3f, spec->mem_base + 0x304);
-   writeb(0x08, spec->mem_base + 0x100);
-   writeb(0x7f, spec->mem_base + 0x304);
-   writeb(0x00, spec->mem_base + 0x100);
-   writeb(0xff, spec->mem_base + 0x304);
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   tmp[0] = 0x03;
+   tmp[1] = 0x03;
+   tmp[2] = 0x07;
+   } else {
+   tmp[0] = 0x0f;
+   tmp[1] = 0x0f;
+   tmp[2] = 0x0f;
+   }
 
-   ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
+   for (i = cur_addr = 0; i < 3; i++, cur_addr++)
+   writeb(tmp[i], spec->mem_base + addr[cur_addr]);
+
+   /*
+* First writes are in single bytes, final are in 4 bytes. So, we use
+* writeb, then writel.
+*/
+   for (i = 0; cur_addr < 12; i++, cur_addr++)
+   writeb(data[i], spec->mem_base + addr[cur_addr]);
+
+   for (; cur_addr < count; i++, cur_addr++)
+   writel(data[i], spec->mem_base + addr[cur_addr]);
+
+   writel(0x0081, spec->mem_base + 0x20c);
+
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
+   ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
+   } else {
+   ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
+   }
 
chipio_8051_write_direct(codec, 0x90, 0x00);
chipio_8051_write_direct(codec, 0x90, 0x10);
 
-   ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
+   if (ca0132_quirk(spec) == QUIRK_AE5)
+   ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
 
chipio_write(codec, 0x18b0a4, 0x00c2);
 
@@ -8918,7 +8958,7 @@ static int ca0132_init(struct hda_codec *codec)
 
snd_hda_power_up_pm(codec);
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
+   if (ca0132_quirk(spec) == QUIRK_AE5 || ca0132_quirk(spec) == QUIRK_AE7)
ae5_register_set(codec);
 
ca0132_init_unsol(codec);
-- 
2.20.1



[PATCH v2 12/20] ALSA: hda/ca0132 - Set AE-7 bools and select mixer.

2020-08-25 Thread Connor McAdams
Set the boolean values used for desktop cards, and select the desktop
mixer.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 6791aaf18e63..bd5d4f0bd6f5 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -9403,6 +9403,10 @@ static int patch_ca0132(struct hda_codec *codec)
spec->mixers[0] = desktop_mixer;
snd_hda_codec_set_name(codec, "Sound BlasterX AE-5");
break;
+   case QUIRK_AE7:
+   spec->mixers[0] = desktop_mixer;
+   snd_hda_codec_set_name(codec, "Sound Blaster AE-7");
+   break;
default:
spec->mixers[0] = ca0132_mixer;
break;
@@ -9413,6 +9417,7 @@ static int patch_ca0132(struct hda_codec *codec)
case QUIRK_SBZ:
case QUIRK_R3D:
case QUIRK_AE5:
+   case QUIRK_AE7:
case QUIRK_ZXR:
spec->use_alt_controls = true;
spec->use_alt_functions = true;
-- 
2.20.1



[PATCH v2 15/20] ALSA: hda/ca0132 - Add init data for SoundBlaster AE-7.

2020-08-25 Thread Connor McAdams
Add initialization data for the SoundBlaster AE-7 card.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index cd46112c827e..dc1eb9bfcc5e 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -3582,6 +3582,7 @@ static void ca0132_gpio_init(struct hda_codec *codec)
switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
+   case QUIRK_AE7:
snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
snd_hda_codec_write(codec, 0x01, 0, 0x790, 0x23);
@@ -8911,6 +8912,19 @@ static void ca0132_alt_init(struct hda_codec *codec)
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
break;
+   case QUIRK_AE7:
+   ca0132_gpio_init(codec);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x49);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, 0x88);
+   snd_hda_sequence_write(codec, spec->chip_init_verbs);
+   snd_hda_sequence_write(codec, spec->desktop_init_verbs);
+   chipio_write(codec, 0x18b008, 0x00f8);
+   chipio_write(codec, 0x18b008, 0x00f0);
+   chipio_write(codec, 0x18b030, 0x0020);
+   ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
+   break;
case QUIRK_ZXR:
snd_hda_sequence_write(codec, spec->chip_init_verbs);
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
-- 
2.20.1



[PATCH v2 04/20] ALSA: hda/ca0132 - Add full-range speaker selection controls.

2020-08-25 Thread Connor McAdams
Add functions for setting full-range speakers and controls to
enable/disable the setting. Setting a speaker to full-range means that
the channels won't have their bass redirected to the LFE channel.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 117 +++
 1 file changed, 117 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 1a5fb30b69ab..469cefe9a51a 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -147,6 +147,8 @@ enum {
AE5_SOUND_FILTER_ENUM,
ZXR_HEADPHONE_GAIN,
SPEAKER_CHANNEL_CFG_ENUM,
+   SPEAKER_FULL_RANGE_FRONT,
+   SPEAKER_FULL_RANGE_REAR,
 #define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
 };
 
@@ -592,6 +594,24 @@ static const struct ct_eq_preset ca0132_alt_eq_presets[] = 
{
}
 };
 
+/*
+ * DSP reqs for handling full-range speakers/bass redirection. If a speaker is
+ * set as not being full range, and bass redirection is enabled, all
+ * frequencies below the crossover frequency are redirected to the LFE
+ * channel. If the surround configuration has no LFE channel, this can't be
+ * enabled. X-Bass must be disabled when using these.
+ */
+enum speaker_range_reqs {
+   SPEAKER_BASS_REDIRECT= 0x15,
+   SPEAKER_BASS_REDIRECT_XOVER_FREQ = 0x16,
+   /* Between 0x16-0x1a are the X-Bass reqs. */
+   SPEAKER_FULL_RANGE_FRONT_L_R = 0x1a,
+   SPEAKER_FULL_RANGE_CENTER_LFE= 0x1b,
+   SPEAKER_FULL_RANGE_REAR_L_R  = 0x1c,
+   SPEAKER_FULL_RANGE_SURROUND_L_R  = 0x1d,
+   SPEAKER_BASS_REDIRECT_SUB_GAIN   = 0x1e,
+};
+
 /*
  * Definitions for the DSP req's to handle speaker tuning. These all belong to
  * module ID 0x96, the output effects module.
@@ -1100,6 +1120,7 @@ struct ca0132_spec {
unsigned char in_enum_val;
unsigned char out_enum_val;
unsigned char channel_cfg_val;
+   unsigned char speaker_range_val[2];
unsigned char mic_boost_enum_val;
unsigned char smart_volume_setting;
long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
@@ -4259,6 +4280,50 @@ static void ae5_mmio_select_out(struct hda_codec *codec)
ae5_ca0113_output_presets[spec->cur_out_type].vals[i]);
 }
 
+static int ca0132_alt_set_full_range_speaker(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp;
+   int err;
+
+   /* 2.0/4.0 setup has no LFE channel, so setting full-range does 
nothing. */
+   if (spec->channel_cfg_val == SPEAKER_CHANNELS_4_0
+   || spec->channel_cfg_val == SPEAKER_CHANNELS_2_0)
+   return 0;
+
+   /* Set front L/R full range. Zero for full-range, one for redirection. 
*/
+   tmp = spec->speaker_range_val[0] ? FLOAT_ZERO : FLOAT_ONE;
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_FRONT_L_R, tmp);
+   if (err < 0)
+   return err;
+
+   /* When setting full-range rear, both rear and center/lfe are set. */
+   tmp = spec->speaker_range_val[1] ? FLOAT_ZERO : FLOAT_ONE;
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_CENTER_LFE, tmp);
+   if (err < 0)
+   return err;
+
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_REAR_L_R, tmp);
+   if (err < 0)
+   return err;
+
+   /*
+* Only the AE series cards set this value when setting full-range,
+* and it's always 1.0f.
+*/
+   if (ca0132_quirk(spec) == QUIRK_AE5) {
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_SURROUND_L_R, FLOAT_ONE);
+   if (err < 0)
+   return err;
+   }
+
+   return 0;
+}
+
 /*
  * These are the commands needed to setup output on each of the different card
  * types.
@@ -4539,6 +4604,9 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
goto exit;
}
 
+   if (spec->cur_out_type == SURROUND_OUT)
+   err = ca0132_alt_set_full_range_speaker(codec);
+
 exit:
snd_hda_power_down_pm(codec);
 
@@ -5269,6 +5337,7 @@ static int ca0132_alt_xbass_xover_slider_ctl_get(struct 
snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
 
*valp = spec->xbass_xover_freq;
+
return 0;
 }
 
@@ -5894,6 +5963,11 @@ static int ca0132_switch_get(struct snd_kcontrol 
*kcontrol,
return 0;
}
 
+   if (nid == SPEAKER_FULL_RANGE_FRONT || nid == SPEAKER_FULL_RANGE_REAR) {
+   *valp = spec->speaker_range_val[nid - SPEAKER_FULL_RANGE_FRONT];
+   return 0;
+   }
+
return 0;
 }
 
@@ -5972,6 +6046,14 @@ static int ca0132_switch_put(struct snd_kcontrol 
*kcontrol,

[PATCH v2 11/20] ALSA: hda/ca0132 - Add SoundBlaster AE-7 pincfg.

2020-08-25 Thread Connor McAdams
Add AE-7 pincfg, based on the values set within Windows.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 284f63dc2749..6791aaf18e63 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1238,6 +1238,20 @@ static const struct hda_pintbl r3di_pincfgs[] = {
{}
 };
 
+static const struct hda_pintbl ae7_pincfgs[] = {
+   { 0x0b, 0x01017010 },
+   { 0x0c, 0x014510f0 },
+   { 0x0d, 0x414510f0 },
+   { 0x0e, 0x01c520f0 },
+   { 0x0f, 0x01017114 },
+   { 0x10, 0x01017011 },
+   { 0x11, 0x018170ff },
+   { 0x12, 0x01a170f0 },
+   { 0x13, 0x908700f0 },
+   { 0x18, 0x50f0 },
+   {}
+};
+
 static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1028, 0x057b, "Alienware M17x R4", 
QUIRK_ALIENWARE_M17XR4),
SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
@@ -9105,6 +9119,10 @@ static void ca0132_config(struct hda_codec *codec)
codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__);
snd_hda_apply_pincfgs(codec, ae5_pincfgs);
break;
+   case QUIRK_AE7:
+   codec_dbg(codec, "%s: QUIRK_AE7 applied.\n", __func__);
+   snd_hda_apply_pincfgs(codec, ae7_pincfgs);
+   break;
default:
break;
}
@@ -9186,6 +9204,7 @@ static void ca0132_config(struct hda_codec *codec)
spec->dig_in = 0x09;
break;
case QUIRK_AE5:
+   case QUIRK_AE7:
spec->num_outputs = 2;
spec->out_pins[0] = 0x0B; /* Line out */
spec->out_pins[1] = 0x11; /* Rear headphone out */
-- 
2.20.1



[PATCH v2 01/20] ALSA: hda/ca0132 - Cleanup ca0132_mmio_init function.

2020-08-25 Thread Connor McAdams
Cleanup the ca0132_mmio_init function, separating into two separate
functions, one for Sound Blaster Z/ZxR/Recon3D, and another for the
AE-5.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 158 ++-
 1 file changed, 99 insertions(+), 59 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index b7dbf2e7f77a..7491e2044638 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8108,78 +8108,118 @@ static void r3di_pre_dsp_setup(struct hda_codec *codec)
  * what they do, or if they're necessary. Could possibly
  * be removed. Figure they're better to leave in.
  */
-static void ca0132_mmio_init(struct hda_codec *codec)
+static const unsigned int ca0113_mmio_init_address_sbz[] = {
+   0x400, 0x408, 0x40c, 0x01c, 0xc0c, 0xc00, 0xc04, 0xc0c, 0xc0c, 0xc0c,
+   0xc0c, 0xc08, 0xc08, 0xc08, 0xc08, 0xc08, 0xc04
+};
+
+static const unsigned int ca0113_mmio_init_data_sbz[] = {
+   0x0030, 0x, 0x0003, 0x0003, 0x0003,
+   0x0003, 0x00c1, 0x00f1, 0x0001, 0x00c7,
+   0x00c1, 0x0080
+};
+
+static const unsigned int ca0113_mmio_init_data_zxr[] = {
+   0x0030, 0x, 0x, 0x0003, 0x0003,
+   0x0003, 0x0001, 0x00f1, 0x0001, 0x00c7,
+   0x00c1, 0x0080
+};
+
+static const unsigned int ca0113_mmio_init_address_ae5[] = {
+   0x400, 0x42c, 0x46c, 0x4ac, 0x4ec, 0x43c, 0x47c, 0x4bc, 0x4fc, 0x408,
+   0x100, 0x410, 0x40c, 0x100, 0x100, 0x830, 0x86c, 0x800, 0x86c, 0x800,
+   0x804, 0x20c, 0x01c, 0xc0c, 0xc00, 0xc04, 0xc0c, 0xc0c, 0xc0c, 0xc0c,
+   0xc08, 0xc08, 0xc08, 0xc08, 0xc08, 0xc04, 0x01c
+};
+
+static const unsigned int ca0113_mmio_init_data_ae5[] = {
+   0x0001, 0x, 0x, 0x, 0x,
+   0x, 0x, 0x, 0x, 0x0001,
+   0x0600, 0x0014, 0x0001, 0x060f, 0x070f,
+   0x0aff, 0x, 0x006b, 0x0001, 0x006b,
+   0x0057, 0x0080, 0x00880680, 0x0080, 0x0030,
+   0x, 0x, 0x0003, 0x0003, 0x0003,
+   0x0001, 0x00f1, 0x0001, 0x00c7, 0x00c1,
+   0x0080, 0x00880680
+};
+
+static void ca0132_mmio_init_sbz(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp[2], i, count, cur_addr;
+   const unsigned int *addr, *data;
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0001, spec->mem_base + 0x400);
-   else
-   writel(0x, spec->mem_base + 0x400);
+   addr = ca0113_mmio_init_address_sbz;
+   for (i = 0; i < 3; i++)
+   writel(0x, spec->mem_base + addr[i]);
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0001, spec->mem_base + 0x408);
-   else
-   writel(0x, spec->mem_base + 0x408);
+   cur_addr = i;
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_ZXR:
+   tmp[0] = 0x00880480;
+   tmp[1] = 0x0080;
+   break;
+   case QUIRK_SBZ:
+   tmp[0] = 0x00820680;
+   tmp[1] = 0x0083;
+   break;
+   case QUIRK_R3D:
+   tmp[0] = 0x00880680;
+   tmp[1] = 0x0083;
+   break;
+   default:
+   tmp[0] = 0x;
+   tmp[1] = 0x;
+   break;
+   }
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0001, spec->mem_base + 0x40c);
-   else
-   writel(0x, spec->mem_base + 0x40C);
+   for (i = 0; i < 2; i++)
+   writel(tmp[i], spec->mem_base + addr[cur_addr + i]);
 
-   if (ca0132_quirk(spec) == QUIRK_ZXR)
-   writel(0x00880640, spec->mem_base + 0x01C);
-   else
-   writel(0x00880680, spec->mem_base + 0x01C);
+   cur_addr += i;
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0080, spec->mem_base + 0xC0C);
-   else
-   writel(0x0083, spec->mem_base + 0xC0C);
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_ZXR:
+   count = ARRAY_SIZE(ca0113_mmio_init_data_zxr);
+   data = ca0113_mmio_init_data_zxr;
+   break;
+   default:
+   count = ARRAY_SIZE(ca0113_mmio_init_data_sbz);
+   data = ca0113_mmio_init_data_sbz;
+   break;
+   }
 
-   writel(0x0030, spec->mem_base + 0xC00);
-   writel(0x, spec->mem_base + 0xC04);
+   for (i = 0; i < count; i++)
+   writel(data[i], spec->mem_base + addr[cur_addr + i]);
+}
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x, spec->mem_base + 0xC0C);
-   el

[PATCH v2 10/20] ALSA: hda/ca0132 - Add new quirk ID for SoundBlaster AE-7.

2020-08-25 Thread Connor McAdams
Add a new PCI subsystem ID for the SoundBlaster AE-7 card.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 138403fd1639..284f63dc2749 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1134,6 +1134,7 @@ enum {
QUIRK_R3DI,
QUIRK_R3D,
QUIRK_AE5,
+   QUIRK_AE7,
 };
 
 #ifdef CONFIG_PCI
@@ -1253,6 +1254,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
+   SND_PCI_QUIRK(0x1102, 0x0081, "Sound Blaster AE-7", QUIRK_AE7),
{}
 };
 
-- 
2.20.1



[PATCH v2 18/20] ALSA: hda/ca0132 - Add AE-7 microphone selection commands.

2020-08-25 Thread Connor McAdams
Add AE-7 quirk data for setting of microphone. The AE-7 has no front
panel connector, so only rear-mic/line-in have new commands.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index dcc8d29d934c..8c6e38734489 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4997,6 +4997,15 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
tmp = FLOAT_THREE;
break;
+   case QUIRK_AE7:
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
+   tmp = FLOAT_THREE;
+   chipio_set_conn_rate(codec, MEM_CONNID_MICIN2,
+   SR_96_000);
+   chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2,
+   SR_96_000);
+   dspio_set_uint_param(codec, 0x80, 0x01, FLOAT_ZERO);
+   break;
default:
tmp = FLOAT_ONE;
break;
@@ -5042,6 +5051,14 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
case QUIRK_AE5:
ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
break;
+   case QUIRK_AE7:
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x3f);
+   chipio_set_conn_rate(codec, MEM_CONNID_MICIN2,
+   SR_96_000);
+   chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2,
+   SR_96_000);
+   dspio_set_uint_param(codec, 0x80, 0x01, FLOAT_ZERO);
+   break;
default:
break;
}
@@ -5051,7 +5068,10 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
 
-   tmp = FLOAT_ZERO;
+   if (ca0132_quirk(spec) == QUIRK_AE7)
+   tmp = FLOAT_THREE;
+   else
+   tmp = FLOAT_ZERO;
dspio_set_uint_param(codec, 0x80, 0x00, tmp);
 
switch (ca0132_quirk(spec)) {
-- 
2.20.1



[PATCH v2 19/20] ALSA: hda/ca0132 - Add AE-7 custom controls.

2020-08-25 Thread Connor McAdams
Add headphone gain and DAC filter controls, which use the same commands
as the AE-5. Also, change input source enumerated control item count to
exclude front microphone.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 8c6e38734489..52f6d3740e0a 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -5839,6 +5839,13 @@ static int ca0132_alt_input_source_put(struct 
snd_kcontrol *kcontrol,
int sel = ucontrol->value.enumerated.item[0];
unsigned int items = IN_SRC_NUM_OF_INPUTS;
 
+   /*
+* The AE-7 has no front microphone, so limit items to 2: rear mic and
+* line-in.
+*/
+   if (ca0132_quirk(spec) == QUIRK_AE7)
+   items = 2;
+
if (sel >= items)
return 0;
 
@@ -7029,20 +7036,25 @@ static int ca0132_build_controls(struct hda_codec 
*codec)
}
}
 
-   if (ca0132_quirk(spec) == QUIRK_AE5) {
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_AE5:
+   case QUIRK_AE7:
err = ae5_add_headphone_gain_enum(codec);
if (err < 0)
return err;
err = ae5_add_sound_filter_enum(codec);
if (err < 0)
return err;
-   }
-
-   if (ca0132_quirk(spec) == QUIRK_ZXR) {
+   break;
+   case QUIRK_ZXR:
err = zxr_add_headphone_gain_switch(codec);
if (err < 0)
return err;
+   break;
+   default:
+   break;
}
+
 #ifdef ENABLE_TUNING_CONTROLS
add_tuning_ctls(codec);
 #endif
-- 
2.20.1



[PATCH v2 16/20] ALSA: hda/ca0132 - Add DSP setup functions for AE-7.

2020-08-25 Thread Connor McAdams
Add DSP setup functions for the Sound Blaster AE-7 post DSP download.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 290 +++
 1 file changed, 290 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index dc1eb9bfcc5e..8519119ef7a6 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7378,6 +7378,7 @@ static void ca0132_alt_init_speaker_tuning(struct 
hda_codec *codec)
values = zxr_default_delay_values;
break;
case QUIRK_AE5:
+   case QUIRK_AE7:
values = ae5_default_delay_values;
break;
default:
@@ -7551,6 +7552,7 @@ static void ca0132_alt_dsp_scp_startup(struct hda_codec 
*codec)
switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
+   case QUIRK_AE7:
tmp = 0x0003;
dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
tmp = 0x;
@@ -7760,6 +7762,206 @@ static void ae5_post_dsp_startup_data(struct hda_codec 
*codec)
mutex_unlock(>chipio_mutex);
 }
 
+static const unsigned int ae7_port_set_data[] = {
+   0x0001e0c0, 0x0001e1c1, 0x0001e4c2, 0x0001e5c3, 0x0001e2c4, 0x0001e3c5,
+   0x0001e8c6, 0x0001e9c7, 0x0001ecc8, 0x0001edc9, 0x0001eaca, 0x0001ebcb
+};
+
+static void ae7_post_dsp_setup_ports(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int i, count, addr;
+
+   mutex_lock(>chipio_mutex);
+
+   chipio_set_stream_channels(codec, 0x0c, 6);
+   chipio_set_stream_control(codec, 0x0c, 1);
+
+   count = ARRAY_SIZE(ae7_port_set_data);
+   addr = 0x190030;
+   for (i = 0; i < count; i++) {
+   chipio_write_no_mutex(codec, addr, ae7_port_set_data[i]);
+
+   /* Addresses are incremented by 4-bytes. */
+   addr += 0x04;
+   }
+
+   /*
+* Port setting always ends with a write of 0x1 to address 0x19042c.
+*/
+   chipio_write_no_mutex(codec, 0x19042c, 0x0001);
+
+   ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
+   ca0113_mmio_command_set(codec, 0x48, 0x0d, 0x40);
+   ca0113_mmio_command_set(codec, 0x48, 0x17, 0x00);
+   ca0113_mmio_command_set(codec, 0x48, 0x19, 0x00);
+   ca0113_mmio_command_set(codec, 0x48, 0x11, 0xff);
+   ca0113_mmio_command_set(codec, 0x48, 0x12, 0xff);
+   ca0113_mmio_command_set(codec, 0x48, 0x13, 0xff);
+   ca0113_mmio_command_set(codec, 0x48, 0x14, 0x7f);
+
+   mutex_unlock(>chipio_mutex);
+}
+
+static void ae7_post_dsp_asi_stream_setup(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+
+   mutex_lock(>chipio_mutex);
+
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x81);
+   ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
+
+   chipio_set_conn_rate_no_mutex(codec, 0x70, SR_96_000);
+   chipio_set_stream_channels(codec, 0x0c, 6);
+   chipio_set_stream_control(codec, 0x0c, 1);
+
+   chipio_set_stream_source_dest(codec, 0x05, 0x43, 0x00);
+   chipio_set_stream_source_dest(codec, 0x18, 0x09, 0xd0);
+
+   chipio_set_conn_rate_no_mutex(codec, 0xd0, SR_96_000);
+   chipio_set_stream_channels(codec, 0x18, 6);
+   chipio_set_stream_control(codec, 0x18, 1);
+
+   chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 4);
+
+   mutex_unlock(>chipio_mutex);
+}
+
+static void ae7_post_dsp_pll_setup(struct hda_codec *codec)
+{
+   const unsigned int addr[] = { 0x41, 0x45, 0x40, 0x43, 0x51 };
+   const unsigned int data[] = { 0xc8, 0xcc, 0xcb, 0xc7, 0x8d };
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(addr); i++) {
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, addr[i]);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, data[i]);
+   }
+}
+
+static void ae7_post_dsp_asi_setup_ports(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   const unsigned int target[] = { 0x0b, 0x04, 0x06, 0x0a, 0x0c, 0x11,
+   0x12, 0x13, 0x14 };
+   const unsigned int data[]   = { 0x12, 0x00, 0x48, 0x05, 0x5f, 0xff,
+   0xff, 0xff, 0x7f };
+   unsigned int i;
+
+   mutex_lock(>chipio_mutex);
+
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
+
+   chipio_write_no_mutex(codec, 0x189000, 0x0001f101);
+   chipio_write_no_mutex(codec, 0x189004, 0x0001f101);
+ 

[PATCH v2 20/20] ALSA: hda/ca0132 - Add AE-7 exit commands.

2020-08-25 Thread Connor McAdams
Add exit commands for the AE-7.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 52f6d3740e0a..9779978e4bc7 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8838,6 +8838,32 @@ static void ae5_exit_chip(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x01, 0, 0x724, 0x83);
 }
 
+static void ae7_exit_chip(struct hda_codec *codec)
+{
+   chipio_set_stream_control(codec, 0x18, 0);
+   chipio_set_stream_source_dest(codec, 0x21, 0xc8, 0xc8);
+   chipio_set_stream_channels(codec, 0x21, 0);
+   chipio_set_control_param(codec, CONTROL_PARAM_NODE_ID, 0x09);
+   chipio_set_control_param(codec, 0x20, 0x01);
+
+   chipio_set_control_param(codec, CONTROL_PARAM_ASI, 0);
+
+   chipio_set_stream_control(codec, 0x18, 0);
+   chipio_set_stream_control(codec, 0x0c, 0);
+
+   ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
+   snd_hda_codec_write(codec, 0x15, 0, 0x724, 0x83);
+   ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
+   ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
+   ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x00);
+   ca0113_mmio_gpio_set(codec, 0, false);
+   ca0113_mmio_gpio_set(codec, 1, false);
+   ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
+
+   snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
+   snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
+}
+
 static void zxr_exit_chip(struct hda_codec *codec)
 {
chipio_set_stream_control(codec, 0x03, 0);
@@ -9457,6 +9483,9 @@ static void ca0132_free(struct hda_codec *codec)
case QUIRK_AE5:
ae5_exit_chip(codec);
break;
+   case QUIRK_AE7:
+   ae7_exit_chip(codec);
+   break;
case QUIRK_R3DI:
r3di_gpio_shutdown(codec);
break;
-- 
2.20.1



[PATCH v2 17/20] ALSA: hda/ca0132 - Add output selection for SoundBlaster AE-7.

2020-08-25 Thread Connor McAdams
Add output selection quirk table information for SoundBlaster AE-7, and
slightly modify the AE-5's ca0113 command table to accommodate the AE-7.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 88 
 1 file changed, 68 insertions(+), 20 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 8519119ef7a6..dcc8d29d934c 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -727,22 +727,29 @@ static const struct ct_dsp_volume_ctl 
ca0132_alt_vol_ctls[] = {
 };
 
 /* Values for ca0113_mmio_command_set for selecting output. */
-#define AE5_CA0113_OUT_SET_COMMANDS 6
-struct ae5_ca0113_output_set {
-   unsigned int group[AE5_CA0113_OUT_SET_COMMANDS];
-   unsigned int target[AE5_CA0113_OUT_SET_COMMANDS];
-   unsigned int vals[AE5_CA0113_OUT_SET_COMMANDS];
+#define AE_CA0113_OUT_SET_COMMANDS 6
+struct ae_ca0113_output_set {
+   unsigned int group[AE_CA0113_OUT_SET_COMMANDS];
+   unsigned int target[AE_CA0113_OUT_SET_COMMANDS];
+   unsigned int vals[NUM_OF_OUTPUTS][AE_CA0113_OUT_SET_COMMANDS];
 };
 
-static const struct ae5_ca0113_output_set ae5_ca0113_output_presets[] = {
-   { .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
- .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
- .vals =   { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f }
-   },
-   { .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
- .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
- .vals =   { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 }
-   }
+static const struct ae_ca0113_output_set ae5_ca0113_output_presets = {
+   .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
+   .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
+   /* Speakers. */
+   .vals =   { { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f },
+   /* Headphones. */
+   { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 } },
+};
+
+static const struct ae_ca0113_output_set ae7_ca0113_output_presets = {
+   .group  = { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
+   .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
+   /* Speakers. */
+   .vals   = { { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f },
+   /* Headphones. */
+   { 0x3f, 0x3f, 0x00, 0x00, 0x02, 0x00 } },
 };
 
 /* ae5 ca0113 command sequences to set headphone gain levels. */
@@ -1427,6 +1434,41 @@ static const struct ca0132_alt_out_set_quirk_data 
quirk_out_set_data[] = {
  .chipio_write_addr = 0x0018b03c,
  .chipio_write_data = 0x0012
} },
+   },
+   { .quirk_id = QUIRK_AE7,
+ .has_headphone_gain = true,
+ .is_ae_series   = true,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port  = 0x58,
+ .has_hda_gpio  = false,
+ .mmio_gpio_count   = 1,
+ .mmio_gpio_pin = { 0 },
+ .mmio_gpio_set = { 1 },
+ .scp_cmds_count= 2,
+ .scp_cmd_mid   = { 0x96, 0x96 },
+ .scp_cmd_req   = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
+SPEAKER_TUNING_FRONT_RIGHT_INVERT },
+ .scp_cmd_val   = { FLOAT_ZERO, FLOAT_ZERO },
+ .has_chipio_write  = true,
+ .chipio_write_addr = 0x0018b03c,
+ .chipio_write_data = 0x
+   },
+   /* Headphones. */
+   { .dac2port  = 0x58,
+ .has_hda_gpio  = false,
+ .mmio_gpio_count   = 1,
+ .mmio_gpio_pin = { 0 },
+ .mmio_gpio_set = { 1 },
+ .scp_cmds_count= 2,
+ .scp_cmd_mid   = { 0x96, 0x96 },
+ .scp_cmd_req   = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
+SPEAKER_TUNING_FRONT_RIGHT_INVERT },
+ .scp_cmd_val   = { FLOAT_ONE, FLOAT_ONE },
+ .has_chipio_write  = true,
+ .chipio_write_addr = 0x0018b03c,
+ .chipio_write_data = 0x0010
+   } },
}
 };
 
@@ -4383,18 +4425,24 @@ static int ca0132_effects_set(struct hda_codec *codec, 
hda_nid_t nid, long val);
 static void ae5_mmio_select_out(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   const struct ae_ca0113_output_set *out_cmds;
unsigned int i;
 
-   for (i = 0; i < AE5_CA0113_OUT_SET_COMMANDS; i++)
-   ca0113_mmio_command_set(codec,
-   ae5_ca0113_output_presets[spec->cur_out_type].group[i],
-   ae5_ca0113_output_presets[spec->cur_out_type].target[i],
-   ae5_ca0113_output_presets[spec->cur_out_type].vals[i]);
+   if (ca0132_quirk(spe

[PATCH v2 07/20] ALSA: hda/ca0132 - Clean up ca0132_alt_out_select.

2020-08-25 Thread Connor McAdams
Remove the output structures that were in use before and instead set the
DSP commands line by line. Now that the commands use is known, it makes
the functionality more clear this way.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 142 ++-
 1 file changed, 57 insertions(+), 85 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 5743bdd7cc88..39e333866be3 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -83,6 +83,7 @@ MODULE_FIRMWARE(R3DI_EFX_FILE);
 static const char *const dirstr[2] = { "Playback", "Capture" };
 
 #define NUM_OF_OUTPUTS 2
+static const char *const out_type_str[2] = { "Speakers", "Headphone" };
 enum {
SPEAKER_OUT,
HEADPHONE_OUT,
@@ -667,39 +668,6 @@ enum speaker_tuning_reqs {
SPEAKER_TUNING_MUTE = 0x3a,
 };
 
-/* DSP command sequences for ca0132_alt_select_out */
-#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
-struct ca0132_alt_out_set {
-   char *name; /*preset name*/
-   unsigned char commands;
-   unsigned int mids[ALT_OUT_SET_MAX_COMMANDS];
-   unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS];
-   unsigned int vals[ALT_OUT_SET_MAX_COMMANDS];
-};
-
-static const struct ca0132_alt_out_set alt_out_presets[] = {
-   { .name = "Line Out",
- .commands = 7,
- .mids = { 0x96, 0x96, 0x96, 0x8F,
-   0x96, 0x96, 0x96 },
- .reqs = { 0x19, 0x17, 0x18, 0x01,
-   0x1F, 0x15, 0x3A },
- .vals = { 0x3F00, 0x42A0, 0x,
-   0x, 0x, 0x,
-   0x }
-   },
-   { .name = "Headphone",
- .commands = 7,
- .mids = { 0x96, 0x96, 0x96, 0x8F,
-   0x96, 0x96, 0x96 },
- .reqs = { 0x19, 0x17, 0x18, 0x01,
-   0x1F, 0x15, 0x3A },
- .vals = { 0x3F00, 0x42A0, 0x,
-   0x, 0x, 0x,
-   0x }
-   },
-};
-
 /* Surround output channel count configuration structures. */
 #define SPEAKER_CHANNEL_CFG_COUNT 5
 enum {
@@ -4428,21 +4396,31 @@ static void ca0132_alt_select_out_quirk_handler(struct 
hda_codec *codec)
}
 }
 
+static void ca0132_set_out_node_pincfg(struct hda_codec *codec, hda_nid_t nid,
+   bool out_enable, bool hp_enable)
+{
+   unsigned int pin_ctl;
+
+   pin_ctl = snd_hda_codec_read(codec, nid, 0,
+   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+
+   pin_ctl = hp_enable ? pin_ctl | PIN_HP_AMP : pin_ctl & ~PIN_HP_AMP;
+   pin_ctl = out_enable ? pin_ctl | PIN_OUT : pin_ctl & ~PIN_OUT;
+   snd_hda_set_pin_ctl(codec, nid, pin_ctl);
+}
+
 /*
  * This function behaves similarly to the ca0132_select_out funciton above,
  * except with a few differences. It adds the ability to select the current
  * output with an enumerated control "output source" if the auto detect
  * mute switch is set to off. If the auto detect mute switch is enabled, it
  * will detect either headphone or lineout(SPEAKER_OUT) from jack detection.
- * It also adds the ability to auto-detect the front headphone port. The only
- * way to select surround is to disable auto detect, and set Surround with the
- * enumerated control.
+ * It also adds the ability to auto-detect the front headphone port.
  */
 static int ca0132_alt_select_out(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
-   unsigned int tmp, outfx_set, i;
-   unsigned int pin_ctl;
+   unsigned int tmp, outfx_set;
int jack_present;
int auto_jack;
int err;
@@ -4473,9 +4451,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
 
outfx_set = spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID];
 
-   /* Begin DSP output switch */
-   tmp = FLOAT_ONE;
-   err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp);
+   /* Begin DSP output switch, mute DSP volume. */
+   err = dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_MUTE, FLOAT_ONE);
if (err < 0)
goto exit;
 
@@ -4485,31 +4462,18 @@ static int ca0132_alt_select_out(struct hda_codec 
*codec)
case SPEAKER_OUT:
codec_dbg(codec, "%s speaker\n", __func__);
 
-   /* disable headphone node */
-
-   pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
-   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-   snd_hda_set_pin_ctl(codec, spec->out_pins[1],
-   pin_ctl & ~PIN_HP);
-   /* enable line-out node */
-   pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
-

[PATCH v2 05/20] ALSA: hda/ca0132 - Add bass redirection controls.

2020-08-25 Thread Connor McAdams
Add bass redirection controls for surround outputs. This uses the DSP to
redirect audio below the bass redirection crossover frequency to the LFE
channel from the front/rear L/R speakers. This only goes into effect if
the speakers aren't set as full range, and only if the surround
configuration has an LFE channel.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 130 +--
 1 file changed, 126 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 469cefe9a51a..8ad2fc5ab30b 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -149,6 +149,8 @@ enum {
SPEAKER_CHANNEL_CFG_ENUM,
SPEAKER_FULL_RANGE_FRONT,
SPEAKER_FULL_RANGE_REAR,
+   BASS_REDIRECTION,
+   BASS_REDIRECTION_XOVER,
 #define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
 };
 
@@ -1123,6 +1125,8 @@ struct ca0132_spec {
unsigned char speaker_range_val[2];
unsigned char mic_boost_enum_val;
unsigned char smart_volume_setting;
+   unsigned char bass_redirection_val;
+   long bass_redirect_xover_freq;
long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
long xbass_xover_freq;
long eq_preset_val;
@@ -4324,6 +4328,35 @@ static int ca0132_alt_set_full_range_speaker(struct 
hda_codec *codec)
return 0;
 }
 
+static int ca0132_alt_surround_set_bass_redirection(struct hda_codec *codec,
+   bool val)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp;
+   int err;
+
+   if (val && spec->channel_cfg_val != SPEAKER_CHANNELS_4_0 &&
+   spec->channel_cfg_val != SPEAKER_CHANNELS_2_0)
+   tmp = FLOAT_ONE;
+   else
+   tmp = FLOAT_ZERO;
+
+   err = dspio_set_uint_param(codec, 0x96, SPEAKER_BASS_REDIRECT, tmp);
+   if (err < 0)
+   return err;
+
+   /* If it is enabled, make sure to set the crossover frequency. */
+   if (tmp) {
+   tmp = float_xbass_xover_lookup[spec->xbass_xover_freq];
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_BASS_REDIRECT_XOVER_FREQ, tmp);
+   if (err < 0)
+   return err;
+   }
+
+   return 0;
+}
+
 /*
  * These are the commands needed to setup output on each of the different card
  * types.
@@ -4593,6 +4626,15 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
ca0132_effects_set(codec, X_BASS,
spec->effects_switch[X_BASS - EFFECT_START_NID]);
 
+   if (spec->cur_out_type == SURROUND_OUT)
+   err = ca0132_alt_surround_set_bass_redirection(codec,
+   spec->bass_redirection_val);
+   else
+   err = ca0132_alt_surround_set_bass_redirection(codec, 0);
+
+   if (err < 0)
+   goto exit;
+
/* run through the output dsp commands for the selected output. */
for (i = 0; i < alt_out_presets[spec->cur_out_type].commands; i++) {
err = dspio_set_uint_param(codec,
@@ -5282,6 +5324,18 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol 
*kcontrol,
return ret;
 }
 /* End of control change helpers. */
+
+static void ca0132_alt_bass_redirection_xover_set(struct hda_codec *codec,
+   long idx)
+{
+   snd_hda_power_up(codec);
+
+   dspio_set_param(codec, 0x96, 0x20, SPEAKER_BASS_REDIRECT_XOVER_FREQ,
+   &(float_xbass_xover_lookup[idx]), sizeof(unsigned int));
+
+   snd_hda_power_down(codec);
+}
+
 /*
  * Below I've added controls to mess with the effect levels, I've only enabled
  * them on the Sound Blaster Z, but they would probably also work on the
@@ -5290,6 +5344,7 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol 
*kcontrol,
  */
 
 /* Sets DSP effect level from the sliders above the controls */
+
 static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid,
  const unsigned int *lookup, int idx)
 {
@@ -5335,8 +5390,12 @@ static int ca0132_alt_xbass_xover_slider_ctl_get(struct 
snd_kcontrol *kcontrol,
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ca0132_spec *spec = codec->spec;
long *valp = ucontrol->value.integer.value;
+   hda_nid_t nid = get_amp_nid(kcontrol);
 
-   *valp = spec->xbass_xover_freq;
+   if (nid == BASS_REDIRECTION_XOVER)
+   *valp = spec->bass_redirect_xover_freq;
+   else
+   *valp = spec->xbass_xover_freq;
 
return 0;
 }
@@ -5391,16 +5450,25 @@ static int ca0132_alt_xbass_xover_slider_put(struct 
snd_kcontrol *kcontrol,
struct ca0132_spec *spec = codec->spec;
hda_nid_t nid = get_amp_nid(kcontrol);
long *valp = ucontrol->value.integer.value;
+ 

[PATCH v2 09/20] ALSA: hda/ca0132 - Fix Recon3D Center/LFE output.

2020-08-25 Thread Connor McAdams
Properly set the GPIO pin to un-mute the Center/LFE channel on the
Recon3D.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ab84ea397552..138403fd1639 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7819,6 +7819,12 @@ static void r3d_setup_defaults(struct hda_codec *codec)
if (ca0132_quirk(spec) == QUIRK_R3DI)
r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
 
+   /* Disable mute on Center/LFE. */
+   if (ca0132_quirk(spec) == QUIRK_R3D) {
+   ca0113_mmio_gpio_set(codec, 2, false);
+   ca0113_mmio_gpio_set(codec, 4, true);
+   }
+
/* Setup effect defaults */
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
for (idx = 0; idx < num_fx; idx++) {
-- 
2.20.1



[PATCH v2 06/20] ALSA: hda/ca0132 - Remove surround output selection.

2020-08-25 Thread Connor McAdams
Remove the surround output selection and merge it with the speaker
output selection. Now that the extra commands that were being run on
surround output setting are known, there's no need to have it be
separate.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 151 +++
 1 file changed, 46 insertions(+), 105 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 8ad2fc5ab30b..5743bdd7cc88 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -82,11 +82,10 @@ MODULE_FIRMWARE(R3DI_EFX_FILE);
 
 static const char *const dirstr[2] = { "Playback", "Capture" };
 
-#define NUM_OF_OUTPUTS 3
+#define NUM_OF_OUTPUTS 2
 enum {
SPEAKER_OUT,
HEADPHONE_OUT,
-   SURROUND_OUT
 };
 
 enum {
@@ -699,16 +698,6 @@ static const struct ca0132_alt_out_set alt_out_presets[] = 
{
0x, 0x, 0x,
0x }
},
-   { .name = "Surround",
- .commands = 8,
- .mids = { 0x96, 0x8F, 0x96, 0x96,
-   0x96, 0x96, 0x96, 0x96 },
- .reqs = { 0x18, 0x01, 0x1F, 0x15,
-   0x3A, 0x1A, 0x1B, 0x1C },
- .vals = { 0x, 0x, 0x,
-   0x, 0x, 0x,
-   0x, 0x }
-   }
 };
 
 /* Surround output channel count configuration structures. */
@@ -785,10 +774,6 @@ static const struct ae5_ca0113_output_set 
ae5_ca0113_output_presets[] = {
{ .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
  .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
  .vals =   { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 }
-   },
-   { .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
- .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
- .vals =   { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f }
}
 };
 
@@ -4440,42 +4425,6 @@ static void ca0132_alt_select_out_quirk_handler(struct 
hda_codec *codec)
break;
}
break;
-   case SURROUND_OUT:
-   switch (ca0132_quirk(spec)) {
-   case QUIRK_SBZ:
-   ca0113_mmio_gpio_set(codec, 7, false);
-   ca0113_mmio_gpio_set(codec, 4, true);
-   ca0113_mmio_gpio_set(codec, 1, true);
-   chipio_set_control_param(codec, 0x0d, 0x18);
-   break;
-   case QUIRK_ZXR:
-   ca0113_mmio_gpio_set(codec, 2, true);
-   ca0113_mmio_gpio_set(codec, 3, true);
-   ca0113_mmio_gpio_set(codec, 5, false);
-   zxr_headphone_gain_set(codec, 0);
-   chipio_set_control_param(codec, 0x0d, 0x24);
-   break;
-   case QUIRK_R3DI:
-   chipio_set_control_param(codec, 0x0d, 0x24);
-   r3di_gpio_out_set(codec, R3DI_LINE_OUT);
-   break;
-   case QUIRK_R3D:
-   ca0113_mmio_gpio_set(codec, 1, true);
-   chipio_set_control_param(codec, 0x0d, 0x24);
-   break;
-   case QUIRK_AE5:
-   ae5_mmio_select_out(codec);
-   ae5_headphone_gain_set(codec, 2);
-   tmp = FLOAT_ZERO;
-   dspio_set_uint_param(codec, 0x96, 0x29, tmp);
-   dspio_set_uint_param(codec, 0x96, 0x2a, tmp);
-   chipio_set_control_param(codec, 0x0d, 0xa4);
-   chipio_write(codec, 0x18b03c, 0x0012);
-   break;
-   default:
-   break;
-   }
-   break;
}
 }
 
@@ -4492,11 +4441,10 @@ static void ca0132_alt_select_out_quirk_handler(struct 
hda_codec *codec)
 static int ca0132_alt_select_out(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp, outfx_set, i;
unsigned int pin_ctl;
int jack_present;
int auto_jack;
-   unsigned int i;
-   unsigned int tmp;
int err;
/* Default Headphone is rear headphone */
hda_nid_t headphone_nid = spec->out_pins[1];
@@ -4523,6 +4471,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
} else
spec->cur_out_type = spec->out_enum_val;
 
+   outfx_set = spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID];
+
/* Begin DSP output switch */
tmp = FLOAT_ONE;
err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp);
@@ -4536,6 +4486,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
codec_dbg(codec, "%s speaker\n", __func__);
 
/* disable headphone node */
+
 

[PATCH v2 00/20] ALSA: hda/ca0132 - Add AE-7 support/Control cleanup.

2020-08-25 Thread Connor McAdams
This patch series adds support for the Sound Blaster AE-7 along with
adding new controls and cleaning up the old ones. I have personally
tested the Recon3D, Recon3Di, Sound Blaster Z/ZxR, and AE-5 cards to
confirm they work with these patches. Another user has confirmed that
they work on the AE-7.

---
v2: Change control names to omit unnecessary information.

Connor McAdams (20):
  ALSA: hda/ca0132 - Cleanup ca0132_mmio_init function.
  ALSA: hda/ca0132 - Add speaker tuning initialization commands.
  ALSA: hda/ca0132 - Add surround channel config control.
  ALSA: hda/ca0132 - Add full-range speaker selection controls.
  ALSA: hda/ca0132 - Add bass redirection controls.
  ALSA: hda/ca0132 - Remove surround output selection.
  ALSA: hda/ca0132 - Clean up ca0132_alt_out_select.
  ALSA: hda/ca0132 - Add quirk output selection structures.
  ALSA: hda/ca0132 - Fix Recon3D Center/LFE output.
  ALSA: hda/ca0132 - Add new quirk ID for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add SoundBlaster AE-7 pincfg.
  ALSA: hda/ca0132 - Set AE-7 bools and select mixer.
  ALSA: hda/ca0132 - Add ca0132_mmio_init data for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add pre-init function for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add init data for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add DSP setup functions for AE-7.
  ALSA: hda/ca0132 - Add output selection for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add AE-7 microphone selection commands.
  ALSA: hda/ca0132 - Add AE-7 custom controls.
  ALSA: hda/ca0132 - Add AE-7 exit commands.

 sound/pci/hda/patch_ca0132.c | 1794 +++---
 1 file changed, 1430 insertions(+), 364 deletions(-)

-- 
2.20.1



[PATCH v2 02/20] ALSA: hda/ca0132 - Add speaker tuning initialization commands.

2020-08-25 Thread Connor McAdams
Add speaker tuning initialization DSP commands, and also define
previously unknown DSP command values.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 119 +++
 1 file changed, 119 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 7491e2044638..2e664aeee1c4 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -589,6 +589,60 @@ static const struct ct_eq_preset ca0132_alt_eq_presets[] = 
{
}
 };
 
+/*
+ * Definitions for the DSP req's to handle speaker tuning. These all belong to
+ * module ID 0x96, the output effects module.
+ */
+enum speaker_tuning_reqs {
+   /*
+* Currently, this value is always set to 0.0f. However, on Windows,
+* when selecting certain headphone profiles on the new Sound Blaster
+* connect software, the QUERY_SPEAKER_EQ_ADDRESS req on mid 0x80 is
+* sent. This gets the speaker EQ address area, which is then used to
+* send over (presumably) an equalizer profile for the specific
+* headphone setup. It is sent using the same method the DSP
+* firmware is uploaded with, which I believe is why the 'ctspeq.bin'
+* file exists in linux firmware tree but goes unused. It would also
+* explain why the QUERY_SPEAKER_EQ_ADDRESS req is defined but unused.
+* Once this profile is sent over, SPEAKER_TUNING_USE_SPEAKER_EQ is
+* set to 1.0f.
+*/
+   SPEAKER_TUNING_USE_SPEAKER_EQ   = 0x1f,
+   SPEAKER_TUNING_ENABLE_CENTER_EQ = 0x20,
+   SPEAKER_TUNING_FRONT_LEFT_VOL_LEVEL = 0x21,
+   SPEAKER_TUNING_FRONT_RIGHT_VOL_LEVEL= 0x22,
+   SPEAKER_TUNING_CENTER_VOL_LEVEL = 0x23,
+   SPEAKER_TUNING_LFE_VOL_LEVEL= 0x24,
+   SPEAKER_TUNING_REAR_LEFT_VOL_LEVEL  = 0x25,
+   SPEAKER_TUNING_REAR_RIGHT_VOL_LEVEL = 0x26,
+   SPEAKER_TUNING_SURROUND_LEFT_VOL_LEVEL  = 0x27,
+   SPEAKER_TUNING_SURROUND_RIGHT_VOL_LEVEL = 0x28,
+   /*
+* Inversion is used when setting headphone virtualization to line
+* out. Not sure why this is, but it's the only place it's ever used.
+*/
+   SPEAKER_TUNING_FRONT_LEFT_INVERT= 0x29,
+   SPEAKER_TUNING_FRONT_RIGHT_INVERT   = 0x2a,
+   SPEAKER_TUNING_CENTER_INVERT= 0x2b,
+   SPEAKER_TUNING_LFE_INVERT   = 0x2c,
+   SPEAKER_TUNING_REAR_LEFT_INVERT = 0x2d,
+   SPEAKER_TUNING_REAR_RIGHT_INVERT= 0x2e,
+   SPEAKER_TUNING_SURROUND_LEFT_INVERT = 0x2f,
+   SPEAKER_TUNING_SURROUND_RIGHT_INVERT= 0x30,
+   /* Delay is used when setting surround speaker distance in Windows. */
+   SPEAKER_TUNING_FRONT_LEFT_DELAY = 0x31,
+   SPEAKER_TUNING_FRONT_RIGHT_DELAY= 0x32,
+   SPEAKER_TUNING_CENTER_DELAY = 0x33,
+   SPEAKER_TUNING_LFE_DELAY= 0x34,
+   SPEAKER_TUNING_REAR_LEFT_DELAY  = 0x35,
+   SPEAKER_TUNING_REAR_RIGHT_DELAY = 0x36,
+   SPEAKER_TUNING_SURROUND_LEFT_DELAY  = 0x37,
+   SPEAKER_TUNING_SURROUND_RIGHT_DELAY = 0x38,
+   /* Of these two, only mute seems to ever be used. */
+   SPEAKER_TUNING_MAIN_VOLUME  = 0x39,
+   SPEAKER_TUNING_MUTE = 0x3a,
+};
+
 /* DSP command sequences for ca0132_alt_select_out */
 #define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
 struct ca0132_alt_out_set {
@@ -6874,6 +6928,67 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
}
 }
 
+/*
+ * Default speaker tuning values setup for alternative codecs.
+ */
+static const unsigned int sbz_default_delay_values[] = {
+   /* Non-zero values are floating point 0.000198. */
+   0x394f9e38, 0x394f9e38, 0x, 0x, 0x, 0x
+};
+
+static const unsigned int zxr_default_delay_values[] = {
+   /* Non-zero values are floating point 0.000220. */
+   0x, 0x, 0x3966afcd, 0x3966afcd, 0x3966afcd, 0x3966afcd
+};
+
+static const unsigned int ae5_default_delay_values[] = {
+   /* Non-zero values are floating point 0.000100. */
+   0x, 0x, 0x38d1b717, 0x38d1b717, 0x38d1b717, 0x38d1b717
+};
+
+/*
+ * If we never change these, probably only need them on initialization.
+ */
+static void ca0132_alt_init_speaker_tuning(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int i, tmp, start_req, end_req;
+   const unsigned int *values;
+
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_SBZ:
+   values = sbz_default_delay_values;
+   break;
+   case QUIRK_ZXR:
+   values = zxr_default_delay_values;
+   break;
+   case QUIRK_AE5:
+   values = ae5_default_delay_values;
+   break;
+   default:
+   val

[PATCH 13/20] ALSA: hda/ca0132 - Add ca0132_mmio_init data for SoundBlaster AE-7.

2020-08-21 Thread Connor McAdams
Modify the AE-5 ca0132_mmio_init function to add AE-7 specific writes.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 20 +++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ffad29ac7290..41838a5587b6 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8748,8 +8748,26 @@ static void ca0132_mmio_init_ae5(struct hda_codec *codec)
data = ca0113_mmio_init_data_ae5;
count = ARRAY_SIZE(ca0113_mmio_init_data_ae5);
 
-   for (i = 0; i < count; i++)
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   writel(0x0680, spec->mem_base + 0x1c);
+   writel(0x00880680, spec->mem_base + 0x1c);
+   }
+
+   for (i = 0; i < count; i++) {
+   /*
+* AE-7 shares all writes with the AE-5, except that it writes
+* a different value to 0x20c.
+*/
+   if (i == 21 && ca0132_quirk(spec) == QUIRK_AE7) {
+   writel(0x0081, spec->mem_base + addr[i]);
+   continue;
+   }
+
writel(data[i], spec->mem_base + addr[i]);
+   }
+
+   if (ca0132_quirk(spec) == QUIRK_AE5)
+   writel(0x00880680, spec->mem_base + 0x1c);
 }
 
 static void ca0132_mmio_init(struct hda_codec *codec)
-- 
2.20.1



[PATCH 09/20] ALSA: hda/ca0132 - Fix Recon3D Center/LFE output.

2020-08-21 Thread Connor McAdams
Properly set the GPIO pin to un-mute the Center/LFE channel on the
Recon3D.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ac9dcaf69a2e..9c61a10114aa 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7819,6 +7819,12 @@ static void r3d_setup_defaults(struct hda_codec *codec)
if (ca0132_quirk(spec) == QUIRK_R3DI)
r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
 
+   /* Disable mute on Center/LFE. */
+   if (ca0132_quirk(spec) == QUIRK_R3D) {
+   ca0113_mmio_gpio_set(codec, 2, false);
+   ca0113_mmio_gpio_set(codec, 4, true);
+   }
+
/* Setup effect defaults */
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
for (idx = 0; idx < num_fx; idx++) {
-- 
2.20.1



[PATCH 14/20] ALSA: hda/ca0132 - Add pre-init function for SoundBlaster AE-7.

2020-08-21 Thread Connor McAdams
Add pre DSP initialization function for the AE-7.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 70 
 1 file changed, 55 insertions(+), 15 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 41838a5587b6..9a1491d33819 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8786,6 +8786,16 @@ static void ca0132_mmio_init(struct hda_codec *codec)
}
 }
 
+static const unsigned int ca0132_ae5_register_set_addresses[] = {
+   0x304, 0x304, 0x304, 0x304, 0x100, 0x304, 0x100, 0x304, 0x100, 0x304,
+   0x100, 0x304, 0x86c, 0x800, 0x86c, 0x800, 0x804
+};
+
+static const unsigned char ca0132_ae5_register_set_data[] = {
+   0x0f, 0x0e, 0x1f, 0x0c, 0x3f, 0x08, 0x7f, 0x00, 0xff, 0x00, 0x6b,
+   0x01, 0x6b, 0x57
+};
+
 /*
  * This function writes to some SFR's, does some region2 writes, and then
  * eventually resets the codec with the 0x7ff verb. Not quite sure why it does
@@ -8794,6 +8804,18 @@ static void ca0132_mmio_init(struct hda_codec *codec)
 static void ae5_register_set(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   unsigned int count = ARRAY_SIZE(ca0132_ae5_register_set_addresses);
+   const unsigned int *addr = ca0132_ae5_register_set_addresses;
+   const unsigned char *data = ca0132_ae5_register_set_data;
+   unsigned int i, cur_addr;
+   unsigned char tmp[3];
+
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x41);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc8);
+   }
 
chipio_8051_write_direct(codec, 0x93, 0x10);
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
@@ -8801,25 +8823,43 @@ static void ae5_register_set(struct hda_codec *codec)
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc2);
 
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0f, spec->mem_base + 0x304);
-   writeb(0x0e, spec->mem_base + 0x100);
-   writeb(0x1f, spec->mem_base + 0x304);
-   writeb(0x0c, spec->mem_base + 0x100);
-   writeb(0x3f, spec->mem_base + 0x304);
-   writeb(0x08, spec->mem_base + 0x100);
-   writeb(0x7f, spec->mem_base + 0x304);
-   writeb(0x00, spec->mem_base + 0x100);
-   writeb(0xff, spec->mem_base + 0x304);
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   tmp[0] = 0x03;
+   tmp[1] = 0x03;
+   tmp[2] = 0x07;
+   } else {
+   tmp[0] = 0x0f;
+   tmp[1] = 0x0f;
+   tmp[2] = 0x0f;
+   }
 
-   ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
+   for (i = cur_addr = 0; i < 3; i++, cur_addr++)
+   writeb(tmp[i], spec->mem_base + addr[cur_addr]);
+
+   /*
+* First writes are in single bytes, final are in 4 bytes. So, we use
+* writeb, then writel.
+*/
+   for (i = 0; cur_addr < 12; i++, cur_addr++)
+   writeb(data[i], spec->mem_base + addr[cur_addr]);
+
+   for (; cur_addr < count; i++, cur_addr++)
+   writel(data[i], spec->mem_base + addr[cur_addr]);
+
+   writel(0x0081, spec->mem_base + 0x20c);
+
+   if (ca0132_quirk(spec) == QUIRK_AE7) {
+   ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
+   ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x3f);
+   } else {
+   ca0113_mmio_command_set(codec, 0x30, 0x2d, 0x3f);
+   }
 
chipio_8051_write_direct(codec, 0x90, 0x00);
chipio_8051_write_direct(codec, 0x90, 0x10);
 
-   ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
+   if (ca0132_quirk(spec) == QUIRK_AE5)
+   ca0113_mmio_command_set(codec, 0x48, 0x07, 0x83);
 
chipio_write(codec, 0x18b0a4, 0x00c2);
 
@@ -8918,7 +8958,7 @@ static int ca0132_init(struct hda_codec *codec)
 
snd_hda_power_up_pm(codec);
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
+   if (ca0132_quirk(spec) == QUIRK_AE5 || ca0132_quirk(spec) == QUIRK_AE7)
ae5_register_set(codec);
 
ca0132_init_unsol(codec);
-- 
2.20.1



[PATCH 06/20] ALSA: hda/ca0132 - Remove surround output selection.

2020-08-21 Thread Connor McAdams
Remove the surround output selection and merge it with the speaker
output selection. Now that the extra commands that were being run on
surround output setting are known, there's no need to have it be
separate.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 151 +++
 1 file changed, 46 insertions(+), 105 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index d97358406401..f0fa1e8f41da 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -82,11 +82,10 @@ MODULE_FIRMWARE(R3DI_EFX_FILE);
 
 static const char *const dirstr[2] = { "Playback", "Capture" };
 
-#define NUM_OF_OUTPUTS 3
+#define NUM_OF_OUTPUTS 2
 enum {
SPEAKER_OUT,
HEADPHONE_OUT,
-   SURROUND_OUT
 };
 
 enum {
@@ -699,16 +698,6 @@ static const struct ca0132_alt_out_set alt_out_presets[] = 
{
0x, 0x, 0x,
0x }
},
-   { .name = "Surround",
- .commands = 8,
- .mids = { 0x96, 0x8F, 0x96, 0x96,
-   0x96, 0x96, 0x96, 0x96 },
- .reqs = { 0x18, 0x01, 0x1F, 0x15,
-   0x3A, 0x1A, 0x1B, 0x1C },
- .vals = { 0x, 0x, 0x,
-   0x, 0x, 0x,
-   0x, 0x }
-   }
 };
 
 /* Surround output channel count configuration structures. */
@@ -785,10 +774,6 @@ static const struct ae5_ca0113_output_set 
ae5_ca0113_output_presets[] = {
{ .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
  .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
  .vals =   { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 }
-   },
-   { .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
- .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
- .vals =   { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f }
}
 };
 
@@ -4440,42 +4425,6 @@ static void ca0132_alt_select_out_quirk_handler(struct 
hda_codec *codec)
break;
}
break;
-   case SURROUND_OUT:
-   switch (ca0132_quirk(spec)) {
-   case QUIRK_SBZ:
-   ca0113_mmio_gpio_set(codec, 7, false);
-   ca0113_mmio_gpio_set(codec, 4, true);
-   ca0113_mmio_gpio_set(codec, 1, true);
-   chipio_set_control_param(codec, 0x0d, 0x18);
-   break;
-   case QUIRK_ZXR:
-   ca0113_mmio_gpio_set(codec, 2, true);
-   ca0113_mmio_gpio_set(codec, 3, true);
-   ca0113_mmio_gpio_set(codec, 5, false);
-   zxr_headphone_gain_set(codec, 0);
-   chipio_set_control_param(codec, 0x0d, 0x24);
-   break;
-   case QUIRK_R3DI:
-   chipio_set_control_param(codec, 0x0d, 0x24);
-   r3di_gpio_out_set(codec, R3DI_LINE_OUT);
-   break;
-   case QUIRK_R3D:
-   ca0113_mmio_gpio_set(codec, 1, true);
-   chipio_set_control_param(codec, 0x0d, 0x24);
-   break;
-   case QUIRK_AE5:
-   ae5_mmio_select_out(codec);
-   ae5_headphone_gain_set(codec, 2);
-   tmp = FLOAT_ZERO;
-   dspio_set_uint_param(codec, 0x96, 0x29, tmp);
-   dspio_set_uint_param(codec, 0x96, 0x2a, tmp);
-   chipio_set_control_param(codec, 0x0d, 0xa4);
-   chipio_write(codec, 0x18b03c, 0x0012);
-   break;
-   default:
-   break;
-   }
-   break;
}
 }
 
@@ -4492,11 +4441,10 @@ static void ca0132_alt_select_out_quirk_handler(struct 
hda_codec *codec)
 static int ca0132_alt_select_out(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp, outfx_set, i;
unsigned int pin_ctl;
int jack_present;
int auto_jack;
-   unsigned int i;
-   unsigned int tmp;
int err;
/* Default Headphone is rear headphone */
hda_nid_t headphone_nid = spec->out_pins[1];
@@ -4523,6 +4471,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
} else
spec->cur_out_type = spec->out_enum_val;
 
+   outfx_set = spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID];
+
/* Begin DSP output switch */
tmp = FLOAT_ONE;
err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp);
@@ -4536,6 +4486,7 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
codec_dbg(codec, "%s speaker\n", __func__);
 
/* disable headphone node */
+
 

[PATCH 07/20] ALSA: hda/ca0132 - Clean up ca0132_alt_out_select.

2020-08-21 Thread Connor McAdams
Remove the output structures that were in use before and instead set the
DSP commands line by line. Now that the commands use is known, it makes
the functionality more clear this way.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 142 ++-
 1 file changed, 57 insertions(+), 85 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index f0fa1e8f41da..ee25265ab600 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -83,6 +83,7 @@ MODULE_FIRMWARE(R3DI_EFX_FILE);
 static const char *const dirstr[2] = { "Playback", "Capture" };
 
 #define NUM_OF_OUTPUTS 2
+static const char *const out_type_str[2] = { "Speakers", "Headphone" };
 enum {
SPEAKER_OUT,
HEADPHONE_OUT,
@@ -667,39 +668,6 @@ enum speaker_tuning_reqs {
SPEAKER_TUNING_MUTE = 0x3a,
 };
 
-/* DSP command sequences for ca0132_alt_select_out */
-#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
-struct ca0132_alt_out_set {
-   char *name; /*preset name*/
-   unsigned char commands;
-   unsigned int mids[ALT_OUT_SET_MAX_COMMANDS];
-   unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS];
-   unsigned int vals[ALT_OUT_SET_MAX_COMMANDS];
-};
-
-static const struct ca0132_alt_out_set alt_out_presets[] = {
-   { .name = "Line Out",
- .commands = 7,
- .mids = { 0x96, 0x96, 0x96, 0x8F,
-   0x96, 0x96, 0x96 },
- .reqs = { 0x19, 0x17, 0x18, 0x01,
-   0x1F, 0x15, 0x3A },
- .vals = { 0x3F00, 0x42A0, 0x,
-   0x, 0x, 0x,
-   0x }
-   },
-   { .name = "Headphone",
- .commands = 7,
- .mids = { 0x96, 0x96, 0x96, 0x8F,
-   0x96, 0x96, 0x96 },
- .reqs = { 0x19, 0x17, 0x18, 0x01,
-   0x1F, 0x15, 0x3A },
- .vals = { 0x3F00, 0x42A0, 0x,
-   0x, 0x, 0x,
-   0x }
-   },
-};
-
 /* Surround output channel count configuration structures. */
 #define SPEAKER_CHANNEL_CFG_COUNT 5
 enum {
@@ -4428,21 +4396,31 @@ static void ca0132_alt_select_out_quirk_handler(struct 
hda_codec *codec)
}
 }
 
+static void ca0132_set_out_node_pincfg(struct hda_codec *codec, hda_nid_t nid,
+   bool out_enable, bool hp_enable)
+{
+   unsigned int pin_ctl;
+
+   pin_ctl = snd_hda_codec_read(codec, nid, 0,
+   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
+
+   pin_ctl = hp_enable ? pin_ctl | PIN_HP_AMP : pin_ctl & ~PIN_HP_AMP;
+   pin_ctl = out_enable ? pin_ctl | PIN_OUT : pin_ctl & ~PIN_OUT;
+   snd_hda_set_pin_ctl(codec, nid, pin_ctl);
+}
+
 /*
  * This function behaves similarly to the ca0132_select_out funciton above,
  * except with a few differences. It adds the ability to select the current
  * output with an enumerated control "output source" if the auto detect
  * mute switch is set to off. If the auto detect mute switch is enabled, it
  * will detect either headphone or lineout(SPEAKER_OUT) from jack detection.
- * It also adds the ability to auto-detect the front headphone port. The only
- * way to select surround is to disable auto detect, and set Surround with the
- * enumerated control.
+ * It also adds the ability to auto-detect the front headphone port.
  */
 static int ca0132_alt_select_out(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
-   unsigned int tmp, outfx_set, i;
-   unsigned int pin_ctl;
+   unsigned int tmp, outfx_set;
int jack_present;
int auto_jack;
int err;
@@ -4473,9 +4451,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
 
outfx_set = spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID];
 
-   /* Begin DSP output switch */
-   tmp = FLOAT_ONE;
-   err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp);
+   /* Begin DSP output switch, mute DSP volume. */
+   err = dspio_set_uint_param(codec, 0x96, SPEAKER_TUNING_MUTE, FLOAT_ONE);
if (err < 0)
goto exit;
 
@@ -4485,31 +4462,18 @@ static int ca0132_alt_select_out(struct hda_codec 
*codec)
case SPEAKER_OUT:
codec_dbg(codec, "%s speaker\n", __func__);
 
-   /* disable headphone node */
-
-   pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
-   AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
-   snd_hda_set_pin_ctl(codec, spec->out_pins[1],
-   pin_ctl & ~PIN_HP);
-   /* enable line-out node */
-   pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
-

[PATCH 17/20] ALSA: hda/ca0132 - Add output selection for SoundBlaster AE-7.

2020-08-21 Thread Connor McAdams
Add output selection quirk table information for SoundBlaster AE-7, and
slightly modify the AE-5's ca0113 command table to accommodate the AE-7.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 88 
 1 file changed, 68 insertions(+), 20 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 040233b33074..ad594c2d47ec 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -727,22 +727,29 @@ static const struct ct_dsp_volume_ctl 
ca0132_alt_vol_ctls[] = {
 };
 
 /* Values for ca0113_mmio_command_set for selecting output. */
-#define AE5_CA0113_OUT_SET_COMMANDS 6
-struct ae5_ca0113_output_set {
-   unsigned int group[AE5_CA0113_OUT_SET_COMMANDS];
-   unsigned int target[AE5_CA0113_OUT_SET_COMMANDS];
-   unsigned int vals[AE5_CA0113_OUT_SET_COMMANDS];
+#define AE_CA0113_OUT_SET_COMMANDS 6
+struct ae_ca0113_output_set {
+   unsigned int group[AE_CA0113_OUT_SET_COMMANDS];
+   unsigned int target[AE_CA0113_OUT_SET_COMMANDS];
+   unsigned int vals[NUM_OF_OUTPUTS][AE_CA0113_OUT_SET_COMMANDS];
 };
 
-static const struct ae5_ca0113_output_set ae5_ca0113_output_presets[] = {
-   { .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
- .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
- .vals =   { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f }
-   },
-   { .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
- .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
- .vals =   { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 }
-   }
+static const struct ae_ca0113_output_set ae5_ca0113_output_presets = {
+   .group =  { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
+   .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
+   /* Speakers. */
+   .vals =   { { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f },
+   /* Headphones. */
+   { 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00 } },
+};
+
+static const struct ae_ca0113_output_set ae7_ca0113_output_presets = {
+   .group  = { 0x30, 0x30, 0x48, 0x48, 0x48, 0x30 },
+   .target = { 0x2e, 0x30, 0x0d, 0x17, 0x19, 0x32 },
+   /* Speakers. */
+   .vals   = { { 0x00, 0x00, 0x40, 0x00, 0x00, 0x3f },
+   /* Headphones. */
+   { 0x3f, 0x3f, 0x00, 0x00, 0x02, 0x00 } },
 };
 
 /* ae5 ca0113 command sequences to set headphone gain levels. */
@@ -1427,6 +1434,41 @@ static const struct ca0132_alt_out_set_quirk_data 
quirk_out_set_data[] = {
  .chipio_write_addr = 0x0018b03c,
  .chipio_write_data = 0x0012
} },
+   },
+   { .quirk_id = QUIRK_AE7,
+ .has_headphone_gain = true,
+ .is_ae_series   = true,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port  = 0x58,
+ .has_hda_gpio  = false,
+ .mmio_gpio_count   = 1,
+ .mmio_gpio_pin = { 0 },
+ .mmio_gpio_set = { 1 },
+ .scp_cmds_count= 2,
+ .scp_cmd_mid   = { 0x96, 0x96 },
+ .scp_cmd_req   = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
+SPEAKER_TUNING_FRONT_RIGHT_INVERT },
+ .scp_cmd_val   = { FLOAT_ZERO, FLOAT_ZERO },
+ .has_chipio_write  = true,
+ .chipio_write_addr = 0x0018b03c,
+ .chipio_write_data = 0x
+   },
+   /* Headphones. */
+   { .dac2port  = 0x58,
+ .has_hda_gpio  = false,
+ .mmio_gpio_count   = 1,
+ .mmio_gpio_pin = { 0 },
+ .mmio_gpio_set = { 1 },
+ .scp_cmds_count= 2,
+ .scp_cmd_mid   = { 0x96, 0x96 },
+ .scp_cmd_req   = { SPEAKER_TUNING_FRONT_LEFT_INVERT,
+SPEAKER_TUNING_FRONT_RIGHT_INVERT },
+ .scp_cmd_val   = { FLOAT_ONE, FLOAT_ONE },
+ .has_chipio_write  = true,
+ .chipio_write_addr = 0x0018b03c,
+ .chipio_write_data = 0x0010
+   } },
}
 };
 
@@ -4383,18 +4425,24 @@ static int ca0132_effects_set(struct hda_codec *codec, 
hda_nid_t nid, long val);
 static void ae5_mmio_select_out(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   const struct ae_ca0113_output_set *out_cmds;
unsigned int i;
 
-   for (i = 0; i < AE5_CA0113_OUT_SET_COMMANDS; i++)
-   ca0113_mmio_command_set(codec,
-   ae5_ca0113_output_presets[spec->cur_out_type].group[i],
-   ae5_ca0113_output_presets[spec->cur_out_type].target[i],
-   ae5_ca0113_output_presets[spec->cur_out_type].vals[i]);
+   if (ca0132_quirk(spe

[PATCH 16/20] ALSA: hda/ca0132 - Add DSP setup functions for AE-7.

2020-08-21 Thread Connor McAdams
Add DSP setup functions for the Sound Blaster AE-7 post DSP download.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 290 +++
 1 file changed, 290 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4ec93a070d73..040233b33074 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7378,6 +7378,7 @@ static void ca0132_alt_init_speaker_tuning(struct 
hda_codec *codec)
values = zxr_default_delay_values;
break;
case QUIRK_AE5:
+   case QUIRK_AE7:
values = ae5_default_delay_values;
break;
default:
@@ -7551,6 +7552,7 @@ static void ca0132_alt_dsp_scp_startup(struct hda_codec 
*codec)
switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
+   case QUIRK_AE7:
tmp = 0x0003;
dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
tmp = 0x;
@@ -7760,6 +7762,206 @@ static void ae5_post_dsp_startup_data(struct hda_codec 
*codec)
mutex_unlock(>chipio_mutex);
 }
 
+static const unsigned int ae7_port_set_data[] = {
+   0x0001e0c0, 0x0001e1c1, 0x0001e4c2, 0x0001e5c3, 0x0001e2c4, 0x0001e3c5,
+   0x0001e8c6, 0x0001e9c7, 0x0001ecc8, 0x0001edc9, 0x0001eaca, 0x0001ebcb
+};
+
+static void ae7_post_dsp_setup_ports(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int i, count, addr;
+
+   mutex_lock(>chipio_mutex);
+
+   chipio_set_stream_channels(codec, 0x0c, 6);
+   chipio_set_stream_control(codec, 0x0c, 1);
+
+   count = ARRAY_SIZE(ae7_port_set_data);
+   addr = 0x190030;
+   for (i = 0; i < count; i++) {
+   chipio_write_no_mutex(codec, addr, ae7_port_set_data[i]);
+
+   /* Addresses are incremented by 4-bytes. */
+   addr += 0x04;
+   }
+
+   /*
+* Port setting always ends with a write of 0x1 to address 0x19042c.
+*/
+   chipio_write_no_mutex(codec, 0x19042c, 0x0001);
+
+   ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
+   ca0113_mmio_command_set(codec, 0x48, 0x0d, 0x40);
+   ca0113_mmio_command_set(codec, 0x48, 0x17, 0x00);
+   ca0113_mmio_command_set(codec, 0x48, 0x19, 0x00);
+   ca0113_mmio_command_set(codec, 0x48, 0x11, 0xff);
+   ca0113_mmio_command_set(codec, 0x48, 0x12, 0xff);
+   ca0113_mmio_command_set(codec, 0x48, 0x13, 0xff);
+   ca0113_mmio_command_set(codec, 0x48, 0x14, 0x7f);
+
+   mutex_unlock(>chipio_mutex);
+}
+
+static void ae7_post_dsp_asi_stream_setup(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+
+   mutex_lock(>chipio_mutex);
+
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x725, 0x81);
+   ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
+
+   chipio_set_conn_rate_no_mutex(codec, 0x70, SR_96_000);
+   chipio_set_stream_channels(codec, 0x0c, 6);
+   chipio_set_stream_control(codec, 0x0c, 1);
+
+   chipio_set_stream_source_dest(codec, 0x05, 0x43, 0x00);
+   chipio_set_stream_source_dest(codec, 0x18, 0x09, 0xd0);
+
+   chipio_set_conn_rate_no_mutex(codec, 0xd0, SR_96_000);
+   chipio_set_stream_channels(codec, 0x18, 6);
+   chipio_set_stream_control(codec, 0x18, 1);
+
+   chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_ASI, 4);
+
+   mutex_unlock(>chipio_mutex);
+}
+
+static void ae7_post_dsp_pll_setup(struct hda_codec *codec)
+{
+   const unsigned int addr[] = { 0x41, 0x45, 0x40, 0x43, 0x51 };
+   const unsigned int data[] = { 0xc8, 0xcc, 0xcb, 0xc7, 0x8d };
+   unsigned int i;
+
+   for (i = 0; i < ARRAY_SIZE(addr); i++) {
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, addr[i]);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, data[i]);
+   }
+}
+
+static void ae7_post_dsp_asi_setup_ports(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   const unsigned int target[] = { 0x0b, 0x04, 0x06, 0x0a, 0x0c, 0x11,
+   0x12, 0x13, 0x14 };
+   const unsigned int data[]   = { 0x12, 0x00, 0x48, 0x05, 0x5f, 0xff,
+   0xff, 0xff, 0x7f };
+   unsigned int i;
+
+   mutex_lock(>chipio_mutex);
+
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x43);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, 0xc7);
+
+   chipio_write_no_mutex(codec, 0x189000, 0x0001f101);
+   chipio_write_no_mutex(codec, 0x189004, 0x0001f101);
+ 

[PATCH 15/20] ALSA: hda/ca0132 - Add init data for SoundBlaster AE-7.

2020-08-21 Thread Connor McAdams
Add initialization data for the SoundBlaster AE-7 card.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9a1491d33819..4ec93a070d73 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -3582,6 +3582,7 @@ static void ca0132_gpio_init(struct hda_codec *codec)
switch (ca0132_quirk(spec)) {
case QUIRK_SBZ:
case QUIRK_AE5:
+   case QUIRK_AE7:
snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
snd_hda_codec_write(codec, 0x01, 0, 0x790, 0x23);
@@ -8911,6 +8912,19 @@ static void ca0132_alt_init(struct hda_codec *codec)
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
break;
+   case QUIRK_AE7:
+   ca0132_gpio_init(codec);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x49);
+   snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
+   VENDOR_CHIPIO_PLL_PMU_WRITE, 0x88);
+   snd_hda_sequence_write(codec, spec->chip_init_verbs);
+   snd_hda_sequence_write(codec, spec->desktop_init_verbs);
+   chipio_write(codec, 0x18b008, 0x00f8);
+   chipio_write(codec, 0x18b008, 0x00f0);
+   chipio_write(codec, 0x18b030, 0x0020);
+   ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
+   break;
case QUIRK_ZXR:
snd_hda_sequence_write(codec, spec->chip_init_verbs);
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
-- 
2.20.1



[PATCH 08/20] ALSA: hda/ca0132 - Add quirk output selection structures.

2020-08-21 Thread Connor McAdams
Add structures containing the changes that need to happen on output
selection for each quirk. This should streamline the addition of new
quirks.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 336 +--
 1 file changed, 241 insertions(+), 95 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ee25265ab600..ac9dcaf69a2e 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1256,6 +1256,164 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
{}
 };
 
+/* Output selection quirk info structures. */
+#define MAX_QUIRK_MMIO_GPIO_SET_VALS 3
+#define MAX_QUIRK_SCP_SET_VALS 2
+struct ca0132_alt_out_set_info {
+   unsigned int dac2port; /* ParamID 0x0d value. */
+
+   bool has_hda_gpio;
+   char hda_gpio_pin;
+   char hda_gpio_set;
+
+   unsigned int mmio_gpio_count;
+   char mmio_gpio_pin[MAX_QUIRK_MMIO_GPIO_SET_VALS];
+   char mmio_gpio_set[MAX_QUIRK_MMIO_GPIO_SET_VALS];
+
+   unsigned int scp_cmds_count;
+   unsigned int scp_cmd_mid[MAX_QUIRK_SCP_SET_VALS];
+   unsigned int scp_cmd_req[MAX_QUIRK_SCP_SET_VALS];
+   unsigned int scp_cmd_val[MAX_QUIRK_SCP_SET_VALS];
+
+   bool has_chipio_write;
+   unsigned int chipio_write_addr;
+   unsigned int chipio_write_data;
+};
+
+struct ca0132_alt_out_set_quirk_data {
+   int quirk_id;
+
+   bool has_headphone_gain;
+   bool is_ae_series;
+
+   struct ca0132_alt_out_set_info out_set_info[NUM_OF_OUTPUTS];
+};
+
+static const struct ca0132_alt_out_set_quirk_data quirk_out_set_data[] = {
+   { .quirk_id = QUIRK_R3DI,
+ .has_headphone_gain = false,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x24,
+ .has_hda_gpio = true,
+ .hda_gpio_pin = 2,
+ .hda_gpio_set = 1,
+ .mmio_gpio_count  = 0,
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   },
+   /* Headphones. */
+   { .dac2port = 0x21,
+ .has_hda_gpio = true,
+ .hda_gpio_pin = 2,
+ .hda_gpio_set = 0,
+ .mmio_gpio_count  = 0,
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   } },
+   },
+   { .quirk_id = QUIRK_R3D,
+ .has_headphone_gain = false,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x24,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 1,
+ .mmio_gpio_pin= { 1 },
+ .mmio_gpio_set= { 1 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   },
+   /* Headphones. */
+   { .dac2port = 0x21,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 1,
+ .mmio_gpio_pin= { 1 },
+ .mmio_gpio_set= { 0 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   } },
+   },
+   { .quirk_id = QUIRK_SBZ,
+ .has_headphone_gain = false,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x18,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 7, 4, 1 },
+ .mmio_gpio_set= { 0, 1, 1 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false, },
+   /* Headphones. */
+   { .dac2port = 0x12,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 7, 4, 1 },
+ .mmio_gpio_set= { 1, 1, 0 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   } },
+   },
+   { .quirk_id = QUIRK_ZXR,
+ .has_headphone_gain = true,
+ .is_ae_series   = false,
+ .out_set_info = {
+   /* Speakers. */
+   { .dac2port = 0x24,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 2, 3, 5 },
+ .mmio_gpio_set= { 1, 1, 0 },
+ .scp_cmds_count   = 0,
+ .has_chipio_write = false,
+   },
+   /* Headphones. */
+   { .dac2port = 0x21,
+ .has_hda_gpio = false,
+ .mmio_gpio_count  = 3,
+ .mmio_gpio_pin= { 2, 3, 5 },
+ .mmio_gpio_set

[PATCH 18/20] ALSA: hda/ca0132 - Add AE-7 microphone selection commands.

2020-08-21 Thread Connor McAdams
Add AE-7 quirk data for setting of microphone. The AE-7 has no front
panel connector, so only rear-mic/line-in have new commands.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 22 +-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index ad594c2d47ec..933f3b0be63e 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4997,6 +4997,15 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
tmp = FLOAT_THREE;
break;
+   case QUIRK_AE7:
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
+   tmp = FLOAT_THREE;
+   chipio_set_conn_rate(codec, MEM_CONNID_MICIN2,
+   SR_96_000);
+   chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2,
+   SR_96_000);
+   dspio_set_uint_param(codec, 0x80, 0x01, FLOAT_ZERO);
+   break;
default:
tmp = FLOAT_ONE;
break;
@@ -5042,6 +5051,14 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
case QUIRK_AE5:
ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
break;
+   case QUIRK_AE7:
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x3f);
+   chipio_set_conn_rate(codec, MEM_CONNID_MICIN2,
+   SR_96_000);
+   chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2,
+   SR_96_000);
+   dspio_set_uint_param(codec, 0x80, 0x01, FLOAT_ZERO);
+   break;
default:
break;
}
@@ -5051,7 +5068,10 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
if (ca0132_quirk(spec) == QUIRK_R3DI)
chipio_set_conn_rate(codec, 0x0F, SR_96_000);
 
-   tmp = FLOAT_ZERO;
+   if (ca0132_quirk(spec) == QUIRK_AE7)
+   tmp = FLOAT_THREE;
+   else
+   tmp = FLOAT_ZERO;
dspio_set_uint_param(codec, 0x80, 0x00, tmp);
 
switch (ca0132_quirk(spec)) {
-- 
2.20.1



[PATCH 10/20] ALSA: hda/ca0132 - Add new quirk ID for SoundBlaster AE-7.

2020-08-21 Thread Connor McAdams
Add a new PCI subsystem ID for the SoundBlaster AE-7 card.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9c61a10114aa..57cb63ea88e6 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1134,6 +1134,7 @@ enum {
QUIRK_R3DI,
QUIRK_R3D,
QUIRK_AE5,
+   QUIRK_AE7,
 };
 
 #ifdef CONFIG_PCI
@@ -1253,6 +1254,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
+   SND_PCI_QUIRK(0x1102, 0x0081, "Sound Blaster AE-7", QUIRK_AE7),
{}
 };
 
-- 
2.20.1



[PATCH 12/20] ALSA: hda/ca0132 - Set AE-7 bools and select mixer.

2020-08-21 Thread Connor McAdams
Set the boolean values used for desktop cards, and select the desktop
mixer.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 5aad9d8ee5e4..ffad29ac7290 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -9403,6 +9403,10 @@ static int patch_ca0132(struct hda_codec *codec)
spec->mixers[0] = desktop_mixer;
snd_hda_codec_set_name(codec, "Sound BlasterX AE-5");
break;
+   case QUIRK_AE7:
+   spec->mixers[0] = desktop_mixer;
+   snd_hda_codec_set_name(codec, "Sound Blaster AE-7");
+   break;
default:
spec->mixers[0] = ca0132_mixer;
break;
@@ -9413,6 +9417,7 @@ static int patch_ca0132(struct hda_codec *codec)
case QUIRK_SBZ:
case QUIRK_R3D:
case QUIRK_AE5:
+   case QUIRK_AE7:
case QUIRK_ZXR:
spec->use_alt_controls = true;
spec->use_alt_functions = true;
-- 
2.20.1



[PATCH 11/20] ALSA: hda/ca0132 - Add SoundBlaster AE-7 pincfg.

2020-08-21 Thread Connor McAdams
Add AE-7 pincfg, based on the values set within Windows.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 57cb63ea88e6..5aad9d8ee5e4 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1238,6 +1238,20 @@ static const struct hda_pintbl r3di_pincfgs[] = {
{}
 };
 
+static const struct hda_pintbl ae7_pincfgs[] = {
+   { 0x0b, 0x01017010 },
+   { 0x0c, 0x014510f0 },
+   { 0x0d, 0x414510f0 },
+   { 0x0e, 0x01c520f0 },
+   { 0x0f, 0x01017114 },
+   { 0x10, 0x01017011 },
+   { 0x11, 0x018170ff },
+   { 0x12, 0x01a170f0 },
+   { 0x13, 0x908700f0 },
+   { 0x18, 0x50f0 },
+   {}
+};
+
 static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1028, 0x057b, "Alienware M17x R4", 
QUIRK_ALIENWARE_M17XR4),
SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
@@ -9105,6 +9119,10 @@ static void ca0132_config(struct hda_codec *codec)
codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__);
snd_hda_apply_pincfgs(codec, ae5_pincfgs);
break;
+   case QUIRK_AE7:
+   codec_dbg(codec, "%s: QUIRK_AE7 applied.\n", __func__);
+   snd_hda_apply_pincfgs(codec, ae7_pincfgs);
+   break;
default:
break;
}
@@ -9186,6 +9204,7 @@ static void ca0132_config(struct hda_codec *codec)
spec->dig_in = 0x09;
break;
case QUIRK_AE5:
+   case QUIRK_AE7:
spec->num_outputs = 2;
spec->out_pins[0] = 0x0B; /* Line out */
spec->out_pins[1] = 0x11; /* Rear headphone out */
-- 
2.20.1



[PATCH 20/20] ALSA: hda/ca0132 - Add AE-7 exit commands.

2020-08-21 Thread Connor McAdams
Add exit commands for the AE-7.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 29 +
 1 file changed, 29 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9c70d85b21e0..4d26440eceb0 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8838,6 +8838,32 @@ static void ae5_exit_chip(struct hda_codec *codec)
snd_hda_codec_write(codec, 0x01, 0, 0x724, 0x83);
 }
 
+static void ae7_exit_chip(struct hda_codec *codec)
+{
+   chipio_set_stream_control(codec, 0x18, 0);
+   chipio_set_stream_source_dest(codec, 0x21, 0xc8, 0xc8);
+   chipio_set_stream_channels(codec, 0x21, 0);
+   chipio_set_control_param(codec, CONTROL_PARAM_NODE_ID, 0x09);
+   chipio_set_control_param(codec, 0x20, 0x01);
+
+   chipio_set_control_param(codec, CONTROL_PARAM_ASI, 0);
+
+   chipio_set_stream_control(codec, 0x18, 0);
+   chipio_set_stream_control(codec, 0x0c, 0);
+
+   ca0113_mmio_command_set(codec, 0x30, 0x2b, 0x00);
+   snd_hda_codec_write(codec, 0x15, 0, 0x724, 0x83);
+   ca0113_mmio_command_set_type2(codec, 0x48, 0x07, 0x83);
+   ca0113_mmio_command_set(codec, 0x30, 0x30, 0x00);
+   ca0113_mmio_command_set(codec, 0x30, 0x2e, 0x00);
+   ca0113_mmio_gpio_set(codec, 0, false);
+   ca0113_mmio_gpio_set(codec, 1, false);
+   ca0113_mmio_command_set(codec, 0x30, 0x32, 0x3f);
+
+   snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
+   snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
+}
+
 static void zxr_exit_chip(struct hda_codec *codec)
 {
chipio_set_stream_control(codec, 0x03, 0);
@@ -9457,6 +9483,9 @@ static void ca0132_free(struct hda_codec *codec)
case QUIRK_AE5:
ae5_exit_chip(codec);
break;
+   case QUIRK_AE7:
+   ae7_exit_chip(codec);
+   break;
case QUIRK_R3DI:
r3di_gpio_shutdown(codec);
break;
-- 
2.20.1



[PATCH 19/20] ALSA: hda/ca0132 - Add AE-7 custom controls.

2020-08-21 Thread Connor McAdams
Add headphone gain and DAC filter controls, which use the same commands
as the AE-5. Also, change input source enumerated control item count to
exclude front microphone.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 20 
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 933f3b0be63e..9c70d85b21e0 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -5839,6 +5839,13 @@ static int ca0132_alt_input_source_put(struct 
snd_kcontrol *kcontrol,
int sel = ucontrol->value.enumerated.item[0];
unsigned int items = IN_SRC_NUM_OF_INPUTS;
 
+   /*
+* The AE-7 has no front microphone, so limit items to 2: rear mic and
+* line-in.
+*/
+   if (ca0132_quirk(spec) == QUIRK_AE7)
+   items = 2;
+
if (sel >= items)
return 0;
 
@@ -7029,20 +7036,25 @@ static int ca0132_build_controls(struct hda_codec 
*codec)
}
}
 
-   if (ca0132_quirk(spec) == QUIRK_AE5) {
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_AE5:
+   case QUIRK_AE7:
err = ae5_add_headphone_gain_enum(codec);
if (err < 0)
return err;
err = ae5_add_sound_filter_enum(codec);
if (err < 0)
return err;
-   }
-
-   if (ca0132_quirk(spec) == QUIRK_ZXR) {
+   break;
+   case QUIRK_ZXR:
err = zxr_add_headphone_gain_switch(codec);
if (err < 0)
return err;
+   break;
+   default:
+   break;
}
+
 #ifdef ENABLE_TUNING_CONTROLS
add_tuning_ctls(codec);
 #endif
-- 
2.20.1



[PATCH 01/20] ALSA: hda/ca0132 - Cleanup ca0132_mmio_init function.

2020-08-21 Thread Connor McAdams
Cleanup the ca0132_mmio_init function, separating into two separate
functions, one for Sound Blaster Z/ZxR/Recon3D, and another for the
AE-5.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 158 ++-
 1 file changed, 99 insertions(+), 59 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index b7dbf2e7f77a..7491e2044638 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8108,78 +8108,118 @@ static void r3di_pre_dsp_setup(struct hda_codec *codec)
  * what they do, or if they're necessary. Could possibly
  * be removed. Figure they're better to leave in.
  */
-static void ca0132_mmio_init(struct hda_codec *codec)
+static const unsigned int ca0113_mmio_init_address_sbz[] = {
+   0x400, 0x408, 0x40c, 0x01c, 0xc0c, 0xc00, 0xc04, 0xc0c, 0xc0c, 0xc0c,
+   0xc0c, 0xc08, 0xc08, 0xc08, 0xc08, 0xc08, 0xc04
+};
+
+static const unsigned int ca0113_mmio_init_data_sbz[] = {
+   0x0030, 0x, 0x0003, 0x0003, 0x0003,
+   0x0003, 0x00c1, 0x00f1, 0x0001, 0x00c7,
+   0x00c1, 0x0080
+};
+
+static const unsigned int ca0113_mmio_init_data_zxr[] = {
+   0x0030, 0x, 0x, 0x0003, 0x0003,
+   0x0003, 0x0001, 0x00f1, 0x0001, 0x00c7,
+   0x00c1, 0x0080
+};
+
+static const unsigned int ca0113_mmio_init_address_ae5[] = {
+   0x400, 0x42c, 0x46c, 0x4ac, 0x4ec, 0x43c, 0x47c, 0x4bc, 0x4fc, 0x408,
+   0x100, 0x410, 0x40c, 0x100, 0x100, 0x830, 0x86c, 0x800, 0x86c, 0x800,
+   0x804, 0x20c, 0x01c, 0xc0c, 0xc00, 0xc04, 0xc0c, 0xc0c, 0xc0c, 0xc0c,
+   0xc08, 0xc08, 0xc08, 0xc08, 0xc08, 0xc04, 0x01c
+};
+
+static const unsigned int ca0113_mmio_init_data_ae5[] = {
+   0x0001, 0x, 0x, 0x, 0x,
+   0x, 0x, 0x, 0x, 0x0001,
+   0x0600, 0x0014, 0x0001, 0x060f, 0x070f,
+   0x0aff, 0x, 0x006b, 0x0001, 0x006b,
+   0x0057, 0x0080, 0x00880680, 0x0080, 0x0030,
+   0x, 0x, 0x0003, 0x0003, 0x0003,
+   0x0001, 0x00f1, 0x0001, 0x00c7, 0x00c1,
+   0x0080, 0x00880680
+};
+
+static void ca0132_mmio_init_sbz(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp[2], i, count, cur_addr;
+   const unsigned int *addr, *data;
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0001, spec->mem_base + 0x400);
-   else
-   writel(0x, spec->mem_base + 0x400);
+   addr = ca0113_mmio_init_address_sbz;
+   for (i = 0; i < 3; i++)
+   writel(0x, spec->mem_base + addr[i]);
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0001, spec->mem_base + 0x408);
-   else
-   writel(0x, spec->mem_base + 0x408);
+   cur_addr = i;
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_ZXR:
+   tmp[0] = 0x00880480;
+   tmp[1] = 0x0080;
+   break;
+   case QUIRK_SBZ:
+   tmp[0] = 0x00820680;
+   tmp[1] = 0x0083;
+   break;
+   case QUIRK_R3D:
+   tmp[0] = 0x00880680;
+   tmp[1] = 0x0083;
+   break;
+   default:
+   tmp[0] = 0x;
+   tmp[1] = 0x;
+   break;
+   }
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0001, spec->mem_base + 0x40c);
-   else
-   writel(0x, spec->mem_base + 0x40C);
+   for (i = 0; i < 2; i++)
+   writel(tmp[i], spec->mem_base + addr[cur_addr + i]);
 
-   if (ca0132_quirk(spec) == QUIRK_ZXR)
-   writel(0x00880640, spec->mem_base + 0x01C);
-   else
-   writel(0x00880680, spec->mem_base + 0x01C);
+   cur_addr += i;
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x0080, spec->mem_base + 0xC0C);
-   else
-   writel(0x0083, spec->mem_base + 0xC0C);
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_ZXR:
+   count = ARRAY_SIZE(ca0113_mmio_init_data_zxr);
+   data = ca0113_mmio_init_data_zxr;
+   break;
+   default:
+   count = ARRAY_SIZE(ca0113_mmio_init_data_sbz);
+   data = ca0113_mmio_init_data_sbz;
+   break;
+   }
 
-   writel(0x0030, spec->mem_base + 0xC00);
-   writel(0x, spec->mem_base + 0xC04);
+   for (i = 0; i < count; i++)
+   writel(data[i], spec->mem_base + addr[cur_addr + i]);
+}
 
-   if (ca0132_quirk(spec) == QUIRK_AE5)
-   writel(0x, spec->mem_base + 0xC0C);
-   el

[PATCH 02/20] ALSA: hda/ca0132 - Add speaker tuning initialization commands.

2020-08-21 Thread Connor McAdams
Add speaker tuning initialization DSP commands, and also define
previously unknown DSP command values.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 119 +++
 1 file changed, 119 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 7491e2044638..2e664aeee1c4 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -589,6 +589,60 @@ static const struct ct_eq_preset ca0132_alt_eq_presets[] = 
{
}
 };
 
+/*
+ * Definitions for the DSP req's to handle speaker tuning. These all belong to
+ * module ID 0x96, the output effects module.
+ */
+enum speaker_tuning_reqs {
+   /*
+* Currently, this value is always set to 0.0f. However, on Windows,
+* when selecting certain headphone profiles on the new Sound Blaster
+* connect software, the QUERY_SPEAKER_EQ_ADDRESS req on mid 0x80 is
+* sent. This gets the speaker EQ address area, which is then used to
+* send over (presumably) an equalizer profile for the specific
+* headphone setup. It is sent using the same method the DSP
+* firmware is uploaded with, which I believe is why the 'ctspeq.bin'
+* file exists in linux firmware tree but goes unused. It would also
+* explain why the QUERY_SPEAKER_EQ_ADDRESS req is defined but unused.
+* Once this profile is sent over, SPEAKER_TUNING_USE_SPEAKER_EQ is
+* set to 1.0f.
+*/
+   SPEAKER_TUNING_USE_SPEAKER_EQ   = 0x1f,
+   SPEAKER_TUNING_ENABLE_CENTER_EQ = 0x20,
+   SPEAKER_TUNING_FRONT_LEFT_VOL_LEVEL = 0x21,
+   SPEAKER_TUNING_FRONT_RIGHT_VOL_LEVEL= 0x22,
+   SPEAKER_TUNING_CENTER_VOL_LEVEL = 0x23,
+   SPEAKER_TUNING_LFE_VOL_LEVEL= 0x24,
+   SPEAKER_TUNING_REAR_LEFT_VOL_LEVEL  = 0x25,
+   SPEAKER_TUNING_REAR_RIGHT_VOL_LEVEL = 0x26,
+   SPEAKER_TUNING_SURROUND_LEFT_VOL_LEVEL  = 0x27,
+   SPEAKER_TUNING_SURROUND_RIGHT_VOL_LEVEL = 0x28,
+   /*
+* Inversion is used when setting headphone virtualization to line
+* out. Not sure why this is, but it's the only place it's ever used.
+*/
+   SPEAKER_TUNING_FRONT_LEFT_INVERT= 0x29,
+   SPEAKER_TUNING_FRONT_RIGHT_INVERT   = 0x2a,
+   SPEAKER_TUNING_CENTER_INVERT= 0x2b,
+   SPEAKER_TUNING_LFE_INVERT   = 0x2c,
+   SPEAKER_TUNING_REAR_LEFT_INVERT = 0x2d,
+   SPEAKER_TUNING_REAR_RIGHT_INVERT= 0x2e,
+   SPEAKER_TUNING_SURROUND_LEFT_INVERT = 0x2f,
+   SPEAKER_TUNING_SURROUND_RIGHT_INVERT= 0x30,
+   /* Delay is used when setting surround speaker distance in Windows. */
+   SPEAKER_TUNING_FRONT_LEFT_DELAY = 0x31,
+   SPEAKER_TUNING_FRONT_RIGHT_DELAY= 0x32,
+   SPEAKER_TUNING_CENTER_DELAY = 0x33,
+   SPEAKER_TUNING_LFE_DELAY= 0x34,
+   SPEAKER_TUNING_REAR_LEFT_DELAY  = 0x35,
+   SPEAKER_TUNING_REAR_RIGHT_DELAY = 0x36,
+   SPEAKER_TUNING_SURROUND_LEFT_DELAY  = 0x37,
+   SPEAKER_TUNING_SURROUND_RIGHT_DELAY = 0x38,
+   /* Of these two, only mute seems to ever be used. */
+   SPEAKER_TUNING_MAIN_VOLUME  = 0x39,
+   SPEAKER_TUNING_MUTE = 0x3a,
+};
+
 /* DSP command sequences for ca0132_alt_select_out */
 #define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
 struct ca0132_alt_out_set {
@@ -6874,6 +6928,67 @@ static void ca0132_refresh_widget_caps(struct hda_codec 
*codec)
}
 }
 
+/*
+ * Default speaker tuning values setup for alternative codecs.
+ */
+static const unsigned int sbz_default_delay_values[] = {
+   /* Non-zero values are floating point 0.000198. */
+   0x394f9e38, 0x394f9e38, 0x, 0x, 0x, 0x
+};
+
+static const unsigned int zxr_default_delay_values[] = {
+   /* Non-zero values are floating point 0.000220. */
+   0x, 0x, 0x3966afcd, 0x3966afcd, 0x3966afcd, 0x3966afcd
+};
+
+static const unsigned int ae5_default_delay_values[] = {
+   /* Non-zero values are floating point 0.000100. */
+   0x, 0x, 0x38d1b717, 0x38d1b717, 0x38d1b717, 0x38d1b717
+};
+
+/*
+ * If we never change these, probably only need them on initialization.
+ */
+static void ca0132_alt_init_speaker_tuning(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int i, tmp, start_req, end_req;
+   const unsigned int *values;
+
+   switch (ca0132_quirk(spec)) {
+   case QUIRK_SBZ:
+   values = sbz_default_delay_values;
+   break;
+   case QUIRK_ZXR:
+   values = zxr_default_delay_values;
+   break;
+   case QUIRK_AE5:
+   values = ae5_default_delay_values;
+   break;
+   default:
+   val

[PATCH 03/20] ALSA: hda/ca0132 - Add surround channel config control.

2020-08-21 Thread Connor McAdams
Add a surround channel configuration enumeration control. Setting up
different channel configurations allows the DSP to upmix stereo audio
into multi-channel audio, and allows for redirection of bass to a
subwoofer.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 110 ++-
 1 file changed, 108 insertions(+), 2 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 2e664aeee1c4..dd580f4b741d 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -38,6 +38,8 @@
 #define FLOAT_ONE  0x3f80
 #define FLOAT_TWO  0x4000
 #define FLOAT_THREE 0x4040
+#define FLOAT_FIVE 0x40a0
+#define FLOAT_SIX   0x40c0
 #define FLOAT_EIGHT 0x4100
 #define FLOAT_MINUS_5  0xc0a0
 
@@ -143,7 +145,8 @@ enum {
MIC_BOOST_ENUM,
AE5_HEADPHONE_GAIN_ENUM,
AE5_SOUND_FILTER_ENUM,
-   ZXR_HEADPHONE_GAIN
+   ZXR_HEADPHONE_GAIN,
+   SPEAKER_CHANNEL_CFG_ENUM,
 #define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
 };
 
@@ -686,6 +689,39 @@ static const struct ca0132_alt_out_set alt_out_presets[] = 
{
}
 };
 
+/* Surround output channel count configuration structures. */
+#define SPEAKER_CHANNEL_CFG_COUNT 5
+enum {
+   SPEAKER_CHANNELS_2_0,
+   SPEAKER_CHANNELS_2_1,
+   SPEAKER_CHANNELS_4_0,
+   SPEAKER_CHANNELS_4_1,
+   SPEAKER_CHANNELS_5_1,
+};
+
+struct ca0132_alt_speaker_channel_cfg {
+   char *name;
+   unsigned int val;
+};
+
+static const struct ca0132_alt_speaker_channel_cfg speaker_channel_cfgs[] = {
+   { .name = "2.0",
+ .val = FLOAT_ONE
+   },
+   { .name = "2.1",
+ .val = FLOAT_TWO
+   },
+   { .name = "4.0",
+ .val = FLOAT_FIVE
+   },
+   { .name = "4.1",
+ .val = FLOAT_SIX
+   },
+   { .name = "5.1",
+ .val = FLOAT_EIGHT
+   }
+};
+
 /*
  * DSP volume setting structs. Req 1 is left volume, req 2 is right volume,
  * and I don't know what the third req is, but it's always zero. I assume it's
@@ -1063,6 +1099,7 @@ struct ca0132_spec {
/* ca0132_alt control related values */
unsigned char in_enum_val;
unsigned char out_enum_val;
+   unsigned char channel_cfg_val;
unsigned char mic_boost_enum_val;
unsigned char smart_volume_setting;
long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
@@ -4476,7 +4513,8 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
snd_hda_set_pin_ctl(codec, spec->out_pins[3],
pin_ctl | PIN_OUT);
 
-   dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_EIGHT);
+   tmp = speaker_channel_cfgs[spec->channel_cfg_val].val;
+   dspio_set_uint_param(codec, 0x80, 0x04, tmp);
break;
}
/*
@@ -5582,6 +5620,54 @@ static int ca0132_alt_output_select_put(struct 
snd_kcontrol *kcontrol,
return 1;
 }
 
+/* Select surround output type: 2.1, 4.0, 4.1, or 5.1. */
+static int ca0132_alt_speaker_channel_cfg_get_info(struct snd_kcontrol 
*kcontrol,
+struct snd_ctl_elem_info *uinfo)
+{
+   unsigned int items = SPEAKER_CHANNEL_CFG_COUNT;
+
+   uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
+   uinfo->count = 1;
+   uinfo->value.enumerated.items = items;
+   if (uinfo->value.enumerated.item >= items)
+   uinfo->value.enumerated.item = items - 1;
+   strcpy(uinfo->value.enumerated.name,
+   
speaker_channel_cfgs[uinfo->value.enumerated.item].name);
+   return 0;
+}
+
+static int ca0132_alt_speaker_channel_cfg_get(struct snd_kcontrol *kcontrol,
+   struct snd_ctl_elem_value *ucontrol)
+{
+   struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+   struct ca0132_spec *spec = codec->spec;
+
+   ucontrol->value.enumerated.item[0] = spec->channel_cfg_val;
+   return 0;
+}
+
+static int ca0132_alt_speaker_channel_cfg_put(struct snd_kcontrol *kcontrol,
+   struct snd_ctl_elem_value *ucontrol)
+{
+   struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
+   struct ca0132_spec *spec = codec->spec;
+   int sel = ucontrol->value.enumerated.item[0];
+   unsigned int items = SPEAKER_CHANNEL_CFG_COUNT;
+
+   if (sel >= items)
+   return 0;
+
+   codec_dbg(codec, "ca0132_alt_speaker_channels: sel=%d, channels=%s\n",
+   sel, speaker_channel_cfgs[sel].name);
+
+   spec->channel_cfg_val = sel;
+
+   if (spec->out_enum_val == SURROUND_OUT)
+   ca0132_alt_select_out(codec);
+
+   return 1;
+}
+
 /*
  * Smart Volume output setting control. Three different settings, Normal,
  * which takes the value from the smart volume 

[PATCH 05/20] ALSA: hda/ca0132 - Add bass redirection controls.

2020-08-21 Thread Connor McAdams
Add bass redirection controls for surround outputs. This uses the DSP to
redirect audio below the bass redirection crossover frequency to the LFE
channel from the front/rear L/R speakers. This only goes into effect if
the speakers aren't set as full range, and only if the surround
configuration has an LFE channel.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 130 +--
 1 file changed, 126 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index c9cd4fc218fe..d97358406401 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -149,6 +149,8 @@ enum {
SPEAKER_CHANNEL_CFG_ENUM,
SPEAKER_FULL_RANGE_FRONT,
SPEAKER_FULL_RANGE_REAR,
+   BASS_REDIRECTION,
+   BASS_REDIRECTION_XOVER,
 #define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
 };
 
@@ -1123,6 +1125,8 @@ struct ca0132_spec {
unsigned char speaker_range_val[2];
unsigned char mic_boost_enum_val;
unsigned char smart_volume_setting;
+   unsigned char bass_redirection_val;
+   long bass_redirect_xover_freq;
long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
long xbass_xover_freq;
long eq_preset_val;
@@ -4324,6 +4328,35 @@ static int ca0132_alt_set_full_range_speaker(struct 
hda_codec *codec)
return 0;
 }
 
+static int ca0132_alt_surround_set_bass_redirection(struct hda_codec *codec,
+   bool val)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp;
+   int err;
+
+   if (val && spec->channel_cfg_val != SPEAKER_CHANNELS_4_0 &&
+   spec->channel_cfg_val != SPEAKER_CHANNELS_2_0)
+   tmp = FLOAT_ONE;
+   else
+   tmp = FLOAT_ZERO;
+
+   err = dspio_set_uint_param(codec, 0x96, SPEAKER_BASS_REDIRECT, tmp);
+   if (err < 0)
+   return err;
+
+   /* If it is enabled, make sure to set the crossover frequency. */
+   if (tmp) {
+   tmp = float_xbass_xover_lookup[spec->xbass_xover_freq];
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_BASS_REDIRECT_XOVER_FREQ, tmp);
+   if (err < 0)
+   return err;
+   }
+
+   return 0;
+}
+
 /*
  * These are the commands needed to setup output on each of the different card
  * types.
@@ -4593,6 +4626,15 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
ca0132_effects_set(codec, X_BASS,
spec->effects_switch[X_BASS - EFFECT_START_NID]);
 
+   if (spec->cur_out_type == SURROUND_OUT)
+   err = ca0132_alt_surround_set_bass_redirection(codec,
+   spec->bass_redirection_val);
+   else
+   err = ca0132_alt_surround_set_bass_redirection(codec, 0);
+
+   if (err < 0)
+   goto exit;
+
/* run through the output dsp commands for the selected output. */
for (i = 0; i < alt_out_presets[spec->cur_out_type].commands; i++) {
err = dspio_set_uint_param(codec,
@@ -5282,6 +5324,18 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol 
*kcontrol,
return ret;
 }
 /* End of control change helpers. */
+
+static void ca0132_alt_bass_redirection_xover_set(struct hda_codec *codec,
+   long idx)
+{
+   snd_hda_power_up(codec);
+
+   dspio_set_param(codec, 0x96, 0x20, SPEAKER_BASS_REDIRECT_XOVER_FREQ,
+   &(float_xbass_xover_lookup[idx]), sizeof(unsigned int));
+
+   snd_hda_power_down(codec);
+}
+
 /*
  * Below I've added controls to mess with the effect levels, I've only enabled
  * them on the Sound Blaster Z, but they would probably also work on the
@@ -5290,6 +5344,7 @@ static int ca0132_vnode_switch_set(struct snd_kcontrol 
*kcontrol,
  */
 
 /* Sets DSP effect level from the sliders above the controls */
+
 static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid,
  const unsigned int *lookup, int idx)
 {
@@ -5335,8 +5390,12 @@ static int ca0132_alt_xbass_xover_slider_ctl_get(struct 
snd_kcontrol *kcontrol,
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct ca0132_spec *spec = codec->spec;
long *valp = ucontrol->value.integer.value;
+   hda_nid_t nid = get_amp_nid(kcontrol);
 
-   *valp = spec->xbass_xover_freq;
+   if (nid == BASS_REDIRECTION_XOVER)
+   *valp = spec->bass_redirect_xover_freq;
+   else
+   *valp = spec->xbass_xover_freq;
 
return 0;
 }
@@ -5391,16 +5450,25 @@ static int ca0132_alt_xbass_xover_slider_put(struct 
snd_kcontrol *kcontrol,
struct ca0132_spec *spec = codec->spec;
hda_nid_t nid = get_amp_nid(kcontrol);
long *valp = ucontrol->value.integer.value;
+ 

[PATCH 04/20] ALSA: hda/ca0132 - Add full-range speaker selection controls.

2020-08-21 Thread Connor McAdams
Add functions for setting full-range speakers and controls to
enable/disable the setting. Setting a speaker to full-range means that
the channels won't have their bass redirected to the LFE channel.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 117 +++
 1 file changed, 117 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index dd580f4b741d..c9cd4fc218fe 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -147,6 +147,8 @@ enum {
AE5_SOUND_FILTER_ENUM,
ZXR_HEADPHONE_GAIN,
SPEAKER_CHANNEL_CFG_ENUM,
+   SPEAKER_FULL_RANGE_FRONT,
+   SPEAKER_FULL_RANGE_REAR,
 #define EFFECTS_COUNT  (EFFECT_END_NID - EFFECT_START_NID)
 };
 
@@ -592,6 +594,24 @@ static const struct ct_eq_preset ca0132_alt_eq_presets[] = 
{
}
 };
 
+/*
+ * DSP reqs for handling full-range speakers/bass redirection. If a speaker is
+ * set as not being full range, and bass redirection is enabled, all
+ * frequencies below the crossover frequency are redirected to the LFE
+ * channel. If the surround configuration has no LFE channel, this can't be
+ * enabled. X-Bass must be disabled when using these.
+ */
+enum speaker_range_reqs {
+   SPEAKER_BASS_REDIRECT= 0x15,
+   SPEAKER_BASS_REDIRECT_XOVER_FREQ = 0x16,
+   /* Between 0x16-0x1a are the X-Bass reqs. */
+   SPEAKER_FULL_RANGE_FRONT_L_R = 0x1a,
+   SPEAKER_FULL_RANGE_CENTER_LFE= 0x1b,
+   SPEAKER_FULL_RANGE_REAR_L_R  = 0x1c,
+   SPEAKER_FULL_RANGE_SURROUND_L_R  = 0x1d,
+   SPEAKER_BASS_REDIRECT_SUB_GAIN   = 0x1e,
+};
+
 /*
  * Definitions for the DSP req's to handle speaker tuning. These all belong to
  * module ID 0x96, the output effects module.
@@ -1100,6 +1120,7 @@ struct ca0132_spec {
unsigned char in_enum_val;
unsigned char out_enum_val;
unsigned char channel_cfg_val;
+   unsigned char speaker_range_val[2];
unsigned char mic_boost_enum_val;
unsigned char smart_volume_setting;
long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
@@ -4259,6 +4280,50 @@ static void ae5_mmio_select_out(struct hda_codec *codec)
ae5_ca0113_output_presets[spec->cur_out_type].vals[i]);
 }
 
+static int ca0132_alt_set_full_range_speaker(struct hda_codec *codec)
+{
+   struct ca0132_spec *spec = codec->spec;
+   unsigned int tmp;
+   int err;
+
+   /* 2.0/4.0 setup has no LFE channel, so setting full-range does 
nothing. */
+   if (spec->channel_cfg_val == SPEAKER_CHANNELS_4_0
+   || spec->channel_cfg_val == SPEAKER_CHANNELS_2_0)
+   return 0;
+
+   /* Set front L/R full range. Zero for full-range, one for redirection. 
*/
+   tmp = spec->speaker_range_val[0] ? FLOAT_ZERO : FLOAT_ONE;
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_FRONT_L_R, tmp);
+   if (err < 0)
+   return err;
+
+   /* When setting full-range rear, both rear and center/lfe are set. */
+   tmp = spec->speaker_range_val[1] ? FLOAT_ZERO : FLOAT_ONE;
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_CENTER_LFE, tmp);
+   if (err < 0)
+   return err;
+
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_REAR_L_R, tmp);
+   if (err < 0)
+   return err;
+
+   /*
+* Only the AE series cards set this value when setting full-range,
+* and it's always 1.0f.
+*/
+   if (ca0132_quirk(spec) == QUIRK_AE5) {
+   err = dspio_set_uint_param(codec, 0x96,
+   SPEAKER_FULL_RANGE_SURROUND_L_R, FLOAT_ONE);
+   if (err < 0)
+   return err;
+   }
+
+   return 0;
+}
+
 /*
  * These are the commands needed to setup output on each of the different card
  * types.
@@ -4539,6 +4604,9 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
goto exit;
}
 
+   if (spec->cur_out_type == SURROUND_OUT)
+   err = ca0132_alt_set_full_range_speaker(codec);
+
 exit:
snd_hda_power_down_pm(codec);
 
@@ -5269,6 +5337,7 @@ static int ca0132_alt_xbass_xover_slider_ctl_get(struct 
snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
 
*valp = spec->xbass_xover_freq;
+
return 0;
 }
 
@@ -5894,6 +5963,11 @@ static int ca0132_switch_get(struct snd_kcontrol 
*kcontrol,
return 0;
}
 
+   if (nid == SPEAKER_FULL_RANGE_FRONT || nid == SPEAKER_FULL_RANGE_REAR) {
+   *valp = spec->speaker_range_val[nid - SPEAKER_FULL_RANGE_FRONT];
+   return 0;
+   }
+
return 0;
 }
 
@@ -5972,6 +6046,14 @@ static int ca0132_switch_put(struct snd_kcontrol 
*kcontrol,

[PATCH 00/20] ALSA: hda/ca0132 - Add AE-7 support/Control cleanup.

2020-08-21 Thread Connor McAdams
This patch series adds support for the Sound Blaster AE-7 along with
adding new controls and cleaning up the old ones. I have personally
tested the Recon3D, Recon3Di, Sound Blaster Z/ZxR, and AE-5 cards to
confirm they work with these patches. Another user has confirmed that
they work on the AE-7.

Connor McAdams (20):
  ALSA: hda/ca0132 - Cleanup ca0132_mmio_init function.
  ALSA: hda/ca0132 - Add speaker tuning initialization commands.
  ALSA: hda/ca0132 - Add surround channel config control.
  ALSA: hda/ca0132 - Add full-range speaker selection controls.
  ALSA: hda/ca0132 - Add bass redirection controls.
  ALSA: hda/ca0132 - Remove surround output selection.
  ALSA: hda/ca0132 - Clean up ca0132_alt_out_select.
  ALSA: hda/ca0132 - Add quirk output selection structures.
  ALSA: hda/ca0132 - Fix Recon3D Center/LFE output.
  ALSA: hda/ca0132 - Add new quirk ID for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add SoundBlaster AE-7 pincfg.
  ALSA: hda/ca0132 - Set AE-7 bools and select mixer.
  ALSA: hda/ca0132 - Add ca0132_mmio_init data for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add pre-init function for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add init data for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add DSP setup functions for AE-7.
  ALSA: hda/ca0132 - Add output selection for SoundBlaster AE-7.
  ALSA: hda/ca0132 - Add AE-7 microphone selection commands.
  ALSA: hda/ca0132 - Add AE-7 custom controls.
  ALSA: hda/ca0132 - Add AE-7 exit commands.

 sound/pci/hda/patch_ca0132.c | 1794 +++---
 1 file changed, 1430 insertions(+), 364 deletions(-)

-- 
2.20.1



[PATCH 3/3] ALSA: hda/ca0132 - Fix AE-5 microphone selection commands.

2020-08-02 Thread Connor McAdams
The ca0113 command had the wrong group_id, 0x48 when it should've been
0x30. The front microphone selection should now work.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 40fa9d82ef95..b7dbf2e7f77a 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4672,7 +4672,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
tmp = FLOAT_ONE;
break;
case QUIRK_AE5:
-   ca0113_mmio_command_set(codec, 0x48, 0x28, 0x00);
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
tmp = FLOAT_THREE;
break;
default:
@@ -4718,7 +4718,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
r3di_gpio_mic_set(codec, R3DI_REAR_MIC);
break;
case QUIRK_AE5:
-   ca0113_mmio_command_set(codec, 0x48, 0x28, 0x00);
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x00);
break;
default:
break;
@@ -4757,7 +4757,7 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
tmp = FLOAT_ONE;
break;
case QUIRK_AE5:
-   ca0113_mmio_command_set(codec, 0x48, 0x28, 0x3f);
+   ca0113_mmio_command_set(codec, 0x30, 0x28, 0x3f);
tmp = FLOAT_THREE;
break;
default:
-- 
2.20.1



[PATCH 2/3] ALSA: hda/ca0132 - Add new quirk ID for Recon3D.

2020-08-02 Thread Connor McAdams
Add a new quirk ID for the Recon3D, as tested by me.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 2cbe01d59c16..40fa9d82ef95 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1182,6 +1182,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
SND_PCI_QUIRK(0x3842, 0x1038, "EVGA X99 Classified", QUIRK_R3DI),
SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
+   SND_PCI_QUIRK(0x1102, 0x0018, "Recon3D", QUIRK_R3D),
SND_PCI_QUIRK(0x1102, 0x0051, "Sound Blaster AE-5", QUIRK_AE5),
{}
 };
-- 
2.20.1



[PATCH 1/3] ALSA: hda/ca0132 - Fix ZxR Headphone gain control get value.

2020-08-02 Thread Connor McAdams
When the ZxR headphone gain control was added, the ca0132_switch_get
function was not updated, which meant that the changes to the control
state were not saved when entering/exiting alsamixer.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 19c575fd28a1..2cbe01d59c16 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -5748,6 +5748,11 @@ static int ca0132_switch_get(struct snd_kcontrol 
*kcontrol,
return 0;
}
 
+   if (nid == ZXR_HEADPHONE_GAIN) {
+   *valp = spec->zxr_gain_set;
+   return 0;
+   }
+
return 0;
 }
 
-- 
2.20.1



Re: [alsa-devel] ca0132 audio in Ubuntu 19.04 only after Windows 10 started, missing ctefx-r3di.bin

2019-06-28 Thread Connor McAdams
Hm... not sure the firmware will fix this issue, as it falls back to
the default ctefx.bin firmware which should work fine. But it's worth
a shot.

His card looks like it's being identified properly, and I've had
reports from others with the same motherboard codecs not having
issues.

There's not too much that I can really troubleshoot with these cards,
as I lack the documentation. All that I know is from capturing the HDA
verbs from a Windows virtual machine with PCI passthrough.

The only thing I can really think of is GPIO potentially, but that
would be re-set when the Linux driver is booted up. I know some users
have to do a full on shutdown to clear the cards internal memory for
it to work in Linux, but it sounds like he may have already done that.

I'll look into this a little bit when I get some time, but the issue
is that I don't have too many options/ideas on what could be
potentially wrong.

On Fri, Jun 28, 2019 at 5:29 AM Kai-Heng Feng
 wrote:
>
> at 17:13, Takashi Iwai  wrote:
>
> > On Fri, 28 Jun 2019 08:35:51 +0200,
> > Kai-Heng Feng wrote:
> >> Hi Connor,
> >>
> >> The bug was filed at Launchpad [1], I think the most notable error is
> >> [3.768667] snd_hda_intel :00:1f.3: Direct firmware load for
> >> ctefx-r3di.bin failed with error -2
> >>
> >> The firmware is indeed listed in patch_ca0132.c, but looks like
> >> there’s no  corresponding file in linux-firmware.
> >
> > FYI, the firmware is found in alsa-firmware git repo for now.
>
> Got it, thanks for the info. Didn’t know there’s alsa-firmware repo.
>
> Kai-Heng
>
> >
> >
> > Takashi
>
>


Re: [PATCH AUTOSEL 4.19 40/68] ALSA: hda/ca0132 - Add new ZxR quirk

2018-11-29 Thread Connor McAdams
This patch won't break anything, but it also won't fix anything
either. Not sure if that matters or not.
On Thu, Nov 29, 2018 at 12:59 AM Sasha Levin  wrote:
>
> From: Connor McAdams 
>
> [ Upstream commit cce997292a5264c5342c968bbd226d7c365f03d6 ]
>
> This patch adds a new PCI subsys ID for the ZxR, as found and tested by
> other users. Without a way to know if any Z's use it as well, it keeps
> the quirk of QUIRK_SBZ and goes through the HDA subsys test function.
>
> Signed-off-by: Connor McAdams 
> Signed-off-by: Takashi Iwai 
> Signed-off-by: Sasha Levin 
> ---
>  sound/pci/hda/patch_ca0132.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
> index dffd60cebc31..cc2bb0057810 100644
> --- a/sound/pci/hda/patch_ca0132.c
> +++ b/sound/pci/hda/patch_ca0132.c
> @@ -1065,6 +1065,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
> SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", 
> QUIRK_ALIENWARE),
> SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
> SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
> +   SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
> SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
> SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
> SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", 
> QUIRK_R3DI),
> --
> 2.17.1
>


Re: [PATCH AUTOSEL 4.19 40/68] ALSA: hda/ca0132 - Add new ZxR quirk

2018-11-29 Thread Connor McAdams
This patch won't break anything, but it also won't fix anything
either. Not sure if that matters or not.
On Thu, Nov 29, 2018 at 12:59 AM Sasha Levin  wrote:
>
> From: Connor McAdams 
>
> [ Upstream commit cce997292a5264c5342c968bbd226d7c365f03d6 ]
>
> This patch adds a new PCI subsys ID for the ZxR, as found and tested by
> other users. Without a way to know if any Z's use it as well, it keeps
> the quirk of QUIRK_SBZ and goes through the HDA subsys test function.
>
> Signed-off-by: Connor McAdams 
> Signed-off-by: Takashi Iwai 
> Signed-off-by: Sasha Levin 
> ---
>  sound/pci/hda/patch_ca0132.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
> index dffd60cebc31..cc2bb0057810 100644
> --- a/sound/pci/hda/patch_ca0132.c
> +++ b/sound/pci/hda/patch_ca0132.c
> @@ -1065,6 +1065,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
> SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", 
> QUIRK_ALIENWARE),
> SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
> SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
> +   SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
> SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
> SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
> SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", 
> QUIRK_R3DI),
> --
> 2.17.1
>


[PATCH 2/2] ALSA: hda/ca0132 - fix AE-5 pincfg

2018-11-16 Thread Connor McAdams
This patch fixes the pincfg assignment for the AE-5, which was
previously using the Recon3D pincfg's by mistake.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4c21bd24bcbd..eee432287c15 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8527,7 +8527,7 @@ static void ca0132_config(struct hda_codec *codec)
break;
case QUIRK_AE5:
codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__);
-   snd_hda_apply_pincfgs(codec, r3di_pincfgs);
+   snd_hda_apply_pincfgs(codec, ae5_pincfgs);
break;
default:
break;
-- 
2.18.1



[PATCH 2/2] ALSA: hda/ca0132 - fix AE-5 pincfg

2018-11-16 Thread Connor McAdams
This patch fixes the pincfg assignment for the AE-5, which was
previously using the Recon3D pincfg's by mistake.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 4c21bd24bcbd..eee432287c15 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8527,7 +8527,7 @@ static void ca0132_config(struct hda_codec *codec)
break;
case QUIRK_AE5:
codec_dbg(codec, "%s: QUIRK_AE5 applied.\n", __func__);
-   snd_hda_apply_pincfgs(codec, r3di_pincfgs);
+   snd_hda_apply_pincfgs(codec, ae5_pincfgs);
break;
default:
break;
-- 
2.18.1



[PATCH 1/2] ALSA: hda/ca0132 - Add new ZxR quirk

2018-11-16 Thread Connor McAdams
This patch adds a new PCI subsys ID for the ZxR, as found and tested by
other users. Without a way to know if any Z's use it as well, it keeps
the quirk of QUIRK_SBZ and goes through the HDA subsys test function.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9c0b94ba786e..4c21bd24bcbd 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1189,6 +1189,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
+   SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
-- 
2.18.1



[PATCH 1/2] ALSA: hda/ca0132 - Add new ZxR quirk

2018-11-16 Thread Connor McAdams
This patch adds a new PCI subsys ID for the ZxR, as found and tested by
other users. Without a way to know if any Z's use it as well, it keeps
the quirk of QUIRK_SBZ and goes through the HDA subsys test function.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 9c0b94ba786e..4c21bd24bcbd 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -1189,6 +1189,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
+   SND_PCI_QUIRK(0x1102, 0x0033, "Sound Blaster ZxR", QUIRK_SBZ),
SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
-- 
2.18.1



Re: [GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-11-09 Thread Connor McAdams
Okay... So, my contact at Creative gave me an email as the 'sign-off
party' for firmware submission. As far as I'm aware, sign-offs also
need names attached, correct? So I'll ask for that. However, they
still want me to send it.

Will that be okay? Would you be more comfortable if I get you in
contact with someone at Creative,Josh?

I apologize for being kind of difficult, I'm doing what I can. Let me
know what I need to do, and I'll do my best.

Thanks,
Connor.
On Sun, Nov 4, 2018 at 1:00 AM Connor McAdams  wrote:
>
> Okay, just got a response from the guy at Creative. He said they'll
> try to sort it out this week. Just a heads up. :)
> On Wed, Oct 24, 2018 at 12:22 PM Connor McAdams  wrote:
> >
> > Understood. I will see what I can do. I already had them contact
> > Takashi, but I will ask if they're willing to give a sign-off. If
> > they're having trouble, is it okay to have them contact you Josh?
> >
> > Let me know.
> > On Wed, Oct 24, 2018 at 9:44 AM Josh Boyer  wrote:
> > >
> > > On Wed, Oct 24, 2018 at 3:37 AM Takashi Iwai  wrote:
> > > >
> > > > On Wed, 10 Oct 2018 19:49:23 +0200,
> > > > Connor McAdams wrote:
> > > > >
> > > > > The following changes since commit 
> > > > > c6b6265d718d118e28e1ce8f91769aa886b54c94:
> > > > >
> > > > >   Merge tag 'iwlwifi-fw-2018-10-03' of 
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
> > > > > (2018-10-08 09:23:53 -0400)
> > > > >
> > > > > are available in the git repository at:
> > > > >
> > > > >   g...@github.com:Conmanx360/linux-firmware.git
> > > > >
> > > > > for you to fetch changes up to 
> > > > > cd8899323352e772c5989230f35b1c494e0ab196:
> > > > >
> > > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
> > > > > (2018-10-09 14:41:12 -0400)
> > > > >
> > > > > 
> > > > > These are additional firmware files for CA0132 based sound cards.
> > > > >
> > > > > Creative has given me permission through email to send these to the
> > > > > linux-firmware repository under the same license as the previous 
> > > > > ca0132
> > > > > firmware. I asked my contact if they would sign-off on it, but they 
> > > > > said
> > > > > to go ahead and submit it and that if there was any issue to contact
> > > > > them.
> > > > >
> > > > > If you need to contact them, or if there's more info needed, let me 
> > > > > know
> > > > > and I can get see what I can do.
> > >
> > > I'd really like to see a Sign-off from someone at Creative.  It's not
> > > that I don't trust your word that they agreed to it, but we have
> > > nothing to go back and verify they actually agreed to allow this to be
> > > redistributable, etc.
> > >
> > > josh
> > >
> > > > > 
> > > > > Connor McAdams (1):
> > > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio 
> > > > > Codec
> > > > >
> > > > >  WHENCE|   2 ++
> > > > >  ctefx-desktop.bin | Bin 0 -> 655856 bytes
> > > > >  ctefx-r3di.bin| Bin 0 -> 655816 bytes
> > > > >  3 files changed, 2 insertions(+)
> > > > >  create mode 100644 ctefx-desktop.bin
> > > > >  create mode 100644 ctefx-r3di.bin
> > > >
> > > > Please can anyone take a look at this pull request?
> > > >
> > > > It's mandatory for the CA0132-based cards that are now supported
> > > > better in the upstream kernel tree.
> > > >
> > > >
> > > > Thanks!
> > > >
> > > > Takashi


Re: [GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-11-09 Thread Connor McAdams
Okay... So, my contact at Creative gave me an email as the 'sign-off
party' for firmware submission. As far as I'm aware, sign-offs also
need names attached, correct? So I'll ask for that. However, they
still want me to send it.

Will that be okay? Would you be more comfortable if I get you in
contact with someone at Creative,Josh?

I apologize for being kind of difficult, I'm doing what I can. Let me
know what I need to do, and I'll do my best.

Thanks,
Connor.
On Sun, Nov 4, 2018 at 1:00 AM Connor McAdams  wrote:
>
> Okay, just got a response from the guy at Creative. He said they'll
> try to sort it out this week. Just a heads up. :)
> On Wed, Oct 24, 2018 at 12:22 PM Connor McAdams  wrote:
> >
> > Understood. I will see what I can do. I already had them contact
> > Takashi, but I will ask if they're willing to give a sign-off. If
> > they're having trouble, is it okay to have them contact you Josh?
> >
> > Let me know.
> > On Wed, Oct 24, 2018 at 9:44 AM Josh Boyer  wrote:
> > >
> > > On Wed, Oct 24, 2018 at 3:37 AM Takashi Iwai  wrote:
> > > >
> > > > On Wed, 10 Oct 2018 19:49:23 +0200,
> > > > Connor McAdams wrote:
> > > > >
> > > > > The following changes since commit 
> > > > > c6b6265d718d118e28e1ce8f91769aa886b54c94:
> > > > >
> > > > >   Merge tag 'iwlwifi-fw-2018-10-03' of 
> > > > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
> > > > > (2018-10-08 09:23:53 -0400)
> > > > >
> > > > > are available in the git repository at:
> > > > >
> > > > >   g...@github.com:Conmanx360/linux-firmware.git
> > > > >
> > > > > for you to fetch changes up to 
> > > > > cd8899323352e772c5989230f35b1c494e0ab196:
> > > > >
> > > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
> > > > > (2018-10-09 14:41:12 -0400)
> > > > >
> > > > > 
> > > > > These are additional firmware files for CA0132 based sound cards.
> > > > >
> > > > > Creative has given me permission through email to send these to the
> > > > > linux-firmware repository under the same license as the previous 
> > > > > ca0132
> > > > > firmware. I asked my contact if they would sign-off on it, but they 
> > > > > said
> > > > > to go ahead and submit it and that if there was any issue to contact
> > > > > them.
> > > > >
> > > > > If you need to contact them, or if there's more info needed, let me 
> > > > > know
> > > > > and I can get see what I can do.
> > >
> > > I'd really like to see a Sign-off from someone at Creative.  It's not
> > > that I don't trust your word that they agreed to it, but we have
> > > nothing to go back and verify they actually agreed to allow this to be
> > > redistributable, etc.
> > >
> > > josh
> > >
> > > > > 
> > > > > Connor McAdams (1):
> > > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio 
> > > > > Codec
> > > > >
> > > > >  WHENCE|   2 ++
> > > > >  ctefx-desktop.bin | Bin 0 -> 655856 bytes
> > > > >  ctefx-r3di.bin| Bin 0 -> 655816 bytes
> > > > >  3 files changed, 2 insertions(+)
> > > > >  create mode 100644 ctefx-desktop.bin
> > > > >  create mode 100644 ctefx-r3di.bin
> > > >
> > > > Please can anyone take a look at this pull request?
> > > >
> > > > It's mandatory for the CA0132-based cards that are now supported
> > > > better in the upstream kernel tree.
> > > >
> > > >
> > > > Thanks!
> > > >
> > > > Takashi


Re: [GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-11-03 Thread Connor McAdams
Okay, just got a response from the guy at Creative. He said they'll
try to sort it out this week. Just a heads up. :)
On Wed, Oct 24, 2018 at 12:22 PM Connor McAdams  wrote:
>
> Understood. I will see what I can do. I already had them contact
> Takashi, but I will ask if they're willing to give a sign-off. If
> they're having trouble, is it okay to have them contact you Josh?
>
> Let me know.
> On Wed, Oct 24, 2018 at 9:44 AM Josh Boyer  wrote:
> >
> > On Wed, Oct 24, 2018 at 3:37 AM Takashi Iwai  wrote:
> > >
> > > On Wed, 10 Oct 2018 19:49:23 +0200,
> > > Connor McAdams wrote:
> > > >
> > > > The following changes since commit 
> > > > c6b6265d718d118e28e1ce8f91769aa886b54c94:
> > > >
> > > >   Merge tag 'iwlwifi-fw-2018-10-03' of 
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
> > > > (2018-10-08 09:23:53 -0400)
> > > >
> > > > are available in the git repository at:
> > > >
> > > >   g...@github.com:Conmanx360/linux-firmware.git
> > > >
> > > > for you to fetch changes up to cd8899323352e772c5989230f35b1c494e0ab196:
> > > >
> > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
> > > > (2018-10-09 14:41:12 -0400)
> > > >
> > > > 
> > > > These are additional firmware files for CA0132 based sound cards.
> > > >
> > > > Creative has given me permission through email to send these to the
> > > > linux-firmware repository under the same license as the previous ca0132
> > > > firmware. I asked my contact if they would sign-off on it, but they said
> > > > to go ahead and submit it and that if there was any issue to contact
> > > > them.
> > > >
> > > > If you need to contact them, or if there's more info needed, let me know
> > > > and I can get see what I can do.
> >
> > I'd really like to see a Sign-off from someone at Creative.  It's not
> > that I don't trust your word that they agreed to it, but we have
> > nothing to go back and verify they actually agreed to allow this to be
> > redistributable, etc.
> >
> > josh
> >
> > > > 
> > > > Connor McAdams (1):
> > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio 
> > > > Codec
> > > >
> > > >  WHENCE|   2 ++
> > > >  ctefx-desktop.bin | Bin 0 -> 655856 bytes
> > > >  ctefx-r3di.bin| Bin 0 -> 655816 bytes
> > > >  3 files changed, 2 insertions(+)
> > > >  create mode 100644 ctefx-desktop.bin
> > > >  create mode 100644 ctefx-r3di.bin
> > >
> > > Please can anyone take a look at this pull request?
> > >
> > > It's mandatory for the CA0132-based cards that are now supported
> > > better in the upstream kernel tree.
> > >
> > >
> > > Thanks!
> > >
> > > Takashi


Re: [GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-11-03 Thread Connor McAdams
Okay, just got a response from the guy at Creative. He said they'll
try to sort it out this week. Just a heads up. :)
On Wed, Oct 24, 2018 at 12:22 PM Connor McAdams  wrote:
>
> Understood. I will see what I can do. I already had them contact
> Takashi, but I will ask if they're willing to give a sign-off. If
> they're having trouble, is it okay to have them contact you Josh?
>
> Let me know.
> On Wed, Oct 24, 2018 at 9:44 AM Josh Boyer  wrote:
> >
> > On Wed, Oct 24, 2018 at 3:37 AM Takashi Iwai  wrote:
> > >
> > > On Wed, 10 Oct 2018 19:49:23 +0200,
> > > Connor McAdams wrote:
> > > >
> > > > The following changes since commit 
> > > > c6b6265d718d118e28e1ce8f91769aa886b54c94:
> > > >
> > > >   Merge tag 'iwlwifi-fw-2018-10-03' of 
> > > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
> > > > (2018-10-08 09:23:53 -0400)
> > > >
> > > > are available in the git repository at:
> > > >
> > > >   g...@github.com:Conmanx360/linux-firmware.git
> > > >
> > > > for you to fetch changes up to cd8899323352e772c5989230f35b1c494e0ab196:
> > > >
> > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
> > > > (2018-10-09 14:41:12 -0400)
> > > >
> > > > 
> > > > These are additional firmware files for CA0132 based sound cards.
> > > >
> > > > Creative has given me permission through email to send these to the
> > > > linux-firmware repository under the same license as the previous ca0132
> > > > firmware. I asked my contact if they would sign-off on it, but they said
> > > > to go ahead and submit it and that if there was any issue to contact
> > > > them.
> > > >
> > > > If you need to contact them, or if there's more info needed, let me know
> > > > and I can get see what I can do.
> >
> > I'd really like to see a Sign-off from someone at Creative.  It's not
> > that I don't trust your word that they agreed to it, but we have
> > nothing to go back and verify they actually agreed to allow this to be
> > redistributable, etc.
> >
> > josh
> >
> > > > 
> > > > Connor McAdams (1):
> > > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio 
> > > > Codec
> > > >
> > > >  WHENCE|   2 ++
> > > >  ctefx-desktop.bin | Bin 0 -> 655856 bytes
> > > >  ctefx-r3di.bin| Bin 0 -> 655816 bytes
> > > >  3 files changed, 2 insertions(+)
> > > >  create mode 100644 ctefx-desktop.bin
> > > >  create mode 100644 ctefx-r3di.bin
> > >
> > > Please can anyone take a look at this pull request?
> > >
> > > It's mandatory for the CA0132-based cards that are now supported
> > > better in the upstream kernel tree.
> > >
> > >
> > > Thanks!
> > >
> > > Takashi


Re: [GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-10-24 Thread Connor McAdams
Understood. I will see what I can do. I already had them contact
Takashi, but I will ask if they're willing to give a sign-off. If
they're having trouble, is it okay to have them contact you Josh?

Let me know.
On Wed, Oct 24, 2018 at 9:44 AM Josh Boyer  wrote:
>
> On Wed, Oct 24, 2018 at 3:37 AM Takashi Iwai  wrote:
> >
> > On Wed, 10 Oct 2018 19:49:23 +0200,
> > Connor McAdams wrote:
> > >
> > > The following changes since commit 
> > > c6b6265d718d118e28e1ce8f91769aa886b54c94:
> > >
> > >   Merge tag 'iwlwifi-fw-2018-10-03' of 
> > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
> > > (2018-10-08 09:23:53 -0400)
> > >
> > > are available in the git repository at:
> > >
> > >   g...@github.com:Conmanx360/linux-firmware.git
> > >
> > > for you to fetch changes up to cd8899323352e772c5989230f35b1c494e0ab196:
> > >
> > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
> > > (2018-10-09 14:41:12 -0400)
> > >
> > > 
> > > These are additional firmware files for CA0132 based sound cards.
> > >
> > > Creative has given me permission through email to send these to the
> > > linux-firmware repository under the same license as the previous ca0132
> > > firmware. I asked my contact if they would sign-off on it, but they said
> > > to go ahead and submit it and that if there was any issue to contact
> > > them.
> > >
> > > If you need to contact them, or if there's more info needed, let me know
> > > and I can get see what I can do.
>
> I'd really like to see a Sign-off from someone at Creative.  It's not
> that I don't trust your word that they agreed to it, but we have
> nothing to go back and verify they actually agreed to allow this to be
> redistributable, etc.
>
> josh
>
> > > 
> > > Connor McAdams (1):
> > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec
> > >
> > >  WHENCE|   2 ++
> > >  ctefx-desktop.bin | Bin 0 -> 655856 bytes
> > >  ctefx-r3di.bin| Bin 0 -> 655816 bytes
> > >  3 files changed, 2 insertions(+)
> > >  create mode 100644 ctefx-desktop.bin
> > >  create mode 100644 ctefx-r3di.bin
> >
> > Please can anyone take a look at this pull request?
> >
> > It's mandatory for the CA0132-based cards that are now supported
> > better in the upstream kernel tree.
> >
> >
> > Thanks!
> >
> > Takashi


Re: [GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-10-24 Thread Connor McAdams
Understood. I will see what I can do. I already had them contact
Takashi, but I will ask if they're willing to give a sign-off. If
they're having trouble, is it okay to have them contact you Josh?

Let me know.
On Wed, Oct 24, 2018 at 9:44 AM Josh Boyer  wrote:
>
> On Wed, Oct 24, 2018 at 3:37 AM Takashi Iwai  wrote:
> >
> > On Wed, 10 Oct 2018 19:49:23 +0200,
> > Connor McAdams wrote:
> > >
> > > The following changes since commit 
> > > c6b6265d718d118e28e1ce8f91769aa886b54c94:
> > >
> > >   Merge tag 'iwlwifi-fw-2018-10-03' of 
> > > git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
> > > (2018-10-08 09:23:53 -0400)
> > >
> > > are available in the git repository at:
> > >
> > >   g...@github.com:Conmanx360/linux-firmware.git
> > >
> > > for you to fetch changes up to cd8899323352e772c5989230f35b1c494e0ab196:
> > >
> > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
> > > (2018-10-09 14:41:12 -0400)
> > >
> > > 
> > > These are additional firmware files for CA0132 based sound cards.
> > >
> > > Creative has given me permission through email to send these to the
> > > linux-firmware repository under the same license as the previous ca0132
> > > firmware. I asked my contact if they would sign-off on it, but they said
> > > to go ahead and submit it and that if there was any issue to contact
> > > them.
> > >
> > > If you need to contact them, or if there's more info needed, let me know
> > > and I can get see what I can do.
>
> I'd really like to see a Sign-off from someone at Creative.  It's not
> that I don't trust your word that they agreed to it, but we have
> nothing to go back and verify they actually agreed to allow this to be
> redistributable, etc.
>
> josh
>
> > > 
> > > Connor McAdams (1):
> > >   linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec
> > >
> > >  WHENCE|   2 ++
> > >  ctefx-desktop.bin | Bin 0 -> 655856 bytes
> > >  ctefx-r3di.bin| Bin 0 -> 655816 bytes
> > >  3 files changed, 2 insertions(+)
> > >  create mode 100644 ctefx-desktop.bin
> > >  create mode 100644 ctefx-r3di.bin
> >
> > Please can anyone take a look at this pull request?
> >
> > It's mandatory for the CA0132-based cards that are now supported
> > better in the upstream kernel tree.
> >
> >
> > Thanks!
> >
> > Takashi


[PATCH] ALSA: hda/ca0132 - Actually fix microphone issue

2018-10-21 Thread Connor McAdams
This patch fixes the microphone issue for all cards. The previous fix
worked on the ZxR, but not on the AE-5 or Z. This patch has been tested
to work for all cards.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 73 ++--
 1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 1a13cea..f0ef52e 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -6983,37 +6983,44 @@ static void sbz_chipio_startup_data(struct hda_codec 
*codec)
 static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
-   unsigned int tmp;
+   unsigned int tmp, i;
 
-   switch (spec->quirk) {
-   case QUIRK_SBZ:
-   case QUIRK_AE5:
-   tmp = 0x0003;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
-   case QUIRK_R3D:
-   case QUIRK_R3DI:
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
+   /*
+* Gotta run these twice, or else mic works inconsistently. Not clear
+* why this is, but multiple tests have confirmed it.
+*/
+   for (i = 0; i < 2; i++) {
+   switch (spec->quirk) {
+   case QUIRK_SBZ:
+   case QUIRK_AE5:
+   tmp = 0x0003;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
+   tmp = 0x0001;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
+   tmp = 0x0004;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x0005;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   break;
+   case QUIRK_R3D:
+   case QUIRK_R3DI:
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
+   tmp = 0x0001;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
+   tmp = 0x0004;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x0005;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   break;
+   }
+   msleep(100);
}
 }
 
@@ -7246,8 +7253,6 @@ static void r3d_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
-   msleep(100);
-
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7292,8 +7297,6 @@ static void sbz_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
-   msleep(100);
-
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7351,8 +7354,6 @@ static void ae5_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
-   msleep(100);
-
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
-- 
2.7.4



[PATCH] ALSA: hda/ca0132 - Actually fix microphone issue

2018-10-21 Thread Connor McAdams
This patch fixes the microphone issue for all cards. The previous fix
worked on the ZxR, but not on the AE-5 or Z. This patch has been tested
to work for all cards.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 73 ++--
 1 file changed, 37 insertions(+), 36 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 1a13cea..f0ef52e 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -6983,37 +6983,44 @@ static void sbz_chipio_startup_data(struct hda_codec 
*codec)
 static void ca0132_alt_dsp_scp_startup(struct hda_codec *codec)
 {
struct ca0132_spec *spec = codec->spec;
-   unsigned int tmp;
+   unsigned int tmp, i;
 
-   switch (spec->quirk) {
-   case QUIRK_SBZ:
-   case QUIRK_AE5:
-   tmp = 0x0003;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
-   case QUIRK_R3D:
-   case QUIRK_R3DI:
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
-   tmp = 0x0001;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
-   tmp = 0x0004;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x0005;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   tmp = 0x;
-   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
-   break;
+   /*
+* Gotta run these twice, or else mic works inconsistently. Not clear
+* why this is, but multiple tests have confirmed it.
+*/
+   for (i = 0; i < 2; i++) {
+   switch (spec->quirk) {
+   case QUIRK_SBZ:
+   case QUIRK_AE5:
+   tmp = 0x0003;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
+   tmp = 0x0001;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
+   tmp = 0x0004;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x0005;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   break;
+   case QUIRK_R3D:
+   case QUIRK_R3DI:
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
+   tmp = 0x0001;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
+   tmp = 0x0004;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x0005;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   tmp = 0x;
+   dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
+   break;
+   }
+   msleep(100);
}
 }
 
@@ -7246,8 +7253,6 @@ static void r3d_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
-   msleep(100);
-
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7292,8 +7297,6 @@ static void sbz_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
-   msleep(100);
-
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7351,8 +7354,6 @@ static void ae5_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
-   msleep(100);
-
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
-- 
2.7.4



[GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-10-10 Thread Connor McAdams
The following changes since commit c6b6265d718d118e28e1ce8f91769aa886b54c94:

  Merge tag 'iwlwifi-fw-2018-10-03' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
(2018-10-08 09:23:53 -0400)

are available in the git repository at:

  g...@github.com:Conmanx360/linux-firmware.git 

for you to fetch changes up to cd8899323352e772c5989230f35b1c494e0ab196:

  linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
(2018-10-09 14:41:12 -0400)


These are additional firmware files for CA0132 based sound cards.

Creative has given me permission through email to send these to the 
linux-firmware repository under the same license as the previous ca0132 
firmware. I asked my contact if they would sign-off on it, but they said 
to go ahead and submit it and that if there was any issue to contact 
them. 

If you need to contact them, or if there's more info needed, let me know
and I can get see what I can do.

Connor McAdams (1):
  linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec

 WHENCE|   2 ++
 ctefx-desktop.bin | Bin 0 -> 655856 bytes
 ctefx-r3di.bin| Bin 0 -> 655816 bytes
 3 files changed, 2 insertions(+)
 create mode 100644 ctefx-desktop.bin
 create mode 100644 ctefx-r3di.bin


[GIT PULL] Additional firmware files for CA0132 HD-audio codec

2018-10-10 Thread Connor McAdams
The following changes since commit c6b6265d718d118e28e1ce8f91769aa886b54c94:

  Merge tag 'iwlwifi-fw-2018-10-03' of 
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/linux-firmware 
(2018-10-08 09:23:53 -0400)

are available in the git repository at:

  g...@github.com:Conmanx360/linux-firmware.git 

for you to fetch changes up to cd8899323352e772c5989230f35b1c494e0ab196:

  linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec 
(2018-10-09 14:41:12 -0400)


These are additional firmware files for CA0132 based sound cards.

Creative has given me permission through email to send these to the 
linux-firmware repository under the same license as the previous ca0132 
firmware. I asked my contact if they would sign-off on it, but they said 
to go ahead and submit it and that if there was any issue to contact 
them. 

If you need to contact them, or if there's more info needed, let me know
and I can get see what I can do.

Connor McAdams (1):
  linux-firmware: Add new firmware for Creative CA0132 HD-Audio Codec

 WHENCE|   2 ++
 ctefx-desktop.bin | Bin 0 -> 655856 bytes
 ctefx-r3di.bin| Bin 0 -> 655816 bytes
 3 files changed, 2 insertions(+)
 create mode 100644 ctefx-desktop.bin
 create mode 100644 ctefx-r3di.bin


[PATCH 2/4] ALSA: hda/ca0132 - Clean up patch_ca0132()

2018-10-08 Thread Connor McAdams
This patch cleans up the patch_ca0132() function with suggestions from
Takashi Sakamoto.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 12a3581..07d50d6 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8697,10 +8697,6 @@ static int patch_ca0132(struct hda_codec *codec)
codec->spec = spec;
spec->codec = codec;
 
-   codec->patch_ops = ca0132_patch_ops;
-   codec->pcm_format_first = 1;
-   codec->no_sticky_stream = 1;
-
/* Detect codec quirk */
quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks);
if (quirk)
@@ -8711,6 +8707,15 @@ static int patch_ca0132(struct hda_codec *codec)
if (spec->quirk == QUIRK_SBZ)
sbz_detect_quirk(codec);
 
+   if (spec->quirk == QUIRK_ZXR_DBPRO)
+   codec->patch_ops = dbpro_patch_ops;
+   else
+   codec->patch_ops = ca0132_patch_ops;
+
+   codec->pcm_format_first = 1;
+   codec->no_sticky_stream = 1;
+
+
spec->dsp_state = DSP_DOWNLOAD_INIT;
spec->num_mixers = 1;
 
@@ -8725,7 +8730,6 @@ static int patch_ca0132(struct hda_codec *codec)
snd_hda_codec_set_name(codec, "Sound Blaster ZxR");
break;
case QUIRK_ZXR_DBPRO:
-   codec->patch_ops = dbpro_patch_ops;
break;
case QUIRK_R3D:
spec->mixers[0] = desktop_mixer;
-- 
2.7.4



[PATCH 4/4] ALSA: hda/ca0132 - Fix input effect controls for desktop cards

2018-10-08 Thread Connor McAdams
This patch removes the echo cancellation control for desktop cards, and
makes use of the special 0x47 SCP command for noise reduction.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 693b063..1a13cea 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4857,7 +4857,7 @@ static int ca0132_effects_set(struct hda_codec *codec, 
hda_nid_t nid, long val)
val = 0;
 
/* If Voice Focus on SBZ, set to two channel. */
-   if ((nid == VOICE_FOCUS) && (spec->quirk == QUIRK_SBZ)
+   if ((nid == VOICE_FOCUS) && (spec->use_pci_mmio)
&& (spec->cur_mic_type != REAR_LINE_IN)) {
if (spec->effects_switch[CRYSTAL_VOICE -
 EFFECT_START_NID]) {
@@ -4876,7 +4876,7 @@ static int ca0132_effects_set(struct hda_codec *codec, 
hda_nid_t nid, long val)
 * For SBZ noise reduction, there's an extra command
 * to module ID 0x47. No clue why.
 */
-   if ((nid == NOISE_REDUCTION) && (spec->quirk == QUIRK_SBZ)
+   if ((nid == NOISE_REDUCTION) && (spec->use_pci_mmio)
&& (spec->cur_mic_type != REAR_LINE_IN)) {
if (spec->effects_switch[CRYSTAL_VOICE -
 EFFECT_START_NID]) {
@@ -6374,8 +6374,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
 */
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
for (i = 0; i < num_fx; i++) {
-   /* SBZ and R3D break if Echo Cancellation is used. */
-   if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3D) {
+   /* Desktop cards break if Echo Cancellation is used. */
+   if (spec->use_pci_mmio) {
if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID +
OUT_EFFECTS_COUNT))
continue;
-- 
2.7.4



[PATCH 4/4] ALSA: hda/ca0132 - Fix input effect controls for desktop cards

2018-10-08 Thread Connor McAdams
This patch removes the echo cancellation control for desktop cards, and
makes use of the special 0x47 SCP command for noise reduction.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 693b063..1a13cea 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -4857,7 +4857,7 @@ static int ca0132_effects_set(struct hda_codec *codec, 
hda_nid_t nid, long val)
val = 0;
 
/* If Voice Focus on SBZ, set to two channel. */
-   if ((nid == VOICE_FOCUS) && (spec->quirk == QUIRK_SBZ)
+   if ((nid == VOICE_FOCUS) && (spec->use_pci_mmio)
&& (spec->cur_mic_type != REAR_LINE_IN)) {
if (spec->effects_switch[CRYSTAL_VOICE -
 EFFECT_START_NID]) {
@@ -4876,7 +4876,7 @@ static int ca0132_effects_set(struct hda_codec *codec, 
hda_nid_t nid, long val)
 * For SBZ noise reduction, there's an extra command
 * to module ID 0x47. No clue why.
 */
-   if ((nid == NOISE_REDUCTION) && (spec->quirk == QUIRK_SBZ)
+   if ((nid == NOISE_REDUCTION) && (spec->use_pci_mmio)
&& (spec->cur_mic_type != REAR_LINE_IN)) {
if (spec->effects_switch[CRYSTAL_VOICE -
 EFFECT_START_NID]) {
@@ -6374,8 +6374,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
 */
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
for (i = 0; i < num_fx; i++) {
-   /* SBZ and R3D break if Echo Cancellation is used. */
-   if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3D) {
+   /* Desktop cards break if Echo Cancellation is used. */
+   if (spec->use_pci_mmio) {
if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID +
OUT_EFFECTS_COUNT))
continue;
-- 
2.7.4



[PATCH 2/4] ALSA: hda/ca0132 - Clean up patch_ca0132()

2018-10-08 Thread Connor McAdams
This patch cleans up the patch_ca0132() function with suggestions from
Takashi Sakamoto.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 14 +-
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 12a3581..07d50d6 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -8697,10 +8697,6 @@ static int patch_ca0132(struct hda_codec *codec)
codec->spec = spec;
spec->codec = codec;
 
-   codec->patch_ops = ca0132_patch_ops;
-   codec->pcm_format_first = 1;
-   codec->no_sticky_stream = 1;
-
/* Detect codec quirk */
quirk = snd_pci_quirk_lookup(codec->bus->pci, ca0132_quirks);
if (quirk)
@@ -8711,6 +8707,15 @@ static int patch_ca0132(struct hda_codec *codec)
if (spec->quirk == QUIRK_SBZ)
sbz_detect_quirk(codec);
 
+   if (spec->quirk == QUIRK_ZXR_DBPRO)
+   codec->patch_ops = dbpro_patch_ops;
+   else
+   codec->patch_ops = ca0132_patch_ops;
+
+   codec->pcm_format_first = 1;
+   codec->no_sticky_stream = 1;
+
+
spec->dsp_state = DSP_DOWNLOAD_INIT;
spec->num_mixers = 1;
 
@@ -8725,7 +8730,6 @@ static int patch_ca0132(struct hda_codec *codec)
snd_hda_codec_set_name(codec, "Sound Blaster ZxR");
break;
case QUIRK_ZXR_DBPRO:
-   codec->patch_ops = dbpro_patch_ops;
break;
case QUIRK_R3D:
spec->mixers[0] = desktop_mixer;
-- 
2.7.4



[PATCH 3/4] ALSA: hda/ca0132 - Add error checking in ca0132_build_controls()

2018-10-08 Thread Connor McAdams
This patch adds error checking to functions creating controls inside of
ca0132_build_controls().

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 47 +---
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 07d50d6..693b063 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -6365,7 +6365,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
NULL, ca0132_alt_slave_pfxs,
"Playback Switch",
true, >vmaster_mute.sw_kctl);
-
+   if (err < 0)
+   return err;
}
 
/* Add in and out effects controls.
@@ -6392,8 +6393,14 @@ static int ca0132_build_controls(struct hda_codec *codec)
 * prefix, and change PlayEnhancement and CrystalVoice to match.
 */
if (spec->use_alt_controls) {
-   ca0132_alt_add_svm_enum(codec);
-   add_ca0132_alt_eq_presets(codec);
+   err = ca0132_alt_add_svm_enum(codec);
+   if (err < 0)
+   return err;
+
+   err = add_ca0132_alt_eq_presets(codec);
+   if (err < 0)
+   return err;
+
err = add_fx_switch(codec, PLAY_ENHANCEMENT,
"Enable OutFX", 0);
if (err < 0)
@@ -6430,7 +6437,9 @@ static int ca0132_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
}
-   add_voicefx(codec);
+   err = add_voicefx(codec);
+   if (err < 0)
+   return err;
 
/*
 * If the codec uses alt_functions, you need the enumerated controls
@@ -6438,23 +6447,37 @@ static int ca0132_build_controls(struct hda_codec 
*codec)
 * setting control.
 */
if (spec->use_alt_functions) {
-   ca0132_alt_add_output_enum(codec);
-   ca0132_alt_add_mic_boost_enum(codec);
+   err = ca0132_alt_add_output_enum(codec);
+   if (err < 0)
+   return err;
+   err = ca0132_alt_add_mic_boost_enum(codec);
+   if (err < 0)
+   return err;
/*
 * ZxR only has microphone input, there is no front panel
 * header on the card, and aux-in is handled by the DBPro board.
 */
-   if (spec->quirk != QUIRK_ZXR)
-   ca0132_alt_add_input_enum(codec);
+   if (spec->quirk != QUIRK_ZXR) {
+   err = ca0132_alt_add_input_enum(codec);
+   if (err < 0)
+   return err;
+   }
}
 
if (spec->quirk == QUIRK_AE5) {
-   ae5_add_headphone_gain_enum(codec);
-   ae5_add_sound_filter_enum(codec);
+   err = ae5_add_headphone_gain_enum(codec);
+   if (err < 0)
+   return err;
+   err = ae5_add_sound_filter_enum(codec);
+   if (err < 0)
+   return err;
}
 
-   if (spec->quirk == QUIRK_ZXR)
-   zxr_add_headphone_gain_switch(codec);
+   if (spec->quirk == QUIRK_ZXR) {
+   err = zxr_add_headphone_gain_switch(codec);
+   if (err < 0)
+   return err;
+   }
 #ifdef ENABLE_TUNING_CONTROLS
add_tuning_ctls(codec);
 #endif
-- 
2.7.4



[PATCH 1/4] ALSA: hda/ca0132 - Fix microphone inconsistency issues

2018-10-08 Thread Connor McAdams
This patch fixes microphone inconsistency issues by adding a delay to
each setup_defaults function. Without this, the microphone only works
intermittently.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index b098504..12a3581 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7223,6 +7223,8 @@ static void r3d_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
+   msleep(100);
+
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7267,6 +7269,8 @@ static void sbz_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
+   msleep(100);
+
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7324,6 +7328,8 @@ static void ae5_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
+   msleep(100);
+
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
-- 
2.7.4



[PATCH 0/4] Various cleanup + Mic Fix

2018-10-08 Thread Connor McAdams
This patch set fixes the microphone inconsistency issue, which means
the microphone now works all the time on all of the cards I've tested
(ZxR, Z, AE-5), along with the input effects.

It also includes changes suggested by Takashi Sakamoto, I believe I did
what he asked properly, but if I messed it up I'm sure you guys will
let me know.

This should finish up most of the ca0132 work, with all inputs and
outputs working on the desktop cards.

Connor McAdams (4):
  ALSA: hda/ca0132 - Fix microphone inconsistency issues
  ALSA: hda/ca0132 - Clean up patch_ca0132()
  ALSA: hda/ca0132 - Add error checking in ca0132_build_controls()
  ALSA: hda/ca0132 - Fix input effect controls for desktop cards

 sound/pci/hda/patch_ca0132.c | 75 +++-
 1 file changed, 54 insertions(+), 21 deletions(-)

-- 
2.7.4



[PATCH 1/4] ALSA: hda/ca0132 - Fix microphone inconsistency issues

2018-10-08 Thread Connor McAdams
This patch fixes microphone inconsistency issues by adding a delay to
each setup_defaults function. Without this, the microphone only works
intermittently.

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index b098504..12a3581 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -7223,6 +7223,8 @@ static void r3d_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
+   msleep(100);
+
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7267,6 +7269,8 @@ static void sbz_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
+   msleep(100);
+
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
@@ -7324,6 +7328,8 @@ static void ae5_setup_defaults(struct hda_codec *codec)
int num_fx;
int idx, i;
 
+   msleep(100);
+
if (spec->dsp_state != DSP_DOWNLOADED)
return;
 
-- 
2.7.4



[PATCH 0/4] Various cleanup + Mic Fix

2018-10-08 Thread Connor McAdams
This patch set fixes the microphone inconsistency issue, which means
the microphone now works all the time on all of the cards I've tested
(ZxR, Z, AE-5), along with the input effects.

It also includes changes suggested by Takashi Sakamoto, I believe I did
what he asked properly, but if I messed it up I'm sure you guys will
let me know.

This should finish up most of the ca0132 work, with all inputs and
outputs working on the desktop cards.

Connor McAdams (4):
  ALSA: hda/ca0132 - Fix microphone inconsistency issues
  ALSA: hda/ca0132 - Clean up patch_ca0132()
  ALSA: hda/ca0132 - Add error checking in ca0132_build_controls()
  ALSA: hda/ca0132 - Fix input effect controls for desktop cards

 sound/pci/hda/patch_ca0132.c | 75 +++-
 1 file changed, 54 insertions(+), 21 deletions(-)

-- 
2.7.4



[PATCH 3/4] ALSA: hda/ca0132 - Add error checking in ca0132_build_controls()

2018-10-08 Thread Connor McAdams
This patch adds error checking to functions creating controls inside of
ca0132_build_controls().

Signed-off-by: Connor McAdams 
---
 sound/pci/hda/patch_ca0132.c | 47 +---
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
index 07d50d6..693b063 100644
--- a/sound/pci/hda/patch_ca0132.c
+++ b/sound/pci/hda/patch_ca0132.c
@@ -6365,7 +6365,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
NULL, ca0132_alt_slave_pfxs,
"Playback Switch",
true, >vmaster_mute.sw_kctl);
-
+   if (err < 0)
+   return err;
}
 
/* Add in and out effects controls.
@@ -6392,8 +6393,14 @@ static int ca0132_build_controls(struct hda_codec *codec)
 * prefix, and change PlayEnhancement and CrystalVoice to match.
 */
if (spec->use_alt_controls) {
-   ca0132_alt_add_svm_enum(codec);
-   add_ca0132_alt_eq_presets(codec);
+   err = ca0132_alt_add_svm_enum(codec);
+   if (err < 0)
+   return err;
+
+   err = add_ca0132_alt_eq_presets(codec);
+   if (err < 0)
+   return err;
+
err = add_fx_switch(codec, PLAY_ENHANCEMENT,
"Enable OutFX", 0);
if (err < 0)
@@ -6430,7 +6437,9 @@ static int ca0132_build_controls(struct hda_codec *codec)
if (err < 0)
return err;
}
-   add_voicefx(codec);
+   err = add_voicefx(codec);
+   if (err < 0)
+   return err;
 
/*
 * If the codec uses alt_functions, you need the enumerated controls
@@ -6438,23 +6447,37 @@ static int ca0132_build_controls(struct hda_codec 
*codec)
 * setting control.
 */
if (spec->use_alt_functions) {
-   ca0132_alt_add_output_enum(codec);
-   ca0132_alt_add_mic_boost_enum(codec);
+   err = ca0132_alt_add_output_enum(codec);
+   if (err < 0)
+   return err;
+   err = ca0132_alt_add_mic_boost_enum(codec);
+   if (err < 0)
+   return err;
/*
 * ZxR only has microphone input, there is no front panel
 * header on the card, and aux-in is handled by the DBPro board.
 */
-   if (spec->quirk != QUIRK_ZXR)
-   ca0132_alt_add_input_enum(codec);
+   if (spec->quirk != QUIRK_ZXR) {
+   err = ca0132_alt_add_input_enum(codec);
+   if (err < 0)
+   return err;
+   }
}
 
if (spec->quirk == QUIRK_AE5) {
-   ae5_add_headphone_gain_enum(codec);
-   ae5_add_sound_filter_enum(codec);
+   err = ae5_add_headphone_gain_enum(codec);
+   if (err < 0)
+   return err;
+   err = ae5_add_sound_filter_enum(codec);
+   if (err < 0)
+   return err;
}
 
-   if (spec->quirk == QUIRK_ZXR)
-   zxr_add_headphone_gain_switch(codec);
+   if (spec->quirk == QUIRK_ZXR) {
+   err = zxr_add_headphone_gain_switch(codec);
+   if (err < 0)
+   return err;
+   }
 #ifdef ENABLE_TUNING_CONTROLS
add_tuning_ctls(codec);
 #endif
-- 
2.7.4



Re: [PATCH 00/11] Add ZxR support + bugfixes

2018-10-07 Thread Connor McAdams
I have fixed the microphone issue, and will try to get the patches
written by the end of the week so they can be in the next kernel (at
least I think that's what Takashi Sakamoto said, two weeks from 7 days
ago). With the two suggestions by Takashi Sakamoto, do I need those in
order for it to be merged? I will work on them regardless, but with
those it may take me longer (they might be simple, I haven't dug into
what they require yet).

Let me know.

Thanks,
Connor.
On Tue, Oct 2, 2018 at 11:23 AM Takashi Iwai  wrote:
>
> On Sun, 30 Sep 2018 05:03:15 +0200,
> Connor McAdams wrote:
> >
> > This patch series adds support for the Sound Blaster ZxR, as well as a
> > few bug fixes. This should be the last ca0132 based Creative card that
> > needed support to be added.
> >
> > Also, I did check to make sure each patch compiles properly this time,
> > but you can check yourself just to be sure. :)
> >
> > Connor McAdams (11):
> >   ALSA: hda/ca0132 - Fix AE-5 control type
> >   ALSA: hda/ca0132 - Fix surround sound with output effects
> >   ALSA: hda/ca0132 - Add ZxR quirks + new quirk check function
> >   ALSA: hda/ca0132 - Add ZxR pincfg
> >   ALSA: hda/ca0132 - Add DBpro hda_codec_ops
> >   ALSA: hda/ca0132 - Add ZxR init commands
> >   ALSA: hda/ca0132 - Add ZxR DSP post-download commands
> >   ALSA: hda/ca0132 - Add ZxR input/output select commands
> >   ALSA: hda/ca0132 - Remove input select enum for ZxR
> >   ALSA: hda/ca0132 - Add ZxR 600 ohm gain control
> >   ALSA: hda/ca0132 - Add ZxR exit commands
>
> Now applied all 11 patches (with Sakamoto-san's Reviewed-by tags).
> Thanks!
>
>
> Takashi


Re: [PATCH 00/11] Add ZxR support + bugfixes

2018-10-07 Thread Connor McAdams
I have fixed the microphone issue, and will try to get the patches
written by the end of the week so they can be in the next kernel (at
least I think that's what Takashi Sakamoto said, two weeks from 7 days
ago). With the two suggestions by Takashi Sakamoto, do I need those in
order for it to be merged? I will work on them regardless, but with
those it may take me longer (they might be simple, I haven't dug into
what they require yet).

Let me know.

Thanks,
Connor.
On Tue, Oct 2, 2018 at 11:23 AM Takashi Iwai  wrote:
>
> On Sun, 30 Sep 2018 05:03:15 +0200,
> Connor McAdams wrote:
> >
> > This patch series adds support for the Sound Blaster ZxR, as well as a
> > few bug fixes. This should be the last ca0132 based Creative card that
> > needed support to be added.
> >
> > Also, I did check to make sure each patch compiles properly this time,
> > but you can check yourself just to be sure. :)
> >
> > Connor McAdams (11):
> >   ALSA: hda/ca0132 - Fix AE-5 control type
> >   ALSA: hda/ca0132 - Fix surround sound with output effects
> >   ALSA: hda/ca0132 - Add ZxR quirks + new quirk check function
> >   ALSA: hda/ca0132 - Add ZxR pincfg
> >   ALSA: hda/ca0132 - Add DBpro hda_codec_ops
> >   ALSA: hda/ca0132 - Add ZxR init commands
> >   ALSA: hda/ca0132 - Add ZxR DSP post-download commands
> >   ALSA: hda/ca0132 - Add ZxR input/output select commands
> >   ALSA: hda/ca0132 - Remove input select enum for ZxR
> >   ALSA: hda/ca0132 - Add ZxR 600 ohm gain control
> >   ALSA: hda/ca0132 - Add ZxR exit commands
>
> Now applied all 11 patches (with Sakamoto-san's Reviewed-by tags).
> Thanks!
>
>
> Takashi


  1   2   3   >