Received: by 10.192.165.148 with SMTP id m20csp4565598imm; Tue, 8 May 2018 10:24:38 -0700 (PDT) X-Google-Smtp-Source: AB8JxZpAiUUfdWSofnHOYULRRJJWLoNhOG1kLI7h5kCYYIbGxeisMtCpLHG6AkQad0ilD9Bcbzi4 X-Received: by 2002:a63:6307:: with SMTP id x7-v6mr1623799pgb.269.1525800278558; Tue, 08 May 2018 10:24:38 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1525800278; cv=none; d=google.com; s=arc-20160816; b=RYcbu7gKGS0EdAqL0Sl7WQwvWSd2kIQsAQFqKUCZLBP3MYKg+vhFqvymq6n64Y7d9Z on5Gy5JNwK+z4KnRUGLzOiV8BP+Gn5MJkfEl+J9FBc+mgcJqrtIuOpZNzas6iQZodQ29 8wXHXCIB5L3JMrEQNCGfD/Wn21Cf54y1ZdRa4+9X4H6sI347Odt0p/Rkap1WkAiwW+HZ HrvCQqrRVkz9VHc9efg/6vZVP6K4tTsX2IATWAdSUh/RxBj8lzMbWEdbapOF1DtjjwrP 2Z3JT6CSiL4JGpSCvVAopX2QxeeIbO2k9bKsqTybB1Ad2bY/hLYhhh+caZriUJSw/KD1 xIkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:to:references:in-reply-to:message-id:date :subject:cc:from:dkim-signature:arc-authentication-results; bh=7JIVHHyiPci4+V240D1BKK0kSRk5l5Z+QxAQgzNwHzs=; b=tZr7mkvhfTMotgZr7HQEWZYzQ3Cl6qhgORXi/RjJ90n2asMPjU6SQqFZJt9kzMA6GO J7oo5HtiXBmbup5fWTKQ0X705JDEkasoztgEXsivo1H7Ma6siTXDrNZn2HpbryZ6Xb3h zefzGzw1YT3/xP1cV3L9skw+PWiEvyS4NOqcimqqimVABWXceGfBMiC39vuRKgTAdnwB nIXIraiSE1P2HqJ4PaS/UuHDbTjrcj0ikIp1BWuS/a0qXxERd7ySNCn+D/5421i0AlIP ccq0E/ixgbqHeD5VrOluUa/xh5iCF4OkVeZ7Wn6abwKidcgCn1a4JYgzbbQGhNxQVayX cwPw== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=qqoL1UDa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v81si9350133pfi.22.2018.05.08.10.24.23; Tue, 08 May 2018 10:24:38 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@gmail.com header.s=20161025 header.b=qqoL1UDa; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755368AbeEHRXq (ORCPT + 99 others); Tue, 8 May 2018 13:23:46 -0400 Received: from mail-io0-f196.google.com ([209.85.223.196]:45733 "EHLO mail-io0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932481AbeEHRU6 (ORCPT ); Tue, 8 May 2018 13:20:58 -0400 Received: by mail-io0-f196.google.com with SMTP id c9-v6so32987213iob.12 for ; Tue, 08 May 2018 10:20:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=7JIVHHyiPci4+V240D1BKK0kSRk5l5Z+QxAQgzNwHzs=; b=qqoL1UDah492JxvE6zDNHXCQ8pHBWLRZjAqFlrqv6ugvhUQIUDzvHhBd9m2X6gBGRV Rh+J0bLteYyHHmKDqQ09cMEDxQjlRLCqfC3mbQN/XcNcnehNCaToHo21wlBqmEzARpuC 8Pv1MyL40leVp2wf1JzaXBAc+8BaIJDgZznu/6T+Kj4AZadYmeShwpeIfc3+jzeDAax7 dOpDhL1rH9lwlG+kupxRmtGPJfZfDr9ZvJLg5WBSizqmWX8z9QpSFn242Zs44awpzLHL teqMrE9/C0LKB258aQHSxfa9d8xgimpNmIG9FY3fVOCqVtTbbAZTokPWeOSwB1+PsZwG qRPw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=7JIVHHyiPci4+V240D1BKK0kSRk5l5Z+QxAQgzNwHzs=; b=T/sK08BWPlTDC2VzE+Z/HxD0OXHSYP10j7kTYFhYWuaE5xxQo69rkc/ZkZG0huOWen n1Dh/E/foAIX4tjXExFT0cMinSqfBjiOf1GBnLs1EP/UOSuZaBQkWbiApMdP/RjmXUAb xUnKmyK+T5ptnkty56HSy3IdoeA+wW/cfFIzyjR++mUHzB8OFVSInrmgNO0ELZ1ds1WE W1JzgGe/JXpo0w2rdcbkBvxfFUK94vooNroQGx9sT/TjWhy6lfBg1Ww1oQFXA7t62bKu A7v1r2Tu0OSGykHFR0QwHSqUvlelnQv06nFXZjfQkIMJL2JNRMXTuD4jUtfuF/oxyiCu nCoQ== X-Gm-Message-State: ALQs6tC6L6Xvi7r2hiiwe11c9+xrbw0QXV1JgUi8UNrqtepKej6warZq NztmhvSHCgIESL/vVBZm6nE= X-Received: by 2002:a6b:dc12:: with SMTP id s18-v6mr48152926ioc.203.1525800057297; Tue, 08 May 2018 10:20:57 -0700 (PDT) Received: from localhost.localdomain ([2605:a000:1316:4462:80cc:335d:e307:b5cb]) by smtp.googlemail.com with ESMTPSA id k62-v6sm13160209ioo.23.2018.05.08.10.20.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 08 May 2018 10:20:56 -0700 (PDT) From: Connor McAdams Cc: o-takashi@sakamocchi.jp, Connor McAdams , Jaroslav Kysela , Takashi Iwai , =?UTF-8?q?J=C3=A9r=C3=A9my=20Lefaure?= , alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 06/13] ALSA: hda/ca0132: update core functions for sbz + r3di Date: Tue, 8 May 2018 13:20:06 -0400 Message-Id: <1525800015-2920-7-git-send-email-conmanx360@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1525800015-2920-1-git-send-email-conmanx360@gmail.com> References: <1525800015-2920-1-git-send-email-conmanx360@gmail.com> To: unlisted-recipients:; (no To-header on input) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This patch updates core functions to accommodate the Sound Blaster Z and Recon3Di by changing which functions they use. It also adds the ability to enable/disable streams. Signed-off-by: Connor McAdams --- sound/pci/hda/patch_ca0132.c | 176 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 153 insertions(+), 23 deletions(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index 5002311..31c9d42 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -770,6 +770,13 @@ struct ca0132_spec { * switching, and other unknown commands. */ void __iomem *mem_base; + + /* + * Whether or not to use the alt functions like alt_select_out, + * alt_select_in, etc. Only used on desktop codecs for now, because of + * surround sound support. + */ + bool use_alt_functions; }; /* @@ -1110,6 +1117,42 @@ static void chipio_set_control_param(struct hda_codec *codec, } /* + * Set chip parameters through the chip I/O widget. NO MUTEX. + */ +static void chipio_set_control_param_no_mutex(struct hda_codec *codec, + enum control_param_id param_id, int param_val) +{ + int val; + + if ((param_id < 32) && (param_val < 8)) { + val = (param_val << 5) | (param_id); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_SET, val); + } else { + if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) { + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_EX_ID_SET, + param_id); + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, + VENDOR_CHIPIO_PARAM_EX_VALUE_SET, + param_val); + } + } +} + +/* + * Enable/Disable audio stream. + */ +static void chipio_set_stream_control(struct hda_codec *codec, + int streamid, int enable) +{ + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_ID, streamid); + chipio_set_control_param_no_mutex(codec, + CONTROL_PARAM_STREAM_CONTROL, enable); +} + +/* * Set sampling rate of the connection point. */ static void chipio_set_conn_rate(struct hda_codec *codec, @@ -2627,14 +2670,16 @@ static int dspxfr_image(struct hda_codec *codec, */ static void dspload_post_setup(struct hda_codec *codec) { + struct ca0132_spec *spec = codec->spec; codec_dbg(codec, "---- dspload_post_setup ------\n"); + if (!spec->use_alt_functions) { + /*set DSP speaker to 2.0 configuration*/ + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080); + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000); - /*set DSP speaker to 2.0 configuration*/ - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080); - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000); - - /*update write pointer*/ - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002); + /*update write pointer*/ + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002); + } } /** @@ -3523,7 +3568,7 @@ static int ca0132_voicefx_set(struct hda_codec *codec, int enable) static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val) { struct ca0132_spec *spec = codec->spec; - unsigned int on; + unsigned int on, tmp; int num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT; int err = 0; int idx = nid - EFFECT_START_NID; @@ -3547,6 +3592,39 @@ static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val) /* Voice Focus applies to 2-ch Mic, Digital Mic */ if ((nid == VOICE_FOCUS) && (spec->cur_mic_type != DIGITAL_MIC)) val = 0; + + /* If Voice Focus on SBZ, set to two channel. */ + if ((nid == VOICE_FOCUS) && (spec->quirk == QUIRK_SBZ)) { + if (spec->effects_switch[CRYSTAL_VOICE - + EFFECT_START_NID]) { + + if (spec->effects_switch[VOICE_FOCUS - + EFFECT_START_NID]) { + tmp = FLOAT_TWO; + val = 1; + } else + tmp = FLOAT_ONE; + + dspio_set_uint_param(codec, 0x80, 0x00, tmp); + } + } + /* + * 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 (spec->effects_switch[CRYSTAL_VOICE - + EFFECT_START_NID]) { + if (spec->effects_switch[NOISE_REDUCTION - + EFFECT_START_NID]) + tmp = FLOAT_ONE; + else + tmp = FLOAT_ZERO; + } else + tmp = FLOAT_ZERO; + + dspio_set_uint_param(codec, 0x47, 0x00, tmp); + } } codec_dbg(codec, "ca0132_effect_set: nid=0x%x, val=%ld\n", @@ -4181,12 +4259,16 @@ static int ca0132_build_pcms(struct hda_codec *codec) info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0]; - info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2"); - if (!info) - return -ENOMEM; - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture; - info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; + /* With the DSP enabled, desktops don't use this ADC. */ + if (spec->use_alt_functions) { + info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2"); + if (!info) + return -ENOMEM; + info->stream[SNDRV_PCM_STREAM_CAPTURE] = + ca0132_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1]; + } info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear"); if (!info) @@ -4441,12 +4523,32 @@ static void ca0132_setup_defaults(struct hda_codec *codec) */ static void ca0132_init_flags(struct hda_codec *codec) { - chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_COMMON_MODE, 0); - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_COMMON_MODE, 0); - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0); - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); - chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1); + struct ca0132_spec *spec = codec->spec; + + if (spec->use_alt_functions) { + chipio_set_control_flag(codec, CONTROL_FLAG_DSP_96KHZ, 1); + chipio_set_control_flag(codec, CONTROL_FLAG_DAC_96KHZ, 1); + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_B_96KHZ, 1); + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_96KHZ, 1); + chipio_set_control_flag(codec, CONTROL_FLAG_SRC_RATE_96KHZ, 1); + chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); + chipio_set_control_flag(codec, CONTROL_FLAG_SPDIF2OUT, 0); + chipio_set_control_flag(codec, + CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); + chipio_set_control_flag(codec, + CONTROL_FLAG_PORT_A_10KOHM_LOAD, 1); + } else { + chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0); + chipio_set_control_flag(codec, + CONTROL_FLAG_PORT_A_COMMON_MODE, 0); + chipio_set_control_flag(codec, + CONTROL_FLAG_PORT_D_COMMON_MODE, 0); + chipio_set_control_flag(codec, + CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0); + chipio_set_control_flag(codec, + CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0); + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1); + } } /* @@ -4454,6 +4556,16 @@ static void ca0132_init_flags(struct hda_codec *codec) */ static void ca0132_init_params(struct hda_codec *codec) { + struct ca0132_spec *spec = codec->spec; + + if (spec->use_alt_functions) { + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000); + chipio_set_conn_rate(codec, 0x0B, SR_48_000); + chipio_set_control_param(codec, CONTROL_PARAM_SPDIF1_SOURCE, 0); + chipio_set_control_param(codec, 0, 0); + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0); + } + chipio_set_control_param(codec, CONTROL_PARAM_PORTA_160OHM_GAIN, 6); chipio_set_control_param(codec, CONTROL_PARAM_PORTD_160OHM_GAIN, 6); } @@ -4554,7 +4666,8 @@ static void ca0132_download_dsp(struct hda_codec *codec) spec->dsp_state = DSP_DOWNLOADED; } - if (spec->dsp_state == DSP_DOWNLOADED) + /* For codecs using alt functions, this is already done earlier */ + if (spec->dsp_state == DSP_DOWNLOADED && (!spec->use_alt_functions)) ca0132_set_dsp_msr(codec, true); } @@ -4601,7 +4714,7 @@ static void ca0132_init_unsol(struct hda_codec *codec) snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP, ca0132_process_dsp_response); /* Front headphone jack detection */ - if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3DI) + if (spec->use_alt_functions) snd_hda_jack_detect_enable_callback(codec, spec->unsol_tag_front_hp, hp_callback); } @@ -4794,12 +4907,16 @@ static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir, static void sbz_exit_chip(struct hda_codec *codec) { + chipio_set_stream_control(codec, 0x03, 0); + chipio_set_stream_control(codec, 0x04, 0); /* Mess with GPIO */ sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1); sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05); sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01); + chipio_set_stream_control(codec, 0x14, 0); + chipio_set_stream_control(codec, 0x0C, 0); chipio_set_conn_rate(codec, 0x41, SR_192_000); chipio_set_conn_rate(codec, 0x91, SR_192_000); @@ -4810,6 +4927,7 @@ static void sbz_exit_chip(struct hda_codec *codec) sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07); sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06); + chipio_set_stream_control(codec, 0x0C, 0); chipio_set_control_param(codec, 0x0D, 0x24); @@ -5027,7 +5145,7 @@ static int ca0132_init(struct hda_codec *codec) init_input(codec, cfg->dig_in_pin, spec->dig_in); - if (spec->quirk == QUIRK_ALIENWARE || spec->quirk == QUIRK_NONE) { + if (!spec->use_alt_functions) { snd_hda_sequence_write(codec, spec->chip_init_verbs); snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, VENDOR_CHIPIO_PARAM_EX_ID_SET, 0x0D); @@ -5112,7 +5230,7 @@ static void ca0132_config(struct hda_codec *codec) spec->multiout.dac_nids = spec->dacs; spec->multiout.num_dacs = 3; - if (spec->quirk == QUIRK_NONE || spec->quirk == QUIRK_ALIENWARE) + if (!spec->use_alt_functions) spec->multiout.max_channels = 2; else spec->multiout.max_channels = 6; @@ -5314,10 +5432,22 @@ static int patch_ca0132(struct hda_codec *codec) spec->quirk = QUIRK_NONE; } } + spec->dsp_state = DSP_DOWNLOAD_INIT; spec->num_mixers = 1; spec->mixers[0] = ca0132_mixer; + /* Setup whether or not to use alt functions */ + switch (spec->quirk) { + case QUIRK_SBZ: + case QUIRK_R3DI: + spec->use_alt_functions = true; + break; + default: + spec->use_alt_functions = false; + break; + } + spec->base_init_verbs = ca0132_base_init_verbs; spec->base_exit_verbs = ca0132_base_exit_verbs; -- 2.7.4